1 #+TITLE: System Configuration
2 #+DESCRIPTION: Armaan's system configuration.
5 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!
7 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.
9 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.
11 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.
13 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.
15 *** TODO Turn keybinding and hook declarations into use-package declarations where possible
16 *** TODO Put configs with passwords in here with some kind of authentication
20 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.
22 ** Bootstrap straight.el
23 straight.el is really nice for managing package, and it integrates nicely with use-package. It uses the bootstrapping system defined here for installation.
24 #+begin_src emacs-lisp
25 (defvar bootstrap-version)
27 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
28 (bootstrap-version 5))
29 (unless (file-exists-p bootstrap-file)
31 (url-retrieve-synchronously
32 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
33 'silent 'inhibit-cookies)
34 (goto-char (point-max))
35 (eval-print-last-sexp)))
36 (load bootstrap-file nil 'nomessage))
38 ** Replace use-package with straight
39 #+begin_src emacs-lisp
40 (straight-use-package 'use-package)
41 (setq straight-use-package-by-default t)
45 Very nice high contrast theme.
47 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.
48 #+begin_src emacs-lisp
49 (setq modus-themes-slanted-constructs t
50 modus-themes-bold-constructs t
51 modus-themes-org-blocks 'grayscale
52 modus-themes-mode-line '3d
53 modus-themes-scale-headings t
54 modus-themes-region 'no-extend
55 modus-themes-diffs 'desaturated)
56 (load-theme 'modus-vivendi t)
60 Great programming font with ligatures.
61 #+begin_src emacs-lisp
62 (add-to-list 'default-frame-alist '(font . "JetBrainsMonoNF-12"))
65 #+begin_src emacs-lisp
67 :straight (ligature :type git :host github :repo "mickeynp/ligature.el")
69 (ligature-set-ligatures
70 '(prog-mode text-mode)
71 '("-|" "-~" "---" "-<<" "-<" "--" "->" "->>" "-->" "///" "/=" "/=="
72 "/>" "//" "/*" "*>" "*/" "<-" "<<-" "<=>" "<=" "<|" "<||"
73 "<|||" "<|>" "<:" "<>" "<-<" "<<<" "<==" "<<=" "<=<" "<==>" "<-|"
74 "<<" "<~>" "<=|" "<~~" "<~" "<$>" "<$" "<+>" "<+" "</>" "</" "<*"
75 "<*>" "<->" "<!--" ":>" ":<" ":::" "::" ":?" ":?>" ":=" "::=" "=>>"
76 "==>" "=/=" "=!=" "=>" "===" "=:=" "==" "!==" "!!" "!=" ">]" ">:"
77 ">>-" ">>=" ">=>" ">>>" ">-" ">=" "&&&" "&&" "|||>" "||>" "|>" "|]"
78 "|}" "|=>" "|->" "|=" "||-" "|-" "||=" "||" ".." ".?" ".=" ".-" "..<"
79 "..." "+++" "+>" "++" "[||]" "[<" "[|" "{|" "??" "?." "?=" "?:" "##"
80 "###" "####" "#[" "#{" "#=" "#!" "#:" "#_(" "#_" "#?" "#(" ";;" "_|_"
81 "__" "~~" "~~>" "~>" "~-" "~@" "$>" "^=" "]#"))
82 (global-ligature-mode t))
85 #+begin_src emacs-lisp
87 :config (global-emojify-mode))
89 ;; http://ergoemacs.org/emacs/emacs_list_and_set_font.html
94 ((member "Twitter Color Emoji" (font-family-list)) "Twitter Color Emoji")
95 ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
96 ((member "Noto Emoji" (font-family-list)) "Noto Emoji")))
99 Display relative line numbers except in some modes
100 #+begin_src emacs-lisp
101 (global-display-line-numbers-mode)
102 (setq display-line-numbers-type 'relative)
103 (dolist (no-line-num '(term-mode-hook
108 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
110 ** Highlight matching parenthesis
111 #+begin_src emacs-lisp
113 :config (show-paren-mode)
114 :custom (show-paren-style 'parenthesis))
117 *** Show current function
118 #+begin_src emacs-lisp
119 (which-function-mode)
121 *** Make position in file more descriptive
122 Show current column and file size.
123 #+begin_src emacs-lisp
125 (size-indication-mode)
128 #+begin_src emacs-lisp
130 :config (minions-mode))
133 Show a ruler at a certain number of chars depending on mode.
134 #+begin_src emacs-lisp
135 (global-display-fill-column-indicator-mode)
138 Whenever starting a key chord, show possible future steps.
139 #+begin_src emacs-lisp
140 (use-package which-key
141 :config (which-key-mode)
142 :custom (which-key-idle-delay 0.3))
144 ** Visual highlights of changes
145 Highlight when changes are made.
146 #+begin_src emacs-lisp
147 (use-package evil-goggles
148 :config (evil-goggles-mode)
149 (evil-goggles-use-diff-faces))
151 ** Highlight TODOs in comments
152 #+begin_src emacs-lisp
154 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
155 :config (global-hl-todo-mode 1))
158 #+begin_src emacs-lisp
162 Soft wrap words and do operations by visual lines.
163 #+begin_src emacs-lisp
164 (add-hook 'text-mode-hook 'turn-on-visual-line-mode)
166 ** Display number of matches in search
167 #+begin_src emacs-lisp
169 :config (global-anzu-mode))
172 Inverts modeline instead of audible bell or the standard visual bell.
173 #+begin_src emacs-lisp
174 (setq visible-bell nil
175 ring-bell-function 'flash-mode-line)
176 (defun flash-mode-line ()
177 (invert-face 'mode-line)
178 (run-with-timer 0.1 nil #'invert-face 'mode-line))
182 #+begin_src emacs-lisp
184 :custom (select-enable-clipboard nil)
187 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
188 ;; Use visual line motions even outside of visual-line-mode buffers
189 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
190 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
191 (global-set-key (kbd "<escape>") 'keyboard-escape-quit))
194 #+begin_src emacs-lisp
195 (use-package evil-collection
197 :init (evil-collection-init)
198 :custom (evil-collection-setup-minibuffer t))
202 #+begin_src emacs-lisp
203 (use-package evil-surround
204 :config (global-evil-surround-mode))
207 #+begin_src emacs-lisp
208 (use-package evil-leader
209 :straight (evil-leader :type git :host github :repo "cofi/evil-leader")
211 (evil-leader/set-leader "<SPC>")
212 (global-evil-leader-mode))
215 #+begin_src emacs-lisp
217 (use-package evil-nerd-commenter
218 :bind (:map evil-normal-state-map
219 ("gc" . evilnc-comment-or-uncomment-lines))
220 :custom (evilnc-invert-comment-line-by-line nil))
224 #+begin_src emacs-lisp
225 (evil-set-undo-system 'undo-tree)
227 ** Number incrementing
229 #+begin_src emacs-lisp
230 (use-package evil-numbers
231 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
232 :bind (:map evil-normal-state-map
233 ("C-M-a" . evil-numbers/inc-at-pt)
234 ("C-M-x" . evil-numbers/dec-at-pt)))
238 #+begin_src emacs-lisp
239 (use-package evil-org
241 :hook (org-mode . evil-org-mode)
243 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
244 (use-package evil-org-agenda
245 :straight (:type built-in)
248 (evil-org-agenda-set-keys))
251 #+begin_src emacs-lisp
252 (evil-leader/set-key-for-mode 'org-mode
253 "T" 'org-show-todo-tree
255 "c" 'org-archive-subtree)
259 #+begin_src emacs-lisp
261 :straight (:type built-in)
262 :commands (org-capture org-agenda)
265 (org-agenda-start-with-log-mode t)
266 (org-agenda-files (quote ("~/Org/tasks.org" "~/Org/break.org")))
268 (org-log-into-drawer t)
269 (org-src-tab-acts-natively t)
270 (org-src-fontify-natively t)
271 (org-startup-indented t)
272 (org-hide-emphasis-markers t)
273 (org-fontify-whole-block-delimiter-line nil)
274 :bind ("C-c a" . org-agenda))
277 #+begin_src emacs-lisp
278 (use-package org-tempo
280 :straight (:type built-in)
282 ;; TODO: There's gotta be a more efficient way to write this
283 (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
284 (add-to-list 'org-structure-template-alist '("sp" . "src conf :tangle ~/.spectrwm.conf"))
285 (add-to-list 'org-structure-template-alist '("zsh" . "src shell :tangle ~/.config/zsh/zshrc"))
286 (add-to-list 'org-structure-template-alist '("al" . "src yml :tangle ~/.config/alacritty/alacritty.yml"))
287 (add-to-list 'org-structure-template-alist '("ipy" . "src python :tangle ~/.ipython/"))
288 (add-to-list 'org-structure-template-alist '("pi" . "src conf :tangle ~/.config/picom/picom.conf"))
289 (add-to-list 'org-structure-template-alist '("git" . "src conf :tangle ~/.gitconfig"))
290 (add-to-list 'org-structure-template-alist '("du" . "src conf :tangle ~/.config/dunst/dunstrc"))
291 (add-to-list 'org-structure-template-alist '("ro" . "src plain :tangle ~/.config/rofi/config.rasi")))
295 Simple, but not too simple autocompletion.
296 #+begin_src emacs-lisp
298 :bind (("C-s" . swiper)
299 :map ivy-minibuffer-map
300 ("TAB" . ivy-alt-done)
301 :map ivy-switch-buffer-map
302 ("M-d" . ivy-switch-buffer-kill))
306 #+begin_src emacs-lisp
307 (use-package ivy-rich
309 :config (ivy-rich-mode))
313 #+begin_src emacs-lisp
315 :bind (("C-M-j" . 'counsel-switch-buffer)
316 :map minibuffer-local-map
317 ("C-r" . 'counsel-minibuffer-history))
318 :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
319 :config (counsel-mode))
321 ** Remember frequent commands
322 #+begin_src emacs-lisp
323 (use-package ivy-prescient
326 (ivy-prescient-enable-filtering nil)
328 (prescient-persist-mode)
329 (ivy-prescient-mode))
332 Better search utility.
333 #+begin_src emacs-lisp
338 Use elfeed for RSS. I have another file with all the feeds in it.
339 #+begin_src emacs-lisp
341 :bind (("C-c e" . elfeed))
343 (load "~/.emacs.d/feeds.el")
344 (add-hook 'elfeed-new-entry-hook
345 (elfeed-make-tagger :feed-url "youtube\\.com"
347 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
349 (use-package elfeed-goodies
351 :config (elfeed-goodies/setup))
354 Use mu4e for reading emails.
356 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.
358 Contexts are a not very well known feature of mu4e that makes it super easy to manage multiple accounts. Much better than some of the hacky methods and external packages that I've seen.
359 #+begin_src emacs-lisp
360 (use-package smtpmail
361 :straight (:type built-in))
363 :load-path "/usr/share/emacs/site-lisp/mu4e"
364 :bind (("C-c m" . mu4e))
366 (setq user-full-name "Armaan Bhojwani"
367 smtpmail-local-domain "armaanb.net"
368 smtpmail-stream-type 'ssl
369 smtpmail-smtp-service '465
370 mu4e-change-filenames-when-moving t
371 message-kill-buffer-on-exit t
372 mu4e-get-mail-command "offlineimap -q"
373 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
374 message-citation-line-function 'message-insert-formatted-citation-line
375 mu4e-context-policy "pick-first"
377 `( ,(make-mu4e-context
379 :enter-func (lambda () (mu4e-message "Entering school context"))
380 :leave-func (lambda () (mu4e-message "Leaving school context"))
381 :match-func (lambda (msg)
383 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
384 :vars '( (user-mail-address . "abhojwani22@nobles.edu")
385 (mu4e-sent-folder . "/school/Sent")
386 (mu4e-drafts-folder . "/school/Drafts")
387 (mu4e-trash-folder . "/school/Trash")
388 (mu4e-refile-folder . "/school/Archive")
389 (user-mail-address . "abhojwani22@nobles.edu")
390 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
391 (smtpmail-smtp-server . "smtp.gmail.com")))
394 :enter-func (lambda () (mu4e-message "Entering personal context"))
395 :leave-func (lambda () (mu4e-message "Leaving personal context"))
396 :match-func (lambda (msg)
398 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
400 (mu4e-sent-folder . "/personal/Sent")
401 (mu4e-drafts-folder . "/personal/Drafts")
402 (mu4e-trash-folder . "/personal/Trash")
403 (mu4e-refile-folder . "/personal/Archive")
404 (user-mail-address . "me@armaanb.net")
405 (smtpmail-smtp-user . "me@armaanb.net")
406 (smtpmail-smtp-server "smtp.mailbox.org")
407 (mu4e-drafts-folder . "/school/Drafts")
408 (mu4e-trash-folder . "/school/Trash")))))
409 (add-to-list 'mu4e-bookmarks
410 '(:name "Unified inbox"
411 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
415 #+begin_src emacs-lisp
417 (use-package calfw-org)
418 (use-package calfw-ical)
420 (defun acheam-calendar ()
423 (shell-command "vdirsyncer sync")
424 (let ((default-directory "~/.local/share/vdirsyncer/"))
425 (cfw:open-calendar-buffer
428 (cfw:ical-create-source "School" (expand-file-name "school/abhojwani22@nobles.edu.ics") "Green")
429 (cfw:ical-create-source "Personal" (expand-file-name "mailbox/Y2FsOi8vMC8zMQ.ics") "Blue")
430 (cfw:ical-create-source "Birthdays" (expand-file-name "mailbox/Y2FsOi8vMS8w.ics") "Gray")
434 Another file has more specific network configuration.
435 #+begin_src emacs-lisp
437 :config (load-file "~/.emacs.d/irc.el"))
439 (use-package circe-chanop
440 :straight (:type built-in)
443 (use-package circe-color-nicks
444 :straight (:type built-in)
448 Set EWW as default browser except for videos.
449 #+begin_src emacs-lisp
450 (defun browse-url-mpv (url &optional new-window)
452 (start-process "mpv" "*mpv*" "mpv" url))
454 (setq browse-url-handlers
456 (("youtu\\.?be" . browse-url-mpv)
457 ("." . eww-browse-url)
461 Some EWW enhancements.
462 *** Give buffer a useful name
463 #+begin_src emacs-lisp
464 ;; From https://protesilaos.com/dotemacs/
465 (defun prot-eww--rename-buffer ()
466 "Rename EWW buffer using page title or URL.
467 To be used by `eww-after-render-hook'."
468 (let ((name (if (eq "" (plist-get eww-data :title))
469 (plist-get eww-data :url)
470 (plist-get eww-data :title))))
471 (rename-buffer (format "*%s # eww*" name) t)))
473 (add-hook 'eww-after-render-hook #'prot-eww--rename-buffer)
475 *** Better entrypoint
476 #+begin_src emacs-lisp
477 ;; From https://protesilaos.com/dotemacs/
478 (defun prot-eww-browse-dwim (url &optional arg)
479 "Visit a URL, maybe from `eww-prompt-history', with completion.
481 With optional prefix ARG (\\[universal-argument]) open URL in a
484 If URL does not look like a valid link, run a web query using
487 When called from an eww buffer, provide the current link as
491 (completing-read "Query:" eww-prompt-history
492 nil nil (plist-get eww-data :url) 'eww-prompt-history)
494 (eww url (if arg 4 nil)))
496 (global-set-key (kbd "C-c w") 'prot-eww-browse-dwim)
499 Use Emacs globally. Use the Emacs daemon and bind a key in your wm to
500 =emacsclient --eval "(emacs-everywhere)"=.
501 #+begin_src emacs-lisp
502 (use-package emacs-everywhere)
507 #+begin_src emacs-lisp
508 (use-package lsp-mode
509 :commands (lsp lsp-deferred)
510 :custom (lsp-keymap-prefix "C-c l")
511 :hook ((lsp-mode . lsp-enable-which-key-integration)))
513 (use-package lsp-ivy)
516 :commands lsp-ui-mode
517 :custom (lsp-ui-doc-position 'bottom))
518 (use-package lsp-ui-flycheck
520 :straight (:type built-in))
523 Company-box adds icons.
524 #+begin_src emacs-lisp
527 :hook (lsp-mode . company-mode)
528 :bind (:map company-active-map
529 ("<tab>" . company-complete-selection))
531 ("<tab>" . company-indent-or-complete-common))
533 (company-minimum-prefix-length 1)
534 (setq company-dabbrev-downcase 0)
535 (company-idle-delay 0.0))
537 (use-package company-box
538 :hook (company-mode . company-box-mode))
542 #+begin_src emacs-lisp
543 (use-package lsp-pyright
544 :hook (python-mode . (lambda ()
545 (use-package lsp-pyright
546 :straight (:type built-in))
550 #+begin_src emacs-lisp
552 :hook (python-mode . blacken-mode)
554 (setq blacken-line-length 79))
557 (use-package ws-butler
559 (ws-butler-global-mode))
562 #+begin_src emacs-lisp
563 (use-package flycheck
565 (global-flycheck-mode))
567 ** Project management
568 #+begin_src emacs-lisp
569 (use-package projectile
570 :config (projectile-mode)
571 :custom ((projectile-completion-system 'ivy))
573 ("C-c p" . projectile-command-map)
575 (when (file-directory-p "~/Code")
576 (setq projectile-project-search-path '("~/Code")))
577 (setq projectile-switch-project-action #'projectile-dired))
579 (use-package counsel-projectile
581 :config (counsel-projectile-mode))
584 #+begin_src emacs-lisp
586 :straight (:type built-in)
587 :commands (dired dired-jump)
588 :custom ((dired-listing-switches "-agho --group-directories-first"))
590 (evil-collection-define-key 'normal 'dired-mode-map
591 "h" 'dired-single-up-directory
592 "l" 'dired-single-buffer))
594 (use-package dired-single
595 :commands (dired dired-jump))
597 (use-package dired-open
598 :commands (dired dired-jump)
600 (dired-open-extensions '(("png" . "feh")
603 (use-package dired-hide-dotfiles
604 :hook (dired-mode . dired-hide-dotfiles-mode)
606 (evil-collection-define-key 'normal 'dired-mode-map
607 "H" 'dired-hide-dotfiles-mode))
611 # TODO: Write a command that commits hunk, skipping staging step.
612 #+begin_src emacs-lisp
615 *** Colored diff in line number area
616 #+begin_src emacs-lisp
618 :straight (diff-hl :type git :host github :repo "dgutov/diff-hl")
619 :hook ((magit-pre-refresh-hook . diff-hl-magit-pre-refresh)
620 (magit-post-refresh-hook . diff-hl-magit-post-refresh))
621 :config (global-diff-hl-mode))
623 * General text editing
625 Indent after every change.
626 #+begin_src emacs-lisp
627 (use-package aggressive-indent
628 :config (global-aggressive-indent-mode))
631 Spell check in text mode, and in prog-mode comments.
632 #+begin_src emacs-lisp
633 (dolist (hook '(text-mode-hook))
634 (add-hook hook (lambda () (flyspell-mode))))
635 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
636 (add-hook hook (lambda () (flyspell-mode -1))))
637 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
639 ** Expand tabs to spaces
640 #+begin_src emacs-lisp
641 (setq-default tab-width 2)
643 ** Copy kill ring to clipboard
644 #+begin_src emacs-lisp
645 (setq x-select-enable-clipboard t)
646 (defun copy-kill-ring-to-xorg ()
647 "Copy the current kill ring to the xorg clipboard."
649 (x-select-text (current-kill 0)))
652 #+begin_src emacs-lisp
653 (use-package browse-kill-ring)
656 Opens file where you left it.
657 #+begin_src emacs-lisp
661 Distraction free writing a la junegunn/goyo.
662 #+begin_src emacs-lisp
663 (use-package olivetti
665 (evil-leader/set-key "o" 'olivetti-mode))
669 #+begin_src emacs-lisp
670 (setq abbrev-file-name "~/.emacs.d/abbrevs")
671 (setq save-abbrevs 'silent)
672 (setq-default abbrev-mode t)
675 #+begin_src emacs-lisp
676 (setq tramp-default-method "ssh")
678 ** Don't ask about following symlinks in vc
679 #+begin_src emacs-lisp
680 (setq vc-follow-symlinks t)
683 ** Easily convert splits
684 Converts splits from horizontal to vertical and vice versa. Lifted from EmacsWiki.
685 #+begin_src emacs-lisp
686 (defun toggle-window-split ()
688 (if (= (count-windows) 2)
689 (let* ((this-win-buffer (window-buffer))
690 (next-win-buffer (window-buffer (next-window)))
691 (this-win-edges (window-edges (selected-window)))
692 (next-win-edges (window-edges (next-window)))
693 (this-win-2nd (not (and (<= (car this-win-edges)
694 (car next-win-edges))
695 (<= (cadr this-win-edges)
696 (cadr next-win-edges)))))
698 (if (= (car this-win-edges)
699 (car (window-edges (next-window))))
700 'split-window-horizontally
701 'split-window-vertically)))
702 (delete-other-windows)
703 (let ((first-win (selected-window)))
705 (if this-win-2nd (other-window 1))
706 (set-window-buffer (selected-window) this-win-buffer)
707 (set-window-buffer (next-window) next-win-buffer)
708 (select-window first-win)
709 (if this-win-2nd (other-window 1))))))
711 (define-key ctl-x-4-map "t" 'toggle-window-split)
714 #+begin_src emacs-lisp
715 (defun insert-date ()
717 (insert (format-time-string "%Y-%m-%d")))
721 #+begin_src emacs-lisp
722 (use-package ace-window
723 :bind ("M-o" . ace-window))
725 ** Kill current buffer
726 Makes "C-x k" binding faster.
727 #+begin_src emacs-lisp
728 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
732 Render OpenSCAD files, and add a preview window.
734 Personal fork just merges a PR.
735 #+begin_src emacs-lisp
736 (use-package scad-mode)
737 (use-package scad-preview
738 :straight (scad-preview :type git :host github :repo "Armaanb/scad-preview"))
740 ** Control backup files
741 Stop backup files from spewing everywhere.
742 #+begin_src emacs-lisp
743 (setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
745 ** Make yes/no easier
746 #+begin_src emacs-lisp
747 (defalias 'yes-or-no-p 'y-or-n-p)
749 ** Move customize file
750 No more clogging up init.el.
751 #+begin_src emacs-lisp
752 (setq custom-file "~/.emacs.d/custom.el")
756 #+begin_src emacs-lisp
758 :commands (helpful-callable helpful-variable helpful-command helpful-key)
760 (counsel-describe-function-function #'helpful-callable)
761 (counsel-describe-variable-function #'helpful-variable)
763 ([remap describe-function] . counsel-describe-function)
764 ([remap describe-command] . helpful-command)
765 ([remap describe-variable] . counsel-describe-variable)
766 ([remap describe-key] . helpful-key))
769 #+begin_src emacs-lisp
770 (use-package epa-file
771 :straight (:type built-in)
773 (epa-file-select-keys nil)
774 (epa-file-encrypt-to '("me@armaanb.net"))
775 (password-cache-expiry (* 60 15)))
777 (use-package pinentry
778 :config (pinentry-start))
781 #+begin_src emacs-lisp
783 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
784 :custom (0x0-default-service 'envs)
785 :config (evil-leader/set-key
787 "0f" '0x0-upload-file
788 "0s" '0x0-upload-string
789 "0c" '0x0-upload-kill-ring
790 "0p" '0x0-upload-popup))
795 #+begin_src conf :tangle ~/.spectrwm.conf
800 autorun = ws[1]:/home/armaa/Code/scripts/autostart
803 #+begin_src conf :tangle ~/.spectrwm.conf
804 color_focus = rgb:00/d3/d0
805 color_focus_maximized = rgb:ee/cc/00
806 color_unfocus = rgb:55/55/55
809 #+begin_src conf :tangle ~/.spectrwm.conf
811 bar_font = xos4 Fira Code:pixelsize=14:antialias=true # any installed font
815 #+begin_src conf :tangle ~/.spectrwm.conf
816 program[lock] = i3lock -c 000000 -ef
817 program[term] = alacritty
818 program[screenshot_all] = flameshot gui
819 program[menu] = rofi -show run # `rofi-dmenu` handles the rest
820 program[switcher] = rofi -show window
821 program[notif] = /home/armaa/Code/scripts/setter status
824 bind[switcher] = MOD+Tab
827 #+begin_src conf :tangle ~/.spectrwm.conf
828 program[paup] = /home/armaa/Code/scripts/setter audio +5
829 program[padown] = /home/armaa/Code/scripts/setter audio -5
830 program[pamute] = /home/armaa/Code/scripts/setter audio
831 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
832 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
833 program[next] = playerctl next
834 program[prev] = playerctl previous
835 program[pause] = playerctl play-pause
837 bind[padown] = XF86AudioLowerVolume
838 bind[paup] = XF86AudioRaiseVolume
839 bind[pamute] = XF86AudioMute
840 bind[brigdown] = XF86MonBrightnessDown
841 bind[brigup] = XF86MonBrightnessUp
842 bind[pause] = XF86AudioPlay
843 bind[next] = XF86AudioNext
844 bind[prev] = XF86AudioPrev
847 #+begin_src conf :tangle ~/.spectrwm.conf
848 program[h] = xdotool keyup h key --clearmodifiers Left
849 program[j] = xdotool keyup j key --clearmodifiers Down
850 program[k] = xdotool keyup k key --clearmodifiers Up
851 program[l] = xdotool keyup l key --clearmodifiers Right
853 bind[h] = Mod1 + Tab + h
854 bind[j] = Mod1 + Tab + j
855 bind[k] = Mod1 + Tab + k
856 bind[l] = Mod1 + Tab + l
859 #+begin_src conf :tangle ~/.spectrwm.conf
860 program[aerc] = alacritty -e aerc
861 program[weechat] = alacritty --hold -e sh -c "while : ; do ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat; sleep 2; done"
862 program[emacs] = emacsclient -c
863 program[emacs-anywhere] = emacsclient --eval "(emacs-everywhere)"
864 program[firefox] = firefox
865 program[thunderbird] = thunderbird
866 program[slack] = slack
868 bind[aerc] = MOD+Control+s
869 bind[weechat] = MOD+Control+d
870 bind[emacs] = MOD+Control+Return
871 bind[emacs-anywhere] = MOD+Control+f
872 bind[firefox] = MOD+Control+u
873 bind[thunderbird] = MOD+Control+i
874 bind[slack] = MOD+Control+o
879 #+begin_src shell :tangle ~/.config/zsh/zshrc
880 autoload -Uz compinit
884 unsetopt glob_complete
887 #+begin_src shell :tangle ~/.config/zsh/zshrc
891 bindkey -M vicmd "^[[3~" delete-char
892 bindkey "^[[3~" delete-char
894 autoload edit-command-line
895 zle -N edit-command-line
896 bindkey -M vicmd ^e edit-command-line
897 bindkey ^e edit-command-line
900 #+begin_src shell :tangle ~/.config/zsh/zshrc
901 setopt extended_history
903 setopt inc_append_history
904 setopt hist_ignore_dups
905 setopt hist_reduce_blanks
909 HISTFILE=~/.local/share/zsh/history
912 I manage plugins using my own plugin manager, ZPE. https://git.sr.ht/~armaan/zpe
914 #+begin_src plain :tangle ~/.config/zpe/repositories
915 https://github.com/Aloxaf/fzf-tab
916 https://github.com/zdharma/fast-syntax-highlighting
917 https://github.com/rupa/z
920 #+begin_src shell :tangle ~/.config/zsh/zshrc
921 source ~/Code/zpe/zpe.sh
922 source ~/Code/admone/admone.zsh
923 source ~/.config/zsh/fzf-bindings.zsh
925 zpe-source fzf-tab/fzf-tab.zsh
926 zstyle ':completion:*:descriptions' format '[%d]'
927 zstyle ':fzf-tab:complete:cd:*' fzf-preview 'exa -1 --color=always $realpath'
928 zstyle ':completion:*' completer _complete
929 zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \
930 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
932 zpe-source fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
933 export _Z_DATA="/home/armaa/.local/share/z"
937 **** Alert after long command
938 #+begin_src shell :tangle ~/.config/zsh/zshrc
940 notify-send --urgency=low -i ${(%):-%(?.terminal.error)} \
941 ${history[$HISTCMD]%[;&|][[:space:]]##alert}
944 **** Time Zsh startup
945 #+begin_src shell :tangle ~/.config/zsh/zshrc
947 for i in $(seq 1 10); do
948 time "zsh" -i -c exit;
952 **** Update all packages
953 #+begin_src shell :tangle ~/.config/zsh/zshrc
954 color=$(tput setaf 5)
958 sudo echo "${color}== upgrading with yay ==${reset}"
961 echo "${color}== checking for pacnew files ==${reset}"
964 echo "${color}== upgrading flatpaks ==${reset}"
967 echo "${color}== upgrading zsh plugins ==${reset}"
970 echo "${color}== updating nvim plugins ==${reset}"
971 nvim +PlugUpdate +PlugUpgrade +qall
972 echo "Updated nvim plugins"
974 echo "${color}You are entirely up to date!${reset}"
977 **** Clean all packages
978 #+begin_src shell :tangle ~/.config/zsh/zshrc
980 sudo echo "${color}== cleaning pacman orphans ==${reset}"
981 (pacman -Qtdq | sudo pacman -Rns - 2> /dev/null) || echo "No orphans"
983 echo "${color}== cleaning flatpaks ==${reset}"
984 flatpak remove --unused
986 echo "${color}== cleaning zsh plugins ==${reset}"
989 echo "${color}== cleaning nvim plugins ==${reset}"
990 nvim +PlugClean +qall
991 echo "Cleaned nvim plugins"
993 echo "${color}All orphans cleaned!${reset}"
997 #+begin_src shell :tangle ~/.config/zsh/zshrc
1000 exa -lh --icons --git --group-directories-first
1004 #+begin_src shell :tangle ~/.config/zsh/zshrc
1006 __conda_setup="$('/opt/anaconda/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
1007 if [ $? -eq 0 ]; then
1008 eval "$__conda_setup"
1010 if [ -f "/opt/anaconda/etc/profile.d/conda.sh" ]; then
1011 . "/opt/anaconda/etc/profile.d/conda.sh"
1013 export PATH="/opt/anaconda/bin:$PATH"
1019 **** Interact with 0x0
1020 #+begin_src shell :tangle ~/.config/zsh/zshrc
1021 zxz="https://envs.sh"
1022 0file() { curl -F"file=@$1" "$zxz" ; }
1023 0pb() { curl -F"file=@-;" "$zxz" ; }
1024 0url() { curl -F"url=$1" "$zxz" ; }
1025 0short() { curl -F"shorten=$1" "$zxz" ; }
1026 0clip() { xclip -out | curl -F"file=@-;" "$zxz" ; }
1029 #+begin_src shell :tangle ~/.config/zsh/zshrc
1038 #+begin_src shell :tangle ~/.config/zsh/zshrc
1039 alias bhoji-drop='ssh -p 23 root@armaanb.net'
1040 alias weechat='ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat'
1041 alias tcf='ssh root@204.48.23.68'
1042 alias ngmun='ssh root@157.245.89.25'
1043 alias prox='ssh root@192.168.1.224'
1044 alias dock='ssh root@192.168.1.225'
1045 alias jenkins='ssh root@192.168.1.226'
1046 alias envs='ssh acheam@envs.net'
1048 **** File management
1049 #+begin_src shell :tangle ~/.config/zsh/zshrc
1050 alias ls='exa -lh --icons --git --group-directories-first'
1051 alias la='exa -lha --icons --git --group-directories-first'
1052 alias df='df -h / /boot'
1054 alias free='free -h'
1059 alias grep='grep -in --exclude-dir=.git --color=auto'
1060 alias mkdir='mkdir -pv'
1061 alias unar='atool -x'
1062 alias wget='wget -e robots=off'
1063 alias lanex='~/.local/share/lxc/lxc'
1066 #+begin_src shell :tangle ~/.config/zsh/zshrc
1067 alias padm='yadm --yadm-repo ~/Code/dotfiles/repo.git'
1068 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1070 alias padu='padm add -u && padm commit && padm push && yadu'
1073 #+begin_src shell :tangle ~/.config/zsh/zshrc
1076 alias vw="nvim ~/Documents/vimwiki/index.md"
1078 **** System management
1079 #+begin_src shell :tangle ~/.config/zsh/zshrc
1080 alias jctl='journalctl -p 3 -xb'
1081 alias pkill='pkill -i'
1083 alias please='sudo $(fc -ln -1)'
1084 alias sudo='sudo ' # allows aliases to be run with sudo
1087 #+begin_src shell :tangle ~/.config/zsh/zshrc
1088 alias ping='ping -c 10'
1089 alias speed='speedtest-cli'
1090 alias ip='ip --color=auto'
1091 alias cip='curl https://armaanb.net/ip'
1092 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1093 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1096 #+begin_src shell :tangle ~/.config/zsh/zshrc
1097 alias dc='docker-compose'
1098 alias dcdu='docker-compose down && docker-compose up -d'
1101 #+begin_src shell :tangle ~/.config/zsh/zshrc
1102 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1103 iflag=fullblock status=progress'
1104 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1105 iflag=fullblock status=progress'
1106 alias ts='gen-shell -c task'
1107 alias ts='gen-shell -c task'
1108 alias tetris='autoload -Uz tetriscurses && tetriscurses'
1109 alias news='newsboat'
1110 alias tilderadio="\mpv https://radio.tildeverse.org/radio/8000/radio.ogg"
1111 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1112 --restrict-filenames -o '%(title)s.%(ext)s'"
1113 alias cal="cal -3 --color=auto"
1115 **** Virtual machines, chroots
1116 #+begin_src shell :tangle ~/.config/zsh/zshrc
1117 alias ckiss="sudo chrooter ~/Virtual/kiss"
1118 alias cdebian="sudo chrooter ~/Virtual/debian bash"
1119 alias cwindows='devour qemu-system-x86_64 \
1124 -device VGA,vgamem_mb=64 \
1126 -device hda-duplex \
1128 -net user,smb=/home/armaa/Public \
1129 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1132 #+begin_src shell :tangle ~/.config/zsh/zshrc
1134 alias zpy="zconda && ipython"
1135 alias math="ipython --profile=math"
1136 alias pypi="python setup.py sdist && twine upload dist/*"
1137 alias pip="python -m pip"
1138 alias black="black -l 79"
1141 #+begin_src shell :tangle ~/.config/zsh/zshrc
1142 alias words='gen-shell -c "words"'
1143 alias words-e='gen-shell -c "words ~E"'
1146 #+begin_src shell :tangle ~/.config/zsh/zshrc
1147 alias zathura='devour zathura'
1148 alias mpv='devour mpv'
1149 alias sql='devour sqlitebrowser'
1150 alias cad='devour openscad'
1151 alias feh='devour feh'
1153 **** Package management (Pacman)
1154 #+begin_src shell :tangle ~/.config/zsh/zshrc
1156 alias api='yay -Syu'
1157 alias apii='sudo pacman -S'
1158 alias app='yay -Rns'
1160 alias apo='yay -Qttd'
1161 alias azf='pacman -Q | fzf'
1162 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1163 alias ufetch='ufetch-arch'
1164 alias reflect='reflector --verbose --sort rate --save \
1165 ~/.local/etc/pacman.d/mirrorlist --download-timeout 60' # Takes ~45m to run
1168 #+begin_src shell :tangle ~/.config/zsh/zshrc
1169 export EDITOR="emacsclient -c"
1170 export VISUAL="$VISUAL"
1171 export TERM=xterm-256color # for compatability
1173 export GPG_TTY="$(tty)"
1174 export MANPAGER='nvim +Man!'
1177 export GTK_USE_PORTAL=1
1179 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
1180 export PATH="$PATH:/home/armaa/Code/scripts"
1181 export PATH="$PATH:/home/armaa/.cargo/bin"
1182 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
1183 export PATH="$PATH:/usr/sbin"
1184 export PATH="$PATH:/opt/FreeTube/freetube"
1186 export LC_ALL="en_US.UTF-8"
1187 export LC_CTYPE="en_US.UTF-8"
1188 export LANGUAGE="en_US.UTF-8"
1190 export KISS_PATH="/home/armaa/kiss/home/armaa/kiss-repo"
1191 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
1192 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
1193 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
1194 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
1195 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
1199 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1202 family: JetBrains Mono Nerd Font
1209 ligatures: true # Requires ligature patch
1216 background_opacity: 1
1219 Send <RET> + modifier through
1220 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1234 Modus vivendi. Source: https://github.com/ishan9299/Nixos/blob/d4bbb7536be95b59466bb9cca4d671be46e04e81/user/alacritty/alacritty.yml#L30-L118
1235 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1239 background: '#000000'
1240 foreground: '#ffffff'
1244 background: '#777777'
1246 # Normal colors (except green it is from intense colors)
1257 # Bright colors [all the faint colors in the modus theme]
1268 # dim [all the intense colors in modus theme]
1281 Symlink profile_default/ipython_config.py to profile_math/ipython_config.py
1282 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1283 c.TerminalInteractiveShell.editing_mode = 'vi'
1284 c.InteractiveShell.colors = 'linux'
1285 c.TerminalInteractiveShell.confirm_exit = False
1288 #+begin_src python :tangle ~/.ipython/profile_math/startup.py
1292 return x * (180 / pi)
1295 return x * (pi / 180)
1298 return (x * (pi / 180)) / unit
1310 Make MPV play a little bit smoother.
1311 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1312 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1316 For any GNU Readline programs
1317 #+begin_src plain :tangle ~/.inputrc
1322 #+begin_src conf :tangle ~/.gitconfig
1324 name = Armaan Bhojwani
1325 email = me@armaanb.net
1326 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1329 #+begin_src conf :tangle ~/.gitconfig
1331 defaultBranch = main
1334 #+begin_src conf :tangle ~/.gitconfig
1339 #+begin_src conf :tangle ~/.gitconfig
1341 smtpserver = smtp.mailbox.org
1342 smtpuser = me@armaanb.net
1343 smtpencryption = ssl
1344 smtpserverport = 465
1348 #+begin_src conf :tangle ~/.gitconfig
1353 #+begin_src conf :tangle ~/.gitconfig
1356 sclone = clone --depth 1
1362 subup = submodule update --remote
1363 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1364 mirror = git config --global alias.mirrormirror
1367 #+begin_src conf :tangle ~/.gitconfig
1372 Lightweight notification daemon.
1374 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1376 font = "JetBrains Mono Medium Nerd Font 11"
1378 format = "<b>%s</b>\n%b"
1380 indicate_hidden = yes
1383 show_age_threshold = 60
1386 geometry = "400x5-10+10"
1388 idle_threshold = 120
1390 sticky_history = yes
1392 separator_height = 4
1394 horizontal_padding = 8
1396 separator_color = "#777777"
1397 startup_notification = false
1400 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1407 close_all = mod4+shift+c
1408 history = mod4+ctrl+c
1411 background = "#222222"
1412 foreground = "#ffffff"
1413 highlight = "#777777"
1417 background = "#222222"
1418 foreground = "#ffffff"
1419 highlight = "#777777"
1423 background = "#222222"
1424 foreground = "#a60000"
1425 highlight = "#777777"
1429 Modus vivendi theme that extends DarkBlue.
1430 #+begin_src plain :tangle ~/.config/rofi/config.rasi
1431 @import "/usr/share/rofi/themes/DarkBlue.rasi"
1433 selected-normal-foreground: rgba ( 0, 0, 0, 100 % );
1434 foreground: rgba ( 255, 255, 255, 100 % );
1435 background: rgba ( 0, 0, 0, 100 % );
1436 lightfg: rgba ( 255, 255, 255, 100 % );
1437 selected-normal-background: rgba ( 255, 255, 255, 100 % );