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 27.2 on Linux, 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-operandi 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-11"))
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))
83 Display relative line numbers except in certain modes.
84 #+begin_src emacs-lisp
85 (global-display-line-numbers-mode)
86 (setq display-line-numbers-type 'relative)
87 (dolist (no-line-num '(
97 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
99 ** Highlight matching parenthesis
100 #+begin_src emacs-lisp
102 :config (show-paren-mode)
103 :custom (show-paren-style 'parenthesis))
106 *** Show current function
107 #+begin_src emacs-lisp
108 (which-function-mode)
110 *** Make position in file more descriptive
111 Show current column and file size.
112 #+begin_src emacs-lisp
114 (size-indication-mode)
117 #+begin_src emacs-lisp
119 :config (minions-mode))
122 Highlight whitespace and other bad text practices.
123 #+begin_src emacs-lisp
124 (use-package whitespace
125 :custom (whitespace-style '(face lines-tail)))
126 (dolist (hook '(prog-mode-hook))
127 (add-hook hook (lambda () (whitespace-mode 1))))
129 ** Highlight todo items in comments
130 #+begin_src emacs-lisp
132 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
133 :config (global-hl-todo-mode 1))
136 #+begin_src emacs-lisp
140 Soft wrap words and do operations by visual lines in some modes.
141 #+begin_src emacs-lisp
142 (dolist (hook '(text-mode-hook
145 mu4e-view-mode-hook))
146 (add-hook hook (lambda () (visual-line-mode 1))))
149 #+begin_src emacs-lisp
150 (dolist (hook '(scdoc-mode-hook
151 mu4e-compose-mode-hook))
152 (add-hook hook (lambda () (auto-fill-mode 1))))
154 ** Display number of matches in search
155 #+begin_src emacs-lisp
158 :config (global-anzu-mode)
160 ([remap isearch-forward] . isearch-forward-regexp)
161 ([remap isearch-backward] . isearch-backward-regexp)
162 ([remap query-replace] . anzu-query-replace)
163 ([remap query-replace] . anzu-query-replace)
164 ([remap query-replace-regexp] . anzu-query-replace-regexp))
166 *** TODO This config doesn't work right
168 Invert modeline color instead of audible bell or the standard visual bell.
169 #+begin_src emacs-lisp
170 (setq visible-bell nil
172 (lambda () (invert-face 'mode-line)
173 (run-with-timer 0.1 nil #'invert-face 'mode-line)))
176 #+begin_src emacs-lisp
180 (setq-default frame-title-format '("%b [%m]"))
183 #+begin_src emacs-lisp
184 (setq auth-sources '("~/.emacs.d/authinfo.gpg"))
187 #+begin_src emacs-lisp
189 :config (shackle-mode)
190 :custom (shackle-rules '(
196 #+begin_src emacs-lisp
198 :custom (select-enable-clipboard nil)
199 :init (setq evil-want-keybinding nil
200 evil-want-minibuffer t
201 evil-want-C-d-scroll t
202 evil-want-C-u-scroll t)
205 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
206 ;; Use visual line motions even outside of visual-line-mode buffers
207 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
208 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
210 ("<escape>" . keyboard-escape-quit)
211 ("C-M-u" . universal-argument))
214 Evil bindings for tons of packages.
215 #+begin_src emacs-lisp
216 (use-package evil-collection
218 :init (evil-collection-init)
219 :custom (evil-collection-setup-minibuffer t))
223 #+begin_src emacs-lisp
224 (use-package evil-surround
225 :config (global-evil-surround-mode))
228 Makes commenting super easy
229 #+begin_src emacs-lisp
230 (use-package evil-nerd-commenter
231 :bind (:map evil-normal-state-map
232 ("gc" . evilnc-comment-or-uncomment-lines))
233 :custom (evilnc-invert-comment-line-by-line nil))
237 #+begin_src emacs-lisp
239 :config (evil-set-undo-system 'undo-fu))
241 (use-package undo-fu-session
242 :config (global-undo-fu-session-mode))
244 ** Number incrementing
245 Add back C-a/C-x bindings.
246 #+begin_src emacs-lisp
247 (use-package evil-numbers
248 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
249 :bind (:map evil-normal-state-map
250 ("C-M-a" . evil-numbers/inc-at-pt)
251 ("C-M-x" . evil-numbers/dec-at-pt)))
254 #+begin_src emacs-lisp
255 (use-package evil-org
257 :hook (org-mode . evil-org-mode)
259 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
261 (use-package evil-org-agenda
262 :straight (:type built-in)
264 :config (evil-org-agenda-set-keys))
268 #+begin_src emacs-lisp
270 :straight (:type built-in)
271 :commands (org-capture org-agenda)
274 (org-agenda-start-with-log-mode t)
275 (org-agenda-files (quote ("~/org/tasks.org")))
277 (org-log-into-drawer t)
278 (org-src-tab-acts-natively t)
279 (org-src-fontify-natively t)
280 (org-startup-indented t)
281 (org-hide-emphasis-markers t)
282 (org-fontify-whole-block-delimiter-line nil)
283 (org-archive-default-command 'org-archive-to-archive-sibling)
285 ("C-c a" . org-agenda)
286 (:map evil-normal-state-map ("ga" . org-archive-subtree-default)))
289 Define templates for lots of common structure elements. Mostly just used within this file.
290 #+begin_src emacs-lisp
291 (use-package org-tempo
293 :straight (:type built-in)
296 ("ash" . "src shell :tangle ~/.config/ash/ashrc")
297 ("el" . "src emacs-lisp")
298 ("git" . "src conf :tangle ~/.config/git/config")
299 ("mb" . "src conf :tangle ~/.config/mbsync/mbsyncrc")
300 ("tm" . "src conf :tangle ~/.config/tmux/f")
301 ("za" . "src conf :tangle ~/.config/zathura/zathurarc")
303 (add-to-list 'org-structure-template-alist addition)))
306 #+begin_src emacs-lisp
307 (use-package org-table-wrap-functions
308 :straight (:repo "analyticd/org-table-wrap-functions" :host github)
309 :bind (:map org-mode-map
310 ("C-\\" . org-table-column-wrap-to-width)
311 ("C-|" . 'org-table-unwrap-cell-region)))
315 A well balanced completion framework.
316 #+begin_src emacs-lisp
318 :bind (:map ivy-minibuffer-map
319 ("TAB" . ivy-alt-done))
320 (:map ivy-switch-buffer-map
321 ("M-d" . ivy-switch-buffer-kill))
325 #+begin_src emacs-lisp
326 (use-package ivy-rich
328 :config (ivy-rich-mode))
332 #+begin_src emacs-lisp
334 :bind ("C-M-j" . 'counsel-switch-buffer)
335 :config (counsel-mode))
337 ** Remember frequent commands
338 #+begin_src emacs-lisp
339 (use-package ivy-prescient
342 (prescient-persist-mode)
343 (ivy-prescient-mode))
347 Use elfeed for reading RSS. I have another file with all the feeds in it that I'd rather keep private.
348 #+begin_src emacs-lisp
350 :bind (("C-c e" . elfeed))
351 :config (load "~/.emacs.d/feeds.el")
352 :custom (elfeed-db-directory "~/.emacs.d/elfeed")
353 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
356 Use mu4e and mbsync for reading emails.
358 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.
361 #+begin_src conf :tangle ~/.config/mbsync/mbsyncrc
367 #+begin_src conf :tangle ~/.config/mbsync/mbsyncrc
368 IMAPStore personal-remote
369 Host imap.mailbox.org
371 PassCmd "pash show login.mailbox.org/me@armaanb.net | head -n 1"
373 MaildirStore personal-local
374 Path ~/mail/personal/
375 Inbox ~/mail/personal/Inbox
378 Channel personal-channel
379 Far :personal-remote:
380 Near :personal-local:
381 Patterns "INBOX*" "Drafts" "Archive" "Sent" "Trash"
384 Channel personal-channel
387 #+begin_src conf :tangle ~/.config/mbsync/mbsyncrc
388 IMAPStore school-remote
391 User abhojwani22@nobles.edu
392 PassCmd "pash show gmail-otp/abhojwani22@nobles.edu | head -n 1"
394 MaildirStore school-local
396 Inbox ~/mail/school/Inbox
399 Channel school-channel
405 Channel school-channel
409 #+begin_src emacs-lisp
410 (use-package smtpmail
411 :straight (:type built-in))
413 :load-path "/usr/share/emacs/site-lisp/mu4e"
414 :straight (:build nil)
415 :bind (("C-c m" . mu4e))
417 (setq user-full-name "Armaan Bhojwani"
418 smtpmail-local-domain "armaanb.net"
419 smtpmail-stream-type 'ssl
420 smtpmail-smtp-service '465
421 mu4e-change-filenames-when-moving t
422 mu4e-get-mail-command "mbsync -a -c ~/.config/mbsync/mbsyncrc"
423 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
424 message-citation-line-function 'message-insert-formatted-citation-line
425 mu4e-completing-read-function 'ivy-completing-read
426 mu4e-confirm-quit nil
428 mail-user-agent 'mu4e-user-agent
429 mu4e-context-policy 'pick-first
431 `( ,(make-mu4e-context
433 :enter-func (lambda () (mu4e-message "Entering school context"))
434 :leave-func (lambda () (mu4e-message "Leaving school context"))
435 :match-func (lambda (msg)
437 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
438 :vars '((user-mail-address . "abhojwani22@nobles.edu")
439 (mu4e-sent-folder . "/school/Sent")
440 (mu4e-drafts-folder . "/school/Drafts")
441 (mu4e-trash-folder . "/school/Trash")
442 (mu4e-refile-folder . "/school/Archive")
443 (message-cite-reply-position . above)
444 (user-mail-address . "abhojwani22@nobles.edu")
445 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
446 (smtpmail-smtp-server . "smtp.gmail.com")))
449 :enter-func (lambda () (mu4e-message "Entering personal context"))
450 :leave-func (lambda () (mu4e-message "Leaving personal context"))
451 :match-func (lambda (msg)
453 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
454 :vars '((mu4e-sent-folder . "/personal/Sent")
455 (mu4e-drafts-folder . "/personal/Drafts")
456 (mu4e-trash-folder . "/personal/Trash")
457 (mu4e-refile-folder . "/personal/Archive")
458 (user-mail-address . "me@armaanb.net")
459 (message-cite-reply-position . below)
460 (smtpmail-smtp-user . "me@armaanb.net")
461 (smtpmail-smtp-server . "smtp.mailbox.org")))))
462 (add-to-list 'mu4e-bookmarks
463 '(:name "Unified inbox"
464 :query "maildir:\"/personal/Inbox\" or maildir:\"/school/Inbox\""
466 :hook ((mu4e-compose-mode . flyspell-mode)
467 (message-send-hook . (lambda () (unless (yes-or-no-p "Ya sure 'bout that?")
468 (signal 'quit nil))))))
470 **** Discourage Gnus from displaying HTML emails
471 #+begin_src emacs-lisp
472 (with-eval-after-load "mm-decode"
473 (add-to-list 'mm-discouraged-alternatives "text/html")
474 (add-to-list 'mm-discouraged-alternatives "text/richtext"))
477 Set EWW as default browser except for multimedia which should open in MPV.
478 #+begin_src emacs-lisp
479 (defun browse-url-mpv (url &optional new-window)
480 "Ask MPV to load URL."
482 (start-process "mpv" "*mpv*" "mpv" url))
484 (setq browse-url-browser-function 'browse-url-generic
485 browse-url-generic-program "chorizo")
487 (setq browse-url-handlers
489 (("youtu\\.?be" . browse-url-mpv)
490 ("peertube.*" . browse-url-mpv)
491 ("vid.*" . browse-url-mpv)
492 ("vid.*" . browse-url-mpv)
493 ("*.mp4" . browse-url-mpv)
494 ("*.mp3" . browse-url-mpv)
495 ("*.ogg" . browse-url-mpv)
499 Some EWW enhancements.
500 *** Give buffer a useful name
501 #+begin_src emacs-lisp
502 ;; From https://protesilaos.com/dotemacs/
503 (defun prot-eww--rename-buffer ()
504 "Rename EWW buffer using page title or URL.
505 To be used by `eww-after-render-hook'."
506 (let ((name (if (eq "" (plist-get eww-data :title))
507 (plist-get eww-data :url)
508 (plist-get eww-data :title))))
509 (rename-buffer (format "*%s # eww*" name) t)))
512 :straight (:type built-in)
513 :bind (("C-c w" . eww))
514 :hook (eww-after-render-hook prot-eww--rename-buffer))
517 #+begin_src emacs-lisp
518 (global-set-key (kbd "C-c w") 'eww)
521 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.
522 #+begin_src emacs-lisp
523 (defun fetch-password (&rest params)
524 (require 'auth-source)
525 (let ((match (car (apply 'auth-source-search params))))
527 (let ((secret (plist-get match :secret)))
528 (if (functionp secret)
531 (error "Password not found for %S" params))))
536 (enable-circe-color-nicks)
537 (setq circe-network-defaults '(("libera"
538 :host "irc.armaanb.net"
543 :pass (lambda (null) (fetch-password
545 :machine "irc.armaanb.net"
548 :host "irc.armaanb.net"
553 :pass (lambda (null) (fetch-password
555 :machine "irc.armaanb.net"
558 :host "irc.armaanb.net"
563 :pass (lambda (null) (fetch-password
565 :machine "irc.armaanb.net"
567 :custom (circe-default-part-message "goodbye!")
568 :bind (:map circe-mode-map ("C-c C-r" . circe-reconnect-all)))
573 (if (get-buffer "irc.armaanb.net:6696")
574 (switch-to-buffer "irc.armaanb.net:6696")
575 (progn (switch-to-buffer "*scratch*")
580 (global-set-key (kbd "C-c i") 'acheam-irc)
583 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.
584 #+begin_src emacs-lisp
585 (defun sync-calendar ()
586 "Sync calendars with vdirsyncer"
588 (async-shell-command "vdirsyncer sync"))
591 :bind (:map cfw:calendar-mode-map ("C-S-u" . sync-calendar)))
592 (use-package calfw-ical)
593 (use-package calfw-org)
595 (defun acheam-calendar ()
598 (cfw:open-calendar-buffer
599 :contents-sources (list
600 (cfw:org-create-source "Green")
601 (cfw:ical-create-source
603 "~/.local/share/vdirsyncer/mailbox/Y2FsOi8vMC8zMQ.ics"
605 (cfw:ical-create-source
607 "~/.local/share/vdirsyncer/mailbox/Y2FsOi8vMC8zMQ.ics"
609 (cfw:ical-create-source
611 "~/.local/share/vdirsyncer/school/abhojwani22@nobles.edu.ics"
615 (global-set-key (kbd "C-c c") 'acheam-calendar)
618 #+begin_src emacs-lisp
619 (use-package pdf-tools
620 :hook (pdf-view-mode . pdf-view-midnight-minor-mode))
624 #+begin_src emacs-lisp
626 :hook (python-mode . blacken-mode)
627 :custom (blacken-line-length 79))
630 ** Strip trailing whitespace
631 #+begin_src emacs-lisp
632 (use-package ws-butler
633 :config (ws-butler-global-mode))
636 Automatic linting. I need to look into configuring this more.
637 #+begin_src emacs-lisp
638 (use-package flycheck
639 :config (global-flycheck-mode))
641 ** Project management
642 I never use this, but apparently its very powerful. Another item on my todo list.
643 #+begin_src emacs-lisp
644 (use-package projectile
645 :config (projectile-mode)
646 :custom ((projectile-completion-system 'ivy))
647 :bind-keymap ("C-c p" . projectile-command-map)
648 :init (setq projectile-switch-project-action #'projectile-dired))
650 (use-package counsel-projectile
652 :config (counsel-projectile-mode))
655 The best file manager!
656 #+begin_src emacs-lisp
658 :straight (:type built-in)
659 :commands (dired dired-jump)
660 :custom (dired-listing-switches "-agh --group-directories-first")
662 ([remap dired-find-file] . dired-single-buffer)
663 ([remap dired-mouse-find-file-other-window] . dired-single-buffer-mouse)
664 ([remap dired-up-directory] . dired-single-up-directory)
665 ("C-x C-j" . dired-jump))
667 (use-package dired-single
668 :commands (dired dired-jump))
670 (use-package dired-open
671 :commands (dired dired-jump)
672 :custom (dired-open-extensions '(("png" . "feh")
675 (use-package dired-hide-dotfiles
676 :hook (dired-mode . dired-hide-dotfiles-mode)
677 :config (evil-collection-define-key 'normal 'dired-mode-map
678 "H" 'dired-hide-dotfiles-mode))
681 #+begin_src emacs-lisp
683 :bind ("C-c t" . man))
687 A very good Git interface.
688 #+begin_src emacs-lisp
692 #+begin_src emacs-lisp
694 ;; (use-package git-email
695 ;; :straight (git-email :repo "https://git.sr.ht/~yoctocell/git-email")
696 ;; :config (git-email-piem-mode))
699 Modified from https://eklitzke.org/smarter-emacs-clang-format.
701 Style is basically ddevault's style guide but with 4 spaces instead of 8 char tabs.
702 #+begin_src emacs-lisp
703 (use-package clang-format
704 :custom (clang-format-style "{
706 AlwaysBreakAfterReturnType: AllDefinitions,
710 (defun clang-format-buffer-smart ()
711 "Reformat buffer if .clang-format exists in the projectile root."
712 (when (file-exists-p (expand-file-name ".clang-format" (projectile-project-root)))
713 (when (if (eq major-mode 'c-mode))
714 (message "Formatting with clang-format...")
715 (clang-format-buffer))))
717 (add-hook 'before-save-hook 'clang-format-buffer-smart nil)
720 #+begin_src emacs-lisp
721 (append auto-mode-alist '("/home/armaa/repos/" . sh-mode))
724 #+begin_src emacs-lisp
725 (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)
727 * General text editing
729 Spell check in text mode, and in prog-mode comments.
730 #+begin_src emacs-lisp
731 (dolist (hook '(text-mode-hook
734 (add-hook hook (lambda () (flyspell-mode))))
735 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
736 (add-hook hook (lambda () (flyspell-mode -1))))
737 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
738 (setq ispell-silently-savep t)
741 #+begin_src emacs-lisp
742 (setq-default tab-width 2)
745 Opens file where you left it.
746 #+begin_src emacs-lisp
750 Distraction free writing a la junegunn/goyo.
751 #+begin_src emacs-lisp
752 (use-package olivetti
753 :bind ("C-c o" . olivetti-mode))
756 Abbreviate things! I just use this for things like my email address and copyright notice.
757 #+begin_src emacs-lisp
758 (setq abbrev-file-name "~/.emacs.d/abbrevs.el")
759 (setq save-abbrevs 'silent)
760 (setq-default abbrev-mode t)
763 #+begin_src emacs-lisp
764 (setq tramp-default-method "ssh")
766 ** Follow version controlled symlinks
767 #+begin_src emacs-lisp
768 (setq vc-follow-symlinks t)
771 #+begin_src emacs-lisp
772 (defun doas-edit (&optional arg)
773 "Edit currently visited file as root.
775 With a prefix ARG prompt for a file to visit. Will also prompt
776 for a file to visit if current buffer is not visiting a file.
778 Modified from Emacs Redux."
780 (if (or arg (not buffer-file-name))
781 (find-file (concat "/doas:root@localhost:"
782 (ido-read-file-name "Find file(as root): ")))
783 (find-alternate-file (concat "/doas:root@localhost:" buffer-file-name))))
785 (global-set-key (kbd "C-x C-r") #'doas-edit)
788 #+begin_src emacs-lisp
789 (use-package markdown-mode)
792 Get it for yourself at https://git.armaanb.net/scdoc
793 #+begin_src emacs-lisp
794 (add-to-list 'load-path "~/src/scdoc-mode")
795 (autoload 'scdoc-mode "scdoc-mode" "Major mode for editing scdoc files" t)
796 (add-to-list 'auto-mode-alist '("\\.scd\\'" . scdoc-mode))
800 #+begin_src emacs-lisp
801 (use-package ace-window
802 :bind ("M-o" . ace-window))
804 ** Kill current buffer
805 Makes "C-x k" binding faster.
806 #+begin_src emacs-lisp
807 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
811 #+begin_src emacs-lisp
812 (use-package scad-mode)
814 ** Control backup and lock files
815 Stop backup files from spewing everywhere.
816 #+begin_src emacs-lisp
817 (setq backup-directory-alist `(("." . "~/.emacs.d/backups"))
818 create-lockfiles nil)
820 ** Make yes/no easier
821 #+begin_src emacs-lisp
822 (defalias 'yes-or-no-p 'y-or-n-p)
824 ** Move customize file
825 No more clogging up init.el.
826 #+begin_src emacs-lisp
827 (setq custom-file "~/.emacs.d/custom.el")
831 #+begin_src emacs-lisp
833 :commands (helpful-callable helpful-variable helpful-command helpful-key)
835 (counsel-describe-function-function #'helpful-callable)
836 (counsel-describe-variable-function #'helpful-variable)
838 ([remap describe-function] . counsel-describe-function)
839 ([remap describe-command] . helpful-command)
840 ([remap describe-variable] . counsel-describe-variable)
841 ([remap describe-key] . helpful-key))
844 #+begin_src emacs-lisp
845 (use-package epa-file
846 :straight (:type built-in)
848 (epa-file-select-keys nil)
849 (epa-file-encrypt-to '("me@armaanb.net"))
850 (password-cache-expiry (* 60 15)))
852 (use-package pinentry
853 :config (pinentry-start))
856 #+begin_src emacs-lisp
858 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
859 :custom (0x0-default-service 'envs))
861 *** TODO Replace this with uploading to my own server
862 Similar to the ufile alias in my ashrc
863 ** Automatically clean buffers
864 Automatically close unused buffers (except those of Circe) at midnight.
865 #+begin_src emacs-lisp
867 (add-to-list 'clean-buffer-list-kill-never-regexps
868 (lambda (buffer-name)
869 (with-current-buffer buffer-name
870 (derived-mode-p 'lui-mode))))
875 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.
876 #+begin_src conf :tangle ~/.config/ash/ashrc
881 #+begin_src shell :tangle ~/.config/ash/ashrc
883 user=$(echo "$1" | cut -f 1 -d '@')
884 host=$(echo "$1" | cut -f 2 -d '@')
885 echo $user | nc "$host" 79
888 **** Upload to ftp.armaanb.net
889 #+begin_src shell :tangle ~/.config/ash/ashrc
891 echo "https://l.armaanb.net/$(basename "$1")" | tee /dev/tty | xclip -sel c
895 rsync "$1" "armaa@armaanb.net:/srv/ftp/pub/$2" --chmod 644 --progress
905 xclip -o -sel c >> "$tmp"
906 basetmp=$(echo "$tmp" | tail -c +5)
907 _uup "$tmp" "$basetmp"
913 **** Default programs
914 #+begin_src shell :tangle ~/.config/ash/ashrc
915 export EDITOR="emacsclient -c"
916 export VISUAL="$EDITOR"
917 export TERM=xterm-256color # for compatability
919 **** General program configs
920 #+begin_src shell :tangle ~/.config/ash/ashrc
921 export GPG_TTY="$(tty)"
923 export GNUPGHOME="$HOME/.local/share/gnupg"
924 export GOPATH="$HOME/.local/share/go"
925 export JUPYTER_CONFIG_DIR="$HOME/.config/jupyter"
926 export IPYTHON_DIR="$HOME/.local/share/ipython"
927 export DISTCC_DIR="$HOME/.local/state/distcc"
930 export GTK_USE_PORTAL=1
932 export LESSHISTFILE=/dev/null
934 export PASH_KEYID=me@armaanb.net
935 export PASH_LENGTH=20
938 #+begin_src shell :tangle ~/.config/ash/ashrc
939 export PATH="/home/armaa/src/bin:$PATH"
940 export PATH="/home/armaa/src/bin/bin:$PATH"
941 export PATH="/home/armaa/.local/bin:$PATH"
942 export PATH="/usr/lib/ccache/bin:$PATH"
945 #+begin_src shell :tangle ~/.config/ash/ashrc
946 export LC_ALL="en_US.UTF-8"
947 export LC_CTYPE="en_US.UTF-8"
948 export LANGUAGE="en_US.UTF-8"
949 export TZ="America/New_York"
952 #+begin_src shell :tangle ~/.config/ash/ashrc
954 export KISS_PATH="$KISS_PATH:$HOME/repos/personal"
955 export KISS_PATH="$KISS_PATH:$HOME/repos/main/core"
956 export KISS_PATH="$KISS_PATH:$HOME/repos/main/extra"
957 export KISS_PATH="$KISS_PATH:$HOME/repos/main/xorg"
958 export KISS_PATH="$KISS_PATH:$HOME/repos/community/community"
959 export KISS_PATH="$KISS_PATH:$HOME/repos/mid/ports"
961 export KISS_COMPRESS=xz
963 **** Compilation flags
964 #+begin_src shell :tangle ~/.config/ash/ashrc
966 export CFLAGS="-O3 -pipe -march=native"
968 export CXXFLAGS="$CFLAGS -stdlib=libc++"
969 export MAKEFLAGS="-j$(nproc)"
970 export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig"
972 **** XDG desktop dirs
973 #+begin_src shell :tangle ~/.config/ash/ashrc
974 export XDG_DESKTOP_DIR="/dev/null"
975 export XDG_DOCUMENTS_DIR="$HOME/documents"
976 export XDG_DOWNLOAD_DIR="$HOME/downloads"
977 export XDG_MUSIC_DIR="$HOME/music"
978 export XDG_PICTURES_DIR="$HOME/pictures"
979 export XDG_VIDEOS_DIR="$HOME/videos"
983 #+begin_src shell :tangle ~/.config/ash/ashrc
984 alias poki='ssh armaanb.net'
985 alias irc='ssh root@armaanb.net -t abduco -A irc catgirl freenode'
986 alias union='ssh 192.168.1.18'
987 alias mine='ssh -p 23 root@pickupserver.cc'
988 alias tcf='ssh root@204.48.23.68'
989 alias ngmun='ssh root@157.245.89.25'
990 alias prox='ssh root@192.168.1.224'
991 alias ncq='ssh root@143.198.123.17'
992 alias envs='ssh acheam@envs.net'
995 #+begin_src shell :tangle ~/.config/ash/ashrc
996 alias ls='LC_COLLATE=C ls -lh --group-directories-first'
998 alias df='df -h / /boot'
1000 alias free='free -m'
1005 alias grep='grep -in'
1006 alias mkdir='mkdir -pv'
1007 alias lanex='java -jar ~/.local/share/lxc/lanxchange.jar && rm lxc*'
1008 emacs() { $EDITOR "$@" & }
1011 **** System management
1012 #+begin_src shell :tangle ~/.config/ash/ashrc
1013 alias crontab='crontab-argh'
1015 alias pasu='git -C ~/.password-store push'
1016 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1020 #+begin_src shell :tangle ~/.config/ash/ashrc
1021 alias ping='ping -c 10'
1022 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1023 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1024 alias plan='T=$(mktemp) && \
1025 rsync armaanb.net:/home/armaa/plan.txt "$T" && \
1027 head -n -2 $T > $TT && \
1030 echo "Last updated: $(date -R)" >> "$TT" && \
1031 fold -sw 72 "$TT" > "$T"| \
1032 rsync "$T" armaanb.net:/home/armaa/plan.txt && \
1035 **** Virtual machines, chroots
1036 #+begin_src shell :tangle ~/.config/ash/ashrc
1037 alias cwindows='qemu-system-x86_64 \
1042 -device VGA,vgamem_mb=64 \
1044 -device hda-duplex \
1046 -net user,smb=/home/armaa/public \
1047 -drive format=qcow2,file=/home/armaa/virtual/windows.qcow2'
1050 #+begin_src shell :tangle ~/.config/ash/ashrc
1051 alias words='gen-shell -c "words"'
1052 alias words-e='gen-shell -c "words ~E"'
1055 #+begin_src shell :tangle ~/.config/ash/ashrc
1056 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1058 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1060 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1061 --restrict-filenames -o '%(title)s.%(ext)s'"
1065 Make MPV play a little bit smoother.
1066 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1067 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1072 #+begin_src conf :tangle ~/.config/git/config
1074 name = Armaan Bhojwani
1075 email = me@armaanb.net
1076 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1079 #+begin_src conf :tangle ~/.config/git/config
1081 defaultBranch = main
1084 #+begin_src conf :tangle ~/.config/git/config
1089 #+begin_src conf :tangle ~/.config/git/config
1091 smtpserver = smtp.mailbox.org
1092 smtpuser = me@armaanb.net
1093 smtpencryption = ssl
1094 smtpserverport = 465
1098 #+begin_src conf :tangle ~/.config/git/config
1103 #+begin_src conf :tangle ~/.config/git/config
1106 sclone = clone --depth 1
1111 quickfix = commit . --amend --no-edit
1113 subup = submodule update --remote
1114 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1115 pushnc = push -o skip-ci
1118 #+begin_src conf :tangle ~/.config/git/config
1124 #+begin_src conf :tangle ~/.config/git/config
1129 The best document reader!
1131 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1132 set selection-clipboard clipboard
1135 set window-title-basename "true"
1136 set selection-clipboard "clipboard"
1139 I use tmux in order to keep my st build light. Still learning how it works.
1140 #+begin_src conf :tangle ~/.config/tmux/tmux.conf
1144 set-option -g history-limit 50000
1146 set -g set-titles on
1147 set -g set-titles-string "#W"
1149 set-window-option -g mode-keys vi
1150 bind-key -T copy-mode-vi 'v' send -X begin-selection
1151 bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'
1155 #+begin_src conf :tangle ~/.local/share/gnupg/gpg.conf
1156 default-key 3C9ED82FFE788E4A
1160 #+begin_src conf :tangle ~/.local/share/gnupg/gpg-agent.conf
1161 pinentry-program /sbin/pinentry
1164 default-cache-ttl 6000
1165 allow-emacs-pinentry
1168 #+begin_src conf :tangle (progn (if (string= (system-name) "frost.armaanb.net") "~/.config/xmodmap" "no"))
1172 ! Turn right alt into super
1176 ! Swap caps and control
1177 remove Lock = Caps_Lock
1178 remove Control = Control_L
1179 remove Lock = Control_L
1180 remove Control = Caps_Lock
1181 keysym Control_L = Caps_Lock
1182 keysym Caps_Lock = Control_L
1183 add Lock = Caps_Lock
1184 add Control = Control_L
1187 #+begin_src shell :tangle ~/.config/sx/sxrc :tangle-mode (identity #o755)