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 "~~" "~~>" "~>" "~-" "~@" "$>" "^=" "]#"))
83 (global-ligature-mode t))
86 #+begin_src emacs-lisp
88 :config (global-emojify-mode))
90 ;; http://ergoemacs.org/emacs/emacs_list_and_set_font.html
95 ((member "Twitter Color Emoji" (font-family-list)) "Twitter Color Emoji")
96 ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
97 ((member "Noto Emoji" (font-family-list)) "Noto Emoji")))
100 Display relative line numbers except in some modes
101 #+begin_src emacs-lisp
102 (global-display-line-numbers-mode)
103 (setq display-line-numbers-type 'relative)
104 (dolist (no-line-num '(term-mode-hook
109 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
111 ** Highlight matching parenthesis
112 #+begin_src emacs-lisp
114 :config (show-paren-mode)
115 :custom (show-paren-style 'parenthesis))
118 *** Show current function
119 #+begin_src emacs-lisp
120 (which-function-mode)
122 *** Make position in file more descriptive
123 Show current column and file size.
124 #+begin_src emacs-lisp
126 (size-indication-mode)
129 #+begin_src emacs-lisp
131 :config (minions-mode))
134 #+begin_src emacs-lisp
136 :straight (wc-mode :type git :host github :repo "bnbeckwith/wc-mode")
137 :hook (text-mode-hook . wc-mode))
140 Show a ruler at a certain number of chars depending on mode.
141 #+begin_src emacs-lisp
142 (global-display-fill-column-indicator-mode)
145 Whenever starting a key chord, show possible future steps.
146 #+begin_src emacs-lisp
147 (use-package which-key
148 :config (which-key-mode)
149 :custom (which-key-idle-delay 0.3))
151 ** Visual highlights of changes
152 Highlight when changes are made.
153 #+begin_src emacs-lisp
154 (use-package evil-goggles
155 :config (evil-goggles-mode)
156 (evil-goggles-use-diff-faces))
158 ** Highlight TODOs in comments
159 #+begin_src emacs-lisp
161 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
162 :config (global-hl-todo-mode 1))
165 #+begin_src emacs-lisp
169 Soft wrap words and do operations by visual lines.
170 #+begin_src emacs-lisp
171 (add-hook 'text-mode-hook 'turn-on-visual-line-mode)
173 ** Display number of matches in search
174 #+begin_src emacs-lisp
176 :config (global-anzu-mode))
179 Inverts modeline instead of audible bell or the standard visual bell.
180 #+begin_src emacs-lisp
181 (setq visible-bell nil
182 ring-bell-function 'flash-mode-line)
183 (defun flash-mode-line ()
184 (invert-face 'mode-line)
185 (run-with-timer 0.1 nil #'invert-face 'mode-line))
189 #+begin_src emacs-lisp
191 :custom (select-enable-clipboard nil)
194 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
195 ;; Use visual line motions even outside of visual-line-mode buffers
196 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
197 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
198 (global-set-key (kbd "<escape>") 'keyboard-escape-quit))
201 #+begin_src emacs-lisp
202 (use-package evil-collection
204 :init (evil-collection-init)
205 :custom (evil-collection-setup-minibuffer t))
209 #+begin_src emacs-lisp
210 (use-package evil-surround
211 :config (global-evil-surround-mode))
214 #+begin_src emacs-lisp
215 (use-package evil-leader
216 :straight (evil-leader :type git :host github :repo "cofi/evil-leader")
218 (evil-leader/set-leader "<SPC>")
219 (global-evil-leader-mode))
222 #+begin_src emacs-lisp
224 (use-package evil-nerd-commenter
225 :bind (:map evil-normal-state-map
226 ("gc" . evilnc-comment-or-uncomment-lines))
227 :custom (evilnc-invert-comment-line-by-line nil))
231 #+begin_src emacs-lisp
232 (evil-set-undo-system 'undo-redo)
234 ** Number incrementing
236 #+begin_src emacs-lisp
237 (use-package evil-numbers
238 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
239 :bind (:map evil-normal-state-map
240 ("C-M-a" . evil-numbers/inc-at-pt)
241 ("C-M-x" . evil-numbers/dec-at-pt)))
245 #+begin_src emacs-lisp
246 (use-package evil-org
248 :hook (org-mode . evil-org-mode)
250 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
251 (use-package evil-org-agenda
252 :straight (:type built-in)
255 (evil-org-agenda-set-keys))
258 #+begin_src emacs-lisp
259 (evil-leader/set-key-for-mode 'org-mode
260 "T" 'org-show-todo-tree
262 "c" 'org-archive-subtree)
266 #+begin_src emacs-lisp
268 :straight (:type built-in)
269 :commands (org-capture org-agenda)
272 (org-agenda-start-with-log-mode t)
273 (org-agenda-files (quote ("~/Org/tasks.org" "~/Org/break.org")))
275 (org-log-into-drawer t)
276 (org-src-tab-acts-natively t)
277 (org-src-fontify-natively t)
278 (org-startup-indented t)
279 (org-hide-emphasis-markers t)
280 (org-fontify-whole-block-delimiter-line nil)
281 :bind ("C-c a" . org-agenda))
284 #+begin_src emacs-lisp
285 (use-package org-tempo
287 :straight (:type built-in)
289 ;; TODO: There's gotta be a more efficient way to write this
290 (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
291 (add-to-list 'org-structure-template-alist '("sp" . "src conf :tangle ~/.spectrwm.conf"))
292 (add-to-list 'org-structure-template-alist '("zsh" . "src shell :tangle ~/.config/zsh/zshrc"))
293 (add-to-list 'org-structure-template-alist '("al" . "src yml :tangle ~/.config/alacritty/alacritty.yml"))
294 (add-to-list 'org-structure-template-alist '("ipy" . "src python :tangle ~/.ipython/"))
295 (add-to-list 'org-structure-template-alist '("pi" . "src conf :tangle ~/.config/picom/picom.conf"))
296 (add-to-list 'org-structure-template-alist '("git" . "src conf :tangle ~/.gitconfig"))
297 (add-to-list 'org-structure-template-alist '("du" . "src conf :tangle ~/.config/dunst/dunstrc"))
298 (add-to-list 'org-structure-template-alist '("ro" . "src plain :tangle ~/.config/rofi/config.rasi"))
299 (add-to-list 'org-structure-template-alist '("za" . "src plain :tangle ~/.config/zathura/zathurarc")))
303 Simple, but not too simple autocompletion.
304 #+begin_src emacs-lisp
306 :bind (("C-s" . swiper)
307 :map ivy-minibuffer-map
308 ("TAB" . ivy-alt-done)
309 :map ivy-switch-buffer-map
310 ("M-d" . ivy-switch-buffer-kill))
314 #+begin_src emacs-lisp
315 (use-package ivy-rich
317 :config (ivy-rich-mode))
321 #+begin_src emacs-lisp
323 :bind (("C-M-j" . 'counsel-switch-buffer)
324 :map minibuffer-local-map
325 ("C-r" . 'counsel-minibuffer-history))
326 :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
327 :config (counsel-mode))
329 ** Remember frequent commands
330 #+begin_src emacs-lisp
331 (use-package ivy-prescient
334 (ivy-prescient-enable-filtering nil)
336 (prescient-persist-mode)
337 (ivy-prescient-mode))
340 Better search utility.
341 #+begin_src emacs-lisp
346 Use elfeed for RSS. I have another file with all the feeds in it.
347 #+begin_src emacs-lisp
349 :bind (("C-c e" . elfeed))
351 (load "~/.emacs.d/feeds.el")
352 (add-hook 'elfeed-new-entry-hook
353 (elfeed-make-tagger :feed-url "youtube\\.com"
355 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
357 (use-package elfeed-goodies
359 :config (elfeed-goodies/setup))
362 Use mu4e for reading emails.
364 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.
366 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.
367 #+begin_src emacs-lisp
368 (use-package smtpmail
369 :straight (:type built-in))
371 :load-path "/usr/share/emacs/site-lisp/mu4e"
372 :bind (("C-c m" . mu4e))
374 (setq user-full-name "Armaan Bhojwani"
375 smtpmail-local-domain "armaanb.net"
376 smtpmail-stream-type 'ssl
377 smtpmail-smtp-service '465
378 mu4e-change-filenames-when-moving t
379 mu4e-get-mail-command "offlineimap -q"
380 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
381 message-citation-line-function 'message-insert-formatted-citation-line
382 mu4e-completing-read-function 'ivy-completing-read
383 mu4e-confirm-quit nil
384 mail-user-agent 'mu4e-user-agent
386 `( ,(make-mu4e-context
388 :enter-func (lambda () (mu4e-message "Entering school context"))
389 :leave-func (lambda () (mu4e-message "Leaving school context"))
390 :match-func (lambda (msg)
392 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
393 :vars '((user-mail-address . "abhojwani22@nobles.edu")
394 (mu4e-sent-folder . "/school/Sent")
395 (mu4e-drafts-folder . "/school/Drafts")
396 (mu4e-trash-folder . "/school/Trash")
397 (mu4e-refile-folder . "/school/Archive")
398 (user-mail-address . "abhojwani22@nobles.edu")
399 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
400 (smtpmail-smtp-server . "smtp.gmail.com")))
403 :enter-func (lambda () (mu4e-message "Entering personal context"))
404 :leave-func (lambda () (mu4e-message "Leaving personal context"))
405 :match-func (lambda (msg)
407 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
408 :vars '((mu4e-sent-folder . "/personal/Sent")
409 (mu4e-drafts-folder . "/personal/Drafts")
410 (mu4e-trash-folder . "/personal/Trash")
411 (mu4e-refile-folder . "/personal/Archive")
412 (user-mail-address . "me@armaanb.net")
413 (smtpmail-smtp-user . "me@armaanb.net")
414 (smtpmail-smtp-server "smtp.mailbox.org")
415 (mu4e-drafts-folder . "/school/Drafts")
416 (mu4e-trash-folder . "/school/Trash")))))
417 (add-to-list 'mu4e-bookmarks
418 '(:name "Unified inbox"
419 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
421 :hook ((mu4e-compose-mode . flyspell-mode)
422 (mu4e-view-mode-hook . turn-on-visual-line-mode)))
425 #+begin_src emacs-lisp
427 (use-package calfw-org)
428 (use-package calfw-ical)
430 (defun acheam-calendar ()
433 (shell-command "vdirsyncer sync")
434 (let ((default-directory "~/.local/share/vdirsyncer/"))
435 (cfw:open-calendar-buffer
438 (cfw:ical-create-source "School" (expand-file-name "school/abhojwani22@nobles.edu.ics") "Green")
439 (cfw:ical-create-source "Personal" (expand-file-name "mailbox/Y2FsOi8vMC8zMQ.ics") "Blue")
440 (cfw:ical-create-source "Birthdays" (expand-file-name "mailbox/Y2FsOi8vMS8w.ics") "Gray")
444 Another file has more specific network configuration.
445 #+begin_src emacs-lisp
447 :config (load-file "~/.emacs.d/irc.el"))
449 (use-package circe-chanop
450 :straight (:type built-in)
453 (use-package circe-color-nicks
454 :straight (:type built-in)
458 Set EWW as default browser except for videos.
459 #+begin_src emacs-lisp
460 (defun browse-url-mpv (url &optional new-window)
462 (start-process "mpv" "*mpv*" "mpv" url))
464 (setq browse-url-handlers
466 (("youtu\\.?be" . browse-url-mpv)
467 ("." . eww-browse-url)
471 Some EWW enhancements.
472 *** Give buffer a useful name
473 #+begin_src emacs-lisp
474 ;; From https://protesilaos.com/dotemacs/
475 (defun prot-eww--rename-buffer ()
476 "Rename EWW buffer using page title or URL.
477 To be used by `eww-after-render-hook'."
478 (let ((name (if (eq "" (plist-get eww-data :title))
479 (plist-get eww-data :url)
480 (plist-get eww-data :title))))
481 (rename-buffer (format "*%s # eww*" name) t)))
483 (add-hook 'eww-after-render-hook #'prot-eww--rename-buffer)
485 *** Better entrypoint
486 #+begin_src emacs-lisp
487 ;; From https://protesilaos.com/dotemacs/
488 (defun prot-eww-browse-dwim (url &optional arg)
489 "Visit a URL, maybe from `eww-prompt-history', with completion.
491 With optional prefix ARG (\\[universal-argument]) open URL in a
494 If URL does not look like a valid link, run a web query using
497 When called from an eww buffer, provide the current link as
501 (completing-read "Query:" eww-prompt-history
502 nil nil (plist-get eww-data :url) 'eww-prompt-history)
504 (eww url (if arg 4 nil)))
506 (global-set-key (kbd "C-c w") 'prot-eww-browse-dwim)
509 Use Emacs globally. Use the Emacs daemon and bind a key in your wm to
510 =emacsclient --eval "(emacs-everywhere)"=.
511 #+begin_src emacs-lisp
512 (use-package emacs-everywhere)
515 #+begin_src emacs-lisp
516 (setq eshell-prompt-function
519 "\n" (eshell/pwd) " ➤ ")
520 'face '(:foreground "cyan")))
521 eshell-highlight-prompt nil)
526 #+begin_src emacs-lisp
527 (use-package lsp-mode
528 :commands (lsp lsp-deferred)
529 :custom (lsp-keymap-prefix "C-c l")
530 :hook ((lsp-mode . lsp-enable-which-key-integration)))
532 (use-package lsp-ivy)
535 :commands lsp-ui-mode
536 :custom (lsp-ui-doc-position 'bottom))
537 (use-package lsp-ui-flycheck
539 :straight (:type built-in))
542 Company-box adds icons.
543 #+begin_src emacs-lisp
546 :hook (lsp-mode . company-mode)
547 :bind (:map company-active-map
548 ("<tab>" . company-complete-selection))
550 ("<tab>" . company-indent-or-complete-common))
552 (company-minimum-prefix-length 1)
553 (setq company-dabbrev-downcase 0)
554 (company-idle-delay 0.0))
556 (use-package company-box
557 :hook (company-mode . company-box-mode))
561 #+begin_src emacs-lisp
562 (use-package lsp-pyright
563 :hook (python-mode . (lambda ()
564 (use-package lsp-pyright
565 :straight (:type built-in))
569 #+begin_src emacs-lisp
571 :hook (python-mode . blacken-mode)
573 (setq blacken-line-length 79))
576 (use-package ws-butler
578 (ws-butler-global-mode))
581 #+begin_src emacs-lisp
582 (use-package flycheck
584 (global-flycheck-mode))
586 ** Project management
587 #+begin_src emacs-lisp
588 (use-package projectile
589 :config (projectile-mode)
590 :custom ((projectile-completion-system 'ivy))
592 ("C-c p" . projectile-command-map)
594 (when (file-directory-p "~/Code")
595 (setq projectile-project-search-path '("~/Code")))
596 (setq projectile-switch-project-action #'projectile-dired))
598 (use-package counsel-projectile
600 :config (counsel-projectile-mode))
603 #+begin_src emacs-lisp
605 :straight (:type built-in)
606 :commands (dired dired-jump)
607 :custom ((dired-listing-switches "-agho --group-directories-first"))
609 (evil-collection-define-key 'normal 'dired-mode-map
610 "h" 'dired-single-up-directory
611 "l" 'dired-single-buffer))
613 (use-package dired-single
614 :commands (dired dired-jump))
616 (use-package dired-open
617 :commands (dired dired-jump)
619 (dired-open-extensions '(("png" . "feh")
622 (use-package dired-hide-dotfiles
623 :hook (dired-mode . dired-hide-dotfiles-mode)
625 (evil-collection-define-key 'normal 'dired-mode-map
626 "H" 'dired-hide-dotfiles-mode))
630 # TODO: Write a command that commits hunk, skipping staging step.
631 #+begin_src emacs-lisp
634 *** Colored diff in line number area
635 #+begin_src emacs-lisp
637 :straight (diff-hl :type git :host github :repo "dgutov/diff-hl")
638 :hook ((magit-pre-refresh-hook . diff-hl-magit-pre-refresh)
639 (magit-post-refresh-hook . diff-hl-magit-post-refresh))
640 :config (global-diff-hl-mode))
642 * General text editing
644 Indent after every change.
645 #+begin_src emacs-lisp
646 (use-package aggressive-indent
647 :config (global-aggressive-indent-mode))
650 Spell check in text mode, and in prog-mode comments.
651 #+begin_src emacs-lisp
652 (dolist (hook '(text-mode-hook))
653 (add-hook hook (lambda () (flyspell-mode))))
654 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
655 (add-hook hook (lambda () (flyspell-mode -1))))
656 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
658 ** Expand tabs to spaces
659 #+begin_src emacs-lisp
660 (setq-default tab-width 2)
662 ** Copy kill ring to clipboard
663 #+begin_src emacs-lisp
664 (setq x-select-enable-clipboard t)
665 (defun copy-kill-ring-to-xorg ()
666 "Copy the current kill ring to the xorg clipboard."
668 (x-select-text (current-kill 0)))
671 #+begin_src emacs-lisp
672 (use-package browse-kill-ring)
675 Opens file where you left it.
676 #+begin_src emacs-lisp
680 Distraction free writing a la junegunn/goyo.
681 #+begin_src emacs-lisp
682 (use-package olivetti
684 (evil-leader/set-key "o" 'olivetti-mode))
688 #+begin_src emacs-lisp
689 (setq abbrev-file-name "~/.emacs.d/abbrevs")
690 (setq save-abbrevs 'silent)
691 (setq-default abbrev-mode t)
694 #+begin_src emacs-lisp
695 (setq tramp-default-method "ssh")
697 ** Don't ask about following symlinks in vc
698 #+begin_src emacs-lisp
699 (setq vc-follow-symlinks t)
702 ** Easily convert splits
703 Converts splits from horizontal to vertical and vice versa. Lifted from EmacsWiki.
704 #+begin_src emacs-lisp
705 (defun toggle-window-split ()
707 (if (= (count-windows) 2)
708 (let* ((this-win-buffer (window-buffer))
709 (next-win-buffer (window-buffer (next-window)))
710 (this-win-edges (window-edges (selected-window)))
711 (next-win-edges (window-edges (next-window)))
712 (this-win-2nd (not (and (<= (car this-win-edges)
713 (car next-win-edges))
714 (<= (cadr this-win-edges)
715 (cadr next-win-edges)))))
717 (if (= (car this-win-edges)
718 (car (window-edges (next-window))))
719 'split-window-horizontally
720 'split-window-vertically)))
721 (delete-other-windows)
722 (let ((first-win (selected-window)))
724 (if this-win-2nd (other-window 1))
725 (set-window-buffer (selected-window) this-win-buffer)
726 (set-window-buffer (next-window) next-win-buffer)
727 (select-window first-win)
728 (if this-win-2nd (other-window 1))))))
730 (define-key ctl-x-4-map "t" 'toggle-window-split)
733 #+begin_src emacs-lisp
734 (defun insert-date ()
736 (insert (format-time-string "%Y-%m-%d")))
740 #+begin_src emacs-lisp
741 (use-package ace-window
742 :bind ("M-o" . ace-window))
744 ** Kill current buffer
745 Makes "C-x k" binding faster.
746 #+begin_src emacs-lisp
747 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
751 Render OpenSCAD files, and add a preview window.
753 Personal fork just merges a PR.
754 #+begin_src emacs-lisp
755 (use-package scad-mode)
756 (use-package scad-preview
757 :straight (scad-preview :type git :host github :repo "Armaanb/scad-preview"))
759 ** Control backup files
760 Stop backup files from spewing everywhere.
761 #+begin_src emacs-lisp
762 (setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
764 ** Make yes/no easier
765 #+begin_src emacs-lisp
766 (defalias 'yes-or-no-p 'y-or-n-p)
768 ** Move customize file
769 No more clogging up init.el.
770 #+begin_src emacs-lisp
771 (setq custom-file "~/.emacs.d/custom.el")
775 #+begin_src emacs-lisp
777 :commands (helpful-callable helpful-variable helpful-command helpful-key)
779 (counsel-describe-function-function #'helpful-callable)
780 (counsel-describe-variable-function #'helpful-variable)
782 ([remap describe-function] . counsel-describe-function)
783 ([remap describe-command] . helpful-command)
784 ([remap describe-variable] . counsel-describe-variable)
785 ([remap describe-key] . helpful-key))
788 #+begin_src emacs-lisp
789 (use-package epa-file
790 :straight (:type built-in)
792 (epa-file-select-keys nil)
793 (epa-file-encrypt-to '("me@armaanb.net"))
794 (password-cache-expiry (* 60 15)))
796 (use-package pinentry
797 :config (pinentry-start))
800 #+begin_src emacs-lisp
802 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
803 :custom (0x0-default-service 'envs)
804 :config (evil-leader/set-key
806 "0f" '0x0-upload-file
807 "0s" '0x0-upload-string
808 "0c" '0x0-upload-kill-ring
809 "0p" '0x0-upload-popup))
814 #+begin_src conf :tangle ~/.spectrwm.conf
819 autorun = ws[1]:/home/armaa/Code/scripts/autostart
822 #+begin_src conf :tangle ~/.spectrwm.conf
823 color_focus = rgb:ff/ff/ff
824 color_focus_maximized = rgb:ee/cc/00
825 color_unfocus = rgb:55/55/55
828 #+begin_src conf :tangle ~/.spectrwm.conf
830 bar_font = xos4 Fira Code:pixelsize=14:antialias=true # any installed font
834 #+begin_src conf :tangle ~/.spectrwm.conf
835 program[lock] = i3lock -c 000000 -ef
836 program[term] = alacritty
837 program[screenshot_all] = flameshot gui
838 program[menu] = rofi -show run # `rofi-dmenu` handles the rest
839 program[switcher] = rofi -show window
840 program[notif] = /home/armaa/Code/scripts/setter status
843 bind[switcher] = MOD+Tab
846 #+begin_src conf :tangle ~/.spectrwm.conf
847 program[paup] = /home/armaa/Code/scripts/setter audio +5
848 program[padown] = /home/armaa/Code/scripts/setter audio -5
849 program[pamute] = /home/armaa/Code/scripts/setter audio
850 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
851 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
852 program[next] = playerctl next
853 program[prev] = playerctl previous
854 program[pause] = playerctl play-pause
856 bind[padown] = XF86AudioLowerVolume
857 bind[paup] = XF86AudioRaiseVolume
858 bind[pamute] = XF86AudioMute
859 bind[brigdown] = XF86MonBrightnessDown
860 bind[brigup] = XF86MonBrightnessUp
861 bind[pause] = XF86AudioPlay
862 bind[next] = XF86AudioNext
863 bind[prev] = XF86AudioPrev
866 #+begin_src conf :tangle ~/.spectrwm.conf
867 program[h] = xdotool keyup h key --clearmodifiers Left
868 program[j] = xdotool keyup j key --clearmodifiers Down
869 program[k] = xdotool keyup k key --clearmodifiers Up
870 program[l] = xdotool keyup l key --clearmodifiers Right
872 bind[h] = Mod1 + Tab + h
873 bind[j] = Mod1 + Tab + j
874 bind[k] = Mod1 + Tab + k
875 bind[l] = Mod1 + Tab + l
878 #+begin_src conf :tangle ~/.spectrwm.conf
879 program[aerc] = alacritty -e aerc
880 program[weechat] = alacritty --hold -e sh -c "while : ; do ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat; sleep 2; done"
881 program[emacs] = emacsclient -c
882 program[emacs-anywhere] = emacsclient --eval "(emacs-everywhere)"
883 program[firefox] = firefox
884 program[thunderbird] = thunderbird
885 program[slack] = slack
887 bind[aerc] = MOD+Control+1
888 bind[weechat] = MOD+Control+2
889 bind[emacs-anywhere] = MOD+Control+3
890 bind[firefox] = MOD+Control+4
891 bind[thunderbird] = MOD+Control+5
892 bind[slack] = MOD+Control+6
893 bind[emacs] = MOD+Control+Return
898 #+begin_src shell :tangle ~/.config/zsh/zshrc
899 autoload -Uz compinit
903 unsetopt glob_complete
906 #+begin_src shell :tangle ~/.config/zsh/zshrc
910 bindkey -M vicmd "^[[3~" delete-char
911 bindkey "^[[3~" delete-char
913 autoload edit-command-line
914 zle -N edit-command-line
915 bindkey -M vicmd ^e edit-command-line
916 bindkey ^e edit-command-line
919 #+begin_src shell :tangle ~/.config/zsh/zshrc
920 setopt extended_history
922 setopt inc_append_history
923 setopt hist_ignore_dups
924 setopt hist_reduce_blanks
928 HISTFILE=~/.local/share/zsh/history
931 I manage plugins using my own plugin manager, ZPE. https://git.sr.ht/~armaan/zpe
933 #+begin_src plain :tangle ~/.config/zpe/repositories
934 https://github.com/Aloxaf/fzf-tab
935 https://github.com/zdharma/fast-syntax-highlighting
936 https://github.com/rupa/z
939 #+begin_src shell :tangle ~/.config/zsh/zshrc
940 source ~/Code/zpe/zpe.sh
941 source ~/Code/admone/admone.zsh
942 source ~/.config/zsh/fzf-bindings.zsh
944 zpe-source fzf-tab/fzf-tab.zsh
945 zstyle ':completion:*:descriptions' format '[%d]'
946 zstyle ':fzf-tab:complete:cd:*' fzf-preview 'exa -1 --color=always $realpath'
947 zstyle ':completion:*' completer _complete
948 zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \
949 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
951 zpe-source fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
952 export _Z_DATA="/home/armaa/.local/share/z"
956 **** Alert after long command
957 #+begin_src shell :tangle ~/.config/zsh/zshrc
959 notify-send --urgency=low -i ${(%):-%(?.terminal.error)} \
960 ${history[$HISTCMD]%[;&|][[:space:]]##alert}
963 **** Time Zsh startup
964 #+begin_src shell :tangle ~/.config/zsh/zshrc
966 for i in $(seq 1 10); do
967 time "zsh" -i -c exit;
971 **** Update all packages
972 #+begin_src shell :tangle ~/.config/zsh/zshrc
973 color=$(tput setaf 5)
977 sudo echo "${color}== upgrading with yay ==${reset}"
980 echo "${color}== checking for pacnew files ==${reset}"
983 echo "${color}== upgrading flatpaks ==${reset}"
986 echo "${color}== upgrading zsh plugins ==${reset}"
989 echo "${color}== updating nvim plugins ==${reset}"
990 nvim +PlugUpdate +PlugUpgrade +qall
991 echo "Updated nvim plugins"
993 echo "${color}You are entirely up to date!${reset}"
996 **** Clean all packages
997 #+begin_src shell :tangle ~/.config/zsh/zshrc
999 sudo echo "${color}== cleaning pacman orphans ==${reset}"
1000 (pacman -Qtdq | sudo pacman -Rns - 2> /dev/null) || echo "No orphans"
1002 echo "${color}== cleaning flatpaks ==${reset}"
1003 flatpak remove --unused
1005 echo "${color}== cleaning zsh plugins ==${reset}"
1008 echo "${color}== cleaning nvim plugins ==${reset}"
1009 nvim +PlugClean +qall
1010 echo "Cleaned nvim plugins"
1012 echo "${color}All orphans cleaned!${reset}"
1016 #+begin_src shell :tangle ~/.config/zsh/zshrc
1019 exa -lh --icons --git --group-directories-first
1023 #+begin_src shell :tangle ~/.config/zsh/zshrc
1025 __conda_setup="$('/opt/anaconda/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
1026 if [ $? -eq 0 ]; then
1027 eval "$__conda_setup"
1029 if [ -f "/opt/anaconda/etc/profile.d/conda.sh" ]; then
1030 . "/opt/anaconda/etc/profile.d/conda.sh"
1032 export PATH="/opt/anaconda/bin:$PATH"
1038 **** Interact with 0x0
1039 #+begin_src shell :tangle ~/.config/zsh/zshrc
1040 zxz="https://envs.sh"
1041 0file() { curl -F"file=@$1" "$zxz" ; }
1042 0pb() { curl -F"file=@-;" "$zxz" ; }
1043 0url() { curl -F"url=$1" "$zxz" ; }
1044 0short() { curl -F"shorten=$1" "$zxz" ; }
1045 0clip() { xclip -out | curl -F"file=@-;" "$zxz" ; }
1048 #+begin_src shell :tangle ~/.config/zsh/zshrc
1057 #+begin_src shell :tangle ~/.config/zsh/zshrc
1058 alias bhoji-drop='ssh -p 23 root@armaanb.net'
1059 alias weechat='ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat'
1060 alias tcf='ssh root@204.48.23.68'
1061 alias ngmun='ssh root@157.245.89.25'
1062 alias prox='ssh root@192.168.1.224'
1063 alias dock='ssh root@192.168.1.225'
1064 alias jenkins='ssh root@192.168.1.226'
1065 alias envs='ssh acheam@envs.net'
1067 **** File management
1068 #+begin_src shell :tangle ~/.config/zsh/zshrc
1069 alias ls='exa -lh --icons --git --group-directories-first'
1070 alias la='exa -lha --icons --git --group-directories-first'
1071 alias df='df -h / /boot'
1073 alias free='free -h'
1078 alias grep='grep -in --exclude-dir=.git --color=auto'
1079 alias mkdir='mkdir -pv'
1080 alias unar='atool -x'
1081 alias wget='wget -e robots=off'
1082 alias lanex='~/.local/share/lxc/lxc'
1085 #+begin_src shell :tangle ~/.config/zsh/zshrc
1086 alias padm='yadm --yadm-repo ~/Code/dotfiles/repo.git'
1087 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1089 alias padu='padm add -u && padm commit && padm push && yadu'
1092 #+begin_src shell :tangle ~/.config/zsh/zshrc
1095 alias vw="nvim ~/Documents/vimwiki/index.md"
1097 **** System management
1098 #+begin_src shell :tangle ~/.config/zsh/zshrc
1099 alias jctl='journalctl -p 3 -xb'
1100 alias pkill='pkill -i'
1102 alias please='sudo $(fc -ln -1)'
1103 alias sudo='sudo ' # allows aliases to be run with sudo
1106 #+begin_src shell :tangle ~/.config/zsh/zshrc
1107 alias ping='ping -c 10'
1108 alias speed='speedtest-cli'
1109 alias ip='ip --color=auto'
1110 alias cip='curl https://armaanb.net/ip'
1111 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1112 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1115 #+begin_src shell :tangle ~/.config/zsh/zshrc
1116 alias dc='docker-compose'
1117 alias dcdu='docker-compose down && docker-compose up -d'
1120 #+begin_src shell :tangle ~/.config/zsh/zshrc
1121 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1122 iflag=fullblock status=progress'
1123 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1124 iflag=fullblock status=progress'
1125 alias ts='gen-shell -c task'
1126 alias ts='gen-shell -c task'
1127 alias tetris='autoload -Uz tetriscurses && tetriscurses'
1128 alias news='newsboat'
1129 alias tilderadio="\mpv https://radio.tildeverse.org/radio/8000/radio.ogg"
1130 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1131 --restrict-filenames -o '%(title)s.%(ext)s'"
1132 alias cal="cal -3 --color=auto"
1134 **** Virtual machines, chroots
1135 #+begin_src shell :tangle ~/.config/zsh/zshrc
1136 alias ckiss="sudo chrooter ~/Virtual/kiss"
1137 alias cdebian="sudo chrooter ~/Virtual/debian bash"
1138 alias cwindows='devour qemu-system-x86_64 \
1143 -device VGA,vgamem_mb=64 \
1145 -device hda-duplex \
1147 -net user,smb=/home/armaa/Public \
1148 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1151 #+begin_src shell :tangle ~/.config/zsh/zshrc
1153 alias zpy="zconda && ipython"
1154 alias math="ipython --profile=math"
1155 alias pypi="python setup.py sdist && twine upload dist/*"
1156 alias pip="python -m pip"
1157 alias black="black -l 79"
1160 #+begin_src shell :tangle ~/.config/zsh/zshrc
1161 alias words='gen-shell -c "words"'
1162 alias words-e='gen-shell -c "words ~E"'
1165 #+begin_src shell :tangle ~/.config/zsh/zshrc
1166 alias zathura='devour zathura'
1167 alias mpv='devour mpv'
1168 alias sql='devour sqlitebrowser'
1169 alias cad='devour openscad'
1170 alias feh='devour feh'
1172 **** Package management (Pacman)
1173 #+begin_src shell :tangle ~/.config/zsh/zshrc
1175 alias api='yay -Syu'
1176 alias apii='sudo pacman -S'
1177 alias app='yay -Rns'
1179 alias apo='yay -Qttd'
1180 alias azf='pacman -Q | fzf'
1181 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1182 alias ufetch='ufetch-arch'
1183 alias reflect='reflector --verbose --sort rate --save \
1184 ~/.local/etc/pacman.d/mirrorlist --download-timeout 60' # Takes ~45m to run
1187 #+begin_src shell :tangle ~/.config/zsh/zshrc
1188 export EDITOR="emacsclient -c"
1189 export VISUAL="$EDITOR"
1190 export TERM=xterm-256color # for compatability
1192 export GPG_TTY="$(tty)"
1193 export MANPAGER='nvim +Man!'
1196 export GTK_USE_PORTAL=1
1198 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
1199 export PATH="$PATH:/home/armaa/Code/scripts"
1200 export PATH="$PATH:/home/armaa/.cargo/bin"
1201 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
1202 export PATH="$PATH:/usr/sbin"
1203 export PATH="$PATH:/opt/FreeTube/freetube"
1205 export LC_ALL="en_US.UTF-8"
1206 export LC_CTYPE="en_US.UTF-8"
1207 export LANGUAGE="en_US.UTF-8"
1209 export KISS_PATH="/home/armaa/kiss/home/armaa/kiss-repo"
1210 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
1211 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
1212 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
1213 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
1214 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
1218 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1221 family: JetBrains Mono Nerd Font
1228 ligatures: true # Requires ligature patch
1235 background_opacity: 1
1238 Send <RET> + modifier through
1239 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1253 Modus vivendi. Source: https://github.com/ishan9299/Nixos/blob/d4bbb7536be95b59466bb9cca4d671be46e04e81/user/alacritty/alacritty.yml#L30-L118
1254 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1258 background: '#000000'
1259 foreground: '#ffffff'
1263 background: '#ffffff'
1265 # Normal colors (except green it is from intense colors)
1276 # Bright colors [all the faint colors in the modus theme]
1287 # dim [all the intense colors in modus theme]
1300 Symlink profile_default/ipython_config.py to profile_math/ipython_config.py
1301 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1302 c.TerminalInteractiveShell.editing_mode = 'vi'
1303 c.InteractiveShell.colors = 'linux'
1304 c.TerminalInteractiveShell.confirm_exit = False
1307 #+begin_src python :tangle ~/.ipython/profile_math/startup.py
1311 return x * (180 / pi)
1314 return x * (pi / 180)
1317 return (x * (pi / 180)) / unit
1329 Make MPV play a little bit smoother.
1330 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1331 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1335 For any GNU Readline programs
1336 #+begin_src plain :tangle ~/.inputrc
1341 #+begin_src conf :tangle ~/.gitconfig
1343 name = Armaan Bhojwani
1344 email = me@armaanb.net
1345 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1348 #+begin_src conf :tangle ~/.gitconfig
1350 defaultBranch = main
1353 #+begin_src conf :tangle ~/.gitconfig
1358 #+begin_src conf :tangle ~/.gitconfig
1360 smtpserver = smtp.mailbox.org
1361 smtpuser = me@armaanb.net
1362 smtpencryption = ssl
1363 smtpserverport = 465
1367 #+begin_src conf :tangle ~/.gitconfig
1372 #+begin_src conf :tangle ~/.gitconfig
1375 sclone = clone --depth 1
1381 subup = submodule update --remote
1382 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1383 mirror = git config --global alias.mirrormirror
1386 #+begin_src conf :tangle ~/.gitconfig
1391 Lightweight notification daemon.
1393 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1395 font = "JetBrains Mono Medium Nerd Font 11"
1397 format = "<b>%s</b>\n%b"
1399 indicate_hidden = yes
1402 show_age_threshold = 60
1405 geometry = "400x5-10+10"
1407 idle_threshold = 120
1409 sticky_history = yes
1411 separator_height = 4
1413 horizontal_padding = 8
1415 separator_color = "#ffffff"
1416 startup_notification = false
1419 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1426 close_all = mod4+shift+c
1427 history = mod4+ctrl+c
1430 background = "#222222"
1431 foreground = "#ffffff"
1432 highlight = "#ffffff"
1436 background = "#222222"
1437 foreground = "#ffffff"
1438 highlight = "#ffffff"
1442 background = "#222222"
1443 foreground = "#a60000"
1444 highlight = "#ffffff"
1448 Modus vivendi theme that extends DarkBlue.
1449 #+begin_src plain :tangle ~/.config/rofi/config.rasi
1450 @import "/usr/share/rofi/themes/DarkBlue.rasi"
1452 white: rgba ( 255, 255, 255, 100 % );
1454 selected-normal-background: @white;
1455 separatorcolor: @white;
1456 background: rgba ( 34, 34, 34, 100 % );
1465 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1467 map <A-b> toggle_statusbar
1468 set selection-clipboard clipboard
1471 set window-title-basename "true"
1472 set selection-clipboard "clipboard"
1475 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1476 set default-bg "#000000"
1477 set default-fg "#ffffff"
1478 set render-loading true
1479 set render-loading-bg "#000000"
1480 set render-loading-fg "#ffffff"
1482 set recolor-lightcolor "#000000" # bg
1483 set recolor-darkcolor "#ffffff" # fg