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)
61 #+begin_src emacs-lisp
62 (use-package tree-sitter-langs)
63 (use-package tree-sitter
64 :config (global-tree-sitter-mode)
65 :hook (tree-sitter-after-on-hook . tree-sitter-hl-mode))
69 Great programming font with ligatures.
70 #+begin_src emacs-lisp
71 (add-to-list 'default-frame-alist '(font . "JetBrainsMonoNF-12"))
74 #+begin_src emacs-lisp
76 :straight (ligature :type git :host github :repo "mickeynp/ligature.el")
78 (ligature-set-ligatures
79 '(prog-mode text-mode)
80 '("-|" "-~" "---" "-<<" "-<" "--" "->" "->>" "-->" "/=" "/=="
81 "/>" "//" "/*" "*>" "*/" "<-" "<<-" "<=>" "<=" "<|" "<||"
82 "<|||" "<|>" "<:" "<>" "<-<" "<<<" "<==" "<<=" "<=<" "<==>"
83 "<-|" "<<" "<~>" "<=|" "<~~" "<~" "<$>" "<$" "<+>" "<+" "</>"
84 "</" "<*" "<*>" "<->" "<!--" ":>" ":<" ":::" "::" ":?" ":?>"
85 ":=" "::=" "=>>" "==>" "=/=" "=!=" "=>" "===" "=:=" "==" "!=="
86 "!!" "!=" ">]" ">:" ">>-" ">>=" ">=>" ">>>" ">-" ">=" "&&&"
87 "&&" "|||>" "||>" "|>" "|]" "|}" "|=>" "|->" "|=" "||-" "|-"
88 "||=" "||" ".." ".?" ".=" ".-" "..<" "..." "+++" "+>" "++"
89 "[||]" "[<" "[|" "{|" "?." "?=" "?:" "##" "###" "####" "#["
90 "#{" "#=" "#!" "#:" "#_(" "#_" "#?" "#(" ";;" "_|_" "__" "~~"
91 "~~>" "~>" "~-" "~@" "$>" "^=" "]#"))
92 (global-ligature-mode t))
95 #+begin_src emacs-lisp
97 :config (global-emojify-mode))
99 ;; http://ergoemacs.org/emacs/emacs_list_and_set_font.html
104 ((member "Twitter Color Emoji" (font-family-list)) "Twitter Color Emoji")
105 ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
106 ((member "Noto Emoji" (font-family-list)) "Noto Emoji")))
109 Display relative line numbers except in some modes
110 #+begin_src emacs-lisp
111 (global-display-line-numbers-mode)
112 (setq display-line-numbers-type 'relative)
113 (dolist (no-line-num '(term-mode-hook
118 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
120 ** Highlight matching parenthesis
121 #+begin_src emacs-lisp
123 :config (show-paren-mode)
124 :custom (show-paren-style 'parenthesis))
127 *** Show current function
128 #+begin_src emacs-lisp
129 (which-function-mode)
131 *** Make position in file more descriptive
132 Show current column and file size.
133 #+begin_src emacs-lisp
135 (size-indication-mode)
138 #+begin_src emacs-lisp
140 :config (minions-mode))
143 #+begin_src emacs-lisp
145 :straight (wc-mode :type git :host github :repo "bnbeckwith/wc-mode")
146 :hook (text-mode-hook . wc-mode))
149 Show a ruler at a certain number of chars depending on mode.
150 #+begin_src emacs-lisp
151 (global-display-fill-column-indicator-mode)
154 Whenever starting a key chord, show possible future steps.
155 #+begin_src emacs-lisp
156 (use-package which-key
157 :config (which-key-mode)
158 :custom (which-key-idle-delay 0.3))
160 ** Highlight TODOs in comments
161 #+begin_src emacs-lisp
163 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
164 :config (global-hl-todo-mode 1))
167 #+begin_src emacs-lisp
171 Soft wrap words and do operations by visual lines.
172 #+begin_src emacs-lisp
173 (add-hook 'text-mode-hook 'turn-on-visual-line-mode)
175 ** Display number of matches in search
176 #+begin_src emacs-lisp
178 :config (global-anzu-mode))
181 Inverts modeline instead of audible bell or the standard visual bell.
182 #+begin_src emacs-lisp
183 (setq visible-bell nil
184 ring-bell-function 'flash-mode-line)
185 (defun flash-mode-line ()
186 (invert-face 'mode-line)
187 (run-with-timer 0.1 nil #'invert-face 'mode-line))
191 #+begin_src emacs-lisp
193 :custom (select-enable-clipboard nil)
196 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
197 ;; Use visual line motions even outside of visual-line-mode buffers
198 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
199 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
200 (global-set-key (kbd "<escape>") 'keyboard-escape-quit))
203 #+begin_src emacs-lisp
204 (use-package evil-collection
206 :init (evil-collection-init)
207 :custom (evil-collection-setup-minibuffer t))
211 #+begin_src emacs-lisp
212 (use-package evil-surround
213 :config (global-evil-surround-mode))
216 #+begin_src emacs-lisp
217 (use-package evil-leader
218 :straight (evil-leader :type git :host github :repo "cofi/evil-leader")
220 (evil-leader/set-leader "<SPC>")
221 (global-evil-leader-mode))
224 #+begin_src emacs-lisp
226 (use-package evil-nerd-commenter
227 :bind (:map evil-normal-state-map
228 ("gc" . evilnc-comment-or-uncomment-lines))
229 :custom (evilnc-invert-comment-line-by-line nil))
233 #+begin_src emacs-lisp
234 (evil-set-undo-system 'undo-redo)
236 ** Number incrementing
238 #+begin_src emacs-lisp
239 (use-package evil-numbers
240 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
241 :bind (:map evil-normal-state-map
242 ("C-M-a" . evil-numbers/inc-at-pt)
243 ("C-M-x" . evil-numbers/dec-at-pt)))
247 #+begin_src emacs-lisp
248 (use-package evil-org
250 :hook (org-mode . evil-org-mode)
252 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
253 (use-package evil-org-agenda
254 :straight (:type built-in)
257 (evil-org-agenda-set-keys))
260 #+begin_src emacs-lisp
261 (evil-leader/set-key-for-mode 'org-mode
262 "T" 'org-show-todo-tree
264 "c" 'org-archive-subtree)
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" "~/Org/break.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 :bind ("C-c a" . org-agenda))
286 #+begin_src emacs-lisp
287 (use-package org-tempo
289 :straight (:type built-in)
291 ;; TODO: There's gotta be a more efficient way to write this
292 (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
293 (add-to-list 'org-structure-template-alist '("sp" . "src conf :tangle ~/.spectrwm.conf"))
294 (add-to-list 'org-structure-template-alist '("zsh" . "src shell :tangle ~/.config/zsh/zshrc"))
295 (add-to-list 'org-structure-template-alist '("al" . "src yml :tangle ~/.config/alacritty/alacritty.yml"))
296 (add-to-list 'org-structure-template-alist '("ipy" . "src python :tangle ~/.ipython/"))
297 (add-to-list 'org-structure-template-alist '("pi" . "src conf :tangle ~/.config/picom/picom.conf"))
298 (add-to-list 'org-structure-template-alist '("git" . "src conf :tangle ~/.gitconfig"))
299 (add-to-list 'org-structure-template-alist '("du" . "src conf :tangle ~/.config/dunst/dunstrc"))
300 (add-to-list 'org-structure-template-alist '("ro" . "src javascript :tangle ~/.config/rofi/config.rasi"))
301 (add-to-list 'org-structure-template-alist '("za" . "src conf :tangle ~/.config/zathura/zathurarc"))
302 (add-to-list 'org-structure-template-alist '("ff1" . "src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css")))
303 (add-to-list 'org-structure-template-alist '("ff2" . "src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userContent.css")))
306 #+begin_src emacs-lisp
307 (use-package org-present
308 :straight (org-present :type git :host github :repo "rlister/org-present"))
312 Simple, but not too simple autocompletion.
313 #+begin_src emacs-lisp
315 :bind (("C-s" . swiper)
316 :map ivy-minibuffer-map
317 ("TAB" . ivy-alt-done)
318 :map ivy-switch-buffer-map
319 ("M-d" . ivy-switch-buffer-kill))
323 #+begin_src emacs-lisp
324 (use-package ivy-rich
326 :config (ivy-rich-mode))
330 #+begin_src emacs-lisp
332 :bind (("C-M-j" . 'counsel-switch-buffer)
333 :map minibuffer-local-map
334 ("C-r" . 'counsel-minibuffer-history))
335 :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
336 :config (counsel-mode))
338 ** Remember frequent commands
339 #+begin_src emacs-lisp
340 (use-package ivy-prescient
343 (ivy-prescient-enable-filtering nil)
345 (prescient-persist-mode)
346 (ivy-prescient-mode))
349 Better search utility.
350 #+begin_src emacs-lisp
355 Use elfeed for RSS. I have another file with all the feeds in it.
356 #+begin_src emacs-lisp
358 :bind (("C-c e" . elfeed))
360 (load "~/.emacs.d/feeds.el")
361 (add-hook 'elfeed-new-entry-hook
362 (elfeed-make-tagger :feed-url "youtube\\.com"
364 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
366 (use-package elfeed-goodies
368 :config (elfeed-goodies/setup))
371 Use mu4e for reading emails.
373 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.
375 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.
376 #+begin_src emacs-lisp
377 (use-package smtpmail
378 :straight (:type built-in))
380 :load-path "/usr/share/emacs/site-lisp/mu4e"
381 :bind (("C-c m" . mu4e))
383 (setq user-full-name "Armaan Bhojwani"
384 smtpmail-local-domain "armaanb.net"
385 smtpmail-stream-type 'ssl
386 smtpmail-smtp-service '465
387 mu4e-change-filenames-when-moving t
388 mu4e-get-mail-command "offlineimap -q"
389 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
390 message-citation-line-function 'message-insert-formatted-citation-line
391 mu4e-completing-read-function 'ivy-completing-read
392 mu4e-confirm-quit nil
393 mail-user-agent 'mu4e-user-agent
395 `( ,(make-mu4e-context
397 :enter-func (lambda () (mu4e-message "Entering school context"))
398 :leave-func (lambda () (mu4e-message "Leaving school context"))
399 :match-func (lambda (msg)
401 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
402 :vars '((user-mail-address . "abhojwani22@nobles.edu")
403 (mu4e-sent-folder . "/school/Sent")
404 (mu4e-drafts-folder . "/school/Drafts")
405 (mu4e-trash-folder . "/school/Trash")
406 (mu4e-refile-folder . "/school/Archive")
407 (user-mail-address . "abhojwani22@nobles.edu")
408 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
409 (smtpmail-smtp-server . "smtp.gmail.com")))
412 :enter-func (lambda () (mu4e-message "Entering personal context"))
413 :leave-func (lambda () (mu4e-message "Leaving personal context"))
414 :match-func (lambda (msg)
416 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
417 :vars '((mu4e-sent-folder . "/personal/Sent")
418 (mu4e-drafts-folder . "/personal/Drafts")
419 (mu4e-trash-folder . "/personal/Trash")
420 (mu4e-refile-folder . "/personal/Archive")
421 (user-mail-address . "me@armaanb.net")
422 (smtpmail-smtp-user . "me@armaanb.net")
423 (smtpmail-smtp-server "smtp.mailbox.org")
424 (mu4e-drafts-folder . "/school/Drafts")
425 (mu4e-trash-folder . "/school/Trash")))))
426 (add-to-list 'mu4e-bookmarks
427 '(:name "Unified inbox"
428 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
430 :hook ((mu4e-compose-mode . flyspell-mode)
431 (mu4e-view-mode-hook . turn-on-visual-line-mode)))
434 #+begin_src emacs-lisp
436 (use-package calfw-org)
437 (use-package calfw-ical)
439 (defun acheam-calendar ()
442 (shell-command "vdirsyncer sync")
443 (let ((default-directory "~/.local/share/vdirsyncer/"))
444 (cfw:open-calendar-buffer
447 (cfw:ical-create-source "School" (expand-file-name "school/abhojwani22@nobles.edu.ics") "Green")
448 (cfw:ical-create-source "Personal" (expand-file-name "mailbox/Y2FsOi8vMC8zMQ.ics") "Blue")
449 (cfw:ical-create-source "Birthdays" (expand-file-name "mailbox/Y2FsOi8vMS8w.ics") "Gray")
453 Another file has more specific network configuration.
454 #+begin_src emacs-lisp
456 :config (load-file "~/.emacs.d/irc.el"))
458 (use-package circe-chanop
459 :straight (:type built-in)
462 (use-package circe-color-nicks
463 :straight (:type built-in)
467 Set EWW as default browser except for videos.
468 #+begin_src emacs-lisp
469 (defun browse-url-mpv (url &optional new-window)
471 (start-process "mpv" "*mpv*" "mpv" url))
473 (setq browse-url-handlers
475 (("youtu\\.?be" . browse-url-mpv)
476 ("." . eww-browse-url)
480 Some EWW enhancements.
481 *** Give buffer a useful name
482 #+begin_src emacs-lisp
483 ;; From https://protesilaos.com/dotemacs/
484 (defun prot-eww--rename-buffer ()
485 "Rename EWW buffer using page title or URL.
486 To be used by `eww-after-render-hook'."
487 (let ((name (if (eq "" (plist-get eww-data :title))
488 (plist-get eww-data :url)
489 (plist-get eww-data :title))))
490 (rename-buffer (format "*%s # eww*" name) t)))
492 (add-hook 'eww-after-render-hook #'prot-eww--rename-buffer)
494 *** Better entrypoint
495 #+begin_src emacs-lisp
496 ;; From https://protesilaos.com/dotemacs/
497 (defun prot-eww-browse-dwim (url &optional arg)
498 "Visit a URL, maybe from `eww-prompt-history', with completion.
500 With optional prefix ARG (\\[universal-argument]) open URL in a
503 If URL does not look like a valid link, run a web query using
506 When called from an eww buffer, provide the current link as
510 (completing-read "Query:" eww-prompt-history
511 nil nil (plist-get eww-data :url) 'eww-prompt-history)
513 (eww url (if arg 4 nil)))
515 (global-set-key (kbd "C-c w") 'prot-eww-browse-dwim)
518 Use Emacs globally. Use the Emacs daemon and bind a key in your wm to
519 =emacsclient --eval "(emacs-everywhere)"=.
520 #+begin_src emacs-lisp
521 (use-package emacs-everywhere)
524 #+begin_src emacs-lisp
525 (setq eshell-prompt-function
528 "\n" (eshell/pwd) " ➤ ")
529 'face '(:foreground "cyan")))
530 eshell-highlight-prompt nil)
534 #+begin_src emacs-lisp
536 :hook (python-mode . blacken-mode)
538 (setq blacken-line-length 79))
541 (use-package ws-butler
543 (ws-butler-global-mode))
546 #+begin_src emacs-lisp
547 (use-package flycheck
549 (global-flycheck-mode))
551 ** Project management
552 #+begin_src emacs-lisp
553 (use-package projectile
554 :config (projectile-mode)
555 :custom ((projectile-completion-system 'ivy))
557 ("C-c p" . projectile-command-map)
559 (when (file-directory-p "~/Code")
560 (setq projectile-project-search-path '("~/Code")))
561 (setq projectile-switch-project-action #'projectile-dired))
563 (use-package counsel-projectile
565 :config (counsel-projectile-mode))
568 #+begin_src emacs-lisp
570 :straight (:type built-in)
571 :commands (dired dired-jump)
572 :custom ((dired-listing-switches "-agho --group-directories-first"))
574 (evil-collection-define-key 'normal 'dired-mode-map
575 "h" 'dired-single-up-directory
576 "l" 'dired-single-buffer))
578 (use-package dired-single
579 :commands (dired dired-jump))
581 (use-package dired-open
582 :commands (dired dired-jump)
584 (dired-open-extensions '(("png" . "feh")
587 (use-package dired-hide-dotfiles
588 :hook (dired-mode . dired-hide-dotfiles-mode)
590 (evil-collection-define-key 'normal 'dired-mode-map
591 "H" 'dired-hide-dotfiles-mode))
595 # TODO: Write a command that commits hunk, skipping staging step.
596 #+begin_src emacs-lisp
599 *** Colored diff in line number area
600 #+begin_src emacs-lisp
602 :straight (diff-hl :type git :host github :repo "dgutov/diff-hl")
603 :hook ((magit-pre-refresh-hook . diff-hl-magit-pre-refresh)
604 (magit-post-refresh-hook . diff-hl-magit-post-refresh))
605 :config (global-diff-hl-mode))
607 * General text editing
609 Indent after every change.
610 #+begin_src emacs-lisp
611 (use-package aggressive-indent
612 :config (global-aggressive-indent-mode))
615 Spell check in text mode, and in prog-mode comments.
616 #+begin_src emacs-lisp
617 (dolist (hook '(text-mode-hook))
618 (add-hook hook (lambda () (flyspell-mode))))
619 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
620 (add-hook hook (lambda () (flyspell-mode -1))))
621 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
623 ** Expand tabs to spaces
624 #+begin_src emacs-lisp
625 (setq-default tab-width 2)
627 ** Copy kill ring to clipboard
628 #+begin_src emacs-lisp
629 (setq x-select-enable-clipboard t)
630 (defun copy-kill-ring-to-xorg ()
631 "Copy the current kill ring to the xorg clipboard."
633 (x-select-text (current-kill 0)))
636 #+begin_src emacs-lisp
637 (use-package browse-kill-ring)
640 Opens file where you left it.
641 #+begin_src emacs-lisp
645 Distraction free writing a la junegunn/goyo.
646 #+begin_src emacs-lisp
647 (use-package olivetti
649 (evil-leader/set-key "o" 'olivetti-mode))
653 #+begin_src emacs-lisp
654 (setq abbrev-file-name "~/.emacs.d/abbrevs")
655 (setq save-abbrevs 'silent)
656 (setq-default abbrev-mode t)
659 #+begin_src emacs-lisp
660 (setq tramp-default-method "ssh")
662 ** Don't ask about following symlinks in vc
663 #+begin_src emacs-lisp
664 (setq vc-follow-symlinks t)
667 ** Easily convert splits
668 Converts splits from horizontal to vertical and vice versa. Lifted from EmacsWiki.
669 #+begin_src emacs-lisp
670 (defun toggle-window-split ()
672 (if (= (count-windows) 2)
673 (let* ((this-win-buffer (window-buffer))
674 (next-win-buffer (window-buffer (next-window)))
675 (this-win-edges (window-edges (selected-window)))
676 (next-win-edges (window-edges (next-window)))
677 (this-win-2nd (not (and (<= (car this-win-edges)
678 (car next-win-edges))
679 (<= (cadr this-win-edges)
680 (cadr next-win-edges)))))
682 (if (= (car this-win-edges)
683 (car (window-edges (next-window))))
684 'split-window-horizontally
685 'split-window-vertically)))
686 (delete-other-windows)
687 (let ((first-win (selected-window)))
689 (if this-win-2nd (other-window 1))
690 (set-window-buffer (selected-window) this-win-buffer)
691 (set-window-buffer (next-window) next-win-buffer)
692 (select-window first-win)
693 (if this-win-2nd (other-window 1))))))
695 (define-key ctl-x-4-map "t" 'toggle-window-split)
698 #+begin_src emacs-lisp
699 (defun insert-date ()
701 (insert (format-time-string "%Y-%m-%d")))
705 #+begin_src emacs-lisp
706 (use-package ace-window
707 :bind ("M-o" . ace-window))
709 ** Kill current buffer
710 Makes "C-x k" binding faster.
711 #+begin_src emacs-lisp
712 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
716 Render OpenSCAD files, and add a preview window.
718 Personal fork just merges a PR.
719 #+begin_src emacs-lisp
720 (use-package scad-mode)
721 (use-package scad-preview
722 :straight (scad-preview :type git :host github :repo "Armaanb/scad-preview"))
724 ** Control backup files
725 Stop backup files from spewing everywhere.
726 #+begin_src emacs-lisp
727 (setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
729 ** Make yes/no easier
730 #+begin_src emacs-lisp
731 (defalias 'yes-or-no-p 'y-or-n-p)
733 ** Move customize file
734 No more clogging up init.el.
735 #+begin_src emacs-lisp
736 (setq custom-file "~/.emacs.d/custom.el")
740 #+begin_src emacs-lisp
742 :commands (helpful-callable helpful-variable helpful-command helpful-key)
744 (counsel-describe-function-function #'helpful-callable)
745 (counsel-describe-variable-function #'helpful-variable)
747 ([remap describe-function] . counsel-describe-function)
748 ([remap describe-command] . helpful-command)
749 ([remap describe-variable] . counsel-describe-variable)
750 ([remap describe-key] . helpful-key))
753 #+begin_src emacs-lisp
754 (use-package epa-file
755 :straight (:type built-in)
757 (epa-file-select-keys nil)
758 (epa-file-encrypt-to '("me@armaanb.net"))
759 (password-cache-expiry (* 60 15)))
761 (use-package pinentry
762 :config (pinentry-start))
765 #+begin_src emacs-lisp
767 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
768 :custom (0x0-default-service 'envs)
769 :config (evil-leader/set-key
771 "0f" '0x0-upload-file
772 "0s" '0x0-upload-string
773 "0c" '0x0-upload-kill-ring
774 "0p" '0x0-upload-popup))
779 #+begin_src conf :tangle ~/.spectrwm.conf
784 autorun = ws[1]:/home/armaa/Code/scripts/autostart
787 #+begin_src conf :tangle ~/.spectrwm.conf
788 color_focus = rgb:ff/ff/ff
789 color_focus_maximized = rgb:ee/cc/00
790 color_unfocus = rgb:55/55/55
793 #+begin_src conf :tangle ~/.spectrwm.conf
795 bar_font = xos4 Fira Code:pixelsize=14:antialias=true # any installed font
799 #+begin_src conf :tangle ~/.spectrwm.conf
800 program[lock] = i3lock -c 000000 -ef
801 program[term] = alacritty
802 program[screenshot_all] = flameshot gui
803 program[menu] = rofi -show run # `rofi-dmenu` handles the rest
804 program[switcher] = rofi -show window
805 program[notif] = /home/armaa/Code/scripts/setter status
808 bind[switcher] = MOD+Tab
811 #+begin_src conf :tangle ~/.spectrwm.conf
812 program[paup] = /home/armaa/Code/scripts/setter audio +5
813 program[padown] = /home/armaa/Code/scripts/setter audio -5
814 program[pamute] = /home/armaa/Code/scripts/setter audio
815 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
816 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
817 program[next] = playerctl next
818 program[prev] = playerctl previous
819 program[pause] = playerctl play-pause
821 bind[padown] = XF86AudioLowerVolume
822 bind[paup] = XF86AudioRaiseVolume
823 bind[pamute] = XF86AudioMute
824 bind[brigdown] = XF86MonBrightnessDown
825 bind[brigup] = XF86MonBrightnessUp
826 bind[pause] = XF86AudioPlay
827 bind[next] = XF86AudioNext
828 bind[prev] = XF86AudioPrev
831 #+begin_src conf :tangle ~/.spectrwm.conf
832 program[h] = xdotool keyup h key --clearmodifiers Left
833 program[j] = xdotool keyup j key --clearmodifiers Down
834 program[k] = xdotool keyup k key --clearmodifiers Up
835 program[l] = xdotool keyup l key --clearmodifiers Right
837 bind[h] = MOD + Control + h
838 bind[j] = MOD + Control + j
839 bind[k] = MOD + Control + k
840 bind[l] = MOD + Control + l
843 #+begin_src conf :tangle ~/.spectrwm.conf
844 program[aerc] = alacritty -e aerc
845 program[catgirl] = alacritty --hold -e sh -c "while : ; do ssh root@armaanb.net -t abduco -A irc catgirl freenode; sleep 2; done"
846 program[emacs] = emacsclient -c
847 program[firefox] = firefox
848 program[emacs-anywhere] = emacsclient --eval "(emacs-everywhere)"
850 bind[aerc] = MOD+Control+1
851 bind[catgirl] = MOD+Control+2
852 bind[firefox] = MOD+Control+3
853 bind[emacs-anywhere] = MOD+Control+4
854 bind[emacs] = MOD+Control+Return
859 #+begin_src shell :tangle ~/.config/zsh/zshrc
860 autoload -Uz compinit
864 unsetopt glob_complete
867 #+begin_src shell :tangle ~/.config/zsh/zshrc
871 bindkey -M vicmd "^[[3~" delete-char
872 bindkey "^[[3~" delete-char
874 autoload edit-command-line
875 zle -N edit-command-line
876 bindkey -M vicmd ^e edit-command-line
877 bindkey ^e edit-command-line
880 #+begin_src shell :tangle ~/.config/zsh/zshrc
881 setopt extended_history
883 setopt inc_append_history
884 setopt hist_ignore_dups
885 setopt hist_reduce_blanks
889 HISTFILE=~/.local/share/zsh/history
892 I manage plugins using my own plugin manager, ZPE. https://git.sr.ht/~armaan/zpe
894 #+begin_src conf :tangle ~/.config/zpe/repositories
895 https://github.com/Aloxaf/fzf-tab
896 https://github.com/zdharma/fast-syntax-highlighting
897 https://github.com/rupa/z
900 #+begin_src shell :tangle ~/.config/zsh/zshrc
901 source ~/Code/zpe/zpe.sh
902 source ~/Code/admone/admone.zsh
903 source ~/.config/zsh/fzf-bindings.zsh
905 zpe-source fzf-tab/fzf-tab.zsh
906 zstyle ':completion:*:descriptions' format '[%d]'
907 zstyle ':fzf-tab:complete:cd:*' fzf-preview 'exa -1 --color=always $realpath'
908 zstyle ':completion:*' completer _complete
909 zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \
910 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
912 zpe-source fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
913 export _Z_DATA="/home/armaa/.local/share/z"
917 **** Alert after long command
918 #+begin_src shell :tangle ~/.config/zsh/zshrc
920 notify-send --urgency=low -i ${(%):-%(?.terminal.error)} \
921 ${history[$HISTCMD]%[;&|][[:space:]]##alert}
924 **** Time Zsh startup
925 #+begin_src shell :tangle ~/.config/zsh/zshrc
927 for i in $(seq 1 10); do
928 time "zsh" -i -c exit;
932 **** Update all packages
933 #+begin_src shell :tangle ~/.config/zsh/zshrc
934 color=$(tput setaf 5)
938 sudo echo "${color}== upgrading with yay ==${reset}"
941 echo "${color}== checking for pacnew files ==${reset}"
944 echo "${color}== upgrading flatpaks ==${reset}"
947 echo "${color}== upgrading zsh plugins ==${reset}"
950 echo "${color}== updating nvim plugins ==${reset}"
951 nvim +PlugUpdate +PlugUpgrade +qall
952 echo "Updated nvim plugins"
954 echo "${color}You are entirely up to date!${reset}"
957 **** Clean all packages
958 #+begin_src shell :tangle ~/.config/zsh/zshrc
960 sudo echo "${color}== cleaning pacman orphans ==${reset}"
961 (pacman -Qtdq | sudo pacman -Rns - 2> /dev/null) || echo "No orphans"
963 echo "${color}== cleaning flatpaks ==${reset}"
964 flatpak remove --unused
966 echo "${color}== cleaning zsh plugins ==${reset}"
969 echo "${color}== cleaning nvim plugins ==${reset}"
970 nvim +PlugClean +qall
971 echo "Cleaned nvim plugins"
973 echo "${color}All orphans cleaned!${reset}"
977 #+begin_src shell :tangle ~/.config/zsh/zshrc
980 exa -lh --icons --git --group-directories-first
983 **** Change default enter behavior
984 If no command given, =ls=, if in a Git repo, =git status= as well.
985 #+begin_src shell :tangle ~/.config/zsh/zshrc
986 acheam-accept-line () {
988 if [ ${#${(z)BUFFER}} -eq 0 ]; then
990 exa -lh --icons --git --group-directories-first
991 [ -d ".git" ] && git status
994 zle -N acheam-accept-line
995 bindkey '^M' acheam-accept-line
998 #+begin_src shell :tangle ~/.config/zsh/zshrc
1000 __conda_setup="$('/opt/anaconda/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
1001 if [ $? -eq 0 ]; then
1002 eval "$__conda_setup"
1004 if [ -f "/opt/anaconda/etc/profile.d/conda.sh" ]; then
1005 . "/opt/anaconda/etc/profile.d/conda.sh"
1007 export PATH="/opt/anaconda/bin:$PATH"
1013 **** Interact with 0x0
1014 #+begin_src shell :tangle ~/.config/zsh/zshrc
1015 zxz="https://envs.sh"
1016 0file() { curl -F"file=@$1" "$zxz" ; }
1017 0pb() { curl -F"file=@-;" "$zxz" ; }
1018 0url() { curl -F"url=$1" "$zxz" ; }
1019 0short() { curl -F"shorten=$1" "$zxz" ; }
1020 0clip() { xclip -out | curl -F"file=@-;" "$zxz" ; }
1023 #+begin_src shell :tangle ~/.config/zsh/zshrc
1031 #+begin_src shell :tangle ~/.config/zsh/zshrc
1033 user=$(echo "$1" | cut -f 1 -d '@')
1034 host=$(echo "$1" | cut -f 2 -d '@')
1035 echo $user | nc "$host" 79 -N
1040 #+begin_src shell :tangle ~/.config/zsh/zshrc
1041 alias bhoji-drop='ssh -p 23 root@armaanb.net'
1042 alias catgirl='ssh root@armaanb.net -t abduco -A irc catgirl freenode'
1043 alias union='ssh 192.168.1.18'
1044 alias mine='ssh -p 23 root@71.184.142.155'
1045 alias minec='ssh -p 23 root@71.184.142.155 su minecraft -c "tmux a -t minecraft"'
1046 alias tcf='ssh root@204.48.23.68'
1047 alias ngmun='ssh root@157.245.89.25'
1048 alias prox='ssh root@192.168.1.224'
1049 alias ncq='ssh root@143.198.123.17'
1050 alias dock='ssh root@192.168.1.225'
1051 alias jenkins='ssh root@192.168.1.226'
1052 alias envs='ssh acheam@envs.net'
1054 **** File management
1055 #+begin_src shell :tangle ~/.config/zsh/zshrc
1056 alias ls='exa -lh --icons --git --group-directories-first'
1057 alias la='exa -lha --icons --git --group-directories-first'
1058 alias df='df -h / /boot'
1060 alias free='free -h'
1065 alias grep='grep -in --exclude-dir=.git --color=auto'
1066 alias fname='find -name'
1067 alias mkdir='mkdir -pv'
1068 alias unar='atool -x'
1069 alias wget='wget -e robots=off'
1070 alias lanex='~/.local/share/lxc/lxc'
1073 #+begin_src shell :tangle ~/.config/zsh/zshrc
1074 alias padm='yadm --yadm-repo ~/Code/dotfiles/repo.git'
1075 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1077 alias padu='padm add -u && padm commit && padm push && yadu'
1080 #+begin_src shell :tangle ~/.config/zsh/zshrc
1083 alias vw="nvim ~/Documents/vimwiki/index.md"
1085 **** System management
1086 #+begin_src shell :tangle ~/.config/zsh/zshrc
1087 alias jctl='journalctl -p 3 -xb'
1088 alias pkill='pkill -i'
1090 alias redoas='doas $(fc -ln -1)'
1091 alias crontab='crontab-argh'
1092 alias sudo='doas ' # allows aliases to be run with doas
1095 #+begin_src shell :tangle ~/.config/zsh/zshrc
1096 alias ping='ping -c 10'
1097 alias speed='speedtest-cli'
1098 alias ip='ip --color=auto'
1099 alias cip='curl https://armaanb.net/ip'
1100 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1101 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1102 alias plan='T=$(mktemp) && \
1103 rsync root@armaanb.net:/etc/finger/plan.txt "$T" && \
1105 head -n -2 $T > $TT && \
1107 echo "\nLast updated: $(date -R)" >> "$TT" && \
1108 rsync "$TT" root@armaanb.net:/etc/finger/plan.txt'
1109 alias wttr='curl -s "wttr.in/02445?n" | head -n -3'
1112 #+begin_src shell :tangle ~/.config/zsh/zshrc
1113 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1114 iflag=fullblock status=progress'
1115 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1116 iflag=fullblock status=progress'
1117 alias ts='gen-shell -c task'
1118 alias ts='gen-shell -c task'
1119 alias tetris='autoload -Uz tetriscurses && tetriscurses'
1120 alias news='newsboat'
1121 alias tilderadio="\mpv https://radio.tildeverse.org/radio/8000/radio.ogg"
1122 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1123 --restrict-filenames -o '%(title)s.%(ext)s'"
1124 alias cal="cal -3 --color=auto"
1127 **** Virtual machines, chroots
1128 #+begin_src shell :tangle ~/.config/zsh/zshrc
1129 alias ckiss="sudo chrooter ~/Virtual/kiss"
1130 alias cdebian="sudo chrooter ~/Virtual/debian bash"
1131 alias cwindows='devour qemu-system-x86_64 \
1136 -device VGA,vgamem_mb=64 \
1138 -device hda-duplex \
1140 -net user,smb=/home/armaa/Public \
1141 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1144 #+begin_src shell :tangle ~/.config/zsh/zshrc
1146 alias zpy="zconda && ipython"
1147 alias math="ipython --profile=math"
1148 alias pypi="python setup.py sdist && twine upload dist/*"
1149 alias pip="python -m pip"
1150 alias black="black -l 79"
1153 #+begin_src shell :tangle ~/.config/zsh/zshrc
1154 alias words='gen-shell -c "words"'
1155 alias words-e='gen-shell -c "words ~E"'
1158 #+begin_src shell :tangle ~/.config/zsh/zshrc
1159 alias zathura='devour zathura'
1160 alias mpv='devour mpv'
1161 alias sql='devour sqlitebrowser'
1162 alias cad='devour openscad'
1163 alias feh='devour feh'
1165 **** Package management (Pacman)
1166 #+begin_src shell :tangle ~/.config/zsh/zshrc
1168 alias api='yay -Syu'
1169 alias apii='sudo pacman -S'
1170 alias app='yay -Rns'
1172 alias apo='yay -Qttd'
1173 alias azf='pacman -Q | fzf'
1174 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1175 alias ufetch='ufetch-arch'
1176 alias reflect='reflector --verbose --sort rate --save \
1177 ~/.local/etc/pacman.d/mirrorlist --download-timeout 60' # Takes ~45m to run
1179 **** Package management (KISS)
1180 #+begin_src shell :tangle ~/.config/zsh/zshrc
1181 alias kzf="kiss s \* | xargs -l basename | \
1182 fzf --preview 'kiss search {} | xargs -l dirname'"
1185 #+begin_src shell :tangle ~/.config/zsh/zshrc
1186 export EDITOR="emacsclient -c"
1187 export VISUAL="$EDITOR"
1188 export TERM=xterm-256color # for compatability
1190 export GPG_TTY="$(tty)"
1191 export MANPAGER='nvim +Man!'
1194 export GTK_USE_PORTAL=1
1196 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
1197 export PATH="/home/armaa/Code/scripts:$PATH" # prioritize my scripts
1198 export PATH="/home/armaa/Code/scripts/bin:$PATH" # prioritize my bins
1199 export PATH="$PATH:/home/armaa/.cargo/bin"
1200 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
1201 export PATH="$PATH:/usr/sbin"
1202 export PATH="$PATH:/opt/FreeTube/freetube"
1204 export LC_ALL="en_US.UTF-8"
1205 export LC_CTYPE="en_US.UTF-8"
1206 export LANGUAGE="en_US.UTF-8"
1208 export KISS_PATH="/home/armaa/Virtual/kiss/home/armaa/kiss-repo"
1209 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
1210 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
1211 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
1212 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
1213 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
1217 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1220 family: JetBrains Mono Nerd Font
1227 ligatures: true # Requires ligature patch
1234 background_opacity: 1
1237 Modus vivendi. Source: https://github.com/ishan9299/Nixos/blob/d4bbb7536be95b59466bb9cca4d671be46e04e81/user/alacritty/alacritty.yml#L30-L118
1238 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1242 background: '#000000'
1243 foreground: '#ffffff'
1247 background: '#ffffff'
1249 # Normal colors (except green it is from intense colors)
1260 # Bright colors [all the faint colors in the modus theme]
1271 # dim [all the intense colors in modus theme]
1284 Symlink profile_default/ipython_config.py to profile_math/ipython_config.py
1285 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1286 c.TerminalInteractiveShell.editing_mode = 'vi'
1287 c.InteractiveShell.colors = 'linux'
1288 c.TerminalInteractiveShell.confirm_exit = False
1291 #+begin_src python :tangle ~/.ipython/profile_math/startup.py
1295 return x * (180 / pi)
1298 return x * (pi / 180)
1301 return (x * (pi / 180)) / unit
1313 Make MPV play a little bit smoother.
1314 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1315 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1319 For any GNU Readline programs
1320 #+begin_src conf :tangle ~/.inputrc
1325 #+begin_src conf :tangle ~/.gitconfig
1327 name = Armaan Bhojwani
1328 email = me@armaanb.net
1329 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1332 #+begin_src conf :tangle ~/.gitconfig
1334 defaultBranch = main
1337 #+begin_src conf :tangle ~/.gitconfig
1342 #+begin_src conf :tangle ~/.gitconfig
1344 smtpserver = smtp.mailbox.org
1345 smtpuser = me@armaanb.net
1346 smtpencryption = ssl
1347 smtpserverport = 465
1351 #+begin_src conf :tangle ~/.gitconfig
1356 #+begin_src conf :tangle ~/.gitconfig
1359 sclone = clone --depth 1
1365 subup = submodule update --remote
1366 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1367 mirror = git config --global alias.mirrormirror
1370 #+begin_src conf :tangle ~/.gitconfig
1376 Lightweight notification daemon.
1378 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1380 font = "JetBrains Mono Medium Nerd Font 11"
1382 format = "<b>%s</b>\n%b"
1384 indicate_hidden = yes
1387 show_age_threshold = 60
1390 geometry = "400x5-10+10"
1392 idle_threshold = 120
1394 sticky_history = yes
1396 separator_height = 1
1398 horizontal_padding = 8
1400 separator_color = "#ffffff"
1401 startup_notification = false
1404 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1411 close_all = mod4+shift+c
1412 history = mod4+ctrl+c
1415 background = "#222222"
1416 foreground = "#ffffff"
1417 highlight = "#ffffff"
1421 background = "#222222"
1422 foreground = "#ffffff"
1423 highlight = "#ffffff"
1427 background = "#222222"
1428 foreground = "#a60000"
1429 highlight = "#ffffff"
1433 Modus vivendi theme that extends DarkBlue.
1434 #+begin_src javascript :tangle ~/.config/rofi/config.rasi
1435 @import "/usr/share/rofi/themes/DarkBlue.rasi"
1437 white: rgba ( 255, 255, 255, 100 % );
1439 selected-normal-background: @white;
1440 separatorcolor: @white;
1441 background: rgba ( 34, 34, 34, 100 % );
1446 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1448 map <A-b> toggle_statusbar
1449 set selection-clipboard clipboard
1452 set window-title-basename "true"
1453 set selection-clipboard "clipboard"
1456 #+begin_src conf :tangle ~/.config/zathura/zathurarc
1457 set default-bg "#000000"
1458 set default-fg "#ffffff"
1459 set render-loading true
1460 set render-loading-bg "#000000"
1461 set render-loading-fg "#ffffff"
1463 set recolor-lightcolor "#000000" # bg
1464 set recolor-darkcolor "#ffffff" # fg
1468 *** Swap tab and URL bars
1469 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1471 -moz-box-ordinal-group: 1 !important;
1475 -moz-box-ordinal-group: 2 !important;
1479 -moz-box-ordinal-group: 3 !important;
1482 *** Hide URL bar when not focused.
1483 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1484 #navigator-toolbox:not(:focus-within):not(:hover) {
1488 #navigator-toolbox {
1489 transition: 0.1s margin-top ease-out;
1492 ** Black screen by default
1493 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userChrome.css
1496 #browser vbox#appcontent tabbrowser,
1498 #tabbrowser-tabpanels,
1500 browser[type="content-primary"],
1501 browser[type="content"] > html,
1503 background: black !important;
1504 color: #fff !important;
1507 #+begin_src css :tangle ~/.mozilla/firefox/armaan-release/chrome/userContent.css
1508 @-moz-document url("about:home"), url("about:blank"), url("about:newtab") {
1510 background: black !important;