1 #+TITLE: System Configuration
2 #+DESCRIPTION: Personal system configuration in org-mode format.
3 #+AUTHOR: Armaan Bhojwani
4 #+EMAIL: me@armaanb.net
7 Welcome to my system configuration! This file contains my Emacs configuration, but also my config files for many of the other programs on my system!
9 I am currently using GCCEmacs 28 from the feature/native-comp branch, so some settings may not be available for older versions of Emacs. This is a purely personal configuration, so while I can garuntee that it works on my setup, I can't for anything else.
11 I chose to create a powerful, yet not overly heavy Emacs configuration. Things like LSP mode are important to my workflow and help me be productive, so despite its weight, it is kept. Things like a fancy modeline or icons on the other hand, do not increase my productivity, and create visual clutter, and thus have been excluded.
13 Another important choice has been to integrate Emacs into a large part of my computing environment (see [[*EmacsOS]]). I use Email, IRC, et cetera, all through Emacs which simplifies my workflow.
15 Lastly, I use Evil mode. I think modal keybindings are simple and more ergonomic than standard Emacs style, and Vim keybindings are what I'm comfortable with and are pervasive throughout computing.
17 *** TODO Turn keybinding and hook declarations into use-package declarations where possible
18 *** TODO Put configs with passwords in here with some kind of authentication
22 Released under the [[https://opensource.org/licenses/MIT][MIT license]] by Armaan Bhojwani, 2021. Note that many snippets are taken from online, and other sources, who are credited for their work at the snippet.
24 ** Bootstrap straight.el
25 straight.el is really nice for managing package, and it integrates nicely with use-package. It uses the bootstrapping system defined here for installation.
26 #+begin_src emacs-lisp
27 (defvar bootstrap-version)
29 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
30 (bootstrap-version 5))
31 (unless (file-exists-p bootstrap-file)
33 (url-retrieve-synchronously
34 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
35 'silent 'inhibit-cookies)
36 (goto-char (point-max))
37 (eval-print-last-sexp)))
38 (load bootstrap-file nil 'nomessage))
40 ** Replace use-package with straight
41 #+begin_src emacs-lisp
42 (straight-use-package 'use-package)
43 (setq straight-use-package-by-default t)
47 Very nice high contrast theme.
49 Its fine to set this here because I run Emacs in daemon mode, but if I were not, then putting it in early-init.el would be a better choice to eliminate the window being white before the theme is loaded.
50 #+begin_src emacs-lisp
51 (setq modus-themes-slanted-constructs t
52 modus-themes-bold-constructs t
53 modus-themes-org-blocks 'grayscale
54 modus-themes-mode-line '3d
55 modus-themes-scale-headings t
56 modus-themes-region 'no-extend
57 modus-themes-diffs 'desaturated)
58 (load-theme 'modus-vivendi t)
62 Great programming font with ligatures.
63 #+begin_src emacs-lisp
64 (add-to-list 'default-frame-alist '(font . "JetBrainsMonoNF-12"))
67 #+begin_src emacs-lisp
69 :straight (ligature :type git :host github :repo "mickeynp/ligature.el")
71 (ligature-set-ligatures
72 '(prog-mode text-mode)
73 '("-|" "-~" "---" "-<<" "-<" "--" "->" "->>" "-->" "/=" "/=="
74 "/>" "//" "/*" "*>" "*/" "<-" "<<-" "<=>" "<=" "<|" "<||"
75 "<|||" "<|>" "<:" "<>" "<-<" "<<<" "<==" "<<=" "<=<" "<==>"
76 "<-|" "<<" "<~>" "<=|" "<~~" "<~" "<$>" "<$" "<+>" "<+" "</>"
77 "</" "<*" "<*>" "<->" "<!--" ":>" ":<" ":::" "::" ":?" ":?>"
78 ":=" "::=" "=>>" "==>" "=/=" "=!=" "=>" "===" "=:=" "==" "!=="
79 "!!" "!=" ">]" ">:" ">>-" ">>=" ">=>" ">>>" ">-" ">=" "&&&"
80 "&&" "|||>" "||>" "|>" "|]" "|}" "|=>" "|->" "|=" "||-" "|-"
81 "||=" "||" ".." ".?" ".=" ".-" "..<" "..." "+++" "+>" "++"
82 "[||]" "[<" "[|" "{|" "?." "?=" "?:" "##" "###" "####" "#["
83 "#{" "#=" "#!" "#:" "#_(" "#_" "#?" "#(" ";;" "_|_" "__" "~~"
84 "~~>" "~>" "~-" "~@" "$>" "^=" "]#"))
85 (global-ligature-mode t))
88 #+begin_src emacs-lisp
90 :config (global-emojify-mode))
92 ;; http://ergoemacs.org/emacs/emacs_list_and_set_font.html
97 ((member "Twitter Color Emoji" (font-family-list)) "Twitter Color Emoji")
98 ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
99 ((member "Noto Emoji" (font-family-list)) "Noto Emoji")))
102 Display relative line numbers except in some modes
103 #+begin_src emacs-lisp
104 (global-display-line-numbers-mode)
105 (setq display-line-numbers-type 'relative)
106 (dolist (no-line-num '(term-mode-hook
111 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
113 ** Highlight matching parenthesis
114 #+begin_src emacs-lisp
116 :config (show-paren-mode)
117 :custom (show-paren-style 'parenthesis))
120 *** Show current function
121 #+begin_src emacs-lisp
122 (which-function-mode)
124 *** Make position in file more descriptive
125 Show current column and file size.
126 #+begin_src emacs-lisp
128 (size-indication-mode)
131 #+begin_src emacs-lisp
133 :config (minions-mode))
136 #+begin_src emacs-lisp
138 :straight (wc-mode :type git :host github :repo "bnbeckwith/wc-mode")
139 :hook (text-mode-hook . wc-mode))
142 Show a ruler at a certain number of chars depending on mode.
143 #+begin_src emacs-lisp
144 (global-display-fill-column-indicator-mode)
147 Whenever starting a key chord, show possible future steps.
148 #+begin_src emacs-lisp
149 (use-package which-key
150 :config (which-key-mode)
151 :custom (which-key-idle-delay 0.3))
153 ** Highlight TODOs in comments
154 #+begin_src emacs-lisp
156 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
157 :config (global-hl-todo-mode 1))
160 #+begin_src emacs-lisp
164 Soft wrap words and do operations by visual lines.
165 #+begin_src emacs-lisp
166 (add-hook 'text-mode-hook 'turn-on-visual-line-mode)
168 ** Display number of matches in search
169 #+begin_src emacs-lisp
171 :config (global-anzu-mode))
174 Inverts modeline instead of audible bell or the standard visual bell.
175 #+begin_src emacs-lisp
176 (setq visible-bell nil
177 ring-bell-function 'flash-mode-line)
178 (defun flash-mode-line ()
179 (invert-face 'mode-line)
180 (run-with-timer 0.1 nil #'invert-face 'mode-line))
184 #+begin_src emacs-lisp
186 :custom (select-enable-clipboard nil)
189 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
190 ;; Use visual line motions even outside of visual-line-mode buffers
191 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
192 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
193 (global-set-key (kbd "<escape>") 'keyboard-escape-quit))
196 #+begin_src emacs-lisp
197 (use-package evil-collection
199 :init (evil-collection-init)
200 :custom (evil-collection-setup-minibuffer t))
204 #+begin_src emacs-lisp
205 (use-package evil-surround
206 :config (global-evil-surround-mode))
209 #+begin_src emacs-lisp
210 (use-package evil-leader
211 :straight (evil-leader :type git :host github :repo "cofi/evil-leader")
213 (evil-leader/set-leader "<SPC>")
214 (global-evil-leader-mode))
217 #+begin_src emacs-lisp
219 (use-package evil-nerd-commenter
220 :bind (:map evil-normal-state-map
221 ("gc" . evilnc-comment-or-uncomment-lines))
222 :custom (evilnc-invert-comment-line-by-line nil))
226 #+begin_src emacs-lisp
227 (evil-set-undo-system 'undo-redo)
229 ** Number incrementing
231 #+begin_src emacs-lisp
232 (use-package evil-numbers
233 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
234 :bind (:map evil-normal-state-map
235 ("C-M-a" . evil-numbers/inc-at-pt)
236 ("C-M-x" . evil-numbers/dec-at-pt)))
240 #+begin_src emacs-lisp
241 (use-package evil-org
243 :hook (org-mode . evil-org-mode)
245 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
246 (use-package evil-org-agenda
247 :straight (:type built-in)
250 (evil-org-agenda-set-keys))
253 #+begin_src emacs-lisp
254 (evil-leader/set-key-for-mode 'org-mode
255 "T" 'org-show-todo-tree
257 "c" 'org-archive-subtree)
261 #+begin_src emacs-lisp
263 :straight (:type built-in)
264 :commands (org-capture org-agenda)
267 (org-agenda-start-with-log-mode t)
268 (org-agenda-files (quote ("~/Org/tasks.org" "~/Org/break.org")))
270 (org-log-into-drawer t)
271 (org-src-tab-acts-natively t)
272 (org-src-fontify-natively t)
273 (org-startup-indented t)
274 (org-hide-emphasis-markers t)
275 (org-fontify-whole-block-delimiter-line nil)
276 :bind ("C-c a" . org-agenda))
279 #+begin_src emacs-lisp
280 (use-package org-tempo
282 :straight (:type built-in)
284 ;; TODO: There's gotta be a more efficient way to write this
285 (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
286 (add-to-list 'org-structure-template-alist '("sp" . "src conf :tangle ~/.spectrwm.conf"))
287 (add-to-list 'org-structure-template-alist '("zsh" . "src shell :tangle ~/.config/zsh/zshrc"))
288 (add-to-list 'org-structure-template-alist '("al" . "src yml :tangle ~/.config/alacritty/alacritty.yml"))
289 (add-to-list 'org-structure-template-alist '("ipy" . "src python :tangle ~/.ipython/"))
290 (add-to-list 'org-structure-template-alist '("pi" . "src conf :tangle ~/.config/picom/picom.conf"))
291 (add-to-list 'org-structure-template-alist '("git" . "src conf :tangle ~/.gitconfig"))
292 (add-to-list 'org-structure-template-alist '("du" . "src conf :tangle ~/.config/dunst/dunstrc"))
293 (add-to-list 'org-structure-template-alist '("za" . "src conf :tangle ~/.config/zathura/zathurarc"))
294 (add-to-list 'org-structure-template-alist '("ff1" . "src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css"))
295 (add-to-list 'org-structure-template-alist '("ff2" . "src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userContent.css"))
296 (add-to-list 'org-structure-template-alist '("xr" . "src conf :tangle ~/.Xresources")))
299 #+begin_src emacs-lisp
300 (use-package org-present
301 :straight (org-present :type git :host github :repo "rlister/org-present"))
305 Simple, but not too simple autocompletion.
306 #+begin_src emacs-lisp
308 :bind (("C-s" . swiper)
309 :map ivy-minibuffer-map
310 ("TAB" . ivy-alt-done)
311 :map ivy-switch-buffer-map
312 ("M-d" . ivy-switch-buffer-kill))
316 #+begin_src emacs-lisp
317 (use-package ivy-rich
319 :config (ivy-rich-mode))
323 #+begin_src emacs-lisp
325 :bind (("C-M-j" . 'counsel-switch-buffer)
326 :map minibuffer-local-map
327 ("C-r" . 'counsel-minibuffer-history))
328 :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
329 :config (counsel-mode))
331 ** Remember frequent commands
332 #+begin_src emacs-lisp
333 (use-package ivy-prescient
336 (ivy-prescient-enable-filtering nil)
338 (prescient-persist-mode)
339 (ivy-prescient-mode))
342 Better search utility.
343 #+begin_src emacs-lisp
348 Use elfeed for RSS. I have another file with all the feeds in it.
349 #+begin_src emacs-lisp
351 :bind (("C-c e" . elfeed))
353 (load "~/.emacs.d/feeds.el")
354 (add-hook 'elfeed-new-entry-hook
355 (elfeed-make-tagger :feed-url "youtube\\.com"
357 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
359 (use-package elfeed-goodies
361 :config (elfeed-goodies/setup))
364 Use mu4e for reading emails.
366 I use `offlineimap` to sync my maildirs. It is slower than mbsync, but is fast enough for me, especially when ran with the =-q= option.
368 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.
369 #+begin_src emacs-lisp
370 (use-package smtpmail
371 :straight (:type built-in))
373 :load-path "/usr/share/emacs/site-lisp/mu4e"
374 :straight (:build nil)
375 :bind (("C-c m" . mu4e))
377 (setq user-full-name "Armaan Bhojwani"
378 smtpmail-local-domain "armaanb.net"
379 smtpmail-stream-type 'ssl
380 smtpmail-smtp-service '465
381 mu4e-change-filenames-when-moving t
382 mu4e-get-mail-command "offlineimap -q"
383 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
384 message-citation-line-function 'message-insert-formatted-citation-line
385 mu4e-completing-read-function 'ivy-completing-read
386 mu4e-confirm-quit nil
387 mail-user-agent 'mu4e-user-agent
389 `( ,(make-mu4e-context
391 :enter-func (lambda () (mu4e-message "Entering school context"))
392 :leave-func (lambda () (mu4e-message "Leaving school context"))
393 :match-func (lambda (msg)
395 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
396 :vars '((user-mail-address . "abhojwani22@nobles.edu")
397 (mu4e-sent-folder . "/school/Sent")
398 (mu4e-drafts-folder . "/school/Drafts")
399 (mu4e-trash-folder . "/school/Trash")
400 (mu4e-refile-folder . "/school/Archive")
401 (user-mail-address . "abhojwani22@nobles.edu")
402 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
403 (smtpmail-smtp-server . "smtp.gmail.com")))
406 :enter-func (lambda () (mu4e-message "Entering personal context"))
407 :leave-func (lambda () (mu4e-message "Leaving personal context"))
408 :match-func (lambda (msg)
410 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
411 :vars '((mu4e-sent-folder . "/personal/Sent")
412 (mu4e-drafts-folder . "/personal/Drafts")
413 (mu4e-trash-folder . "/personal/Trash")
414 (mu4e-refile-folder . "/personal/Archive")
415 (user-mail-address . "me@armaanb.net")
416 (smtpmail-smtp-user . "me@armaanb.net")
417 (smtpmail-smtp-server "smtp.mailbox.org")
418 (mu4e-drafts-folder . "/school/Drafts")
419 (mu4e-trash-folder . "/school/Trash")))))
420 (add-to-list 'mu4e-bookmarks
421 '(:name "Unified inbox"
422 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
424 :hook ((mu4e-compose-mode . flyspell-mode)
425 (mu4e-view-mode-hook . turn-on-visual-line-mode)))
428 Set EWW as default browser except for videos.
429 #+begin_src emacs-lisp
430 (defun browse-url-mpv (url &optional new-window)
432 (start-process "mpv" "*mpv*" "mpv" url))
434 (setq browse-url-handlers
436 (("youtu\\.?be" . browse-url-mpv)
437 ("peertube.*" . browse-url-mpv)
438 ("vid.*" . browse-url-mpv)
439 ("vid.*" . browse-url-mpv)
440 ("." . eww-browse-url)
444 Some EWW enhancements.
445 *** Give buffer a useful name
446 #+begin_src emacs-lisp
447 ;; From https://protesilaos.com/dotemacs/
448 (defun prot-eww--rename-buffer ()
449 "Rename EWW buffer using page title or URL.
450 To be used by `eww-after-render-hook'."
451 (let ((name (if (eq "" (plist-get eww-data :title))
452 (plist-get eww-data :url)
453 (plist-get eww-data :title))))
454 (rename-buffer (format "*%s # eww*" name) t)))
456 (add-hook 'eww-after-render-hook #'prot-eww--rename-buffer)
458 *** Better entrypoint
459 #+begin_src emacs-lisp
460 ;; From https://protesilaos.com/dotemacs/
461 (defun prot-eww-browse-dwim (url &optional arg)
462 "Visit a URL, maybe from `eww-prompt-history', with completion.
464 With optional prefix ARG (\\[universal-argument]) open URL in a
467 If URL does not look like a valid link, run a web query using
470 When called from an eww buffer, provide the current link as
474 (completing-read "Query:" eww-prompt-history
475 nil nil (plist-get eww-data :url) 'eww-prompt-history)
477 (eww url (if arg 4 nil)))
479 (global-set-key (kbd "C-c w") 'prot-eww-browse-dwim)
482 #+begin_src emacs-lisp
484 :straight (:type built-in)
486 (load "~/.emacs.d/irc.el")
488 (erc-notifications-enable)
489 (erc-smiley-disable))
491 (use-package erc-hl-nicks
492 :config (erc-hl-nicks-mode 1))
495 Use Emacs globally. Use the Emacs daemon and bind a key in your wm to
496 =emacsclient --eval "(emacs-everywhere)"=.
497 #+begin_src emacs-lisp
498 (use-package emacs-everywhere)
502 #+begin_src emacs-lisp
504 :hook (python-mode . blacken-mode)
506 (setq blacken-line-length 79))
509 (use-package ws-butler
511 (ws-butler-global-mode))
514 #+begin_src emacs-lisp
515 (use-package flycheck
517 (global-flycheck-mode))
519 ** Project management
520 #+begin_src emacs-lisp
521 (use-package projectile
522 :config (projectile-mode)
523 :custom ((projectile-completion-system 'ivy))
525 ("C-c p" . projectile-command-map)
527 (when (file-directory-p "~/Code")
528 (setq projectile-project-search-path '("~/Code")))
529 (setq projectile-switch-project-action #'projectile-dired))
531 (use-package counsel-projectile
533 :config (counsel-projectile-mode))
536 #+begin_src emacs-lisp
538 :straight (:type built-in)
539 :commands (dired dired-jump)
540 :custom ((dired-listing-switches "-agho --group-directories-first"))
542 (evil-collection-define-key 'normal 'dired-mode-map
543 "h" 'dired-single-up-directory
544 "l" 'dired-single-buffer))
546 (use-package dired-single
547 :commands (dired dired-jump))
549 (use-package dired-open
550 :commands (dired dired-jump)
552 (dired-open-extensions '(("png" . "feh")
555 (use-package dired-hide-dotfiles
556 :hook (dired-mode . dired-hide-dotfiles-mode)
558 (evil-collection-define-key 'normal 'dired-mode-map
559 "H" 'dired-hide-dotfiles-mode))
563 # TODO: Write a command that commits hunk, skipping staging step.
564 #+begin_src emacs-lisp
567 *** Colored diff in line number area
568 #+begin_src emacs-lisp
570 :straight (diff-hl :type git :host github :repo "dgutov/diff-hl")
571 :hook ((magit-pre-refresh-hook . diff-hl-magit-pre-refresh)
572 (magit-post-refresh-hook . diff-hl-magit-post-refresh))
573 :config (global-diff-hl-mode))
575 * General text editing
577 Indent after every change.
578 #+begin_src emacs-lisp
579 (use-package aggressive-indent
580 :config (global-aggressive-indent-mode))
583 Spell check in text mode, and in prog-mode comments.
584 #+begin_src emacs-lisp
585 (dolist (hook '(text-mode-hook))
586 (add-hook hook (lambda () (flyspell-mode))))
587 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
588 (add-hook hook (lambda () (flyspell-mode -1))))
589 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
591 ** Expand tabs to spaces
592 #+begin_src emacs-lisp
593 (setq-default tab-width 2)
595 ** Copy kill ring to clipboard
596 #+begin_src emacs-lisp
597 (setq x-select-enable-clipboard t)
598 (defun copy-kill-ring-to-xorg ()
599 "Copy the current kill ring to the xorg clipboard."
601 (x-select-text (current-kill 0)))
604 #+begin_src emacs-lisp
605 (use-package browse-kill-ring)
608 Opens file where you left it.
609 #+begin_src emacs-lisp
613 Distraction free writing a la junegunn/goyo.
614 #+begin_src emacs-lisp
615 (use-package olivetti
617 (evil-leader/set-key "o" 'olivetti-mode))
621 #+begin_src emacs-lisp
622 (setq abbrev-file-name "~/.emacs.d/abbrevs")
623 (setq save-abbrevs 'silent)
624 (setq-default abbrev-mode t)
627 #+begin_src emacs-lisp
628 (setq tramp-default-method "ssh")
630 ** Don't ask about following symlinks in vc
631 #+begin_src emacs-lisp
632 (setq vc-follow-symlinks t)
634 ** Don't ask to save custom dictionary
635 #+begin_src emacs-lisp
636 (setq ispell-silently-savep t)
639 ** Easily convert splits
640 Converts splits from horizontal to vertical and vice versa. Lifted from EmacsWiki.
641 #+begin_src emacs-lisp
642 (defun toggle-window-split ()
644 (if (= (count-windows) 2)
645 (let* ((this-win-buffer (window-buffer))
646 (next-win-buffer (window-buffer (next-window)))
647 (this-win-edges (window-edges (selected-window)))
648 (next-win-edges (window-edges (next-window)))
649 (this-win-2nd (not (and (<= (car this-win-edges)
650 (car next-win-edges))
651 (<= (cadr this-win-edges)
652 (cadr next-win-edges)))))
654 (if (= (car this-win-edges)
655 (car (window-edges (next-window))))
656 'split-window-horizontally
657 'split-window-vertically)))
658 (delete-other-windows)
659 (let ((first-win (selected-window)))
661 (if this-win-2nd (other-window 1))
662 (set-window-buffer (selected-window) this-win-buffer)
663 (set-window-buffer (next-window) next-win-buffer)
664 (select-window first-win)
665 (if this-win-2nd (other-window 1))))))
667 (define-key ctl-x-4-map "t" 'toggle-window-split)
670 #+begin_src emacs-lisp
671 (defun insert-date ()
673 (insert (format-time-string "%Y-%m-%d")))
677 #+begin_src emacs-lisp
678 (use-package ace-window
679 :bind ("M-o" . ace-window))
681 ** Kill current buffer
682 Makes "C-x k" binding faster.
683 #+begin_src emacs-lisp
684 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
688 Render OpenSCAD files, and add a preview window.
690 Personal fork just merges a PR.
691 #+begin_src emacs-lisp
692 (use-package scad-mode)
693 (use-package scad-preview
694 :straight (scad-preview :type git :host github :repo "Armaanb/scad-preview"))
696 ** Control backup files
697 Stop backup files from spewing everywhere.
698 #+begin_src emacs-lisp
699 (setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
701 ** Make yes/no easier
702 #+begin_src emacs-lisp
703 (defalias 'yes-or-no-p 'y-or-n-p)
705 ** Move customize file
706 No more clogging up init.el.
707 #+begin_src emacs-lisp
708 (setq custom-file "~/.emacs.d/custom.el")
712 #+begin_src emacs-lisp
714 :commands (helpful-callable helpful-variable helpful-command helpful-key)
716 (counsel-describe-function-function #'helpful-callable)
717 (counsel-describe-variable-function #'helpful-variable)
719 ([remap describe-function] . counsel-describe-function)
720 ([remap describe-command] . helpful-command)
721 ([remap describe-variable] . counsel-describe-variable)
722 ([remap describe-key] . helpful-key))
725 #+begin_src emacs-lisp
726 (use-package epa-file
727 :straight (:type built-in)
729 (epa-file-select-keys nil)
730 (epa-file-encrypt-to '("me@armaanb.net"))
731 (password-cache-expiry (* 60 15)))
733 (use-package pinentry
734 :config (pinentry-start))
737 #+begin_src emacs-lisp
739 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
740 :custom (0x0-default-service 'envs)
741 :config (evil-leader/set-key
743 "0f" '0x0-upload-file
744 "0s" '0x0-upload-string
745 "0c" '0x0-upload-kill-ring
746 "0p" '0x0-upload-popup))
751 #+begin_src conf :tangle ~/.spectrwm.conf
755 autorun = ws[1]:/home/armaa/Code/scripts/autostart
758 #+begin_src conf :tangle ~/.spectrwm.conf
760 bar_font = xos4 Fira Code:pixelsize=14:antialias=true # any installed font
764 #+begin_src conf :tangle ~/.spectrwm.conf
765 program[term] = alacritty
766 program[screenshot_all] = flameshot gui
767 program[notif] = /home/armaa/Code/scripts/setter status
768 program[pass] = /home/armaa/Code/scripts/passmenu
771 bind[pass] = MOD+Shift+p
774 #+begin_src conf :tangle ~/.spectrwm.conf
775 program[paup] = /home/armaa/Code/scripts/setter audio +5
776 program[padown] = /home/armaa/Code/scripts/setter audio -5
777 program[pamute] = /home/armaa/Code/scripts/setter audio
778 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
779 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
780 program[next] = playerctl next
781 program[prev] = playerctl previous
782 program[pause] = playerctl play-pause
784 bind[padown] = XF86AudioLowerVolume
785 bind[paup] = XF86AudioRaiseVolume
786 bind[pamute] = XF86AudioMute
787 bind[brigdown] = XF86MonBrightnessDown
788 bind[brigup] = XF86MonBrightnessUp
789 bind[pause] = XF86AudioPlay
790 bind[next] = XF86AudioNext
791 bind[prev] = XF86AudioPrev
794 #+begin_src conf :tangle ~/.spectrwm.conf
795 program[h] = xdotool keyup h key --clearmodifiers Left
796 program[j] = xdotool keyup j key --clearmodifiers Down
797 program[k] = xdotool keyup k key --clearmodifiers Up
798 program[l] = xdotool keyup l key --clearmodifiers Right
800 bind[h] = MOD + Control + h
801 bind[j] = MOD + Control + j
802 bind[k] = MOD + Control + k
803 bind[l] = MOD + Control + l
806 #+begin_src conf :tangle ~/.spectrwm.conf
807 program[aerc] = alacritty -e aerc
808 program[catgirl] = alacritty --hold -e sh -c "while : ; do ssh root@armaanb.net -t abduco -A irc catgirl freenode; sleep 2; done"
809 program[emacs] = emacsclient -c
810 program[firefox] = firefox
811 program[calc] = alacritty -e bc
812 program[emacs-anywhere] = emacsclient --eval "(emacs-everywhere)"
814 bind[aerc] = MOD+Control+1
815 bind[catgirl] = MOD+Control+2
816 bind[firefox] = MOD+Control+3
817 bind[emacs-anywhere] = MOD+Control+4
818 bind[calc] = MOD+Control+5
819 bind[emacs] = MOD+Control+Return
822 #+begin_src conf :tangle ~/.spectrwm.conf
823 quirk[Castle Menu] = FLOAT
828 #+begin_src shell :tangle ~/.config/zsh/zshrc
829 autoload -Uz compinit
833 unsetopt glob_complete
835 # Fragment completions
836 zstyle ':completion:*' list-suffixes
zstyle ':completion:*' expand prefix suffix
839 zstyle ':completion:*' menu select
840 zmodload zsh/complist
841 bindkey -M menuselect '^n' expand-or-complete
842 bindkey -M menuselect '^p' reverse-menu-complete
846 #+begin_src shell :tangle ~/.config/zsh/zshrc
850 bindkey -M vicmd "^[[3~" delete-char
851 bindkey "^[[3~" delete-char
853 autoload edit-command-line
854 zle -N edit-command-line
855 bindkey -M vicmd ^e edit-command-line
856 bindkey ^e edit-command-line
859 #+begin_src shell :tangle ~/.config/zsh/zshrc
860 setopt extended_history
862 setopt inc_append_history
863 setopt hist_ignore_dups
864 setopt hist_reduce_blanks
868 HISTFILE=~/.local/share/zsh/history
871 I manage plugins using my own plugin manager, ZPE. https://git.sr.ht/~armaan/zpe
873 Right now, I'm only using fast-syntax-highlighting. It's a really nice visual addition.
875 #+begin_src conf :tangle ~/.config/zpe/repositories
876 https://github.com/zdharma/fast-syntax-highlighting
879 #+begin_src shell :tangle ~/.config/zsh/zshrc
880 source ~/Code/zpe/zpe.sh
881 source ~/Code/admone/admone.zsh
882 source ~/.config/zsh/fzf-bindings.zsh
884 zpe-source fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
887 **** Time Zsh startup
888 #+begin_src shell :tangle ~/.config/zsh/zshrc
890 for i in $(seq 1 10); do time "$1" -i -c exit; done
893 **** Update all packages
894 #+begin_src shell :tangle ~/.config/zsh/zshrc
895 color=$(tput setaf 5)
899 sudo echo "${color}== upgrading with yay ==${reset}"
902 echo "${color}== checking for pacnew files ==${reset}"
905 echo "${color}== upgrading flatpaks ==${reset}"
908 echo "${color}== upgrading zsh plugins ==${reset}"
911 echo "${color}== updating nvim plugins ==${reset}"
912 nvim +PlugUpdate +PlugUpgrade +qall
913 echo "Updated nvim plugins"
915 echo "${color}You are entirely up to date!${reset}"
918 **** Clean all packages
919 #+begin_src shell :tangle ~/.config/zsh/zshrc
921 sudo echo "${color}== cleaning pacman orphans ==${reset}"
922 (pacman -Qtdq | sudo pacman -Rns - 2> /dev/null) || echo "No orphans"
924 echo "${color}== cleaning flatpaks ==${reset}"
925 flatpak remove --unused
927 echo "${color}== cleaning zsh plugins ==${reset}"
930 echo "${color}== cleaning nvim plugins ==${reset}"
931 nvim +PlugClean +qall
932 echo "Cleaned nvim plugins"
934 echo "${color}All orphans cleaned!${reset}"
938 #+begin_src shell :tangle ~/.config/zsh/zshrc
940 __conda_setup="$('/opt/anaconda/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
941 if [ $? -eq 0 ]; then
942 eval "$__conda_setup"
944 if [ -f "/opt/anaconda/etc/profile.d/conda.sh" ]; then
945 . "/opt/anaconda/etc/profile.d/conda.sh"
947 export PATH="/opt/anaconda/bin:$PATH"
953 **** Interact with 0x0
954 #+begin_src shell :tangle ~/.config/zsh/zshrc
955 zxz="https://envs.sh"
956 0file() { curl -F"file=@$1" "$zxz" ; }
957 0pb() { curl -F"file=@-;" "$zxz" ; }
958 0url() { curl -F"url=$1" "$zxz" ; }
959 0short() { curl -F"shorten=$1" "$zxz" ; }
960 0clip() { xclip -out | curl -F"file=@-;" "$zxz" ; }
963 #+begin_src shell :tangle ~/.config/zsh/zshrc
965 user=$(echo "$1" | cut -f 1 -d '@')
966 host=$(echo "$1" | cut -f 2 -d '@')
967 echo $user | nc "$host" 79 -N
970 **** Upload to ftp.armaanb.net
971 #+begin_src shell :tangle ~/.config/zsh/zshrc
973 rsync "$1" "root@armaanb.net:/var/ftp/pub/${2}"
974 echo "https://ftp.armaanb.net/pub/"$(basename "$1") | tee /dev/tty | xclip -sel c
979 #+begin_src shell :tangle ~/.config/zsh/zshrc
980 alias bhoji-drop='ssh -p 23 root@armaanb.net'
981 alias catgirl='ssh root@armaanb.net -t abduco -A irc catgirl freenode'
982 alias union='ssh 192.168.1.18'
983 alias mine='ssh -p 23 root@pickupserver.cc'
984 alias tcf='ssh root@204.48.23.68'
985 alias ngmun='ssh root@157.245.89.25'
986 alias prox='ssh root@192.168.1.224'
987 alias ncq='ssh root@143.198.123.17'
988 alias dock='ssh root@192.168.1.225'
989 alias jenkins='ssh root@192.168.1.226'
990 alias envs='ssh acheam@envs.net'
993 #+begin_src shell :tangle ~/.config/zsh/zshrc
994 alias ls='exa -lh --icons --git --group-directories-first'
995 alias la='exa -lha --icons --git --group-directories-first'
996 alias df='df -h / /boot'
1003 alias grep='grep -in --exclude-dir=.git --color=auto'
1004 alias fname='find -name'
1005 alias mkdir='mkdir -pv'
1006 alias unar='atool -x'
1007 alias wget='wget -e robots=off'
1008 alias lanex='~/.local/share/lxc/lxc'
1011 #+begin_src shell :tangle ~/.config/zsh/zshrc
1014 alias vw="nvim ~/Documents/vimwiki/index.md"
1016 **** System management
1017 #+begin_src shell :tangle ~/.config/zsh/zshrc
1018 alias jctl='journalctl -p 3 -xb'
1019 alias pkill='pkill -i'
1021 alias redoas='doas $(fc -ln -1)'
1022 alias crontab='crontab-argh'
1023 alias sudo='doas ' # allows aliases to be run with doas
1024 alias pasc='pass -c'
1025 alias pasu='\pass git push'
1026 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1030 #+begin_src shell :tangle ~/.config/zsh/zshrc
1031 alias ping='ping -c 10'
1032 alias speed='speedtest-cli'
1033 alias ip='ip --color=auto'
1034 alias cip='curl https://armaanb.net/ip'
1035 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1036 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1037 alias plan='T=$(mktemp) && \
1038 rsync root@armaanb.net:/etc/finger/plan.txt "$T" && \
1040 head -n -2 $T > $TT && \
1042 echo "\nLast updated: $(date -R)" >> "$TT" && \
1043 rsync "$TT" root@armaanb.net:/etc/finger/plan.txt'
1044 alias wttr='curl -s "wttr.in/02445?n" | head -n -3'
1047 #+begin_src shell :tangle ~/.config/zsh/zshrc
1048 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1049 iflag=fullblock status=progress'
1050 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1051 iflag=fullblock status=progress'
1052 alias ts='gen-shell -c task'
1053 alias ts='gen-shell -c task'
1054 alias tetris='autoload -Uz tetriscurses && tetriscurses'
1055 alias news='newsboat'
1056 alias tilderadio="\mpv https://radio.tildeverse.org/radio/8000/radio.ogg"
1057 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1058 --restrict-filenames -o '%(title)s.%(ext)s'"
1059 alias cal="cal -3 --color=auto"
1062 **** Virtual machines, chroots
1063 #+begin_src shell :tangle ~/.config/zsh/zshrc
1064 alias ckiss="sudo chrooter ~/Virtual/kiss"
1065 alias cdebian="sudo chrooter ~/Virtual/debian bash"
1066 alias cwindows='devour qemu-system-x86_64 \
1071 -device VGA,vgamem_mb=64 \
1073 -device hda-duplex \
1075 -net user,smb=/home/armaa/Public \
1076 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1079 #+begin_src shell :tangle ~/.config/zsh/zshrc
1081 alias zpy="zconda && ipython"
1082 alias math="ipython --profile=math"
1083 alias pypi="python setup.py sdist && twine upload dist/*"
1084 alias pip="python -m pip"
1085 alias black="black -l 79"
1088 #+begin_src shell :tangle ~/.config/zsh/zshrc
1089 alias words='gen-shell -c "words"'
1090 alias words-e='gen-shell -c "words ~E"'
1093 #+begin_src shell :tangle ~/.config/zsh/zshrc
1094 alias zathura='devour zathura'
1095 alias mpv='devour mpv'
1096 alias sql='devour sqlitebrowser'
1097 alias cad='devour openscad'
1098 alias feh='devour feh'
1100 **** Package management (Pacman)
1101 #+begin_src shell :tangle ~/.config/zsh/zshrc
1103 alias api='yay -Syu'
1104 alias apii='sudo pacman -S'
1105 alias app='yay -Rns'
1107 alias apo='yay -Qttd'
1108 alias azf='pacman -Q | fzf'
1109 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1110 alias ufetch='ufetch-arch'
1111 alias reflect='reflector --verbose --sort rate --save \
1112 ~/.local/etc/pacman.d/mirrorlist --download-timeout 60' # Takes ~45m to run
1114 **** Package management (KISS)
1115 #+begin_src shell :tangle ~/.config/zsh/zshrc
1116 alias kzf="kiss s \* | xargs -l basename | \
1117 fzf --preview 'kiss search {} | xargs -l dirname'"
1120 #+begin_src shell :tangle ~/.config/zsh/zshrc
1121 export EDITOR="emacsclient -c"
1122 export VISUAL="$EDITOR"
1123 export TERM=xterm-256color # for compatability
1125 export GPG_TTY="$(tty)"
1126 export MANPAGER='nvim +Man!'
1129 export GTK_USE_PORTAL=1
1131 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
1132 export PATH="/home/armaa/Code/scripts:$PATH" # prioritize my scripts
1133 export PATH="/home/armaa/Code/scripts/bin:$PATH" # prioritize my bins
1134 export PATH="$PATH:/home/armaa/.cargo/bin"
1135 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
1136 export PATH="$PATH:/usr/sbin"
1137 export PATH="$PATH:/opt/FreeTube/freetube"
1139 export LC_ALL="en_US.UTF-8"
1140 export LC_CTYPE="en_US.UTF-8"
1141 export LANGUAGE="en_US.UTF-8"
1143 export KISS_PATH="/home/armaa/Virtual/kiss/home/armaa/kiss-repo"
1144 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
1145 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
1146 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
1147 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
1148 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
1152 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1155 family: JetBrains Mono Nerd Font
1162 ligatures: true # Requires ligature patch
1169 background_opacity: 1
1172 Modus vivendi. Source: https://github.com/ishan9299/Nixos/blob/d4bbb7536be95b59466bb9cca4d671be46e04e81/user/alacritty/alacritty.yml#L30-L118
1173 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1177 background: '#000000'
1178 foreground: '#ffffff'
1182 background: '#ffffff'
1184 # Normal colors (except green it is from intense colors)
1195 # Bright colors [all the faint colors in the modus theme]
1206 # dim [all the intense colors in modus theme]
1219 Symlink profile_default/ipython_config.py to profile_math/ipython_config.py
1220 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1221 c.TerminalInteractiveShell.editing_mode = 'vi'
1222 c.InteractiveShell.colors = 'linux'
1223 c.TerminalInteractiveShell.confirm_exit = False
1226 #+begin_src python :tangle ~/.ipython/profile_math/startup.py
1230 return x * (180 / pi)
1233 return x * (pi / 180)
1236 return (x * (pi / 180)) / unit
1248 Make MPV play a little bit smoother.
1249 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1250 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1254 For any GNU Readline programs
1255 #+begin_src conf :tangle ~/.inputrc
1260 #+begin_src conf :tangle ~/.gitconfig
1262 name = Armaan Bhojwani
1263 email = me@armaanb.net
1264 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1267 #+begin_src conf :tangle ~/.gitconfig
1269 defaultBranch = main
1272 #+begin_src conf :tangle ~/.gitconfig
1277 #+begin_src conf :tangle ~/.gitconfig
1279 smtpserver = smtp.mailbox.org
1280 smtpuser = me@armaanb.net
1281 smtpencryption = ssl
1282 smtpserverport = 465
1286 #+begin_src conf :tangle ~/.gitconfig
1291 #+begin_src conf :tangle ~/.gitconfig
1294 sclone = clone --depth 1
1300 subup = submodule update --remote
1301 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1302 mirror = git config --global alias.mirrormirror
1305 #+begin_src conf :tangle ~/.gitconfig
1311 Lightweight notification daemon.
1313 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1315 font = "JetBrains Mono Medium Nerd Font 11"
1317 format = "<b>%s</b>\n%b"
1319 indicate_hidden = yes
1322 show_age_threshold = 60
1325 geometry = "400x5-10+10"
1327 idle_threshold = 120
1329 sticky_history = yes
1331 separator_height = 1
1333 horizontal_padding = 8
1335 separator_color = "#ffffff"
1336 startup_notification = false
1339 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1346 close_all = mod4+shift+c
1347 history = mod4+ctrl+c
1350 background = "#222222"
1351 foreground = "#ffffff"
1352 highlight = "#ffffff"
1356 background = "#222222"
1357 foreground = "#ffffff"
1358 highlight = "#ffffff"
1362 background = "#222222"
1363 foreground = "#a60000"
1364 highlight = "#ffffff"
1369 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1371 map <A-b> toggle_statusbar
1372 set selection-clipboard clipboard
1375 set window-title-basename "true"
1376 set selection-clipboard "clipboard"
1379 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1380 set default-bg "#000000"
1381 set default-fg "#ffffff"
1382 set render-loading true
1383 set render-loading-bg "#000000"
1384 set render-loading-fg "#ffffff"
1386 set recolor-lightcolor "#000000" # bg
1387 set recolor-darkcolor "#ffffff" # fg
1391 *** Swap tab and URL bars
1392 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1394 -moz-box-ordinal-group: 1 !important;
1398 -moz-box-ordinal-group: 2 !important;
1402 -moz-box-ordinal-group: 3 !important;
1405 *** Hide URL bar when not focused.
1406 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1407 #navigator-toolbox:not(:focus-within):not(:hover) {
1411 #navigator-toolbox {
1412 transition: 0.1s margin-top ease-out;
1415 ** Black screen by default
1416 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1419 #browser vbox#appcontent tabbrowser,
1421 #tabbrowser-tabpanels,
1423 browser[type="content-primary"],
1424 browser[type="content"] > html,
1426 background: black !important;
1427 color: #fff !important;
1430 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userContent.css
1431 @-moz-document url("about:home"), url("about:blank"), url("about:newtab") {
1433 background: black !important;
1439 #+begin_src conf :tangle ~/.Xresources
1440 XTerm.vt100.translations: #override \n\
1441 Ctrl <Key> minus: smaller-vt-font() \n\
1442 Ctrl <Key> plus: larger-vt-font()
1446 #+begin_src conf :tangle ~/.Xresources
1448 ,*.foreground: #ffffff
1449 ,*.background: #000000
1450 ,*.cursorColor: #ffffff
1485 #+begin_src conf :tangle ~/.Xresources
1486 xterm*VT100.Translations: #override \
1487 Shift <KeyPress> Insert: insert-selection(CLIPBOARD) \n\
1488 Ctrl Shift <Key>V: insert-selection(CLIPBOARD) \n\
1489 Ctrl Shift <Key>C: copy-selection(CLIPBOARD) \n\
1490 Ctrl <Btn1Up>: exec-formatted("xdg-open '%t'", PRIMARY)
1493 #+begin_src conf :tangle ~/.Xresources
1494 xterm*cursorBlink: true
1497 #+begin_src conf :tangle ~/.Xresources
1498 XTerm*eightBitInput: false
1499 XTerm*eightBitOutput: true