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
148 (add-hook hook (lambda () (visual-line-mode 1))))
151 #+begin_src emacs-lisp
153 mu4e-compose-mode-hook
156 (add-hook hook (lambda () (auto-fill-mode 1))))
158 ** Display number of matches in search
159 #+begin_src emacs-lisp
162 :config (global-anzu-mode)
164 ([remap isearch-forward] . isearch-forward-regexp)
165 ([remap isearch-backward] . isearch-backward-regexp)
166 ([remap query-replace] . anzu-query-replace)
167 ([remap query-replace] . anzu-query-replace)
168 ([remap query-replace-regexp] . anzu-query-replace-regexp))
170 *** TODO This config doesn't work right
172 Invert modeline color instead of audible bell or the standard visual bell.
173 #+begin_src emacs-lisp
174 (setq visible-bell nil
176 (lambda () (invert-face 'mode-line)
177 (run-with-timer 0.1 nil #'invert-face 'mode-line)))
180 #+begin_src emacs-lisp
184 (setq-default frame-title-format '("%b [%m]"))
187 #+begin_src emacs-lisp
188 (setq auth-sources '("~/.emacs.d/authinfo.gpg"))
191 #+begin_src emacs-lisp
193 :config (shackle-mode)
194 :custom (shackle-rules '(
200 #+begin_src emacs-lisp
202 :custom (select-enable-clipboard nil)
203 :init (setq evil-want-keybinding nil
204 evil-want-minibuffer t
205 evil-want-C-d-scroll t
206 evil-want-C-u-scroll t)
209 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
210 ;; Use visual line motions even outside of visual-line-mode buffers
211 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
212 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
214 ("<escape>" . keyboard-escape-quit)
215 ("C-M-u" . universal-argument))
218 Evil bindings for tons of packages.
219 #+begin_src emacs-lisp
220 (use-package evil-collection
222 :init (evil-collection-init)
223 :custom (evil-collection-setup-minibuffer t))
227 #+begin_src emacs-lisp
228 (use-package evil-surround
229 :config (global-evil-surround-mode))
232 Makes commenting super easy
233 #+begin_src emacs-lisp
234 (use-package evil-nerd-commenter
235 :bind (:map evil-normal-state-map
236 ("gc" . evilnc-comment-or-uncomment-lines))
237 :custom (evilnc-invert-comment-line-by-line nil))
241 #+begin_src emacs-lisp
243 :config (evil-set-undo-system 'undo-fu))
245 (use-package undo-fu-session
246 :config (global-undo-fu-session-mode))
248 ** Number incrementing
249 Add back C-a/C-x bindings.
250 #+begin_src emacs-lisp
251 (use-package evil-numbers
252 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
253 :bind (:map evil-normal-state-map
254 ("C-M-a" . evil-numbers/inc-at-pt)
255 ("C-M-x" . evil-numbers/dec-at-pt)))
258 #+begin_src emacs-lisp
259 (use-package evil-org
261 :hook (org-mode . evil-org-mode)
263 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
265 (use-package evil-org-agenda
266 :straight (:type built-in)
268 :config (evil-org-agenda-set-keys))
272 #+begin_src emacs-lisp
274 :straight (:type built-in)
275 :commands (org-capture org-agenda)
277 (org-ellipsis " â–¾")
278 (org-agenda-start-with-log-mode t)
279 (org-agenda-files (quote ("~/org/tasks.org")))
281 (org-log-into-drawer t)
282 (org-src-tab-acts-natively t)
283 (org-src-fontify-natively t)
284 (org-startup-indented t)
285 (org-hide-emphasis-markers t)
286 (org-fontify-whole-block-delimiter-line nil)
287 (org-archive-default-command 'org-archive-to-archive-sibling)
289 ("C-c a" . org-agenda)
290 (:map evil-normal-state-map ("ga" . org-archive-subtree-default)))
293 Define templates for lots of common structure elements. Mostly just used within this file.
294 #+begin_src emacs-lisp
295 (use-package org-tempo
297 :straight (:type built-in)
300 ("ash" . "src shell :tangle ~/.config/ash/ashrc")
301 ("el" . "src emacs-lisp")
302 ("git" . "src conf :tangle ~/.config/git/config")
303 ("mb" . "src conf :tangle ~/.config/mbsync/mbsyncrc")
304 ("tm" . "src conf :tangle ~/.config/tmux/f")
305 ("za" . "src conf :tangle ~/.config/zathura/zathurarc")
307 (add-to-list 'org-structure-template-alist addition)))
310 #+begin_src emacs-lisp
311 (use-package org-table-wrap-functions
312 :straight (:repo "analyticd/org-table-wrap-functions" :host github)
313 :bind (:map org-mode-map
314 ("C-\\" . org-table-column-wrap-to-width)
315 ("C-|" . 'org-table-unwrap-cell-region)))
319 A well balanced completion framework.
320 #+begin_src emacs-lisp
322 :bind (:map ivy-minibuffer-map
323 ("TAB" . ivy-alt-done))
324 (:map ivy-switch-buffer-map
325 ("M-d" . ivy-switch-buffer-kill))
329 #+begin_src emacs-lisp
330 (use-package ivy-rich
332 :config (ivy-rich-mode))
336 #+begin_src emacs-lisp
338 :bind ("C-M-j" . 'counsel-switch-buffer)
339 :config (counsel-mode))
341 ** Remember frequent commands
342 #+begin_src emacs-lisp
343 (use-package ivy-prescient
346 (prescient-persist-mode)
347 (ivy-prescient-mode))
351 Use elfeed for reading RSS. I have another file with all the feeds in it that I'd rather keep private.
352 #+begin_src emacs-lisp
354 :bind (("C-c e" . elfeed))
355 :config (load "~/.emacs.d/feeds.el")
356 :custom (elfeed-db-directory "~/.emacs.d/elfeed")
357 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
360 Use mu4e and mbsync for reading emails.
362 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.
365 #+begin_src conf :tangle ~/.config/mbsync/mbsyncrc
371 #+begin_src conf :tangle ~/.config/mbsync/mbsyncrc
372 IMAPStore personal-remote
373 Host imap.mailbox.org
375 PassCmd "pash show login.mailbox.org/me@armaanb.net | head -n 1"
377 MaildirStore personal-local
378 Path ~/mail/personal/
379 Inbox ~/mail/personal/Inbox
382 Channel personal-channel
383 Far :personal-remote:
384 Near :personal-local:
385 Patterns "INBOX*" "Drafts" "Archive" "Sent" "Trash"
388 Channel personal-channel
391 #+begin_src conf :tangle ~/.config/mbsync/mbsyncrc
392 IMAPStore school-remote
395 User abhojwani22@nobles.edu
396 PassCmd "pash show gmail-otp/abhojwani22@nobles.edu | head -n 1"
398 MaildirStore school-local
400 Inbox ~/mail/school/Inbox
403 Channel school-channel
409 Channel school-channel
413 #+begin_src emacs-lisp
414 (use-package smtpmail
415 :straight (:type built-in))
417 :load-path "/usr/share/emacs/site-lisp/mu4e"
418 :straight (:build nil)
419 :bind (("C-c m" . mu4e))
421 (setq user-full-name "Armaan Bhojwani"
422 smtpmail-local-domain "armaanb.net"
423 smtpmail-stream-type 'ssl
424 smtpmail-smtp-service '465
425 mu4e-change-filenames-when-moving t
426 mu4e-get-mail-command "mbsync -a -c ~/.config/mbsync/mbsyncrc"
427 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
428 message-citation-line-function 'message-insert-formatted-citation-line
429 mu4e-completing-read-function 'ivy-completing-read
430 mu4e-confirm-quit nil
432 mail-user-agent 'mu4e-user-agent
433 mu4e-context-policy 'pick-first
435 `( ,(make-mu4e-context
437 :enter-func (lambda () (mu4e-message "Entering school context"))
438 :leave-func (lambda () (mu4e-message "Leaving school context"))
439 :match-func (lambda (msg)
441 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
442 :vars '((user-mail-address . "abhojwani22@nobles.edu")
443 (mu4e-sent-folder . "/school/Sent")
444 (mu4e-drafts-folder . "/school/Drafts")
445 (mu4e-trash-folder . "/school/Trash")
446 (mu4e-refile-folder . "/school/Archive")
447 (message-cite-reply-position . above)
448 (user-mail-address . "abhojwani22@nobles.edu")
449 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
450 (smtpmail-smtp-server . "smtp.gmail.com")))
453 :enter-func (lambda () (mu4e-message "Entering personal context"))
454 :leave-func (lambda () (mu4e-message "Leaving personal context"))
455 :match-func (lambda (msg)
457 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
458 :vars '((mu4e-sent-folder . "/personal/Sent")
459 (mu4e-drafts-folder . "/personal/Drafts")
460 (mu4e-trash-folder . "/personal/Trash")
461 (mu4e-refile-folder . "/personal/Archive")
462 (user-mail-address . "me@armaanb.net")
463 (message-cite-reply-position . below)
464 (smtpmail-smtp-user . "me@armaanb.net")
465 (smtpmail-smtp-server . "smtp.mailbox.org")))))
466 (add-to-list 'mu4e-bookmarks
467 '(:name "Unified inbox"
468 :query "maildir:\"/personal/Inbox\" or maildir:\"/school/Inbox\""
470 :hook ((mu4e-compose-mode . flyspell-mode)
471 (message-send-hook . (lambda () (unless (yes-or-no-p "Ya sure 'bout that?")
472 (signal 'quit nil))))))
474 **** Discourage Gnus from displaying HTML emails
475 #+begin_src emacs-lisp
476 (with-eval-after-load "mm-decode"
477 (add-to-list 'mm-discouraged-alternatives "text/html")
478 (add-to-list 'mm-discouraged-alternatives "text/richtext"))
481 Set EWW as default browser except for multimedia which should open in MPV.
482 #+begin_src emacs-lisp
483 (defun browse-url-mpv (url &optional new-window)
484 "Ask MPV to load URL."
486 (start-process "mpv" "*mpv*" "mpv" url))
488 (setq browse-url-browser-function 'browse-url-generic
489 browse-url-generic-program "chorizo")
491 (setq browse-url-handlers
493 (("youtu\\.?be" . browse-url-mpv)
494 ("peertube.*" . browse-url-mpv)
495 ("vid.*" . browse-url-mpv)
496 ("vid.*" . browse-url-mpv)
497 ("*.mp4" . browse-url-mpv)
498 ("*.mp3" . browse-url-mpv)
499 ("*.ogg" . browse-url-mpv)
503 Some EWW enhancements.
504 *** Give buffer a useful name
505 #+begin_src emacs-lisp
506 ;; From https://protesilaos.com/dotemacs/
507 (defun prot-eww--rename-buffer ()
508 "Rename EWW buffer using page title or URL.
509 To be used by `eww-after-render-hook'."
510 (let ((name (if (eq "" (plist-get eww-data :title))
511 (plist-get eww-data :url)
512 (plist-get eww-data :title))))
513 (rename-buffer (format "*%s # eww*" name) t)))
516 :straight (:type built-in)
517 :bind (("C-c w" . eww))
518 :hook (eww-after-render-hook prot-eww--rename-buffer))
521 #+begin_src emacs-lisp
522 (global-set-key (kbd "C-c w") 'eww)
525 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.
526 #+begin_src emacs-lisp
527 (defun fetch-password (&rest params)
528 (require 'auth-source)
529 (let ((match (car (apply 'auth-source-search params))))
531 (let ((secret (plist-get match :secret)))
532 (if (functionp secret)
535 (error "Password not found for %S" params))))
540 (enable-circe-color-nicks)
541 (setq circe-network-defaults '(("libera"
542 :host "irc.armaanb.net"
547 :pass (lambda (null) (fetch-password
549 :machine "irc.armaanb.net"
552 :host "irc.armaanb.net"
557 :pass (lambda (null) (fetch-password
559 :machine "irc.armaanb.net"
562 :host "irc.armaanb.net"
567 :pass (lambda (null) (fetch-password
569 :machine "irc.armaanb.net"
571 :custom (circe-default-part-message "goodbye!")
572 :bind (:map circe-mode-map ("C-c C-r" . circe-reconnect-all)))
577 (if (get-buffer "irc.armaanb.net:6696")
578 (switch-to-buffer "irc.armaanb.net:6696")
579 (progn (switch-to-buffer "*scratch*")
584 (global-set-key (kbd "C-c i") 'acheam-irc)
587 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.
588 #+begin_src emacs-lisp
589 (defun sync-calendar ()
590 "Sync calendars with vdirsyncer"
592 (async-shell-command "vdirsyncer sync"))
595 :bind (:map cfw:calendar-mode-map ("C-S-u" . sync-calendar)))
596 (use-package calfw-ical)
597 (use-package calfw-org)
599 (defun acheam-calendar ()
602 (cfw:open-calendar-buffer
603 :contents-sources (list
604 (cfw:org-create-source "Green")
605 (cfw:ical-create-source
607 "~/.local/share/vdirsyncer/mailbox/Y2FsOi8vMC8zMQ.ics"
609 (cfw:ical-create-source
611 "~/.local/share/vdirsyncer/mailbox/Y2FsOi8vMC8zMQ.ics"
613 (cfw:ical-create-source
615 "~/.local/share/vdirsyncer/school/abhojwani22@nobles.edu.ics"
619 (global-set-key (kbd "C-c c") 'acheam-calendar)
622 #+begin_src emacs-lisp
623 (use-package pdf-tools
624 :hook (pdf-view-mode . pdf-view-midnight-minor-mode))
628 #+begin_src emacs-lisp
630 :hook (python-mode . blacken-mode)
631 :custom (blacken-line-length 79))
634 ** Strip trailing whitespace
635 #+begin_src emacs-lisp
636 (use-package ws-butler
637 :config (ws-butler-global-mode))
640 Automatic linting. I need to look into configuring this more.
641 #+begin_src emacs-lisp
642 (use-package flycheck
643 :config (global-flycheck-mode))
645 ** Project management
646 I never use this, but apparently its very powerful. Another item on my todo list.
647 #+begin_src emacs-lisp
648 (use-package projectile
649 :config (projectile-mode)
650 :custom ((projectile-completion-system 'ivy))
651 :bind-keymap ("C-c p" . projectile-command-map)
652 :init (setq projectile-switch-project-action #'projectile-dired))
654 (use-package counsel-projectile
656 :config (counsel-projectile-mode))
659 The best file manager!
660 #+begin_src emacs-lisp
662 :straight (:type built-in)
663 :commands (dired dired-jump)
664 :custom (dired-listing-switches "-agh --group-directories-first")
666 ([remap dired-find-file] . dired-single-buffer)
667 ([remap dired-mouse-find-file-other-window] . dired-single-buffer-mouse)
668 ([remap dired-up-directory] . dired-single-up-directory)
669 ("C-x C-j" . dired-jump))
671 (use-package dired-single
672 :commands (dired dired-jump))
674 (use-package dired-open
675 :commands (dired dired-jump)
676 :custom (dired-open-extensions '(("png" . "feh")
679 (use-package dired-hide-dotfiles
680 :hook (dired-mode . dired-hide-dotfiles-mode)
681 :config (evil-collection-define-key 'normal 'dired-mode-map
682 "H" 'dired-hide-dotfiles-mode))
685 #+begin_src emacs-lisp
687 :bind ("C-c t" . man))
691 A very good Git interface.
692 #+begin_src emacs-lisp
696 #+begin_src emacs-lisp
698 ;; (use-package git-email
699 ;; :straight (git-email :repo "https://git.sr.ht/~yoctocell/git-email")
700 ;; :config (git-email-piem-mode))
703 Modified from https://eklitzke.org/smarter-emacs-clang-format.
705 Style is basically ddevault's style guide but with 4 spaces instead of 8 char tabs.
706 #+begin_src emacs-lisp
707 (use-package clang-format
708 :custom (clang-format-style "{
710 AlwaysBreakAfterReturnType: AllDefinitions,
714 (defun clang-format-buffer-smart ()
715 "Reformat buffer if .clang-format exists in the projectile root."
716 (when (file-exists-p (expand-file-name ".clang-format" (projectile-project-root)))
717 (when (if (eq major-mode 'c-mode))
718 (message "Formatting with clang-format...")
719 (clang-format-buffer))))
721 (add-hook 'before-save-hook 'clang-format-buffer-smart nil)
724 #+begin_src emacs-lisp
725 (append auto-mode-alist '("/home/armaa/repos/" . sh-mode))
728 #+begin_src emacs-lisp
729 (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)
731 * General text editing
733 Spell check in text mode, and in prog-mode comments.
734 #+begin_src emacs-lisp
740 (add-hook hook (lambda () (flyspell-mode))))
741 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
742 (add-hook hook (lambda () (flyspell-mode -1))))
743 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
744 (setq ispell-silently-savep t)
747 #+begin_src emacs-lisp
748 (setq-default tab-width 2)
751 Opens file where you left it.
752 #+begin_src emacs-lisp
756 Distraction free writing a la junegunn/goyo.
757 #+begin_src emacs-lisp
758 (use-package olivetti
759 :bind ("C-c o" . olivetti-mode))
762 Abbreviate things! I just use this for things like my email address and copyright notice.
763 #+begin_src emacs-lisp
764 (setq abbrev-file-name "~/.emacs.d/abbrevs.el")
765 (setq save-abbrevs 'silent)
766 (setq-default abbrev-mode t)
769 #+begin_src emacs-lisp
770 (setq tramp-default-method "ssh")
772 ** Follow version controlled symlinks
773 #+begin_src emacs-lisp
774 (setq vc-follow-symlinks t)
777 #+begin_src emacs-lisp
778 (defun doas-edit (&optional arg)
779 "Edit currently visited file as root.
781 With a prefix ARG prompt for a file to visit. Will also prompt
782 for a file to visit if current buffer is not visiting a file.
784 Modified from Emacs Redux."
786 (if (or arg (not buffer-file-name))
787 (find-file (concat "/doas:root@localhost:"
788 (ido-read-file-name "Find file(as root): ")))
789 (find-alternate-file (concat "/doas:root@localhost:" buffer-file-name))))
791 (global-set-key (kbd "C-x C-r") #'doas-edit)
794 #+begin_src emacs-lisp
795 (use-package markdown-mode)
798 Get it for yourself at https://git.armaanb.net/scdoc
799 #+begin_src emacs-lisp
800 (add-to-list 'load-path "~/src/scdoc-mode")
801 (autoload 'scdoc-mode "scdoc-mode" "Major mode for editing scdoc files" t)
802 (add-to-list 'auto-mode-alist '("\\.scd\\'" . scdoc-mode))
806 #+begin_src emacs-lisp
807 (use-package ace-window
808 :bind ("M-o" . ace-window))
810 ** Kill current buffer
811 Makes "C-x k" binding faster.
812 #+begin_src emacs-lisp
813 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
817 #+begin_src emacs-lisp
818 (use-package scad-mode)
820 ** Control backup and lock files
821 Stop backup files from spewing everywhere.
822 #+begin_src emacs-lisp
823 (setq backup-directory-alist `(("." . "~/.emacs.d/backups"))
824 create-lockfiles nil)
826 ** Make yes/no easier
827 #+begin_src emacs-lisp
828 (defalias 'yes-or-no-p 'y-or-n-p)
830 ** Move customize file
831 No more clogging up init.el.
832 #+begin_src emacs-lisp
833 (setq custom-file "~/.emacs.d/custom.el")
837 #+begin_src emacs-lisp
839 :commands (helpful-callable helpful-variable helpful-command helpful-key)
841 (counsel-describe-function-function #'helpful-callable)
842 (counsel-describe-variable-function #'helpful-variable)
844 ([remap describe-function] . counsel-describe-function)
845 ([remap describe-command] . helpful-command)
846 ([remap describe-variable] . counsel-describe-variable)
847 ([remap describe-key] . helpful-key))
850 #+begin_src emacs-lisp
851 (use-package epa-file
852 :straight (:type built-in)
854 (epa-file-select-keys nil)
855 (epa-file-encrypt-to '("me@armaanb.net"))
856 (password-cache-expiry (* 60 15)))
858 (use-package pinentry
859 :config (pinentry-start))
862 #+begin_src emacs-lisp
864 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
865 :custom (0x0-default-service 'envs))
867 *** TODO Replace this with uploading to my own server
868 Similar to the ufile alias in my ashrc
869 ** Automatically clean buffers
870 Automatically close unused buffers (except those of Circe) at midnight.
871 #+begin_src emacs-lisp
873 (add-to-list 'clean-buffer-list-kill-never-regexps
874 (lambda (buffer-name)
875 (with-current-buffer buffer-name
876 (derived-mode-p 'lui-mode))))
881 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.
882 #+begin_src conf :tangle ~/.config/ash/ashrc
887 #+begin_src shell :tangle ~/.config/ash/ashrc
889 user=$(echo "$1" | cut -f 1 -d '@')
890 host=$(echo "$1" | cut -f 2 -d '@')
891 echo $user | nc "$host" 79
894 **** Upload to ftp.armaanb.net
895 #+begin_src shell :tangle ~/.config/ash/ashrc
897 echo "https://l.armaanb.net/$(basename "$1")" | tee /dev/tty | xclip -sel c
901 rsync "$1" "armaa@armaanb.net:/srv/ftp/pub/$2" --chmod 644 --progress
911 xclip -o -sel c >> "$tmp"
912 basetmp=$(echo "$tmp" | tail -c +5)
913 _uup "$tmp" "$basetmp"
919 **** Default programs
920 #+begin_src shell :tangle ~/.config/ash/ashrc
921 export EDITOR="emacsclient -c"
922 export VISUAL="$EDITOR"
923 export TERM=xterm-256color # for compatability
925 **** General program configs
926 #+begin_src shell :tangle ~/.config/ash/ashrc
927 export GPG_TTY="$(tty)"
929 export GNUPGHOME="$HOME/.local/share/gnupg"
930 export GOPATH="$HOME/.local/share/go"
931 export JUPYTER_CONFIG_DIR="$HOME/.config/jupyter"
932 export IPYTHON_DIR="$HOME/.local/share/ipython"
933 export DISTCC_DIR="$HOME/.local/state/distcc"
936 export GTK_USE_PORTAL=1
938 export LESSHISTFILE=/dev/null
940 export PASH_KEYID=me@armaanb.net
941 export PASH_LENGTH=20
944 #+begin_src shell :tangle ~/.config/ash/ashrc
945 export PATH="/home/armaa/src/bin:$PATH"
946 export PATH="/home/armaa/src/bin/bin:$PATH"
947 export PATH="/home/armaa/.local/bin:$PATH"
948 export PATH="/usr/lib/ccache/bin:$PATH"
951 #+begin_src shell :tangle ~/.config/ash/ashrc
952 export LC_ALL="en_US.UTF-8"
953 export LC_CTYPE="en_US.UTF-8"
954 export LANGUAGE="en_US.UTF-8"
955 export TZ="America/New_York"
958 #+begin_src shell :tangle ~/.config/ash/ashrc
960 export KISS_PATH="$KISS_PATH:$HOME/repos/personal"
961 export KISS_PATH="$KISS_PATH:$HOME/repos/main/core"
962 export KISS_PATH="$KISS_PATH:$HOME/repos/main/extra"
963 export KISS_PATH="$KISS_PATH:$HOME/repos/main/xorg"
964 export KISS_PATH="$KISS_PATH:$HOME/repos/community/community"
965 export KISS_PATH="$KISS_PATH:$HOME/repos/mid/ports"
967 export KISS_COMPRESS=zst
969 **** Compilation flags
970 #+begin_src shell :tangle ~/.config/ash/ashrc
972 export CFLAGS="-O3 -pipe -march=native"
974 export CXXFLAGS="$CFLAGS -stdlib=libc++"
975 export MAKEFLAGS="-j$(nproc)"
976 export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig"
978 **** XDG desktop dirs
979 #+begin_src shell :tangle ~/.config/ash/ashrc
980 export XDG_DESKTOP_DIR="/dev/null"
981 export XDG_DOCUMENTS_DIR="$HOME/documents"
982 export XDG_DOWNLOAD_DIR="$HOME/downloads"
983 export XDG_MUSIC_DIR="$HOME/music"
984 export XDG_PICTURES_DIR="$HOME/pictures"
985 export XDG_VIDEOS_DIR="$HOME/videos"
989 #+begin_src shell :tangle ~/.config/ash/ashrc
990 alias poki='ssh armaanb.net'
991 alias irc='ssh root@armaanb.net -t abduco -A irc catgirl freenode'
992 alias union='ssh 192.168.1.18'
993 alias mine='ssh -p 23 root@pickupserver.cc'
994 alias tcf='ssh root@204.48.23.68'
995 alias ngmun='ssh root@157.245.89.25'
996 alias prox='ssh root@192.168.1.224'
997 alias ncq='ssh root@143.198.123.17'
998 alias envs='ssh acheam@envs.net'
1000 **** File management
1001 #+begin_src shell :tangle ~/.config/ash/ashrc
1002 alias ls='LC_COLLATE=C ls -lh --group-directories-first'
1004 alias df='df -h / /boot'
1006 alias free='free -m'
1011 alias grep='grep -in'
1012 alias mkdir='mkdir -pv'
1013 emacs() { $EDITOR "$@" & }
1016 **** System management
1017 #+begin_src shell :tangle ~/.config/ash/ashrc
1018 alias crontab='crontab-argh'
1020 alias pasu='git -C ~/.password-store push'
1021 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1025 #+begin_src shell :tangle ~/.config/ash/ashrc
1026 alias ping='ping -c 10'
1027 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1028 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1029 alias plan='T=$(mktemp) && \
1030 rsync armaanb.net:/home/armaa/plan.txt "$T" && \
1032 head -n -2 $T > $TT && \
1035 echo "Last updated: $(date -R)" >> "$TT" && \
1036 fold -sw 72 "$TT" > "$T"| \
1037 rsync "$T" armaanb.net:/home/armaa/plan.txt && \
1040 **** Virtual machines, chroots
1041 #+begin_src shell :tangle ~/.config/ash/ashrc
1042 alias cwindows='qemu-system-x86_64 \
1047 -device VGA,vgamem_mb=64 \
1049 -device hda-duplex \
1051 -net user,smb=/home/armaa/public \
1052 -drive format=qcow2,file=/home/armaa/virtual/windows.qcow2'
1055 #+begin_src shell :tangle ~/.config/ash/ashrc
1056 alias words='gen-shell -c "words"'
1057 alias words-e='gen-shell -c "words ~E"'
1060 #+begin_src shell :tangle ~/.config/ash/ashrc
1061 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1063 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1065 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1066 --restrict-filenames -o '%(title)s.%(ext)s'"
1070 Make MPV play a little bit smoother.
1071 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1072 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1077 #+begin_src conf :tangle ~/.config/git/config
1079 name = Armaan Bhojwani
1080 email = me@armaanb.net
1081 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1084 #+begin_src conf :tangle ~/.config/git/config
1086 defaultBranch = main
1089 #+begin_src conf :tangle ~/.config/git/config
1094 #+begin_src conf :tangle ~/.config/git/config
1096 smtpserver = smtp.mailbox.org
1097 smtpuser = me@armaanb.net
1098 smtpencryption = ssl
1099 smtpserverport = 465
1103 #+begin_src conf :tangle ~/.config/git/config
1108 #+begin_src conf :tangle ~/.config/git/config
1111 sclone = clone --depth 1
1116 quickfix = commit . --amend --no-edit
1118 subup = submodule update --remote
1119 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1120 pushnc = push -o skip-ci
1123 #+begin_src conf :tangle ~/.config/git/config
1129 #+begin_src conf :tangle ~/.config/git/config
1134 The best document reader!
1136 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1137 set selection-clipboard clipboard
1140 set window-title-basename "true"
1141 set selection-clipboard "clipboard"
1144 I use tmux in order to keep my st build light. Still learning how it works.
1145 #+begin_src conf :tangle ~/.config/tmux/tmux.conf
1149 set-option -g history-limit 50000
1151 set -g set-titles on
1152 set -g set-titles-string "#W"
1154 set-window-option -g mode-keys vi
1155 bind-key -T copy-mode-vi 'v' send -X begin-selection
1156 bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'
1160 #+begin_src conf :tangle ~/.local/share/gnupg/gpg.conf
1161 default-key 3C9ED82FFE788E4A
1165 #+begin_src conf :tangle ~/.local/share/gnupg/gpg-agent.conf
1166 pinentry-program /sbin/pinentry
1169 default-cache-ttl 6000
1170 allow-emacs-pinentry
1173 #+begin_src conf :tangle (progn (if (string= (system-name) "frost.armaanb.net") "~/.config/xmodmap" "no"))
1177 ! Turn right alt into super
1181 ! Swap caps and control
1182 remove Lock = Caps_Lock
1183 remove Control = Control_L
1184 remove Lock = Control_L
1185 remove Control = Caps_Lock
1186 keysym Control_L = Caps_Lock
1187 keysym Caps_Lock = Control_L
1188 add Lock = Caps_Lock
1189 add Control = Control_L
1192 #+begin_src shell :tangle ~/.config/sx/sxrc :tangle-mode (identity #o755)