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)
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 ncq='ssh root@143.198.123.17'
1074 alias dock='ssh root@192.168.1.225'
1075 alias jenkins='ssh root@192.168.1.226'
1076 alias envs='ssh acheam@envs.net'
1078 **** File management
1079 #+begin_src shell :tangle ~/.config/zsh/zshrc
1080 alias ls='exa -lh --icons --git --group-directories-first'
1081 alias la='exa -lha --icons --git --group-directories-first'
1082 alias df='df -h / /boot'
1084 alias free='free -h'
1089 alias grep='grep -in --exclude-dir=.git --color=auto'
1090 alias mkdir='mkdir -pv'
1091 alias unar='atool -x'
1092 alias wget='wget -e robots=off'
1093 alias lanex='~/.local/share/lxc/lxc'
1096 #+begin_src shell :tangle ~/.config/zsh/zshrc
1097 alias padm='yadm --yadm-repo ~/Code/dotfiles/repo.git'
1098 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1100 alias padu='padm add -u && padm commit && padm push && yadu'
1103 #+begin_src shell :tangle ~/.config/zsh/zshrc
1106 alias vw="nvim ~/Documents/vimwiki/index.md"
1108 **** System management
1109 #+begin_src shell :tangle ~/.config/zsh/zshrc
1110 alias jctl='journalctl -p 3 -xb'
1111 alias pkill='pkill -i'
1113 alias redoas='doas $(fc -ln -1)'
1114 alias crontab='crontab-argh'
1115 alias sudo='doas ' # allows aliases to be run with doas
1118 #+begin_src shell :tangle ~/.config/zsh/zshrc
1119 alias ping='ping -c 10'
1120 alias speed='speedtest-cli'
1121 alias ip='ip --color=auto'
1122 alias cip='curl https://armaanb.net/ip'
1123 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1124 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1127 #+begin_src shell :tangle ~/.config/zsh/zshrc
1128 alias dc='docker-compose'
1129 alias dcdu='docker-compose down && docker-compose up -d'
1132 #+begin_src shell :tangle ~/.config/zsh/zshrc
1133 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1134 iflag=fullblock status=progress'
1135 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1136 iflag=fullblock status=progress'
1137 alias ts='gen-shell -c task'
1138 alias ts='gen-shell -c task'
1139 alias tetris='autoload -Uz tetriscurses && tetriscurses'
1140 alias news='newsboat'
1141 alias tilderadio="\mpv https://radio.tildeverse.org/radio/8000/radio.ogg"
1142 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1143 --restrict-filenames -o '%(title)s.%(ext)s'"
1144 alias cal="cal -3 --color=auto"
1146 **** Virtual machines, chroots
1147 #+begin_src shell :tangle ~/.config/zsh/zshrc
1148 alias ckiss="sudo chrooter ~/Virtual/kiss"
1149 alias cdebian="sudo chrooter ~/Virtual/debian bash"
1150 alias cwindows='devour qemu-system-x86_64 \
1155 -device VGA,vgamem_mb=64 \
1157 -device hda-duplex \
1159 -net user,smb=/home/armaa/Public \
1160 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1163 #+begin_src shell :tangle ~/.config/zsh/zshrc
1165 alias zpy="zconda && ipython"
1166 alias math="ipython --profile=math"
1167 alias pypi="python setup.py sdist && twine upload dist/*"
1168 alias pip="python -m pip"
1169 alias black="black -l 79"
1172 #+begin_src shell :tangle ~/.config/zsh/zshrc
1173 alias words='gen-shell -c "words"'
1174 alias words-e='gen-shell -c "words ~E"'
1177 #+begin_src shell :tangle ~/.config/zsh/zshrc
1178 alias zathura='devour zathura'
1179 alias mpv='devour mpv'
1180 alias sql='devour sqlitebrowser'
1181 alias cad='devour openscad'
1182 alias feh='devour feh'
1184 **** Package management (Pacman)
1185 #+begin_src shell :tangle ~/.config/zsh/zshrc
1187 alias api='yay -Syu'
1188 alias apii='sudo pacman -S'
1189 alias app='yay -Rns'
1191 alias apo='yay -Qttd'
1192 alias azf='pacman -Q | fzf'
1193 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1194 alias ufetch='ufetch-arch'
1195 alias reflect='reflector --verbose --sort rate --save \
1196 ~/.local/etc/pacman.d/mirrorlist --download-timeout 60' # Takes ~45m to run
1199 #+begin_src shell :tangle ~/.config/zsh/zshrc
1200 export EDITOR="emacsclient -c"
1201 export VISUAL="$EDITOR"
1202 export TERM=xterm-256color # for compatability
1204 export GPG_TTY="$(tty)"
1205 export MANPAGER='nvim +Man!'
1208 export GTK_USE_PORTAL=1
1210 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
1211 export PATH="/home/armaa/Code/scripts:$PATH" # prioritize my scripts
1212 export PATH="/home/armaa/Code/scripts/bin:$PATH" # prioritize my bins
1213 export PATH="$PATH:/home/armaa/.cargo/bin"
1214 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
1215 export PATH="$PATH:/usr/sbin"
1216 export PATH="$PATH:/opt/FreeTube/freetube"
1218 export LC_ALL="en_US.UTF-8"
1219 export LC_CTYPE="en_US.UTF-8"
1220 export LANGUAGE="en_US.UTF-8"
1222 export KISS_PATH="/home/armaa/kiss/home/armaa/kiss-repo"
1223 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
1224 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
1225 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
1226 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
1227 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
1231 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1234 family: JetBrains Mono Nerd Font
1241 ligatures: true # Requires ligature patch
1248 background_opacity: 1
1251 Modus vivendi. Source: https://github.com/ishan9299/Nixos/blob/d4bbb7536be95b59466bb9cca4d671be46e04e81/user/alacritty/alacritty.yml#L30-L118
1252 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1256 background: '#000000'
1257 foreground: '#ffffff'
1261 background: '#ffffff'
1263 # Normal colors (except green it is from intense colors)
1274 # Bright colors [all the faint colors in the modus theme]
1285 # dim [all the intense colors in modus theme]
1298 Symlink profile_default/ipython_config.py to profile_math/ipython_config.py
1299 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1300 c.TerminalInteractiveShell.editing_mode = 'vi'
1301 c.InteractiveShell.colors = 'linux'
1302 c.TerminalInteractiveShell.confirm_exit = False
1305 #+begin_src python :tangle ~/.ipython/profile_math/startup.py
1309 return x * (180 / pi)
1312 return x * (pi / 180)
1315 return (x * (pi / 180)) / unit
1327 Make MPV play a little bit smoother.
1328 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1329 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1333 For any GNU Readline programs
1334 #+begin_src plain :tangle ~/.inputrc
1339 #+begin_src conf :tangle ~/.gitconfig
1341 name = Armaan Bhojwani
1342 email = me@armaanb.net
1343 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1346 #+begin_src conf :tangle ~/.gitconfig
1348 defaultBranch = main
1351 #+begin_src conf :tangle ~/.gitconfig
1356 #+begin_src conf :tangle ~/.gitconfig
1358 smtpserver = smtp.mailbox.org
1359 smtpuser = me@armaanb.net
1360 smtpencryption = ssl
1361 smtpserverport = 465
1365 #+begin_src conf :tangle ~/.gitconfig
1370 #+begin_src conf :tangle ~/.gitconfig
1373 sclone = clone --depth 1
1379 subup = submodule update --remote
1380 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1381 mirror = git config --global alias.mirrormirror
1384 #+begin_src conf :tangle ~/.gitconfig
1390 Lightweight notification daemon.
1392 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1394 font = "JetBrains Mono Medium Nerd Font 11"
1396 format = "<b>%s</b>\n%b"
1398 indicate_hidden = yes
1401 show_age_threshold = 60
1404 geometry = "400x5-10+10"
1406 idle_threshold = 120
1408 sticky_history = yes
1410 separator_height = 4
1412 horizontal_padding = 8
1414 separator_color = "#ffffff"
1415 startup_notification = false
1418 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1425 close_all = mod4+shift+c
1426 history = mod4+ctrl+c
1429 background = "#222222"
1430 foreground = "#ffffff"
1431 highlight = "#ffffff"
1435 background = "#222222"
1436 foreground = "#ffffff"
1437 highlight = "#ffffff"
1441 background = "#222222"
1442 foreground = "#a60000"
1443 highlight = "#ffffff"
1447 Modus vivendi theme that extends DarkBlue.
1448 #+begin_src plain :tangle ~/.config/rofi/config.rasi
1449 @import "/usr/share/rofi/themes/DarkBlue.rasi"
1451 white: rgba ( 255, 255, 255, 100 % );
1453 selected-normal-background: @white;
1454 separatorcolor: @white;
1455 background: rgba ( 34, 34, 34, 100 % );
1464 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1466 map <A-b> toggle_statusbar
1467 set selection-clipboard clipboard
1470 set window-title-basename "true"
1471 set selection-clipboard "clipboard"
1474 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1475 set default-bg "#000000"
1476 set default-fg "#ffffff"
1477 set render-loading true
1478 set render-loading-bg "#000000"
1479 set render-loading-fg "#ffffff"
1481 set recolor-lightcolor "#000000" # bg
1482 set recolor-darkcolor "#ffffff" # fg