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 Emacs 28 with native compilation, so some settings and packages may not be available for older versions of Emacs. This is a purely personal configuration, so while I can guarantee that it works on my setup, it might not work for you.
11 I chose to create a powerful, yet not overly heavy Emacs configuration. Things like a fancy modeline, icons, or LSP mode 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 [[*Emacs OS]]). I use email, IRC, RSS, et cetera, all through Emacs which simplifies my workflow and creates an amazingly integrated environment.
15 Lastly, I use Evil mode. Modal keybindings are simpler and more ergonomic than standard Emacs style, and Vim keybindings are what I'm comfortable with and are pervasive throughout computing.
17 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 near their contributions.
19 ** Bootstrap straight.el
20 straight.el is really nice for managing package, and it integrates nicely with use-package. It uses the bootstrapping system defined here for installation.
21 #+begin_src emacs-lisp
22 (defvar native-comp-deferred-compilation-deny-list ())
23 (defvar bootstrap-version)
25 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
26 (bootstrap-version 5))
27 (unless (file-exists-p bootstrap-file)
29 (url-retrieve-synchronously
30 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
31 'silent 'inhibit-cookies)
32 (goto-char (point-max))
33 (eval-print-last-sexp)))
34 (load bootstrap-file nil 'nomessage))
36 ** Replace package.el with straight
37 #+begin_src emacs-lisp
38 (straight-use-package 'use-package)
39 (setq straight-use-package-by-default t)
43 Use the Modus Operandi theme by Protesilaos Stavrou. Its the best theme for Emacs by far, because how clear and readable it is. It is highly customizable, but I just set a few options here.
44 #+begin_src emacs-lisp
45 (use-package modus-themes
47 (modus-themes-slanted-constructs t)
48 (modus-themes-bold-constructs t)
49 (modus-themes-mode-line '3d)
50 (modus-themes-scale-headings t)
51 (modus-themes-diffs 'desaturated)
52 :config (load-theme 'modus-vivendi t))
56 JetBrains Mono is a great programming font with ligatures. The "NF" means that it has been patched with the [[https://www.nerdfonts.com/][Nerd Fonts]].
57 #+begin_src emacs-lisp
58 (add-to-list 'default-frame-alist '(font . "JetBrainsMonoNF-12"))
61 #+begin_src emacs-lisp
63 :straight (ligature :type git :host github :repo "mickeynp/ligature.el")
65 (ligature-set-ligatures
66 '(prog-mode text-mode)
67 '("-|" "-~" "---" "-<<" "-<" "--" "->" "->>" "-->" "/=" "/=="
68 "/>" "//" "/*" "*>" "*/" "<-" "<<-" "<=>" "<=" "<|" "<||"
69 "<|||" "<|>" "<:" "<>" "<-<" "<<<" "<==" "<<=" "<=<" "<==>"
70 "<-|" "<<" "<~>" "<=|" "<~~" "<~" "<$>" "<$" "<+>" "<+" "</>"
71 "</" "<*" "<*>" "<->" "<!--" ":>" ":<" ":::" "::" ":?" ":?>"
72 ":=" "::=" "=>>" "==>" "=/=" "=!=" "=>" "===" "=:=" "==" "!=="
73 "!!" "!=" ">]" ">:" ">>-" ">>=" ">=>" ">>>" ">-" ">=" "&&&"
74 "&&" "|||>" "||>" "|>" "|]" "|}" "|=>" "|->" "|=" "||-" "|-"
75 "||=" "||" ".." ".?" ".=" ".-" "..<" "..." "+++" "+>" "++"
76 "[||]" "[<" "[|" "{|" "?." "?=" "?:" "##" "###" "####" "#["
77 "#{" "#=" "#!" "#:" "#_(" "#_" "#?" "#(" ";;" "_|_" "__" "~~"
78 "~~>" "~>" "~-" "~@" "$>" "^=" "]#"))
79 (global-ligature-mode t))
82 Display relative line numbers except in certain modes.
83 #+begin_src emacs-lisp
84 (global-display-line-numbers-mode)
85 (setq display-line-numbers-type 'relative)
86 (dolist (no-line-num '(term-mode-hook
92 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
94 ** Highlight matching parenthesis
95 #+begin_src emacs-lisp
97 :config (show-paren-mode)
98 :custom (show-paren-style 'parenthesis))
101 *** Show current function
102 #+begin_src emacs-lisp
103 (which-function-mode)
105 *** Make position in file more descriptive
106 Show current column and file size.
107 #+begin_src emacs-lisp
109 (size-indication-mode)
112 #+begin_src emacs-lisp
114 :config (minions-mode))
117 Show a ruler at a certain number of chars depending on mode.
118 #+begin_src emacs-lisp
119 (setq display-fill-column-indicator-column 80)
120 (global-display-fill-column-indicator-mode)
122 ** Highlight todo items in comments
123 #+begin_src emacs-lisp
125 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
126 :config (global-hl-todo-mode 1))
129 #+begin_src emacs-lisp
133 Soft wrap words and do operations by visual lines in some modes.
134 #+begin_src emacs-lisp
135 (dolist (hook '(text-mode-hook
138 mu4e-view-mode-hook))
139 (add-hook hook (lambda () (visual-line-mode 1))))
142 #+begin_src emacs-lisp
143 (dolist (hook '(scdoc-mode-hook
144 mu4e-compose-mode-hook))
145 (add-hook hook (lambda () (auto-fill-mode 1))))
147 ** Display number of matches in search
148 #+begin_src emacs-lisp
150 :config (global-anzu-mode)
152 ([remap query-replace] . anzu-query-replace)
153 ([remap query-replace-regexp] . anzu-query-replace-regexp))
155 *** TODO This config doesn't work right
157 Invert modeline color instead of audible bell or the standard visual bell.
158 #+begin_src emacs-lisp
159 (setq visible-bell nil
161 (lambda () (invert-face 'mode-line)
162 (run-with-timer 0.1 nil #'invert-face 'mode-line)))
166 #+begin_src emacs-lisp
168 :custom (select-enable-clipboard nil)
171 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
172 ;; Use visual line motions even outside of visual-line-mode buffers
173 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
174 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
175 (global-set-key (kbd "<escape>") 'keyboard-escape-quit))
178 Evil bindings for tons of packages.
179 #+begin_src emacs-lisp
180 (use-package evil-collection
182 :init (evil-collection-init)
183 :custom (evil-collection-setup-minibuffer t))
187 #+begin_src emacs-lisp
188 (use-package evil-surround
189 :config (global-evil-surround-mode))
192 Makes commenting super easy
193 #+begin_src emacs-lisp
194 (use-package evil-nerd-commenter
195 :bind (:map evil-normal-state-map
196 ("gc" . evilnc-comment-or-uncomment-lines))
197 :custom (evilnc-invert-comment-line-by-line nil))
201 #+begin_src emacs-lisp
202 (evil-set-undo-system 'undo-redo)
204 ** Number incrementing
205 Add back C-a/C-x bindings.
206 #+begin_src emacs-lisp
207 (use-package evil-numbers
208 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
209 :bind (:map evil-normal-state-map
210 ("C-M-a" . evil-numbers/inc-at-pt)
211 ("C-M-x" . evil-numbers/dec-at-pt)))
214 #+begin_src emacs-lisp
215 (use-package evil-org
217 :hook (org-mode . evil-org-mode)
219 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
221 (use-package evil-org-agenda
222 :straight (:type built-in)
224 :config (evil-org-agenda-set-keys))
228 #+begin_src emacs-lisp
230 :straight (:type built-in)
231 :commands (org-capture org-agenda)
234 (org-agenda-start-with-log-mode t)
235 (org-agenda-files (quote ("~/Org/tasks.org" "~/Org/break.org")))
237 (org-log-into-drawer t)
238 (org-src-tab-acts-natively t)
239 (org-src-fontify-natively t)
240 (org-startup-indented t)
241 (org-hide-emphasis-markers t)
242 (org-fontify-whole-block-delimiter-line nil)
243 (org-archive-default-command 'org-archive-to-archive-sibling)
245 ("C-c a" . org-agenda)
246 (:map evil-normal-state-map ("ga" . org-archive-subtree-default)))
249 Define templates for lots of common structure elements. Mostly just used within this file.
250 #+begin_src emacs-lisp
251 (use-package org-tempo
253 :straight (:type built-in)
255 (dolist (addition '(("el" . "src emacs-lisp")
256 ("el" . "src emacs-lisp")
257 ("sp" . "src conf :tangle ~/.spectrwm.conf")
258 ("ash" . "src shell :tangle ~/.config/ash/ashrc")
259 ("pi" . "src conf :tangle ~/.config/picom/picom.conf")
260 ("git" . "src conf :tangle ~/.gitconfig")
261 ("du" . "src conf :tangle ~/.config/dunst/dunstrc")
262 ("za" . "src conf :tangle ~/.config/zathura/zathurarc")
263 ("ff1" . "src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css")
264 ("ff2" . "src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userContent.css")
265 ("xr" . "src conf :tangle ~/.Xresources")
266 ("tm" . "src conf :tangle ~/.tmux.conf")
267 ("gp" . "src conf :tangle ~/.gnupg/gpg.conf")
268 ("ag" . "src conf :tangle ~/.gnupg/gpg-agent.conf")
269 ("xm" . "src conf :tangle ~/.config/xmodmap")))
270 (add-to-list 'org-structure-template-alist addition)))
274 A well balanced completion framework.
275 #+begin_src emacs-lisp
277 :bind (:map ivy-minibuffer-map
278 ("TAB" . ivy-alt-done))
279 (:map ivy-switch-buffer-map
280 ("M-d" . ivy-switch-buffer-kill))
284 #+begin_src emacs-lisp
285 (use-package ivy-rich
287 :config (ivy-rich-mode))
291 #+begin_src emacs-lisp
293 :bind ("C-M-j" . 'counsel-switch-buffer)
294 :config (counsel-mode))
296 ** Remember frequent commands
297 #+begin_src emacs-lisp
298 (use-package ivy-prescient
301 (prescient-persist-mode)
302 (ivy-prescient-mode))
306 Use elfeed for reading RSS. I have another file with all the feeds in it that I'd rather keep private.
307 #+begin_src emacs-lisp
309 :bind (("C-c e" . elfeed))
310 :config (load "~/.emacs.d/feeds.el")
311 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
314 Use mu4e for reading emails.
315 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.
316 *** TODO Switch to mbsync
317 =offlineimap= really crappy (slow and requires python2), and I need to replace it with =mbsync=.
318 *** TODO Include mbsync/offlineimap config
319 *** TODO Split up and document this config a bit
321 #+begin_src emacs-lisp
322 (use-package smtpmail
323 :straight (:type built-in))
325 :load-path "/usr/share/emacs/site-lisp/mu4e"
326 :straight (:build nil)
327 :bind (("C-c m" . mu4e))
329 (setq user-full-name "Armaan Bhojwani"
330 smtpmail-local-domain "armaanb.net"
331 smtpmail-stream-type 'ssl
332 smtpmail-smtp-service '465
333 mu4e-change-filenames-when-moving t
334 mu4e-get-mail-command "offlineimap -q"
335 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
336 message-citation-line-function 'message-insert-formatted-citation-line
337 mu4e-completing-read-function 'ivy-completing-read
338 mu4e-confirm-quit nil
340 mail-user-agent 'mu4e-user-agent
341 mu4e-context-policy 'pick-first
343 `( ,(make-mu4e-context
345 :enter-func (lambda () (mu4e-message "Entering school context"))
346 :leave-func (lambda () (mu4e-message "Leaving school context"))
347 :match-func (lambda (msg)
349 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
350 :vars '((user-mail-address . "abhojwani22@nobles.edu")
351 (mu4e-sent-folder . "/school/Sent")
352 (mu4e-drafts-folder . "/school/Drafts")
353 (mu4e-trash-folder . "/school/Trash")
354 (mu4e-refile-folder . "/school/Archive")
355 (message-cite-reply-position . above)
356 (user-mail-address . "abhojwani22@nobles.edu")
357 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
358 (smtpmail-smtp-server . "smtp.gmail.com")))
361 :enter-func (lambda () (mu4e-message "Entering personal context"))
362 :leave-func (lambda () (mu4e-message "Leaving personal context"))
363 :match-func (lambda (msg)
365 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
366 :vars '((mu4e-sent-folder . "/personal/Sent")
367 (mu4e-drafts-folder . "/personal/Drafts")
368 (mu4e-trash-folder . "/personal/Trash")
369 (mu4e-refile-folder . "/personal/Archive")
370 (user-mail-address . "me@armaanb.net")
371 (message-cite-reply-position . below)
372 (smtpmail-smtp-user . "me@armaanb.net")
373 (smtpmail-smtp-server . "smtp.mailbox.org")))))
374 (add-to-list 'mu4e-bookmarks
375 '(:name "Unified inbox"
376 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
378 :hook ((mu4e-compose-mode . flyspell-mode)
379 (message-send-hook . (lambda () (unless (yes-or-no-p "Ya sure 'bout that?")
380 (signal 'quit nil))))))
382 *** Discourage Gnus from displaying HTML emails
383 #+begin_src emacs-lisp
384 (with-eval-after-load "mm-decode"
385 (add-to-list 'mm-discouraged-alternatives "text/html")
386 (add-to-list 'mm-discouraged-alternatives "text/richtext"))
389 Set EWW as default browser except for multimedia which should open in MPV.
390 #+begin_src emacs-lisp
391 (defun browse-url-mpv (url &optional new-window)
392 "Ask MPV to load URL."
394 (start-process "mpv" "*mpv*" "mpv" url))
396 (setq browse-url-handlers
398 (("youtu\\.?be" . browse-url-mpv)
399 ("peertube.*" . browse-url-mpv)
400 ("vid.*" . browse-url-mpv)
401 ("vid.*" . browse-url-mpv)
402 ("*.mp4" . browse-url-mpv)
403 ("*.mp3" . browse-url-mpv)
404 ("*.ogg" . browse-url-mpv)
405 ("." . eww-browse-url)
409 Some EWW enhancements.
410 *** Give buffer a useful name
411 #+begin_src emacs-lisp
412 ;; From https://protesilaos.com/dotemacs/
413 (defun prot-eww--rename-buffer ()
414 "Rename EWW buffer using page title or URL.
415 To be used by `eww-after-render-hook'."
416 (let ((name (if (eq "" (plist-get eww-data :title))
417 (plist-get eww-data :url)
418 (plist-get eww-data :title))))
419 (rename-buffer (format "*%s # eww*" name) t)))
422 :straight (:type built-in)
423 :bind (("C-c w" . eww))
424 :hook (eww-after-render-hook prot-eww--rename-buffer))
427 #+begin_src emacs-lisp
428 (global-set-key (kbd "C-c w") 'eww)
431 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.
432 #+begin_src emacs-lisp
433 (defun fetch-password (&rest params)
434 (require 'auth-source)
435 (let ((match (car (apply 'auth-source-search params))))
437 (let ((secret (plist-get match :secret)))
438 (if (functionp secret)
441 (error "Password not found for %S" params))))
446 (enable-circe-color-nicks)
447 (setq circe-network-defaults '(("libera"
448 :host "irc.armaanb.net"
453 :pass (lambda (null) (fetch-password
455 :machine "irc.armaanb.net"
458 :host "irc.armaanb.net"
463 :pass (lambda (null) (fetch-password
465 :machine "irc.armaanb.net"
468 :host "irc.armaanb.net"
473 :pass (lambda (null) (fetch-password
475 :machine "irc.armaanb.net"
477 :custom (circe-default-part-message "goodbye!")
478 :bind (:map circe-mode-map ("C-c C-r" . circe-reconnect-all)))
483 (if (get-buffer "irc.armaanb.net:6696")
484 (switch-to-buffer "irc.armaanb.net:6696")
485 (progn (switch-to-buffer "*scratch*")
490 (global-set-key (kbd "C-c i") 'acheam-irc)
493 Still experimenting with this setup. Not sure if I will keep it, but it works well for seeing my calendar events. I use =vdirsyncer= to sync my calendar events which I'm really not happy with.
494 #+begin_src emacs-lisp
495 (defun sync-calendar ()
496 "Sync calendars with vdirsyncer"
498 (async-shell-command "vdirsyncer sync"))
501 :bind (:map cfw:calendar-mode-map ("C-S-u" . sync-calendar)))
502 (use-package calfw-ical)
503 (use-package calfw-org)
505 (defun acheam-calendar ()
508 (cfw:open-calendar-buffer
509 :contents-sources (list
510 (cfw:org-create-source "Green")
511 (cfw:ical-create-source
513 "~/.local/share/vdirsyncer/mailbox/Y2FsOi8vMC8zMQ.ics"
515 (cfw:ical-create-source
517 "~/.local/share/vdirsyncer/mailbox/Y2FsOi8vMC8zMQ.ics"
519 (cfw:ical-create-source
521 "~/.local/share/vdirsyncer/school/abhojwani22@nobles.edu.ics"
525 (global-set-key (kbd "C-c c") 'acheam-calendar)
528 #+begin_src emacs-lisp
529 (use-package pdf-tools
530 :hook (pdf-view-mode . pdf-view-midnight-minor-mode))
534 #+begin_src emacs-lisp
536 :hook (python-mode . blacken-mode)
537 :custom (blacken-line-length 79))
540 ** Strip trailing whitespace
541 #+begin_src emacs-lisp
542 (use-package ws-butler
543 :config (ws-butler-global-mode))
546 Automatic linting. I need to look into configuring this more.
547 #+begin_src emacs-lisp
548 (use-package flycheck
549 :config (global-flycheck-mode))
551 ** Project management
552 I never use this, but apparently its very powerful. Another item on my todo list.
553 #+begin_src emacs-lisp
554 (use-package projectile
555 :config (projectile-mode)
556 :custom ((projectile-completion-system 'ivy))
558 ("C-c p" . projectile-command-map)
560 (when (file-directory-p "~/Code")
561 (setq projectile-project-search-path '("~/Code")))
562 (setq projectile-switch-project-action #'projectile-dired))
564 (use-package counsel-projectile
566 :config (counsel-projectile-mode))
569 The best file manager!
570 #+begin_src emacs-lisp
572 :straight (:type built-in)
573 :commands (dired dired-jump)
574 :custom ((dired-listing-switches "-agho --group-directories-first"))
575 :config (evil-collection-define-key 'normal 'dired-mode-map
576 "h" 'dired-single-up-directory
577 "l" 'dired-single-buffer))
579 (use-package dired-single
580 :commands (dired dired-jump))
582 (use-package dired-open
583 :commands (dired dired-jump)
584 :custom (dired-open-extensions '(("png" . "feh")
587 (use-package dired-hide-dotfiles
588 :hook (dired-mode . dired-hide-dotfiles-mode)
590 (evil-collection-define-key 'normal 'dired-mode-map
591 "H" 'dired-hide-dotfiles-mode))
595 A very good Git interface.
596 #+begin_src emacs-lisp
600 #+begin_src emacs-lisp
602 (use-package git-email
603 :straight (git-email :repo "https://git.sr.ht/~yoctocell/git-email")
604 :config (git-email-piem-mode))
606 * General text editing
608 Automatically indent after every change. I'm not sure how much I like this. It slows down the editor and code sometimes ends up in a half-indented state meaning I have to manually reformat using "==" anyways.
609 #+begin_src emacs-lisp
610 (use-package aggressive-indent
611 :config (global-aggressive-indent-mode))
614 Spell check in text mode, and in prog-mode comments.
615 #+begin_src emacs-lisp
616 (dolist (hook '(text-mode-hook
619 (add-hook hook (lambda () (flyspell-mode))))
620 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
621 (add-hook hook (lambda () (flyspell-mode -1))))
622 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
623 (setq ispell-silently-savep t)
626 #+begin_src emacs-lisp
627 (setq-default tab-width 2)
630 Opens file where you left it.
631 #+begin_src emacs-lisp
635 Distraction free writing a la junegunn/goyo.
636 #+begin_src emacs-lisp
637 (use-package olivetti
638 :bind ("C-c o" . olivetti-mode))
641 Abbreviate things! I just use this for things like my email address and copyright notice.
642 #+begin_src emacs-lisp
643 (setq abbrev-file-name "~/.emacs.d/abbrevs.el")
644 (setq save-abbrevs 'silent)
645 (setq-default abbrev-mode t)
648 #+begin_src emacs-lisp
649 (setq tramp-default-method "ssh")
651 ** Follow version controlled symlinks
652 #+begin_src emacs-lisp
653 (setq vc-follow-symlinks t)
656 #+begin_src emacs-lisp
657 (defun doas-edit (&optional arg)
658 "Edit currently visited file as root.
660 With a prefix ARG prompt for a file to visit.
661 Will also prompt for a file to visit if current
662 buffer is not visiting a file.
664 Modified from Emacs Redux."
666 (if (or arg (not buffer-file-name))
667 (find-file (concat "/doas:root@localhost:"
668 (ido-read-file-name "Find file(as root): ")))
669 (find-alternate-file (concat "/doas:root@localhost:" buffer-file-name))))
671 (global-set-key (kbd "C-x C-r") #'doas-edit)
674 #+begin_src emacs-lisp
675 (use-package markdown-mode)
678 Get it for yourself at https://git.armaanb.net/scdoc
679 #+begin_src emacs-lisp
680 (add-to-list 'load-path "~/Code/scdoc-mode")
681 (autoload 'scdoc-mode "scdoc-mode" "Major mode for editing scdoc files" t)
682 (add-to-list 'auto-mode-alist '("\\.scd\\'" . scdoc-mode))
686 #+begin_src emacs-lisp
687 (use-package ace-window
688 :bind ("M-o" . ace-window))
690 ** Kill current buffer
691 Makes "C-x k" binding faster.
692 #+begin_src emacs-lisp
693 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
697 #+begin_src emacs-lisp
698 (use-package scad-mode)
700 ** Control backup and lock files
701 Stop backup files from spewing everywhere.
702 #+begin_src emacs-lisp
703 (setq backup-directory-alist `(("." . "~/.emacs.d/backups"))
704 create-lockfiles nil)
706 ** Make yes/no easier
707 #+begin_src emacs-lisp
708 (defalias 'yes-or-no-p 'y-or-n-p)
710 ** Move customize file
711 No more clogging up init.el.
712 #+begin_src emacs-lisp
713 (setq custom-file "~/.emacs.d/custom.el")
717 #+begin_src emacs-lisp
719 :commands (helpful-callable helpful-variable helpful-command helpful-key)
721 (counsel-describe-function-function #'helpful-callable)
722 (counsel-describe-variable-function #'helpful-variable)
724 ([remap describe-function] . counsel-describe-function)
725 ([remap describe-command] . helpful-command)
726 ([remap describe-variable] . counsel-describe-variable)
727 ([remap describe-key] . helpful-key))
730 #+begin_src emacs-lisp
731 (use-package epa-file
732 :straight (:type built-in)
734 (epa-file-select-keys nil)
735 (epa-file-encrypt-to '("me@armaanb.net"))
736 (password-cache-expiry (* 60 15)))
738 (use-package pinentry
739 :config (pinentry-start))
742 #+begin_src emacs-lisp
744 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
745 :custom (0x0-default-service 'envs))
747 *** TODO Replace this with uploading to my own server
748 Similar to the ufile alias in my ashrc
749 ** Automatically clean buffers
750 Automatically close unused buffers (except those of Circe) at midnight.
751 #+begin_src emacs-lisp
753 (add-to-list 'clean-buffer-list-kill-never-regexps (lambda (buffer-name)
754 (with-current-buffer buffer-name
755 (derived-mode-p 'lui-mode))))
759 Spectrwm is a really awesome window manager! Would highly recommend.
761 #+begin_src conf :tangle ~/.spectrwm.conf
765 autorun = ws[1]:/home/armaa/Code/scripts/autostart
768 Disable the bar by default (it can still be brought back up with MOD+b). The font just needs to be set to something that you have installed, otherwise spectrwm won't launch.
769 #+begin_src conf :tangle ~/.spectrwm.conf
771 bar_font = xos4 JetBrains Mono:pixelsize=14:antialias=true # any installed font
774 I'm not a huge fan of how spectrwm handles keybindings, probably my biggest gripe with it.
776 #+begin_src conf :tangle ~/.spectrwm.conf
777 program[term] = st -e tmux
778 program[screenshot_all] = flameshot gui
779 program[notif] = /home/armaa/Code/scripts/setter status
780 program[pass] = /home/armaa/Code/scripts/passmenu
783 bind[pass] = MOD+Shift+p
786 #+begin_src conf :tangle ~/.spectrwm.conf
787 program[paup] = /home/armaa/Code/scripts/setter audio +5
788 program[padown] = /home/armaa/Code/scripts/setter audio -5
789 program[pamute] = /home/armaa/Code/scripts/setter audio
790 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
791 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
792 program[next] = playerctl next
793 program[prev] = playerctl previous
794 program[pause] = playerctl play-pause
796 bind[padown] = XF86AudioLowerVolume
797 bind[paup] = XF86AudioRaiseVolume
798 bind[pamute] = XF86AudioMute
799 bind[brigdown] = XF86MonBrightnessDown
800 bind[brigup] = XF86MonBrightnessUp
801 bind[pause] = XF86AudioPlay
802 bind[next] = XF86AudioNext
803 bind[prev] = XF86AudioPrev
806 #+begin_src conf :tangle ~/.spectrwm.conf
807 program[h] = xdotool keyup h key --clearmodifiers Left
808 program[j] = xdotool keyup j key --clearmodifiers Down
809 program[k] = xdotool keyup k key --clearmodifiers Up
810 program[l] = xdotool keyup l key --clearmodifiers Right
812 bind[h] = MOD + Control + h
813 bind[j] = MOD + Control + j
814 bind[k] = MOD + Control + k
815 bind[l] = MOD + Control + l
818 #+begin_src conf :tangle ~/.spectrwm.conf
819 program[email] = emacsclient -ce '(progn (switch-to-buffer "*scratch*") (mu4e))'
820 program[irc] = emacsclient -ce '(acheam-irc)'
821 program[rss] = emacsclient -ce '(elfeed)'
822 program[calendar] = emacsclient -ce '(acheam-calendar)'
823 program[calc] = emacsclient -ce '(progn (calc) (windmove-up) (delete-window))'
824 program[firefox] = firefox
825 program[emacs] = emacsclient -c
827 bind[email] = MOD+Control+1
828 bind[irc] = MOD+Control+2
829 bind[rss] = MOD+Control+3
830 bind[calendar] = MOD+Control+4
831 bind[calc] = MOD+Control+5
832 bind[firefox] = MOD+Control+0
833 bind[emacs] = MOD+Control+Return
836 Float some specific programs by default.
837 #+begin_src conf :tangle ~/.spectrwm.conf
838 quirk[Castle Menu] = FLOAT
843 Use the vi editing mode. I still haven't found a good way to show visual feedback of the current mode. Ideally the cursor would change to a beam when in insert mode, and a box when in normal mode.
844 #+begin_src conf :tangle ~/.config/ash/ashrc
849 #+begin_src shell :tangle ~/.config/ash/ashrc
851 user=$(echo "$1" | cut -f 1 -d '@')
852 host=$(echo "$1" | cut -f 2 -d '@')
853 echo $user | nc "$host" 79
856 **** Upload to ftp.armaanb.net
857 #+begin_src shell :tangle ~/.config/ash/ashrc
859 echo "https://l.armaanb.net/$(basename "$1")" | tee /dev/tty | xclip -sel c
863 rsync "$1" "root@armaanb.net:/var/ftp/pub/$2" --chmod 644
873 xclip -o -sel c >> "$tmp"
874 basetmp=$(echo "$tmp" | tail -c +5)
875 _uup "$tmp" "$basetmp"
881 #+begin_src shell :tangle ~/.config/ash/ashrc
882 export EDITOR="emacsclient -c"
883 export VISUAL="$EDITOR"
884 export TERM=xterm-256color # for compatability
886 export GPG_TTY="$(tty)"
887 export MANPAGER='nvim +Man!'
890 export GTK_USE_PORTAL=1
892 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
893 export PATH="/home/armaa/Code/scripts:$PATH" # prioritize my scripts
894 export PATH="/home/armaa/Code/scripts/bin:$PATH" # prioritize my bins
895 export PATH="$PATH:/home/armaa/.cargo/bin"
896 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
897 export PATH="$PATH:/usr/sbin"
898 export PATH="$PATH:/opt/FreeTube/freetube"
900 export LC_ALL="en_US.UTF-8"
901 export LC_CTYPE="en_US.UTF-8"
902 export LANGUAGE="en_US.UTF-8"
906 export KISS_PATH="/home/armaa/Virtual/kiss/home/armaa/kiss-repo"
907 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
908 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
909 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
910 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
911 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
912 export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig"
916 #+begin_src shell :tangle ~/.config/ash/ashrc
917 alias bhoji-drop='ssh -p 23 root@armaanb.net'
918 alias irc='ssh root@armaanb.net -t abduco -A irc catgirl freenode'
919 alias union='ssh 192.168.1.18'
920 alias mine='ssh -p 23 root@pickupserver.cc'
921 alias tcf='ssh root@204.48.23.68'
922 alias ngmun='ssh root@157.245.89.25'
923 alias prox='ssh root@192.168.1.224'
924 alias ncq='ssh root@143.198.123.17'
925 alias envs='ssh acheam@envs.net'
928 #+begin_src shell :tangle ~/.config/ash/ashrc
929 alias ls='LC_COLLATE=C ls -lh --group-directories-first'
931 alias df='df -h / /boot'
938 alias grep='grep -in'
939 alias mkdir='mkdir -pv'
940 alias lanex='java -jar ~/.local/share/lxc/lanxchange.jar'
941 emacs() { $EDITOR "$@" & }
944 **** System management
945 #+begin_src shell :tangle ~/.config/ash/ashrc
946 alias crontab='crontab-argh'
948 alias pasu='git -C ~/.password-store push'
949 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
953 #+begin_src shell :tangle ~/.config/ash/ashrc
954 alias ping='ping -c 10'
955 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
956 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
957 alias plan='T=$(mktemp) && \
958 rsync root@armaanb.net:/etc/finger/plan.txt "$T" && \
960 head -n -2 $T > $TT && \
963 echo "Last updated: $(date -R)" >> "$TT" && \
964 fold -sw 72 "$TT" > "$T"| \
965 rsync "$T" root@armaanb.net:/etc/finger/plan.txt && \
968 **** Virtual machines, chroots
969 #+begin_src shell :tangle ~/.config/ash/ashrc
970 alias ckiss="doas chrooter ~/Virtual/kiss"
971 alias cdebian="doas chrooter ~/Virtual/debian bash"
972 alias cwindows='devour qemu-system-x86_64 \
977 -device VGA,vgamem_mb=64 \
981 -net user,smb=/home/armaa/Public \
982 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
985 #+begin_src shell :tangle ~/.config/ash/ashrc
986 alias words='gen-shell -c "words"'
987 alias words-e='gen-shell -c "words ~E"'
990 #+begin_src shell :tangle ~/.config/ash/ashrc
991 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
993 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
995 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
996 --restrict-filenames -o '%(title)s.%(ext)s'"
1000 Make MPV play a little bit smoother.
1001 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1002 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1006 This file is used for any GNU Readline programs. I use Emacs editing mode mostly because of one annoyance which is that to clear the screen using ^L, you have to be in normal mode which is a pain. If there is a way to rebind this, I'd love to know!.
1007 #+begin_src conf :tangle ~/.inputrc
1008 set editing-mode emacs
1012 #+begin_src conf :tangle ~/.gitconfig
1014 name = Armaan Bhojwani
1015 email = me@armaanb.net
1016 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1019 #+begin_src conf :tangle ~/.gitconfig
1021 defaultBranch = main
1024 #+begin_src conf :tangle ~/.gitconfig
1029 #+begin_src conf :tangle ~/.gitconfig
1031 smtpserver = smtp.mailbox.org
1032 smtpuser = me@armaanb.net
1033 smtpencryption = ssl
1034 smtpserverport = 465
1038 #+begin_src conf :tangle ~/.gitconfig
1043 #+begin_src conf :tangle ~/.gitconfig
1046 sclone = clone --depth 1
1051 quickfix = commit . --amend --no-edit
1053 subup = submodule update --remote
1054 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1055 pushnc = push -o skip-ci
1058 #+begin_src conf :tangle ~/.gitconfig
1064 Lightweight notification daemon. Eventually I'd like to replace this with something dbus-less.
1066 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1068 font = "JetBrains Mono Medium Nerd Font 11"
1070 format = "<b>%s</b>\n%b"
1072 indicate_hidden = yes
1075 show_age_threshold = 60
1078 geometry = "400x5-10+10"
1080 idle_threshold = 120
1082 sticky_history = yes
1084 separator_height = 1
1086 horizontal_padding = 8
1088 separator_color = "#ffffff"
1089 startup_notification = false
1092 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1099 close_all = mod4+shift+c
1100 history = mod4+ctrl+c
1103 background = "#222222"
1104 foreground = "#ffffff"
1105 highlight = "#ffffff"
1109 background = "#222222"
1110 foreground = "#ffffff"
1111 highlight = "#ffffff"
1115 background = "#222222"
1116 foreground = "#a60000"
1117 highlight = "#ffffff"
1121 The best document reader!
1123 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1125 map <A-b> toggle_statusbar
1126 set selection-clipboard clipboard
1129 set window-title-basename "true"
1130 set selection-clipboard "clipboard"
1133 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1134 set default-bg "#000000"
1135 set default-fg "#ffffff"
1136 set render-loading true
1137 set render-loading-bg "#000000"
1138 set render-loading-fg "#ffffff"
1140 set recolor-lightcolor "#000000" # bg
1141 set recolor-darkcolor "#ffffff" # fg
1145 Just some basic Firefox CSS. Will probably have to rewrite for the Proton redesign.
1146 *** Swap tab and URL bars
1147 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1149 -moz-box-ordinal-group: 1 !important;
1153 -moz-box-ordinal-group: 2 !important;
1157 -moz-box-ordinal-group: 3 !important;
1160 *** Hide URL bar when not focused.
1161 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1162 #navigator-toolbox:not(:focus-within):not(:hover) {
1166 #navigator-toolbox {
1167 transition: 0.1s margin-top ease-out;
1170 *** Black screen by default
1172 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1175 #browser vbox#appcontent tabbrowser,
1177 #tabbrowser-tabpanels,
1179 browser[type="content-primary"],
1180 browser[type="content"] > html,
1182 background: black !important;
1183 color: #fff !important;
1188 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userContent.css
1189 @-moz-document url("about:home"), url("about:blank"), url("about:newtab") {
1191 background: black !important;
1196 Modus operandi theme. No program I use checks for anything beyond foreground and background, but hey, it can't hurt to have all the colors in there.
1197 #+begin_src conf :tangle ~/.Xresources
1199 ,*.foreground: #ffffff
1200 ,*.background: #000000
1201 ,*.cursorColor: #ffffff
1236 I use tmux in order to keep my st build light. Still learning how it works.
1237 #+begin_src conf :tangle ~/.tmux.conf
1240 set-option -g history-limit 50000
1241 set-window-option -g mode-keys vi
1242 bind-key -T copy-mode-vi 'v' send -X begin-selection
1243 bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'
1247 #+begin_src conf :tangle ~/.gnupg/gpg.conf
1248 default-key 3C9ED82FFE788E4A
1252 #+begin_src conf :tangle ~/.gnupg/gpg-agent.conf
1253 pinentry-program /sbin/pinentry-gnome3
1255 default-cache-ttl 600
1256 allow-emacs-pinentry
1259 #+begin_src conf :tangle ~/.config/xmodmap
1266 ! Turn right alt into super
1272 ! Swap caps and control
1274 remove Lock = Caps_Lock
1275 remove Control = Control_L
1276 remove Lock = Control_L
1277 remove Control = Caps_Lock
1278 keysym Control_L = Caps_Lock
1279 keysym Caps_Lock = Control_L
1280 add Lock = Caps_Lock
1281 add Control = Control_L