1 #+TITLE: System Configuration
2 #+DESCRIPTION: Personal system configuration in org-mode format.
3 #+AUTHOR: Armaan Bhojwani
4 #+EMAIL: me@armaanb.net
7 Welcome to my system configuration! This file contains my Emacs configuration, but also my config files for many of the other programs on my system!
9 I am currently using GCCEmacs 28 from the feature/native-comp branch, so some settings may not be available for older versions of Emacs. This is a purely personal configuration, so while I can garuntee that it works on my setup, I can't for anything else.
11 I chose to create a powerful, yet not overly heavy Emacs configuration. Things like LSP mode are important to my workflow and help me be productive, so despite its weight, it is kept. Things like a fancy modeline or icons on the other hand, do not increase my productivity, and create visual clutter, and thus have been excluded.
13 Another important choice has been to integrate Emacs into a large part of my computing environment (see [[*EmacsOS]]). I use Email, IRC, et cetera, all through Emacs which simplifies my workflow.
15 Lastly, I use Evil mode. I think modal keybindings are simple and more ergonomic than standard Emacs style, and Vim keybindings are what I'm comfortable with and are pervasive throughout computing.
17 *** TODO Turn keybinding and hook declarations into use-package declarations where possible
18 *** TODO Include offlineimap config
20 Released under the [[https://opensource.org/licenses/MIT][MIT license]] by Armaan Bhojwani, 2021. Note that many snippets are taken from online, and other sources, who are credited for their work at the snippet.
22 ** Bootstrap straight.el
23 straight.el is really nice for managing package, and it integrates nicely with use-package. It uses the bootstrapping system defined here for installation.
24 #+begin_src emacs-lisp
25 (defvar bootstrap-version)
27 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
28 (bootstrap-version 5))
29 (unless (file-exists-p bootstrap-file)
31 (url-retrieve-synchronously
32 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
33 'silent 'inhibit-cookies)
34 (goto-char (point-max))
35 (eval-print-last-sexp)))
36 (load bootstrap-file nil 'nomessage))
38 ** Replace use-package with straight
39 #+begin_src emacs-lisp
40 (straight-use-package 'use-package)
41 (setq straight-use-package-by-default t)
45 Very nice high contrast theme.
47 Its fine to set this here because I run Emacs in daemon mode, but if I were not, then putting it in early-init.el would be a better choice to eliminate the window being white before the theme is loaded.
48 #+begin_src emacs-lisp
49 (setq modus-themes-slanted-constructs t
50 modus-themes-bold-constructs t
51 modus-themes-mode-line '3d
52 modus-themes-scale-headings t
53 modus-themes-diffs 'desaturated)
54 (load-theme 'modus-vivendi t)
58 Great programming font with ligatures.
59 #+begin_src emacs-lisp
60 (add-to-list 'default-frame-alist '(font . "JetBrainsMonoNF-12"))
63 #+begin_src emacs-lisp
65 :straight (ligature :type git :host github :repo "mickeynp/ligature.el")
67 (ligature-set-ligatures
68 '(prog-mode text-mode)
69 '("-|" "-~" "---" "-<<" "-<" "--" "->" "->>" "-->" "/=" "/=="
70 "/>" "//" "/*" "*>" "*/" "<-" "<<-" "<=>" "<=" "<|" "<||"
71 "<|||" "<|>" "<:" "<>" "<-<" "<<<" "<==" "<<=" "<=<" "<==>"
72 "<-|" "<<" "<~>" "<=|" "<~~" "<~" "<$>" "<$" "<+>" "<+" "</>"
73 "</" "<*" "<*>" "<->" "<!--" ":>" ":<" ":::" "::" ":?" ":?>"
74 ":=" "::=" "=>>" "==>" "=/=" "=!=" "=>" "===" "=:=" "==" "!=="
75 "!!" "!=" ">]" ">:" ">>-" ">>=" ">=>" ">>>" ">-" ">=" "&&&"
76 "&&" "|||>" "||>" "|>" "|]" "|}" "|=>" "|->" "|=" "||-" "|-"
77 "||=" "||" ".." ".?" ".=" ".-" "..<" "..." "+++" "+>" "++"
78 "[||]" "[<" "[|" "{|" "?." "?=" "?:" "##" "###" "####" "#["
79 "#{" "#=" "#!" "#:" "#_(" "#_" "#?" "#(" ";;" "_|_" "__" "~~"
80 "~~>" "~>" "~-" "~@" "$>" "^=" "]#"))
81 (global-ligature-mode t))
84 Display relative line numbers except in some modes
85 #+begin_src emacs-lisp
86 (global-display-line-numbers-mode)
87 (setq display-line-numbers-type 'relative)
88 (dolist (no-line-num '(term-mode-hook
93 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
95 ** Highlight matching parenthesis
96 #+begin_src emacs-lisp
98 :config (show-paren-mode)
99 :custom (show-paren-style 'parenthesis))
102 *** Show current function
103 #+begin_src emacs-lisp
104 (which-function-mode)
106 *** Make position in file more descriptive
107 Show current column and file size.
108 #+begin_src emacs-lisp
110 (size-indication-mode)
113 #+begin_src emacs-lisp
115 :config (minions-mode))
118 Show a ruler at a certain number of chars depending on mode.
119 #+begin_src emacs-lisp
120 (setq display-fill-column-indicator-column 80)
121 (global-display-fill-column-indicator-mode)
124 Whenever starting a key chord, show possible future steps.
125 #+begin_src emacs-lisp
126 (use-package which-key
127 :config (which-key-mode)
128 :custom (which-key-idle-delay 0.3))
130 ** Highlight TODOs in comments
131 #+begin_src emacs-lisp
133 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
134 :config (global-hl-todo-mode 1))
137 #+begin_src emacs-lisp
141 Soft wrap words and do operations by visual lines.
142 #+begin_src emacs-lisp
143 (add-hook 'text-mode-hook 'visual-line-mode 1)
145 ** Display number of matches in search
146 #+begin_src emacs-lisp
148 :config (global-anzu-mode))
151 Inverts modeline instead of audible bell or the standard visual bell.
152 #+begin_src emacs-lisp
153 (setq visible-bell nil
155 (lambda () (invert-face 'mode-line)
156 (run-with-timer 0.1 nil #'invert-face 'mode-line)))
160 #+begin_src emacs-lisp
162 :custom (select-enable-clipboard nil)
165 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
166 ;; Use visual line motions even outside of visual-line-mode buffers
167 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
168 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
169 (global-set-key (kbd "<escape>") 'keyboard-escape-quit))
172 #+begin_src emacs-lisp
173 (use-package evil-collection
175 :init (evil-collection-init)
176 :custom (evil-collection-setup-minibuffer t))
180 #+begin_src emacs-lisp
181 (use-package evil-surround
182 :config (global-evil-surround-mode))
185 #+begin_src emacs-lisp
186 (use-package evil-leader
187 :straight (evil-leader :type git :host github :repo "cofi/evil-leader")
189 (evil-leader/set-leader "<SPC>")
190 (global-evil-leader-mode))
193 #+begin_src emacs-lisp
195 (use-package evil-nerd-commenter
196 :bind (:map evil-normal-state-map
197 ("gc" . evilnc-comment-or-uncomment-lines))
198 :custom (evilnc-invert-comment-line-by-line nil))
202 #+begin_src emacs-lisp
203 (evil-set-undo-system 'undo-redo)
205 ** Number incrementing
207 #+begin_src emacs-lisp
208 (use-package evil-numbers
209 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
210 :bind (:map evil-normal-state-map
211 ("C-M-a" . evil-numbers/inc-at-pt)
212 ("C-M-x" . evil-numbers/dec-at-pt)))
216 #+begin_src emacs-lisp
217 (use-package evil-org
219 :hook (org-mode . evil-org-mode)
221 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
222 (use-package evil-org-agenda
223 :straight (:type built-in)
225 :config (evil-org-agenda-set-keys))
228 #+begin_src emacs-lisp
229 (evil-leader/set-key-for-mode 'org-mode
230 "T" 'org-show-todo-tree
232 "c" 'org-archive-subtree)
236 #+begin_src emacs-lisp
238 :straight (:type built-in)
239 :commands (org-capture org-agenda)
241 (org-ellipsis " â–¾")
242 (org-agenda-start-with-log-mode t)
243 (org-agenda-files (quote ("~/Org/tasks.org" "~/Org/break.org")))
245 (org-log-into-drawer t)
246 (org-src-tab-acts-natively t)
247 (org-src-fontify-natively t)
248 (org-startup-indented t)
249 (org-hide-emphasis-markers t)
250 (org-fontify-whole-block-delimiter-line nil)
251 :bind ("C-c a" . org-agenda))
254 #+begin_src emacs-lisp
255 (use-package org-tempo
257 :straight (:type built-in)
259 ;; TODO: There's gotta be a more efficient way to write this
260 (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
261 (add-to-list 'org-structure-template-alist '("sp" . "src conf :tangle ~/.spectrwm.conf"))
262 (add-to-list 'org-structure-template-alist '("ash" . "src shell :tangle ~/.config/ash/ashrc"))
263 (add-to-list 'org-structure-template-alist '("ipy" . "src python :tangle ~/.ipython/"))
264 (add-to-list 'org-structure-template-alist '("pi" . "src conf :tangle ~/.config/picom/picom.conf"))
265 (add-to-list 'org-structure-template-alist '("git" . "src conf :tangle ~/.gitconfig"))
266 (add-to-list 'org-structure-template-alist '("du" . "src conf :tangle ~/.config/dunst/dunstrc"))
267 (add-to-list 'org-structure-template-alist '("za" . "src conf :tangle ~/.config/zathura/zathurarc"))
268 (add-to-list 'org-structure-template-alist '("ff1" . "src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css"))
269 (add-to-list 'org-structure-template-alist '("ff2" . "src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userContent.css"))
270 (add-to-list 'org-structure-template-alist '("xr" . "src conf :tangle ~/.Xresources"))
271 (add-to-list 'org-structure-template-alist '("tm" . "src conf :tangle ~/.tmux.conf"))
272 (add-to-list 'org-structure-template-alist '("gp" . "src conf :tangle ~/.gnupg/gpg.conf"))
273 (add-to-list 'org-structure-template-alist '("ag" . "src conf :tangle ~/.gnupg/gpg-agent.conf")))
277 Simple, but not too simple autocompletion.
278 #+begin_src emacs-lisp
280 :bind (("C-s" . swiper)
281 :map ivy-minibuffer-map
282 ("TAB" . ivy-alt-done)
283 :map ivy-switch-buffer-map
284 ("M-d" . ivy-switch-buffer-kill))
288 #+begin_src emacs-lisp
289 (use-package ivy-rich
291 :config (ivy-rich-mode))
295 #+begin_src emacs-lisp
297 :bind (("C-M-j" . 'counsel-switch-buffer)
298 :map minibuffer-local-map
299 ("C-r" . 'counsel-minibuffer-history))
300 :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
301 :config (counsel-mode))
303 ** Remember frequent commands
304 #+begin_src emacs-lisp
305 (use-package ivy-prescient
307 :custom (ivy-prescient-enable-filtering nil)
309 (prescient-persist-mode)
310 (ivy-prescient-mode))
313 Better search utility.
314 #+begin_src emacs-lisp
319 Use elfeed for RSS. I have another file with all the feeds in it.
320 #+begin_src emacs-lisp
322 :bind (("C-c e" . elfeed))
324 (load "~/.emacs.d/feeds.el")
325 (add-hook 'elfeed-new-entry-hook
326 (elfeed-make-tagger :feed-url "youtube\\.com"
328 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
330 (use-package elfeed-goodies
332 :config (elfeed-goodies/setup))
335 Use mu4e for reading emails.
337 I use `offlineimap` to sync my maildirs. It is slower than mbsync, but is fast enough for me, especially when ran with the =-q= option.
339 Contexts are a not very well known feature of mu4e that makes it super easy to manage multiple accounts. Much better than some of the hacky methods and external packages that I've seen.
340 #+begin_src emacs-lisp
341 (use-package smtpmail
342 :straight (:type built-in))
344 :load-path "/usr/share/emacs/site-lisp/mu4e"
345 :straight (:build nil)
346 :bind (("C-c m" . mu4e))
348 (setq user-full-name "Armaan Bhojwani"
349 smtpmail-local-domain "armaanb.net"
350 smtpmail-stream-type 'ssl
351 smtpmail-smtp-service '465
352 mu4e-change-filenames-when-moving t
353 mu4e-get-mail-command "offlineimap -q"
354 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
355 message-citation-line-function 'message-insert-formatted-citation-line
356 mu4e-completing-read-function 'ivy-completing-read
357 mu4e-confirm-quit nil
359 mail-user-agent 'mu4e-user-agent
360 mail-context-policy 'pick-first
362 `( ,(make-mu4e-context
364 :enter-func (lambda () (mu4e-message "Entering school context"))
365 :leave-func (lambda () (mu4e-message "Leaving school context"))
366 :match-func (lambda (msg)
368 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
369 :vars '((user-mail-address . "abhojwani22@nobles.edu")
370 (mu4e-sent-folder . "/school/Sent")
371 (mu4e-drafts-folder . "/school/Drafts")
372 (mu4e-trash-folder . "/school/Trash")
373 (mu4e-refile-folder . "/school/Archive")
374 (message-cite-reply-position . above)
375 (user-mail-address . "abhojwani22@nobles.edu")
376 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
377 (smtpmail-smtp-server . "smtp.gmail.com")))
380 :enter-func (lambda () (mu4e-message "Entering personal context"))
381 :leave-func (lambda () (mu4e-message "Leaving personal context"))
382 :match-func (lambda (msg)
384 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
385 :vars '((mu4e-sent-folder . "/personal/Sent")
386 (mu4e-drafts-folder . "/personal/Drafts")
387 (mu4e-trash-folder . "/personal/Trash")
388 (mu4e-refile-folder . "/personal/Archive")
389 (user-mail-address . "me@armaanb.net")
390 (message-cite-reply-position . below)
391 (smtpmail-smtp-user . "me@armaanb.net")
392 (smtpmail-smtp-server . "smtp.mailbox.org")))))
393 (add-to-list 'mu4e-bookmarks
394 '(:name "Unified inbox"
395 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
397 :hook ((mu4e-compose-mode . flyspell-mode)
398 (mu4e-compose-mode . auto-fill-mode)
399 (mu4e-view-mode-hook . turn-on-visual-line-mode)
400 (message-send-hook . (lambda () (unless (yes-or-no-p "Ya sure 'bout that?")
401 (signal 'quit nil))))))
403 Discourage Gnus from displaying HTML emails
404 #+begin_src emacs-lisp
405 (with-eval-after-load "mm-decode"
406 (add-to-list 'mm-discouraged-alternatives "text/html")
407 (add-to-list 'mm-discouraged-alternatives "text/richtext"))
410 Set EWW as default browser except for videos.
411 #+begin_src emacs-lisp
412 (defun browse-url-mpv (url &optional new-window)
414 (start-process "mpv" "*mpv*" "mpv" url))
416 (setq browse-url-handlers
418 (("youtu\\.?be" . browse-url-mpv)
419 ("peertube.*" . browse-url-mpv)
420 ("vid.*" . browse-url-mpv)
421 ("vid.*" . browse-url-mpv)
422 ("." . eww-browse-url)
426 Some EWW enhancements.
427 *** Give buffer a useful name
428 #+begin_src emacs-lisp
429 ;; From https://protesilaos.com/dotemacs/
430 (defun prot-eww--rename-buffer ()
431 "Rename EWW buffer using page title or URL.
432 To be used by `eww-after-render-hook'."
433 (let ((name (if (eq "" (plist-get eww-data :title))
434 (plist-get eww-data :url)
435 (plist-get eww-data :title))))
436 (rename-buffer (format "*%s # eww*" name) t)))
439 :straight (:type built-in)
440 :bind (("C-c w" . eww))
441 :hook (eww-after-render-hook prot-eww--rename-buffer))
444 #+begin_src emacs-lisp
445 (global-set-key (kbd "C-c w") 'eww)
448 Circe is a really nice IRC client, that claims to be above RCIRC and below ERC in terms of features. ERC felt a bit messy and finicky to me, and Circe has all the features that I need. This setup gets the password for my bouncer (Pounce) instances via my =~/.authinfo.gpg= file.
449 #+begin_src emacs-lisp
450 (defun fetch-password (&rest params)
451 (require 'auth-source)
452 (let ((match (car (apply 'auth-source-search params))))
454 (let ((secret (plist-get match :secret)))
455 (if (functionp secret)
458 (error "Password not found for %S" params))))
463 (enable-circe-color-nicks)
467 (setq circe-networks '(("libera"
468 :host "irc.armaanb.net"
473 :pass (lambda (null) (fetch-password
475 :machine "irc.armaanb.net"
478 :host "irc.armaanb.net"
483 :pass (lambda (null) (fetch-password
485 :machine "irc.armaanb.net"
488 :host "irc.armaanb.net"
493 :pass (lambda (null) (fetch-password
495 :machine "irc.armaanb.net"
498 :custom (circe-default-part-message "goodbye!")
499 :bind (:map circe-mode-map ("C-c C-r" . circe-reconnect-all)))
502 #+begin_src emacs-lisp
503 (defun sync-calendar ()
504 "Sync calendars with vdirsyncer"
506 (shell-command "vdirsyncer -vcritical sync"))
509 :bind (:map cfw:calendar-mode-map ("C-S-u" . sync-calendar)))
510 (use-package calfw-ical)
511 (use-package calfw-org)
513 (defun acheam-calendar ()
516 (cfw:open-calendar-buffer
517 :contents-sources (list
518 (cfw:org-create-source "Green")
519 (cfw:ical-create-source
521 "~/.local/share/vdirsyncer/mailbox/Y2FsOi8vMC8zMQ.ics"
523 (cfw:ical-create-source
525 "~/.local/share/vdirsyncer/mailbox/Y2FsOi8vMC8zMQ.ics"
527 (cfw:ical-create-source
529 "~/.local/share/vdirsyncer/school/abhojwani22@nobles.edu.ics"
532 (global-set-key (kbd "C-c c") 'acheam-calendar)
536 #+begin_src emacs-lisp
538 :hook (python-mode . blacken-mode)
539 :config (setq blacken-line-length 79))
542 (use-package ws-butler
543 :config (ws-butler-global-mode))
546 #+begin_src emacs-lisp
547 (use-package flycheck
548 :config (global-flycheck-mode))
550 ** Project management
551 #+begin_src emacs-lisp
552 (use-package projectile
553 :config (projectile-mode)
554 :custom ((projectile-completion-system 'ivy))
556 ("C-c p" . projectile-command-map)
558 (when (file-directory-p "~/Code")
559 (setq projectile-project-search-path '("~/Code")))
560 (setq projectile-switch-project-action #'projectile-dired))
562 (use-package counsel-projectile
564 :config (counsel-projectile-mode))
567 #+begin_src emacs-lisp
569 :straight (:type built-in)
570 :commands (dired dired-jump)
571 :custom ((dired-listing-switches "-agho --group-directories-first"))
572 :config (evil-collection-define-key 'normal 'dired-mode-map
573 "h" 'dired-single-up-directory
574 "l" 'dired-single-buffer))
576 (use-package dired-single
577 :commands (dired dired-jump))
579 (use-package dired-open
580 :commands (dired dired-jump)
581 :custom (dired-open-extensions '(("png" . "feh")
584 (use-package dired-hide-dotfiles
585 :hook (dired-mode . dired-hide-dotfiles-mode)
587 (evil-collection-define-key 'normal 'dired-mode-map
588 "H" 'dired-hide-dotfiles-mode))
592 # TODO: Write a command that commits hunk, skipping staging step.
593 #+begin_src emacs-lisp
596 *** Colored diff in line number area
597 #+begin_src emacs-lisp
599 :straight (diff-hl :type git :host github :repo "dgutov/diff-hl")
600 :hook ((magit-pre-refresh-hook . diff-hl-magit-pre-refresh)
601 (magit-post-refresh-hook . diff-hl-magit-post-refresh))
602 :config (global-diff-hl-mode))
605 #+begin_src emacs-lisp
607 (use-package git-email
608 :straight (git-email :repo "https://git.sr.ht/~yoctocell/git-email")
609 :config (git-email-piem-mode))
612 *** Evaluate current buffer
613 Stolen from https://stackoverflow.com/questions/19953924/how-do-you-run-java-codes-in-emacs
614 #+begin_src emacs-lisp
615 (defun java-eval-buffer ()
616 "run current program (that requires no input)"
618 (let* ((source (file-name-nondirectory buffer-file-name))
619 (out (file-name-sans-extension source))
620 (class (concat out ".class")))
622 (shell-command (format "rm -f %s && javac %s" class source))
623 (if (file-exists-p class)
624 (shell-command (format "java %s" out) "*scratch*")
626 (set (make-local-variable 'compile-command)
627 (format "javac %s" source))
628 (command-execute 'compile)))))
630 * General text editing
632 Indent after every change.
633 #+begin_src emacs-lisp
634 (use-package aggressive-indent
635 :config (global-aggressive-indent-mode))
638 Spell check in text mode, and in prog-mode comments.
639 #+begin_src emacs-lisp
640 (dolist (hook '(text-mode-hook))
641 (add-hook hook (lambda () (flyspell-mode))))
642 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
643 (add-hook hook (lambda () (flyspell-mode -1))))
644 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
646 ** Expand tabs to spaces
647 #+begin_src emacs-lisp
648 (setq-default tab-width 2)
650 ** Copy kill ring to clipboard
651 #+begin_src emacs-lisp
652 (setq x-select-enable-clipboard t)
653 (defun copy-kill-ring-to-xorg ()
654 "Copy the current kill ring to the xorg clipboard."
656 (x-select-text (current-kill 0)))
659 Opens file where you left it.
660 #+begin_src emacs-lisp
664 Distraction free writing a la junegunn/goyo.
665 #+begin_src emacs-lisp
666 (use-package olivetti
668 (evil-leader/set-key "o" 'olivetti-mode))
672 #+begin_src emacs-lisp
673 (setq abbrev-file-name "~/.emacs.d/abbrevs.el")
674 (setq save-abbrevs 'silent)
675 (setq-default abbrev-mode t)
678 #+begin_src emacs-lisp
679 (setq tramp-default-method "ssh")
681 ** Don't ask about following symlinks in vc
682 #+begin_src emacs-lisp
683 (setq vc-follow-symlinks t)
685 ** Don't ask to save custom dictionary
686 #+begin_src emacs-lisp
687 (setq ispell-silently-savep t)
690 #+begin_src emacs-lisp
691 (defun doas-edit (&optional arg)
692 "Edit currently visited file as root.
694 With a prefix ARG prompt for a file to visit.
695 Will also prompt for a file to visit if current
696 buffer is not visiting a file.
698 Modified from Emacs Redux."
700 (if (or arg (not buffer-file-name))
701 (find-file (concat "/doas:root@localhost:"
702 (ido-read-file-name "Find file(as root): ")))
703 (find-alternate-file (concat "/doas:root@localhost:" buffer-file-name))))
705 (global-set-key (kbd "C-x C-r") #'doas-edit)
709 #+begin_src emacs-lisp
710 (use-package ace-window
711 :bind ("M-o" . ace-window))
713 ** Kill current buffer
714 Makes "C-x k" binding faster.
715 #+begin_src emacs-lisp
716 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
720 #+begin_src emacs-lisp
721 (use-package scad-mode)
723 ** Control backup files
724 Stop backup files from spewing everywhere.
725 #+begin_src emacs-lisp
726 (setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
728 ** Make yes/no easier
729 #+begin_src emacs-lisp
730 (defalias 'yes-or-no-p 'y-or-n-p)
732 ** Move customize file
733 No more clogging up init.el.
734 #+begin_src emacs-lisp
735 (setq custom-file "~/.emacs.d/custom.el")
739 #+begin_src emacs-lisp
741 :commands (helpful-callable helpful-variable helpful-command helpful-key)
743 (counsel-describe-function-function #'helpful-callable)
744 (counsel-describe-variable-function #'helpful-variable)
746 ([remap describe-function] . counsel-describe-function)
747 ([remap describe-command] . helpful-command)
748 ([remap describe-variable] . counsel-describe-variable)
749 ([remap describe-key] . helpful-key))
752 #+begin_src emacs-lisp
753 (use-package epa-file
754 :straight (:type built-in)
756 (epa-file-select-keys nil)
757 (epa-file-encrypt-to '("me@armaanb.net"))
758 (password-cache-expiry (* 60 15)))
760 (use-package pinentry
761 :config (pinentry-start))
764 #+begin_src emacs-lisp
766 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
767 :custom (0x0-default-service 'envs)
768 :config (evil-leader/set-key
770 "0f" '0x0-upload-file
771 "0s" '0x0-upload-string
772 "0c" '0x0-upload-kill-ring
773 "0p" '0x0-upload-popup))
775 ** Automatically clean buffers
776 #+begin_src emacs-lisp
777 ;; Don't kill Circe buffers
778 (add-to-list 'clean-buffer-list-kill-never-regexps (lambda (buffer-name)
779 (with-current-buffer buffer-name
780 (derived-mode-p 'lui-mode))))
786 #+begin_src conf :tangle ~/.spectrwm.conf
790 autorun = ws[1]:/home/armaa/Code/scripts/autostart
793 #+begin_src conf :tangle ~/.spectrwm.conf
795 bar_font = xos4 Fira Code:pixelsize=14:antialias=true # any installed font
799 #+begin_src conf :tangle ~/.spectrwm.conf
800 program[term] = st -e tmux
801 program[screenshot_all] = flameshot gui
802 program[notif] = /home/armaa/Code/scripts/setter status
803 program[pass] = /home/armaa/Code/scripts/passmenu
806 bind[pass] = MOD+Shift+p
809 #+begin_src conf :tangle ~/.spectrwm.conf
810 program[paup] = /home/armaa/Code/scripts/setter audio +5
811 program[padown] = /home/armaa/Code/scripts/setter audio -5
812 program[pamute] = /home/armaa/Code/scripts/setter audio
813 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
814 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
815 program[next] = playerctl next
816 program[prev] = playerctl previous
817 program[pause] = playerctl play-pause
819 bind[padown] = XF86AudioLowerVolume
820 bind[paup] = XF86AudioRaiseVolume
821 bind[pamute] = XF86AudioMute
822 bind[brigdown] = XF86MonBrightnessDown
823 bind[brigup] = XF86MonBrightnessUp
824 bind[pause] = XF86AudioPlay
825 bind[next] = XF86AudioNext
826 bind[prev] = XF86AudioPrev
829 #+begin_src conf :tangle ~/.spectrwm.conf
830 program[h] = xdotool keyup h key --clearmodifiers Left
831 program[j] = xdotool keyup j key --clearmodifiers Down
832 program[k] = xdotool keyup k key --clearmodifiers Up
833 program[l] = xdotool keyup l key --clearmodifiers Right
835 bind[h] = MOD + Control + h
836 bind[j] = MOD + Control + j
837 bind[k] = MOD + Control + k
838 bind[l] = MOD + Control + l
841 #+begin_src conf :tangle ~/.spectrwm.conf
842 program[email] = emacsclient -c --eval "(mu4e)"
843 program[irc] = emacsclient -c --eval '(switch-to-buffer "irc.armaanb.net:6698")'
844 program[rss] = emacsclient -c --eval '(elfeed)'
845 program[emacs] = emacsclient -c
846 program[firefox] = firefox
847 program[calc] = st -e because -l
849 bind[email] = MOD+Control+1
850 bind[irc] = MOD+Control+2
851 bind[rss] = MOD+Control+3
852 bind[firefox] = MOD+Control+4
853 bind[calc] = MOD+Control+5
854 bind[emacs] = MOD+Control+Return
857 #+begin_src conf :tangle ~/.spectrwm.conf
858 quirk[Castle Menu] = FLOAT
863 #+begin_src conf :tangle ~/.config/ash/ashrc
867 **** Update all packages
868 #+begin_src shell :tangle ~/.config/ash/ashrc
869 color=$(tput setaf 5)
873 doas echo "${color}== upgrading with yay ==${reset}"
876 echo "${color}== checking for pacnew files ==${reset}"
879 echo "${color}== upgrading flatpaks ==${reset}"
882 echo "${color}== updating nvim plugins ==${reset}"
883 nvim +PlugUpdate +PlugUpgrade +qall
884 echo "Updated nvim plugins"
886 echo "${color}You are entirely up to date!${reset}"
889 **** Clean all packages
890 #+begin_src shell :tangle ~/.config/ash/ashrc
892 doas echo "${color}== cleaning pacman orphans ==${reset}"
893 (pacman -Qtdq | doas pacman -Rns - 2> /dev/null) || echo "No orphans"
895 echo "${color}== cleaning flatpaks ==${reset}"
896 flatpak remove --unused
898 echo "${color}== cleaning nvim plugins ==${reset}"
899 nvim +PlugClean +qall
900 echo "Cleaned nvim plugins"
902 echo "${color}All orphans cleaned!${reset}"
905 **** Interact with 0x0
906 #+begin_src shell :tangle ~/.config/ash/ashrc
907 zxz="https://envs.sh"
908 ufile() { curl -F"file=@$1" "$zxz" ; }
909 upb() { curl -F"file=@-;" "$zxz" ; }
910 uurl() { curl -F"url=$1" "$zxz" ; }
911 ushort() { curl -F"shorten=$1" "$zxz" ; }
912 uclip() { xclip -out | curl -F"file=@-;" "$zxz" ; }
915 #+begin_src shell :tangle ~/.config/ash/ashrc
917 user=$(echo "$1" | cut -f 1 -d '@')
918 host=$(echo "$1" | cut -f 2 -d '@')
919 echo $user | nc "$host" 79
922 **** Upload to ftp.armaanb.net
923 #+begin_src shell :tangle ~/.config/ash/ashrc
925 rsync "$1" "root@armaanb.net:/var/ftp/pub/${2}"
926 echo "https://ftp.armaanb.net/pub/"$(basename "$1") | tee /dev/tty | xclip -sel c
930 #+begin_src shell :tangle ~/.config/ash/ashrc
931 export EDITOR="emacsclient -c"
932 export VISUAL="$EDITOR"
933 export TERM=xterm-256color # for compatability
935 export GPG_TTY="$(tty)"
936 export MANPAGER='nvim +Man!'
939 export GTK_USE_PORTAL=1
941 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
942 export PATH="/home/armaa/Code/scripts:$PATH" # prioritize my scripts
943 export PATH="/home/armaa/Code/scripts/bin:$PATH" # prioritize my bins
944 export PATH="$PATH:/home/armaa/.cargo/bin"
945 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
946 export PATH="$PATH:/usr/sbin"
947 export PATH="$PATH:/opt/FreeTube/freetube"
949 export LC_ALL="en_US.UTF-8"
950 export LC_CTYPE="en_US.UTF-8"
951 export LANGUAGE="en_US.UTF-8"
953 export KISS_PATH="/home/armaa/Virtual/kiss/home/armaa/kiss-repo"
954 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
955 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
956 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
957 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
958 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
962 #+begin_src shell :tangle ~/.config/ash/ashrc
963 alias bhoji-drop='ssh -p 23 root@armaanb.net'
964 alias irc='ssh root@armaanb.net -t abduco -A irc catgirl freenode'
965 alias union='ssh 192.168.1.18'
966 alias mine='ssh -p 23 root@pickupserver.cc'
967 alias tcf='ssh root@204.48.23.68'
968 alias ngmun='ssh root@157.245.89.25'
969 alias prox='ssh root@192.168.1.224'
970 alias ncq='ssh root@143.198.123.17'
971 alias envs='ssh acheam@envs.net'
974 #+begin_src shell :tangle ~/.config/ash/ashrc
975 alias ls='ls -lh --group-directories-first'
977 alias df='df -h / /boot'
984 alias grep='grep -in --color=auto'
985 alias mkdir='mkdir -pv'
986 alias lanex='java -jar ~/.local/share/lxc/lanxchange.jar'
987 emacs() { $EDITOR "$@" & }
990 **** System management
991 #+begin_src shell :tangle ~/.config/ash/ashrc
992 alias crontab='crontab-argh'
994 alias pasu='git -C ~/.password-store push'
995 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
999 #+begin_src shell :tangle ~/.config/ash/ashrc
1000 alias ping='ping -c 10'
1001 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1002 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1003 alias plan='T=$(mktemp) && \
1004 rsync root@armaanb.net:/etc/finger/plan.txt "$T" && \
1006 head -n -2 $T > $TT && \
1008 echo "\nLast updated: $(date -R)" >> "$TT" && \
1009 fold -sw 72 "$TT" > "$T"| \
1010 rsync "$T" root@armaanb.net:/etc/finger/plan.txt'
1012 **** Virtual machines, chroots
1013 #+begin_src shell :tangle ~/.config/ash/ashrc
1014 alias ckiss="doas chrooter ~/Virtual/kiss"
1015 alias cdebian="doas chrooter ~/Virtual/debian bash"
1016 alias cwindows='devour qemu-system-x86_64 \
1021 -device VGA,vgamem_mb=64 \
1023 -device hda-duplex \
1025 -net user,smb=/home/armaa/Public \
1026 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1029 #+begin_src shell :tangle ~/.config/ash/ashrc
1030 alias pip="python -m pip"
1031 alias black="black -l 79"
1034 #+begin_src shell :tangle ~/.config/ash/ashrc
1035 alias words='gen-shell -c "words"'
1036 alias words-e='gen-shell -c "words ~E"'
1039 #+begin_src shell :tangle ~/.config/ash/ashrc
1040 alias zathura='devour zathura'
1041 alias cad='devour openscad'
1042 alias feh='devour feh'
1045 #+begin_src shell :tangle ~/.config/ash/ashrc
1047 alias api='yay -Syu'
1048 alias apii='doas pacman -S'
1049 alias app='yay -Rns'
1050 alias azf='pacman -Q | fzf'
1051 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1054 #+begin_src shell :tangle ~/.config/ash/ashrc
1055 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1056 iflag=fullblock status=progress'
1057 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1058 iflag=fullblock status=progress'
1059 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1060 --restrict-filenames -o '%(title)s.%(ext)s'"
1061 alias cal="cal -3 --color=auto"
1065 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1066 c.TerminalInteractiveShell.editing_mode = 'vi'
1067 c.InteractiveShell.colors = 'linux'
1068 c.TerminalInteractiveShell.confirm_exit = False
1071 Make MPV play a little bit smoother.
1072 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1073 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1077 For any GNU Readline programs
1078 #+begin_src conf :tangle ~/.inputrc
1079 set editing-mode emacs
1083 #+begin_src conf :tangle ~/.gitconfig
1085 name = Armaan Bhojwani
1086 email = me@armaanb.net
1087 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1090 #+begin_src conf :tangle ~/.gitconfig
1092 defaultBranch = main
1095 #+begin_src conf :tangle ~/.gitconfig
1100 #+begin_src conf :tangle ~/.gitconfig
1102 smtpserver = smtp.mailbox.org
1103 smtpuser = me@armaanb.net
1104 smtpencryption = ssl
1105 smtpserverport = 465
1109 #+begin_src conf :tangle ~/.gitconfig
1114 #+begin_src conf :tangle ~/.gitconfig
1117 sclone = clone --depth 1
1122 quickfix = commit . --amend --no-edit
1124 subup = submodule update --remote
1125 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1126 pushnc = push -o skip-ci
1129 #+begin_src conf :tangle ~/.gitconfig
1135 Lightweight notification daemon.
1137 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1139 font = "JetBrains Mono Medium Nerd Font 11"
1141 format = "<b>%s</b>\n%b"
1143 indicate_hidden = yes
1146 show_age_threshold = 60
1149 geometry = "400x5-10+10"
1151 idle_threshold = 120
1153 sticky_history = yes
1155 separator_height = 1
1157 horizontal_padding = 8
1159 separator_color = "#ffffff"
1160 startup_notification = false
1163 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1170 close_all = mod4+shift+c
1171 history = mod4+ctrl+c
1174 background = "#222222"
1175 foreground = "#ffffff"
1176 highlight = "#ffffff"
1180 background = "#222222"
1181 foreground = "#ffffff"
1182 highlight = "#ffffff"
1186 background = "#222222"
1187 foreground = "#a60000"
1188 highlight = "#ffffff"
1193 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1195 map <A-b> toggle_statusbar
1196 set selection-clipboard clipboard
1199 set window-title-basename "true"
1200 set selection-clipboard "clipboard"
1203 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1204 set default-bg "#000000"
1205 set default-fg "#ffffff"
1206 set render-loading true
1207 set render-loading-bg "#000000"
1208 set render-loading-fg "#ffffff"
1210 set recolor-lightcolor "#000000" # bg
1211 set recolor-darkcolor "#ffffff" # fg
1215 *** Swap tab and URL bars
1216 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1218 -moz-box-ordinal-group: 1 !important;
1222 -moz-box-ordinal-group: 2 !important;
1226 -moz-box-ordinal-group: 3 !important;
1229 *** Hide URL bar when not focused.
1230 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1231 #navigator-toolbox:not(:focus-within):not(:hover) {
1235 #navigator-toolbox {
1236 transition: 0.1s margin-top ease-out;
1239 *** Black screen by default
1241 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1244 #browser vbox#appcontent tabbrowser,
1246 #tabbrowser-tabpanels,
1248 browser[type="content-primary"],
1249 browser[type="content"] > html,
1251 background: black !important;
1252 color: #fff !important;
1257 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userContent.css
1258 @-moz-document url("about:home"), url("about:blank"), url("about:newtab") {
1260 background: black !important;
1265 Modus operandi theme.
1266 #+begin_src conf :tangle ~/.Xresources
1268 ,*.foreground: #ffffff
1269 ,*.background: #000000
1270 ,*.cursorColor: #ffffff
1305 #+begin_src conf :tangle ~/.tmux.conf
1308 set-window-option -g mode-keys vi
1309 bind-key -T copy-mode-vi 'v' send -X begin-selection
1310 bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'
1314 #+begin_src conf :tangle ~/.gnupg/gpg.conf
1315 default-key 3C9ED82FFE788E4A
1319 #+begin_src conf :tangle ~/.gnupg/gpg-agent.conf
1320 pinentry-program /sbin/pinentry-gnome3
1322 default-cache-ttl 600
1323 allow-emacs-pinentry