1 #+TITLE: System Configuration
2 #+DESCRIPTION: Personal system configuration in org-mode format.
3 #+AUTHOR: Armaan Bhojwani
4 #+EMAIL: me@armaanb.net
7 Welcome to my system configuration! This file contains my Emacs configuration, but also my config files for many of the other programs on my system!
9 I am currently using GCCEmacs 28 from the feature/native-comp branch, so some settings may not be available for older versions of Emacs. This is a purely personal configuration, so while I can garuntee that it works on my setup, I can't for anything else.
11 I chose to create a powerful, yet not overly heavy Emacs configuration. Things like LSP mode are important to my workflow and help me be productive, so despite its weight, it is kept. Things like a fancy modeline or icons on the other hand, do not increase my productivity, and create visual clutter, and thus have been excluded.
13 Another important choice has been to integrate Emacs into a large part of my computing environment (see [[*EmacsOS]]). I use Email, IRC, et cetera, all through Emacs which simplifies my workflow.
15 Lastly, I use Evil mode. I think modal keybindings are simple and more ergonomic than standard Emacs style, and Vim keybindings are what I'm comfortable with and are pervasive throughout computing.
17 *** TODO Turn keybinding and hook declarations into use-package declarations where possible
18 *** TODO Put configs with passwords in here with some kind of authentication
22 Released under the [[https://opensource.org/licenses/MIT][MIT license]] by Armaan Bhojwani, 2021. Note that many snippets are taken from online, and other sources, who are credited for their work at the snippet.
24 ** Bootstrap straight.el
25 straight.el is really nice for managing package, and it integrates nicely with use-package. It uses the bootstrapping system defined here for installation.
26 #+begin_src emacs-lisp
27 (defvar bootstrap-version)
29 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
30 (bootstrap-version 5))
31 (unless (file-exists-p bootstrap-file)
33 (url-retrieve-synchronously
34 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
35 'silent 'inhibit-cookies)
36 (goto-char (point-max))
37 (eval-print-last-sexp)))
38 (load bootstrap-file nil 'nomessage))
40 ** Replace use-package with straight
41 #+begin_src emacs-lisp
42 (straight-use-package 'use-package)
43 (setq straight-use-package-by-default t)
47 Very nice high contrast theme.
49 Its fine to set this here because I run Emacs in daemon mode, but if I were not, then putting it in early-init.el would be a better choice to eliminate the window being white before the theme is loaded.
50 #+begin_src emacs-lisp
51 (setq modus-themes-slanted-constructs t
52 modus-themes-bold-constructs t
53 modus-themes-org-blocks 'grayscale
54 modus-themes-mode-line '3d
55 modus-themes-scale-headings t
56 modus-themes-region 'no-extend
57 modus-themes-diffs 'desaturated)
58 (load-theme 'modus-vivendi t)
62 Great programming font with ligatures.
63 #+begin_src emacs-lisp
64 (add-to-list 'default-frame-alist '(font . "JetBrainsMonoNF-12"))
67 #+begin_src emacs-lisp
69 :straight (ligature :type git :host github :repo "mickeynp/ligature.el")
71 (ligature-set-ligatures
72 '(prog-mode text-mode)
73 '("-|" "-~" "---" "-<<" "-<" "--" "->" "->>" "-->" "/=" "/=="
74 "/>" "//" "/*" "*>" "*/" "<-" "<<-" "<=>" "<=" "<|" "<||"
75 "<|||" "<|>" "<:" "<>" "<-<" "<<<" "<==" "<<=" "<=<" "<==>"
76 "<-|" "<<" "<~>" "<=|" "<~~" "<~" "<$>" "<$" "<+>" "<+" "</>"
77 "</" "<*" "<*>" "<->" "<!--" ":>" ":<" ":::" "::" ":?" ":?>"
78 ":=" "::=" "=>>" "==>" "=/=" "=!=" "=>" "===" "=:=" "==" "!=="
79 "!!" "!=" ">]" ">:" ">>-" ">>=" ">=>" ">>>" ">-" ">=" "&&&"
80 "&&" "|||>" "||>" "|>" "|]" "|}" "|=>" "|->" "|=" "||-" "|-"
81 "||=" "||" ".." ".?" ".=" ".-" "..<" "..." "+++" "+>" "++"
82 "[||]" "[<" "[|" "{|" "??" "?." "?=" "?:" "##" "###" "####"
83 "#[" "#{" "#=" "#!" "#:" "#_(" "#_" "#?" "#(" ";;" "_|_" "__"
84 "~~" "~~>" "~>" "~-" "~@" "$>" "^=" "]#"))
85 (global-ligature-mode t))
88 #+begin_src emacs-lisp
90 :config (global-emojify-mode))
92 ;; http://ergoemacs.org/emacs/emacs_list_and_set_font.html
97 ((member "Twitter Color Emoji" (font-family-list)) "Twitter Color Emoji")
98 ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
99 ((member "Noto Emoji" (font-family-list)) "Noto Emoji")))
102 Display relative line numbers except in some modes
103 #+begin_src emacs-lisp
104 (global-display-line-numbers-mode)
105 (setq display-line-numbers-type 'relative)
106 (dolist (no-line-num '(term-mode-hook
111 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
113 ** Highlight matching parenthesis
114 #+begin_src emacs-lisp
116 :config (show-paren-mode)
117 :custom (show-paren-style 'parenthesis))
120 *** Show current function
121 #+begin_src emacs-lisp
122 (which-function-mode)
124 *** Make position in file more descriptive
125 Show current column and file size.
126 #+begin_src emacs-lisp
128 (size-indication-mode)
131 #+begin_src emacs-lisp
133 :config (minions-mode))
136 #+begin_src emacs-lisp
138 :straight (wc-mode :type git :host github :repo "bnbeckwith/wc-mode")
139 :hook (text-mode-hook . wc-mode))
142 Show a ruler at a certain number of chars depending on mode.
143 #+begin_src emacs-lisp
144 (global-display-fill-column-indicator-mode)
147 Whenever starting a key chord, show possible future steps.
148 #+begin_src emacs-lisp
149 (use-package which-key
150 :config (which-key-mode)
151 :custom (which-key-idle-delay 0.3))
153 ** Visual highlights of changes
154 Highlight when changes are made.
155 #+begin_src emacs-lisp
156 (use-package evil-goggles
157 :config (evil-goggles-mode)
158 (evil-goggles-use-diff-faces))
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)
273 (org-ellipsis " â–¾")
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 plain :tangle ~/.config/rofi/config.rasi"))
301 (add-to-list 'org-structure-template-alist '("za" . "src plain :tangle ~/.config/zathura/zathurarc")))
304 #+begin_src emacs-lisp
305 (use-package org-present
306 :straight (org-present :type git :host github :repo "rlister/org-present"))
310 Simple, but not too simple autocompletion.
311 #+begin_src emacs-lisp
313 :bind (("C-s" . swiper)
314 :map ivy-minibuffer-map
315 ("TAB" . ivy-alt-done)
316 :map ivy-switch-buffer-map
317 ("M-d" . ivy-switch-buffer-kill))
321 #+begin_src emacs-lisp
322 (use-package ivy-rich
324 :config (ivy-rich-mode))
328 #+begin_src emacs-lisp
330 :bind (("C-M-j" . 'counsel-switch-buffer)
331 :map minibuffer-local-map
332 ("C-r" . 'counsel-minibuffer-history))
333 :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
334 :config (counsel-mode))
336 ** Remember frequent commands
337 #+begin_src emacs-lisp
338 (use-package ivy-prescient
341 (ivy-prescient-enable-filtering nil)
343 (prescient-persist-mode)
344 (ivy-prescient-mode))
347 Better search utility.
348 #+begin_src emacs-lisp
353 Use elfeed for RSS. I have another file with all the feeds in it.
354 #+begin_src emacs-lisp
356 :bind (("C-c e" . elfeed))
358 (load "~/.emacs.d/feeds.el")
359 (add-hook 'elfeed-new-entry-hook
360 (elfeed-make-tagger :feed-url "youtube\\.com"
362 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
364 (use-package elfeed-goodies
366 :config (elfeed-goodies/setup))
369 Use mu4e for reading emails.
371 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.
373 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.
374 #+begin_src emacs-lisp
375 (use-package smtpmail
376 :straight (:type built-in))
378 :load-path "/usr/share/emacs/site-lisp/mu4e"
379 :bind (("C-c m" . mu4e))
381 (setq user-full-name "Armaan Bhojwani"
382 smtpmail-local-domain "armaanb.net"
383 smtpmail-stream-type 'ssl
384 smtpmail-smtp-service '465
385 mu4e-change-filenames-when-moving t
386 mu4e-get-mail-command "offlineimap -q"
387 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
388 message-citation-line-function 'message-insert-formatted-citation-line
389 mu4e-completing-read-function 'ivy-completing-read
390 mu4e-confirm-quit nil
391 mail-user-agent 'mu4e-user-agent
393 `( ,(make-mu4e-context
395 :enter-func (lambda () (mu4e-message "Entering school context"))
396 :leave-func (lambda () (mu4e-message "Leaving school context"))
397 :match-func (lambda (msg)
399 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
400 :vars '((user-mail-address . "abhojwani22@nobles.edu")
401 (mu4e-sent-folder . "/school/Sent")
402 (mu4e-drafts-folder . "/school/Drafts")
403 (mu4e-trash-folder . "/school/Trash")
404 (mu4e-refile-folder . "/school/Archive")
405 (user-mail-address . "abhojwani22@nobles.edu")
406 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
407 (smtpmail-smtp-server . "smtp.gmail.com")))
410 :enter-func (lambda () (mu4e-message "Entering personal context"))
411 :leave-func (lambda () (mu4e-message "Leaving personal context"))
412 :match-func (lambda (msg)
414 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
415 :vars '((mu4e-sent-folder . "/personal/Sent")
416 (mu4e-drafts-folder . "/personal/Drafts")
417 (mu4e-trash-folder . "/personal/Trash")
418 (mu4e-refile-folder . "/personal/Archive")
419 (user-mail-address . "me@armaanb.net")
420 (smtpmail-smtp-user . "me@armaanb.net")
421 (smtpmail-smtp-server "smtp.mailbox.org")
422 (mu4e-drafts-folder . "/school/Drafts")
423 (mu4e-trash-folder . "/school/Trash")))))
424 (add-to-list 'mu4e-bookmarks
425 '(:name "Unified inbox"
426 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
428 :hook ((mu4e-compose-mode . flyspell-mode)
429 (mu4e-view-mode-hook . turn-on-visual-line-mode)))
432 #+begin_src emacs-lisp
434 (use-package calfw-org)
435 (use-package calfw-ical)
437 (defun acheam-calendar ()
440 (shell-command "vdirsyncer sync")
441 (let ((default-directory "~/.local/share/vdirsyncer/"))
442 (cfw:open-calendar-buffer
445 (cfw:ical-create-source "School" (expand-file-name "school/abhojwani22@nobles.edu.ics") "Green")
446 (cfw:ical-create-source "Personal" (expand-file-name "mailbox/Y2FsOi8vMC8zMQ.ics") "Blue")
447 (cfw:ical-create-source "Birthdays" (expand-file-name "mailbox/Y2FsOi8vMS8w.ics") "Gray")
451 Another file has more specific network configuration.
452 #+begin_src emacs-lisp
454 :config (load-file "~/.emacs.d/irc.el"))
456 (use-package circe-chanop
457 :straight (:type built-in)
460 (use-package circe-color-nicks
461 :straight (:type built-in)
465 Set EWW as default browser except for videos.
466 #+begin_src emacs-lisp
467 (defun browse-url-mpv (url &optional new-window)
469 (start-process "mpv" "*mpv*" "mpv" url))
471 (setq browse-url-handlers
473 (("youtu\\.?be" . browse-url-mpv)
474 ("." . eww-browse-url)
478 Some EWW enhancements.
479 *** Give buffer a useful name
480 #+begin_src emacs-lisp
481 ;; From https://protesilaos.com/dotemacs/
482 (defun prot-eww--rename-buffer ()
483 "Rename EWW buffer using page title or URL.
484 To be used by `eww-after-render-hook'."
485 (let ((name (if (eq "" (plist-get eww-data :title))
486 (plist-get eww-data :url)
487 (plist-get eww-data :title))))
488 (rename-buffer (format "*%s # eww*" name) t)))
490 (add-hook 'eww-after-render-hook #'prot-eww--rename-buffer)
492 *** Better entrypoint
493 #+begin_src emacs-lisp
494 ;; From https://protesilaos.com/dotemacs/
495 (defun prot-eww-browse-dwim (url &optional arg)
496 "Visit a URL, maybe from `eww-prompt-history', with completion.
498 With optional prefix ARG (\\[universal-argument]) open URL in a
501 If URL does not look like a valid link, run a web query using
504 When called from an eww buffer, provide the current link as
508 (completing-read "Query:" eww-prompt-history
509 nil nil (plist-get eww-data :url) 'eww-prompt-history)
511 (eww url (if arg 4 nil)))
513 (global-set-key (kbd "C-c w") 'prot-eww-browse-dwim)
516 Use Emacs globally. Use the Emacs daemon and bind a key in your wm to
517 =emacsclient --eval "(emacs-everywhere)"=.
518 #+begin_src emacs-lisp
519 (use-package emacs-everywhere)
522 #+begin_src emacs-lisp
523 (setq eshell-prompt-function
526 "\n" (eshell/pwd) " ➤ ")
527 'face '(:foreground "cyan")))
528 eshell-highlight-prompt nil)
533 #+begin_src emacs-lisp
534 (use-package lsp-mode
535 :commands (lsp lsp-deferred)
536 :custom (lsp-keymap-prefix "C-c l")
537 :hook ((lsp-mode . lsp-enable-which-key-integration)))
539 (use-package lsp-ivy)
542 :commands lsp-ui-mode
543 :custom (lsp-ui-doc-position 'bottom))
544 (use-package lsp-ui-flycheck
546 :straight (:type built-in))
549 Company-box adds icons.
550 #+begin_src emacs-lisp
553 :hook (lsp-mode . company-mode)
554 :bind (:map company-active-map
555 ("<tab>" . company-complete-selection))
557 ("<tab>" . company-indent-or-complete-common))
559 (company-minimum-prefix-length 1)
560 (setq company-dabbrev-downcase 0)
561 (company-idle-delay 0.0))
563 (use-package company-box
564 :hook (company-mode . company-box-mode))
568 #+begin_src emacs-lisp
569 (use-package lsp-pyright
570 :hook (python-mode . (lambda ()
571 (use-package lsp-pyright
572 :straight (:type built-in))
576 #+begin_src emacs-lisp
578 :hook (python-mode . blacken-mode)
580 (setq blacken-line-length 79))
583 (use-package ws-butler
585 (ws-butler-global-mode))
588 #+begin_src emacs-lisp
589 (use-package flycheck
591 (global-flycheck-mode))
593 ** Project management
594 #+begin_src emacs-lisp
595 (use-package projectile
596 :config (projectile-mode)
597 :custom ((projectile-completion-system 'ivy))
599 ("C-c p" . projectile-command-map)
601 (when (file-directory-p "~/Code")
602 (setq projectile-project-search-path '("~/Code")))
603 (setq projectile-switch-project-action #'projectile-dired))
605 (use-package counsel-projectile
607 :config (counsel-projectile-mode))
610 #+begin_src emacs-lisp
612 :straight (:type built-in)
613 :commands (dired dired-jump)
614 :custom ((dired-listing-switches "-agho --group-directories-first"))
616 (evil-collection-define-key 'normal 'dired-mode-map
617 "h" 'dired-single-up-directory
618 "l" 'dired-single-buffer))
620 (use-package dired-single
621 :commands (dired dired-jump))
623 (use-package dired-open
624 :commands (dired dired-jump)
626 (dired-open-extensions '(("png" . "feh")
629 (use-package dired-hide-dotfiles
630 :hook (dired-mode . dired-hide-dotfiles-mode)
632 (evil-collection-define-key 'normal 'dired-mode-map
633 "H" 'dired-hide-dotfiles-mode))
637 # TODO: Write a command that commits hunk, skipping staging step.
638 #+begin_src emacs-lisp
641 *** Colored diff in line number area
642 #+begin_src emacs-lisp
644 :straight (diff-hl :type git :host github :repo "dgutov/diff-hl")
645 :hook ((magit-pre-refresh-hook . diff-hl-magit-pre-refresh)
646 (magit-post-refresh-hook . diff-hl-magit-post-refresh))
647 :config (global-diff-hl-mode))
649 * General text editing
651 Indent after every change.
652 #+begin_src emacs-lisp
653 (use-package aggressive-indent
654 :config (global-aggressive-indent-mode))
657 Spell check in text mode, and in prog-mode comments.
658 #+begin_src emacs-lisp
659 (dolist (hook '(text-mode-hook))
660 (add-hook hook (lambda () (flyspell-mode))))
661 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
662 (add-hook hook (lambda () (flyspell-mode -1))))
663 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
665 ** Expand tabs to spaces
666 #+begin_src emacs-lisp
667 (setq-default tab-width 2)
669 ** Copy kill ring to clipboard
670 #+begin_src emacs-lisp
671 (setq x-select-enable-clipboard t)
672 (defun copy-kill-ring-to-xorg ()
673 "Copy the current kill ring to the xorg clipboard."
675 (x-select-text (current-kill 0)))
678 #+begin_src emacs-lisp
679 (use-package browse-kill-ring)
682 Opens file where you left it.
683 #+begin_src emacs-lisp
687 Distraction free writing a la junegunn/goyo.
688 #+begin_src emacs-lisp
689 (use-package olivetti
691 (evil-leader/set-key "o" 'olivetti-mode))
695 #+begin_src emacs-lisp
696 (setq abbrev-file-name "~/.emacs.d/abbrevs")
697 (setq save-abbrevs 'silent)
698 (setq-default abbrev-mode t)
701 #+begin_src emacs-lisp
702 (setq tramp-default-method "ssh")
704 ** Don't ask about following symlinks in vc
705 #+begin_src emacs-lisp
706 (setq vc-follow-symlinks t)
709 ** Easily convert splits
710 Converts splits from horizontal to vertical and vice versa. Lifted from EmacsWiki.
711 #+begin_src emacs-lisp
712 (defun toggle-window-split ()
714 (if (= (count-windows) 2)
715 (let* ((this-win-buffer (window-buffer))
716 (next-win-buffer (window-buffer (next-window)))
717 (this-win-edges (window-edges (selected-window)))
718 (next-win-edges (window-edges (next-window)))
719 (this-win-2nd (not (and (<= (car this-win-edges)
720 (car next-win-edges))
721 (<= (cadr this-win-edges)
722 (cadr next-win-edges)))))
724 (if (= (car this-win-edges)
725 (car (window-edges (next-window))))
726 'split-window-horizontally
727 'split-window-vertically)))
728 (delete-other-windows)
729 (let ((first-win (selected-window)))
731 (if this-win-2nd (other-window 1))
732 (set-window-buffer (selected-window) this-win-buffer)
733 (set-window-buffer (next-window) next-win-buffer)
734 (select-window first-win)
735 (if this-win-2nd (other-window 1))))))
737 (define-key ctl-x-4-map "t" 'toggle-window-split)
740 #+begin_src emacs-lisp
741 (defun insert-date ()
743 (insert (format-time-string "%Y-%m-%d")))
747 #+begin_src emacs-lisp
748 (use-package ace-window
749 :bind ("M-o" . ace-window))
751 ** Kill current buffer
752 Makes "C-x k" binding faster.
753 #+begin_src emacs-lisp
754 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
758 Render OpenSCAD files, and add a preview window.
760 Personal fork just merges a PR.
761 #+begin_src emacs-lisp
762 (use-package scad-mode)
763 (use-package scad-preview
764 :straight (scad-preview :type git :host github :repo "Armaanb/scad-preview"))
766 ** Control backup files
767 Stop backup files from spewing everywhere.
768 #+begin_src emacs-lisp
769 (setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
771 ** Make yes/no easier
772 #+begin_src emacs-lisp
773 (defalias 'yes-or-no-p 'y-or-n-p)
775 ** Move customize file
776 No more clogging up init.el.
777 #+begin_src emacs-lisp
778 (setq custom-file "~/.emacs.d/custom.el")
782 #+begin_src emacs-lisp
784 :commands (helpful-callable helpful-variable helpful-command helpful-key)
786 (counsel-describe-function-function #'helpful-callable)
787 (counsel-describe-variable-function #'helpful-variable)
789 ([remap describe-function] . counsel-describe-function)
790 ([remap describe-command] . helpful-command)
791 ([remap describe-variable] . counsel-describe-variable)
792 ([remap describe-key] . helpful-key))
795 #+begin_src emacs-lisp
796 (use-package epa-file
797 :straight (:type built-in)
799 (epa-file-select-keys nil)
800 (epa-file-encrypt-to '("me@armaanb.net"))
801 (password-cache-expiry (* 60 15)))
803 (use-package pinentry
804 :config (pinentry-start))
807 #+begin_src emacs-lisp
809 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
810 :custom (0x0-default-service 'envs)
811 :config (evil-leader/set-key
813 "0f" '0x0-upload-file
814 "0s" '0x0-upload-string
815 "0c" '0x0-upload-kill-ring
816 "0p" '0x0-upload-popup))
821 #+begin_src conf :tangle ~/.spectrwm.conf
826 autorun = ws[1]:/home/armaa/Code/scripts/autostart
829 #+begin_src conf :tangle ~/.spectrwm.conf
830 color_focus = rgb:ff/ff/ff
831 color_focus_maximized = rgb:ee/cc/00
832 color_unfocus = rgb:55/55/55
835 #+begin_src conf :tangle ~/.spectrwm.conf
837 bar_font = xos4 Fira Code:pixelsize=14:antialias=true # any installed font
841 #+begin_src conf :tangle ~/.spectrwm.conf
842 program[lock] = i3lock -c 000000 -ef
843 program[term] = alacritty
844 program[screenshot_all] = flameshot gui
845 program[menu] = rofi -show run # `rofi-dmenu` handles the rest
846 program[switcher] = rofi -show window
847 program[notif] = /home/armaa/Code/scripts/setter status
850 bind[switcher] = MOD+Tab
853 #+begin_src conf :tangle ~/.spectrwm.conf
854 program[paup] = /home/armaa/Code/scripts/setter audio +5
855 program[padown] = /home/armaa/Code/scripts/setter audio -5
856 program[pamute] = /home/armaa/Code/scripts/setter audio
857 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
858 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
859 program[next] = playerctl next
860 program[prev] = playerctl previous
861 program[pause] = playerctl play-pause
863 bind[padown] = XF86AudioLowerVolume
864 bind[paup] = XF86AudioRaiseVolume
865 bind[pamute] = XF86AudioMute
866 bind[brigdown] = XF86MonBrightnessDown
867 bind[brigup] = XF86MonBrightnessUp
868 bind[pause] = XF86AudioPlay
869 bind[next] = XF86AudioNext
870 bind[prev] = XF86AudioPrev
873 #+begin_src conf :tangle ~/.spectrwm.conf
874 program[h] = xdotool keyup h key --clearmodifiers Left
875 program[j] = xdotool keyup j key --clearmodifiers Down
876 program[k] = xdotool keyup k key --clearmodifiers Up
877 program[l] = xdotool keyup l key --clearmodifiers Right
879 bind[h] = MOD + Control + h
880 bind[j] = MOD + Control + j
881 bind[k] = MOD + Control + k
882 bind[l] = MOD + Control + l
885 #+begin_src conf :tangle ~/.spectrwm.conf
886 program[aerc] = alacritty -e aerc
887 program[weechat] = alacritty --hold -e sh -c "while : ; do ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat; sleep 2; done"
888 program[catgirl] = alacritty --hold -e sh -c "while : ; do ssh -p 23 -t root@armaanb.net tmux attach-session -t catgirl; sleep 2; done"
889 program[emacs] = emacsclient -c
890 program[emacs-anywhere] = emacsclient --eval "(emacs-everywhere)"
891 program[firefox] = firefox
892 program[thunderbird] = thunderbird
893 program[slack] = slack
895 bind[aerc] = MOD+Control+1
896 # bind[weechat] = MOD+Control+2
897 bind[catgirl] = MOD+Control+2
898 bind[emacs-anywhere] = MOD+Control+3
899 bind[firefox] = MOD+Control+4
900 bind[thunderbird] = MOD+Control+5
901 bind[slack] = MOD+Control+6
902 bind[emacs] = MOD+Control+Return
907 #+begin_src shell :tangle ~/.config/zsh/zshrc
908 autoload -Uz compinit
912 unsetopt glob_complete
915 #+begin_src shell :tangle ~/.config/zsh/zshrc
919 bindkey -M vicmd "^[[3~" delete-char
920 bindkey "^[[3~" delete-char
922 autoload edit-command-line
923 zle -N edit-command-line
924 bindkey -M vicmd ^e edit-command-line
925 bindkey ^e edit-command-line
928 #+begin_src shell :tangle ~/.config/zsh/zshrc
929 setopt extended_history
931 setopt inc_append_history
932 setopt hist_ignore_dups
933 setopt hist_reduce_blanks
937 HISTFILE=~/.local/share/zsh/history
940 I manage plugins using my own plugin manager, ZPE. https://git.sr.ht/~armaan/zpe
942 #+begin_src plain :tangle ~/.config/zpe/repositories
943 https://github.com/Aloxaf/fzf-tab
944 https://github.com/zdharma/fast-syntax-highlighting
945 https://github.com/rupa/z
948 #+begin_src shell :tangle ~/.config/zsh/zshrc
949 source ~/Code/zpe/zpe.sh
950 source ~/Code/admone/admone.zsh
951 source ~/.config/zsh/fzf-bindings.zsh
953 zpe-source fzf-tab/fzf-tab.zsh
954 zstyle ':completion:*:descriptions' format '[%d]'
955 zstyle ':fzf-tab:complete:cd:*' fzf-preview 'exa -1 --color=always $realpath'
956 zstyle ':completion:*' completer _complete
957 zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \
958 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
960 zpe-source fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
961 export _Z_DATA="/home/armaa/.local/share/z"
965 **** Alert after long command
966 #+begin_src shell :tangle ~/.config/zsh/zshrc
968 notify-send --urgency=low -i ${(%):-%(?.terminal.error)} \
969 ${history[$HISTCMD]%[;&|][[:space:]]##alert}
972 **** Time Zsh startup
973 #+begin_src shell :tangle ~/.config/zsh/zshrc
975 for i in $(seq 1 10); do
976 time "zsh" -i -c exit;
980 **** Update all packages
981 #+begin_src shell :tangle ~/.config/zsh/zshrc
982 color=$(tput setaf 5)
986 sudo echo "${color}== upgrading with yay ==${reset}"
989 echo "${color}== checking for pacnew files ==${reset}"
992 echo "${color}== upgrading flatpaks ==${reset}"
995 echo "${color}== upgrading zsh plugins ==${reset}"
998 echo "${color}== updating nvim plugins ==${reset}"
999 nvim +PlugUpdate +PlugUpgrade +qall
1000 echo "Updated nvim plugins"
1002 echo "${color}You are entirely up to date!${reset}"
1005 **** Clean all packages
1006 #+begin_src shell :tangle ~/.config/zsh/zshrc
1008 sudo echo "${color}== cleaning pacman orphans ==${reset}"
1009 (pacman -Qtdq | sudo pacman -Rns - 2> /dev/null) || echo "No orphans"
1011 echo "${color}== cleaning flatpaks ==${reset}"
1012 flatpak remove --unused
1014 echo "${color}== cleaning zsh plugins ==${reset}"
1017 echo "${color}== cleaning nvim plugins ==${reset}"
1018 nvim +PlugClean +qall
1019 echo "Cleaned nvim plugins"
1021 echo "${color}All orphans cleaned!${reset}"
1025 #+begin_src shell :tangle ~/.config/zsh/zshrc
1028 exa -lh --icons --git --group-directories-first
1032 #+begin_src shell :tangle ~/.config/zsh/zshrc
1034 __conda_setup="$('/opt/anaconda/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
1035 if [ $? -eq 0 ]; then
1036 eval "$__conda_setup"
1038 if [ -f "/opt/anaconda/etc/profile.d/conda.sh" ]; then
1039 . "/opt/anaconda/etc/profile.d/conda.sh"
1041 export PATH="/opt/anaconda/bin:$PATH"
1047 **** Interact with 0x0
1048 #+begin_src shell :tangle ~/.config/zsh/zshrc
1049 zxz="https://envs.sh"
1050 0file() { curl -F"file=@$1" "$zxz" ; }
1051 0pb() { curl -F"file=@-;" "$zxz" ; }
1052 0url() { curl -F"url=$1" "$zxz" ; }
1053 0short() { curl -F"shorten=$1" "$zxz" ; }
1054 0clip() { xclip -out | curl -F"file=@-;" "$zxz" ; }
1057 #+begin_src shell :tangle ~/.config/zsh/zshrc
1066 #+begin_src shell :tangle ~/.config/zsh/zshrc
1067 alias bhoji-drop='ssh -p 23 root@armaanb.net'
1068 alias weechat='ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat'
1069 alias catgirl='ssh -p 23 -t root@armaanb.net tmux attach-session -t catgirl'
1070 alias tcf='ssh root@204.48.23.68'
1071 alias ngmun='ssh root@157.245.89.25'
1072 alias prox='ssh root@192.168.1.224'
1073 alias dock='ssh root@192.168.1.225'
1074 alias jenkins='ssh root@192.168.1.226'
1075 alias envs='ssh acheam@envs.net'
1077 **** File management
1078 #+begin_src shell :tangle ~/.config/zsh/zshrc
1079 alias ls='exa -lh --icons --git --group-directories-first'
1080 alias la='exa -lha --icons --git --group-directories-first'
1081 alias df='df -h / /boot'
1083 alias free='free -h'
1088 alias grep='grep -in --exclude-dir=.git --color=auto'
1089 alias mkdir='mkdir -pv'
1090 alias unar='atool -x'
1091 alias wget='wget -e robots=off'
1092 alias lanex='~/.local/share/lxc/lxc'
1095 #+begin_src shell :tangle ~/.config/zsh/zshrc
1096 alias padm='yadm --yadm-repo ~/Code/dotfiles/repo.git'
1097 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1099 alias padu='padm add -u && padm commit && padm push && yadu'
1102 #+begin_src shell :tangle ~/.config/zsh/zshrc
1105 alias vw="nvim ~/Documents/vimwiki/index.md"
1107 **** System management
1108 #+begin_src shell :tangle ~/.config/zsh/zshrc
1109 alias jctl='journalctl -p 3 -xb'
1110 alias pkill='pkill -i'
1112 alias redoas='doas $(fc -ln -1)'
1113 alias sudo='doas ' # allows aliases to be run with doas
1116 #+begin_src shell :tangle ~/.config/zsh/zshrc
1117 alias ping='ping -c 10'
1118 alias speed='speedtest-cli'
1119 alias ip='ip --color=auto'
1120 alias cip='curl https://armaanb.net/ip'
1121 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1122 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1125 #+begin_src shell :tangle ~/.config/zsh/zshrc
1126 alias dc='docker-compose'
1127 alias dcdu='docker-compose down && docker-compose up -d'
1130 #+begin_src shell :tangle ~/.config/zsh/zshrc
1131 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1132 iflag=fullblock status=progress'
1133 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1134 iflag=fullblock status=progress'
1135 alias ts='gen-shell -c task'
1136 alias ts='gen-shell -c task'
1137 alias tetris='autoload -Uz tetriscurses && tetriscurses'
1138 alias news='newsboat'
1139 alias tilderadio="\mpv https://radio.tildeverse.org/radio/8000/radio.ogg"
1140 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1141 --restrict-filenames -o '%(title)s.%(ext)s'"
1142 alias cal="cal -3 --color=auto"
1144 **** Virtual machines, chroots
1145 #+begin_src shell :tangle ~/.config/zsh/zshrc
1146 alias ckiss="sudo chrooter ~/Virtual/kiss"
1147 alias cdebian="sudo chrooter ~/Virtual/debian bash"
1148 alias cwindows='devour qemu-system-x86_64 \
1153 -device VGA,vgamem_mb=64 \
1155 -device hda-duplex \
1157 -net user,smb=/home/armaa/Public \
1158 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1161 #+begin_src shell :tangle ~/.config/zsh/zshrc
1163 alias zpy="zconda && ipython"
1164 alias math="ipython --profile=math"
1165 alias pypi="python setup.py sdist && twine upload dist/*"
1166 alias pip="python -m pip"
1167 alias black="black -l 79"
1170 #+begin_src shell :tangle ~/.config/zsh/zshrc
1171 alias words='gen-shell -c "words"'
1172 alias words-e='gen-shell -c "words ~E"'
1175 #+begin_src shell :tangle ~/.config/zsh/zshrc
1176 alias zathura='devour zathura'
1177 alias mpv='devour mpv'
1178 alias sql='devour sqlitebrowser'
1179 alias cad='devour openscad'
1180 alias feh='devour feh'
1182 **** Package management (Pacman)
1183 #+begin_src shell :tangle ~/.config/zsh/zshrc
1185 alias api='yay -Syu'
1186 alias apii='sudo pacman -S'
1187 alias app='yay -Rns'
1189 alias apo='yay -Qttd'
1190 alias azf='pacman -Q | fzf'
1191 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1192 alias ufetch='ufetch-arch'
1193 alias reflect='reflector --verbose --sort rate --save \
1194 ~/.local/etc/pacman.d/mirrorlist --download-timeout 60' # Takes ~45m to run
1197 #+begin_src shell :tangle ~/.config/zsh/zshrc
1198 export EDITOR="emacsclient -c"
1199 export VISUAL="$EDITOR"
1200 export TERM=xterm-256color # for compatability
1202 export GPG_TTY="$(tty)"
1203 export MANPAGER='nvim +Man!'
1206 export GTK_USE_PORTAL=1
1208 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
1209 export PATH="/home/armaa/Code/scripts:$PATH" # prioritize my scripts
1210 export PATH="/home/armaa/Code/scripts/bin:$PATH" # prioritize my bins
1211 export PATH="$PATH:/home/armaa/.cargo/bin"
1212 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
1213 export PATH="$PATH:/usr/sbin"
1214 export PATH="$PATH:/opt/FreeTube/freetube"
1216 export LC_ALL="en_US.UTF-8"
1217 export LC_CTYPE="en_US.UTF-8"
1218 export LANGUAGE="en_US.UTF-8"
1220 export KISS_PATH="/home/armaa/kiss/home/armaa/kiss-repo"
1221 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
1222 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
1223 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
1224 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
1225 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
1229 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1232 family: JetBrains Mono Nerd Font
1239 ligatures: true # Requires ligature patch
1246 background_opacity: 1
1249 Modus vivendi. Source: https://github.com/ishan9299/Nixos/blob/d4bbb7536be95b59466bb9cca4d671be46e04e81/user/alacritty/alacritty.yml#L30-L118
1250 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1254 background: '#000000'
1255 foreground: '#ffffff'
1259 background: '#ffffff'
1261 # Normal colors (except green it is from intense colors)
1272 # Bright colors [all the faint colors in the modus theme]
1283 # dim [all the intense colors in modus theme]
1296 Symlink profile_default/ipython_config.py to profile_math/ipython_config.py
1297 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1298 c.TerminalInteractiveShell.editing_mode = 'vi'
1299 c.InteractiveShell.colors = 'linux'
1300 c.TerminalInteractiveShell.confirm_exit = False
1303 #+begin_src python :tangle ~/.ipython/profile_math/startup.py
1307 return x * (180 / pi)
1310 return x * (pi / 180)
1313 return (x * (pi / 180)) / unit
1325 Make MPV play a little bit smoother.
1326 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1327 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1331 For any GNU Readline programs
1332 #+begin_src plain :tangle ~/.inputrc
1337 #+begin_src conf :tangle ~/.gitconfig
1339 name = Armaan Bhojwani
1340 email = me@armaanb.net
1341 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1344 #+begin_src conf :tangle ~/.gitconfig
1346 defaultBranch = main
1349 #+begin_src conf :tangle ~/.gitconfig
1354 #+begin_src conf :tangle ~/.gitconfig
1356 smtpserver = smtp.mailbox.org
1357 smtpuser = me@armaanb.net
1358 smtpencryption = ssl
1359 smtpserverport = 465
1363 #+begin_src conf :tangle ~/.gitconfig
1368 #+begin_src conf :tangle ~/.gitconfig
1371 sclone = clone --depth 1
1377 subup = submodule update --remote
1378 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1379 mirror = git config --global alias.mirrormirror
1382 #+begin_src conf :tangle ~/.gitconfig
1388 Lightweight notification daemon.
1390 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1392 font = "JetBrains Mono Medium Nerd Font 11"
1394 format = "<b>%s</b>\n%b"
1396 indicate_hidden = yes
1399 show_age_threshold = 60
1402 geometry = "400x5-10+10"
1404 idle_threshold = 120
1406 sticky_history = yes
1408 separator_height = 4
1410 horizontal_padding = 8
1412 separator_color = "#ffffff"
1413 startup_notification = false
1416 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1423 close_all = mod4+shift+c
1424 history = mod4+ctrl+c
1427 background = "#222222"
1428 foreground = "#ffffff"
1429 highlight = "#ffffff"
1433 background = "#222222"
1434 foreground = "#ffffff"
1435 highlight = "#ffffff"
1439 background = "#222222"
1440 foreground = "#a60000"
1441 highlight = "#ffffff"
1445 Modus vivendi theme that extends DarkBlue.
1446 #+begin_src plain :tangle ~/.config/rofi/config.rasi
1447 @import "/usr/share/rofi/themes/DarkBlue.rasi"
1449 white: rgba ( 255, 255, 255, 100 % );
1451 selected-normal-background: @white;
1452 separatorcolor: @white;
1453 background: rgba ( 34, 34, 34, 100 % );
1462 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1464 map <A-b> toggle_statusbar
1465 set selection-clipboard clipboard
1468 set window-title-basename "true"
1469 set selection-clipboard "clipboard"
1472 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1473 set default-bg "#000000"
1474 set default-fg "#ffffff"
1475 set render-loading true
1476 set render-loading-bg "#000000"
1477 set render-loading-fg "#ffffff"
1479 set recolor-lightcolor "#000000" # bg
1480 set recolor-darkcolor "#ffffff" # fg