1 #+TITLE: System Configuration
2 #+DESCRIPTION: Armaan's system configuration.
5 Welcome to my system configuration! This file contains my Emacs configuration, but also my config files for many of the other programs on my system!
7 I am currently using GCCEmacs 28 from the feature/native-comp branch, so some settings may not be available for older versions of Emacs. This is a purely personal configuration, so while I can garuntee that it works on my setup, I can't for anything else.
9 I chose to create a powerful, yet not overly heavy Emacs configuration. Things like LSP mode are important to my workflow and help me be productive, so despite its weight, it is kept. Things like a fancy modeline or icons on the other hand, do not increase my productivity, and create visual clutter, and thus have been excluded.
11 Another important choice has been to integrate Emacs into a large part of my computing environment (see [[*EmacsOS]]). I use Email, IRC, et cetera, all through Emacs which simplifies my workflow.
13 Lastly, I use Evil mode. I think modal keybindings are simple and more ergonomic than standard Emacs style, and Vim keybindings are what I'm comfortable with and are pervasive throughout computing.
15 *** TODO Turn keybinding and hook declarations into use-package declarations where possible
16 *** TODO Put configs with passwords in here with some kind of authentication
20 Released under the [[https://opensource.org/licenses/MIT][MIT license]] by Armaan Bhojwani, 2021. Note that many snippets are taken from online, and other sources, who are credited for their work at the snippet.
22 ** Bootstrap straight.el
23 straight.el is really nice for managing package, and it integrates nicely with use-package. It uses the bootstrapping system defined here for installation.
24 #+begin_src emacs-lisp
25 (defvar bootstrap-version)
27 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
28 (bootstrap-version 5))
29 (unless (file-exists-p bootstrap-file)
31 (url-retrieve-synchronously
32 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
33 'silent 'inhibit-cookies)
34 (goto-char (point-max))
35 (eval-print-last-sexp)))
36 (load bootstrap-file nil 'nomessage))
38 ** Replace use-package with straight
39 #+begin_src emacs-lisp
40 (straight-use-package 'use-package)
41 (setq straight-use-package-by-default t)
45 Very nice high contrast theme.
47 Its fine to set this here because I run Emacs in daemon mode, but if I were not, then putting it in early-init.el would be a better choice to eliminate the window being white before the theme is loaded.
48 #+begin_src emacs-lisp
49 (setq modus-themes-slanted-constructs t
50 modus-themes-bold-constructs t
51 modus-themes-org-blocks 'grayscale
52 modus-themes-mode-line '3d
53 modus-themes-scale-headings t
54 modus-themes-region 'no-extend
55 modus-themes-diffs 'desaturated)
56 (load-theme 'modus-vivendi t)
60 Great programming font with ligatures.
61 #+begin_src emacs-lisp
62 (add-to-list 'default-frame-alist '(font . "JetBrainsMonoNF-12"))
65 #+begin_src emacs-lisp
67 :straight (ligature :type git :host github :repo "mickeynp/ligature.el")
69 (ligature-set-ligatures
70 '(prog-mode text-mode)
71 '("-|" "-~" "---" "-<<" "-<" "--" "->" "->>" "-->" "/=" "/=="
72 "/>" "//" "/*" "*>" "*/" "<-" "<<-" "<=>" "<=" "<|" "<||"
73 "<|||" "<|>" "<:" "<>" "<-<" "<<<" "<==" "<<=" "<=<" "<==>" "<-|"
74 "<<" "<~>" "<=|" "<~~" "<~" "<$>" "<$" "<+>" "<+" "</>" "</" "<*"
75 "<*>" "<->" "<!--" ":>" ":<" ":::" "::" ":?" ":?>" ":=" "::=" "=>>"
76 "==>" "=/=" "=!=" "=>" "===" "=:=" "==" "!==" "!!" "!=" ">]" ">:"
77 ">>-" ">>=" ">=>" ">>>" ">-" ">=" "&&&" "&&" "|||>" "||>" "|>" "|]"
78 "|}" "|=>" "|->" "|=" "||-" "|-" "||=" "||" ".." ".?" ".=" ".-" "..<"
79 "..." "+++" "+>" "++" "[||]" "[<" "[|" "{|" "??" "?." "?=" "?:" "##"
80 "###" "####" "#[" "#{" "#=" "#!" "#:" "#_(" "#_" "#?" "#(" ";;" "_|_"
81 "__" "~~" "~~>" "~>" "~-" "~@" "$>" "^=" "]#"))
82 (global-ligature-mode t))
85 #+begin_src emacs-lisp
87 :config (global-emojify-mode))
89 ;; http://ergoemacs.org/emacs/emacs_list_and_set_font.html
94 ((member "Twitter Color Emoji" (font-family-list)) "Twitter Color Emoji")
95 ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
96 ((member "Noto Emoji" (font-family-list)) "Noto Emoji")))
99 Display relative line numbers except in some modes
100 #+begin_src emacs-lisp
101 (global-display-line-numbers-mode)
102 (setq display-line-numbers-type 'relative)
103 (dolist (no-line-num '(term-mode-hook
108 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
110 ** Highlight matching parenthesis
111 #+begin_src emacs-lisp
113 :config (show-paren-mode)
114 :custom (show-paren-style 'parenthesis))
117 *** Show current function
118 #+begin_src emacs-lisp
119 (which-function-mode)
121 *** Make position in file more descriptive
122 Show current column and file size.
123 #+begin_src emacs-lisp
125 (size-indication-mode)
128 #+begin_src emacs-lisp
130 :config (minions-mode))
133 #+begin_src emacs-lisp
135 :straight (wc-mode :type git :host github :repo "bnbeckwith/wc-mode")
136 :hook (text-mode-hook . wc-mode))
139 Show a ruler at a certain number of chars depending on mode.
140 #+begin_src emacs-lisp
141 (global-display-fill-column-indicator-mode)
144 Whenever starting a key chord, show possible future steps.
145 #+begin_src emacs-lisp
146 (use-package which-key
147 :config (which-key-mode)
148 :custom (which-key-idle-delay 0.3))
150 ** Visual highlights of changes
151 Highlight when changes are made.
152 #+begin_src emacs-lisp
153 (use-package evil-goggles
154 :config (evil-goggles-mode)
155 (evil-goggles-use-diff-faces))
157 ** Highlight TODOs in comments
158 #+begin_src emacs-lisp
160 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
161 :config (global-hl-todo-mode 1))
164 #+begin_src emacs-lisp
168 Soft wrap words and do operations by visual lines.
169 #+begin_src emacs-lisp
170 (add-hook 'text-mode-hook 'turn-on-visual-line-mode)
172 ** Display number of matches in search
173 #+begin_src emacs-lisp
175 :config (global-anzu-mode))
178 Inverts modeline instead of audible bell or the standard visual bell.
179 #+begin_src emacs-lisp
180 (setq visible-bell nil
181 ring-bell-function 'flash-mode-line)
182 (defun flash-mode-line ()
183 (invert-face 'mode-line)
184 (run-with-timer 0.1 nil #'invert-face 'mode-line))
188 #+begin_src emacs-lisp
190 :custom (select-enable-clipboard nil)
193 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
194 ;; Use visual line motions even outside of visual-line-mode buffers
195 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
196 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
197 (global-set-key (kbd "<escape>") 'keyboard-escape-quit))
200 #+begin_src emacs-lisp
201 (use-package evil-collection
203 :init (evil-collection-init)
204 :custom (evil-collection-setup-minibuffer t))
208 #+begin_src emacs-lisp
209 (use-package evil-surround
210 :config (global-evil-surround-mode))
213 #+begin_src emacs-lisp
214 (use-package evil-leader
215 :straight (evil-leader :type git :host github :repo "cofi/evil-leader")
217 (evil-leader/set-leader "<SPC>")
218 (global-evil-leader-mode))
221 #+begin_src emacs-lisp
223 (use-package evil-nerd-commenter
224 :bind (:map evil-normal-state-map
225 ("gc" . evilnc-comment-or-uncomment-lines))
226 :custom (evilnc-invert-comment-line-by-line nil))
230 #+begin_src emacs-lisp
231 (evil-set-undo-system 'undo-redo)
233 ** Number incrementing
235 #+begin_src emacs-lisp
236 (use-package evil-numbers
237 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
238 :bind (:map evil-normal-state-map
239 ("C-M-a" . evil-numbers/inc-at-pt)
240 ("C-M-x" . evil-numbers/dec-at-pt)))
244 #+begin_src emacs-lisp
245 (use-package evil-org
247 :hook (org-mode . evil-org-mode)
249 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
250 (use-package evil-org-agenda
251 :straight (:type built-in)
254 (evil-org-agenda-set-keys))
257 #+begin_src emacs-lisp
258 (evil-leader/set-key-for-mode 'org-mode
259 "T" 'org-show-todo-tree
261 "c" 'org-archive-subtree)
265 #+begin_src emacs-lisp
267 :straight (:type built-in)
268 :commands (org-capture org-agenda)
271 (org-agenda-start-with-log-mode t)
272 (org-agenda-files (quote ("~/Org/tasks.org" "~/Org/break.org")))
274 (org-log-into-drawer t)
275 (org-src-tab-acts-natively t)
276 (org-src-fontify-natively t)
277 (org-startup-indented t)
278 (org-hide-emphasis-markers t)
279 (org-fontify-whole-block-delimiter-line nil)
280 :bind ("C-c a" . org-agenda))
283 #+begin_src emacs-lisp
284 (use-package org-tempo
286 :straight (:type built-in)
288 ;; TODO: There's gotta be a more efficient way to write this
289 (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
290 (add-to-list 'org-structure-template-alist '("sp" . "src conf :tangle ~/.spectrwm.conf"))
291 (add-to-list 'org-structure-template-alist '("zsh" . "src shell :tangle ~/.config/zsh/zshrc"))
292 (add-to-list 'org-structure-template-alist '("al" . "src yml :tangle ~/.config/alacritty/alacritty.yml"))
293 (add-to-list 'org-structure-template-alist '("ipy" . "src python :tangle ~/.ipython/"))
294 (add-to-list 'org-structure-template-alist '("pi" . "src conf :tangle ~/.config/picom/picom.conf"))
295 (add-to-list 'org-structure-template-alist '("git" . "src conf :tangle ~/.gitconfig"))
296 (add-to-list 'org-structure-template-alist '("du" . "src conf :tangle ~/.config/dunst/dunstrc"))
297 (add-to-list 'org-structure-template-alist '("ro" . "src plain :tangle ~/.config/rofi/config.rasi"))
298 (add-to-list 'org-structure-template-alist '("za" . "src plain :tangle ~/.config/zathura/zathurarc")))
302 Simple, but not too simple autocompletion.
303 #+begin_src emacs-lisp
305 :bind (("C-s" . swiper)
306 :map ivy-minibuffer-map
307 ("TAB" . ivy-alt-done)
308 :map ivy-switch-buffer-map
309 ("M-d" . ivy-switch-buffer-kill))
313 #+begin_src emacs-lisp
314 (use-package ivy-rich
316 :config (ivy-rich-mode))
320 #+begin_src emacs-lisp
322 :bind (("C-M-j" . 'counsel-switch-buffer)
323 :map minibuffer-local-map
324 ("C-r" . 'counsel-minibuffer-history))
325 :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
326 :config (counsel-mode))
328 ** Remember frequent commands
329 #+begin_src emacs-lisp
330 (use-package ivy-prescient
333 (ivy-prescient-enable-filtering nil)
335 (prescient-persist-mode)
336 (ivy-prescient-mode))
339 Better search utility.
340 #+begin_src emacs-lisp
345 Use elfeed for RSS. I have another file with all the feeds in it.
346 #+begin_src emacs-lisp
348 :bind (("C-c e" . elfeed))
350 (load "~/.emacs.d/feeds.el")
351 (add-hook 'elfeed-new-entry-hook
352 (elfeed-make-tagger :feed-url "youtube\\.com"
354 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
356 (use-package elfeed-goodies
358 :config (elfeed-goodies/setup))
361 Use mu4e for reading emails.
363 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.
365 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.
366 #+begin_src emacs-lisp
367 (use-package smtpmail
368 :straight (:type built-in))
370 :load-path "/usr/share/emacs/site-lisp/mu4e"
371 :bind (("C-c m" . mu4e))
373 (setq user-full-name "Armaan Bhojwani"
374 smtpmail-local-domain "armaanb.net"
375 smtpmail-stream-type 'ssl
376 smtpmail-smtp-service '465
377 mu4e-change-filenames-when-moving t
378 mu4e-get-mail-command "offlineimap -q"
379 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
380 message-citation-line-function 'message-insert-formatted-citation-line
381 mu4e-completing-read-function 'ivy-completing-read
382 mu4e-confirm-quit nil
383 mail-user-agent 'mu4e-user-agent
385 `( ,(make-mu4e-context
387 :enter-func (lambda () (mu4e-message "Entering school context"))
388 :leave-func (lambda () (mu4e-message "Leaving school context"))
389 :match-func (lambda (msg)
391 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
392 :vars '((user-mail-address . "abhojwani22@nobles.edu")
393 (mu4e-sent-folder . "/school/Sent")
394 (mu4e-drafts-folder . "/school/Drafts")
395 (mu4e-trash-folder . "/school/Trash")
396 (mu4e-refile-folder . "/school/Archive")
397 (user-mail-address . "abhojwani22@nobles.edu")
398 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
399 (smtpmail-smtp-server . "smtp.gmail.com")))
402 :enter-func (lambda () (mu4e-message "Entering personal context"))
403 :leave-func (lambda () (mu4e-message "Leaving personal context"))
404 :match-func (lambda (msg)
406 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
407 :vars '((mu4e-sent-folder . "/personal/Sent")
408 (mu4e-drafts-folder . "/personal/Drafts")
409 (mu4e-trash-folder . "/personal/Trash")
410 (mu4e-refile-folder . "/personal/Archive")
411 (user-mail-address . "me@armaanb.net")
412 (smtpmail-smtp-user . "me@armaanb.net")
413 (smtpmail-smtp-server "smtp.mailbox.org")
414 (mu4e-drafts-folder . "/school/Drafts")
415 (mu4e-trash-folder . "/school/Trash")))))
416 (add-to-list 'mu4e-bookmarks
417 '(:name "Unified inbox"
418 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
420 :hook ((mu4e-compose-mode . flyspell-mode)
421 (mu4e-view-mode-hook . turn-on-visual-line-mode)))
424 #+begin_src emacs-lisp
426 (use-package calfw-org)
427 (use-package calfw-ical)
429 (defun acheam-calendar ()
432 (shell-command "vdirsyncer sync")
433 (let ((default-directory "~/.local/share/vdirsyncer/"))
434 (cfw:open-calendar-buffer
437 (cfw:ical-create-source "School" (expand-file-name "school/abhojwani22@nobles.edu.ics") "Green")
438 (cfw:ical-create-source "Personal" (expand-file-name "mailbox/Y2FsOi8vMC8zMQ.ics") "Blue")
439 (cfw:ical-create-source "Birthdays" (expand-file-name "mailbox/Y2FsOi8vMS8w.ics") "Gray")
443 Another file has more specific network configuration.
444 #+begin_src emacs-lisp
446 :config (load-file "~/.emacs.d/irc.el"))
448 (use-package circe-chanop
449 :straight (:type built-in)
452 (use-package circe-color-nicks
453 :straight (:type built-in)
457 Set EWW as default browser except for videos.
458 #+begin_src emacs-lisp
459 (defun browse-url-mpv (url &optional new-window)
461 (start-process "mpv" "*mpv*" "mpv" url))
463 (setq browse-url-handlers
465 (("youtu\\.?be" . browse-url-mpv)
466 ("." . eww-browse-url)
470 Some EWW enhancements.
471 *** Give buffer a useful name
472 #+begin_src emacs-lisp
473 ;; From https://protesilaos.com/dotemacs/
474 (defun prot-eww--rename-buffer ()
475 "Rename EWW buffer using page title or URL.
476 To be used by `eww-after-render-hook'."
477 (let ((name (if (eq "" (plist-get eww-data :title))
478 (plist-get eww-data :url)
479 (plist-get eww-data :title))))
480 (rename-buffer (format "*%s # eww*" name) t)))
482 (add-hook 'eww-after-render-hook #'prot-eww--rename-buffer)
484 *** Better entrypoint
485 #+begin_src emacs-lisp
486 ;; From https://protesilaos.com/dotemacs/
487 (defun prot-eww-browse-dwim (url &optional arg)
488 "Visit a URL, maybe from `eww-prompt-history', with completion.
490 With optional prefix ARG (\\[universal-argument]) open URL in a
493 If URL does not look like a valid link, run a web query using
496 When called from an eww buffer, provide the current link as
500 (completing-read "Query:" eww-prompt-history
501 nil nil (plist-get eww-data :url) 'eww-prompt-history)
503 (eww url (if arg 4 nil)))
505 (global-set-key (kbd "C-c w") 'prot-eww-browse-dwim)
508 Use Emacs globally. Use the Emacs daemon and bind a key in your wm to
509 =emacsclient --eval "(emacs-everywhere)"=.
510 #+begin_src emacs-lisp
511 (use-package emacs-everywhere)
516 #+begin_src emacs-lisp
517 (use-package lsp-mode
518 :commands (lsp lsp-deferred)
519 :custom (lsp-keymap-prefix "C-c l")
520 :hook ((lsp-mode . lsp-enable-which-key-integration)))
522 (use-package lsp-ivy)
525 :commands lsp-ui-mode
526 :custom (lsp-ui-doc-position 'bottom))
527 (use-package lsp-ui-flycheck
529 :straight (:type built-in))
532 Company-box adds icons.
533 #+begin_src emacs-lisp
536 :hook (lsp-mode . company-mode)
537 :bind (:map company-active-map
538 ("<tab>" . company-complete-selection))
540 ("<tab>" . company-indent-or-complete-common))
542 (company-minimum-prefix-length 1)
543 (setq company-dabbrev-downcase 0)
544 (company-idle-delay 0.0))
546 (use-package company-box
547 :hook (company-mode . company-box-mode))
551 #+begin_src emacs-lisp
552 (use-package lsp-pyright
553 :hook (python-mode . (lambda ()
554 (use-package lsp-pyright
555 :straight (:type built-in))
559 #+begin_src emacs-lisp
561 :hook (python-mode . blacken-mode)
563 (setq blacken-line-length 79))
566 (use-package ws-butler
568 (ws-butler-global-mode))
571 #+begin_src emacs-lisp
572 (use-package flycheck
574 (global-flycheck-mode))
576 ** Project management
577 #+begin_src emacs-lisp
578 (use-package projectile
579 :config (projectile-mode)
580 :custom ((projectile-completion-system 'ivy))
582 ("C-c p" . projectile-command-map)
584 (when (file-directory-p "~/Code")
585 (setq projectile-project-search-path '("~/Code")))
586 (setq projectile-switch-project-action #'projectile-dired))
588 (use-package counsel-projectile
590 :config (counsel-projectile-mode))
593 #+begin_src emacs-lisp
595 :straight (:type built-in)
596 :commands (dired dired-jump)
597 :custom ((dired-listing-switches "-agho --group-directories-first"))
599 (evil-collection-define-key 'normal 'dired-mode-map
600 "h" 'dired-single-up-directory
601 "l" 'dired-single-buffer))
603 (use-package dired-single
604 :commands (dired dired-jump))
606 (use-package dired-open
607 :commands (dired dired-jump)
609 (dired-open-extensions '(("png" . "feh")
612 (use-package dired-hide-dotfiles
613 :hook (dired-mode . dired-hide-dotfiles-mode)
615 (evil-collection-define-key 'normal 'dired-mode-map
616 "H" 'dired-hide-dotfiles-mode))
620 # TODO: Write a command that commits hunk, skipping staging step.
621 #+begin_src emacs-lisp
624 *** Colored diff in line number area
625 #+begin_src emacs-lisp
627 :straight (diff-hl :type git :host github :repo "dgutov/diff-hl")
628 :hook ((magit-pre-refresh-hook . diff-hl-magit-pre-refresh)
629 (magit-post-refresh-hook . diff-hl-magit-post-refresh))
630 :config (global-diff-hl-mode))
632 * General text editing
634 Indent after every change.
635 #+begin_src emacs-lisp
636 (use-package aggressive-indent
637 :config (global-aggressive-indent-mode))
640 Spell check in text mode, and in prog-mode comments.
641 #+begin_src emacs-lisp
642 (dolist (hook '(text-mode-hook))
643 (add-hook hook (lambda () (flyspell-mode))))
644 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
645 (add-hook hook (lambda () (flyspell-mode -1))))
646 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
648 ** Expand tabs to spaces
649 #+begin_src emacs-lisp
650 (setq-default tab-width 2)
652 ** Copy kill ring to clipboard
653 #+begin_src emacs-lisp
654 (setq x-select-enable-clipboard t)
655 (defun copy-kill-ring-to-xorg ()
656 "Copy the current kill ring to the xorg clipboard."
658 (x-select-text (current-kill 0)))
661 #+begin_src emacs-lisp
662 (use-package browse-kill-ring)
665 Opens file where you left it.
666 #+begin_src emacs-lisp
670 Distraction free writing a la junegunn/goyo.
671 #+begin_src emacs-lisp
672 (use-package olivetti
674 (evil-leader/set-key "o" 'olivetti-mode))
678 #+begin_src emacs-lisp
679 (setq abbrev-file-name "~/.emacs.d/abbrevs")
680 (setq save-abbrevs 'silent)
681 (setq-default abbrev-mode t)
684 #+begin_src emacs-lisp
685 (setq tramp-default-method "ssh")
687 ** Don't ask about following symlinks in vc
688 #+begin_src emacs-lisp
689 (setq vc-follow-symlinks t)
692 ** Easily convert splits
693 Converts splits from horizontal to vertical and vice versa. Lifted from EmacsWiki.
694 #+begin_src emacs-lisp
695 (defun toggle-window-split ()
697 (if (= (count-windows) 2)
698 (let* ((this-win-buffer (window-buffer))
699 (next-win-buffer (window-buffer (next-window)))
700 (this-win-edges (window-edges (selected-window)))
701 (next-win-edges (window-edges (next-window)))
702 (this-win-2nd (not (and (<= (car this-win-edges)
703 (car next-win-edges))
704 (<= (cadr this-win-edges)
705 (cadr next-win-edges)))))
707 (if (= (car this-win-edges)
708 (car (window-edges (next-window))))
709 'split-window-horizontally
710 'split-window-vertically)))
711 (delete-other-windows)
712 (let ((first-win (selected-window)))
714 (if this-win-2nd (other-window 1))
715 (set-window-buffer (selected-window) this-win-buffer)
716 (set-window-buffer (next-window) next-win-buffer)
717 (select-window first-win)
718 (if this-win-2nd (other-window 1))))))
720 (define-key ctl-x-4-map "t" 'toggle-window-split)
723 #+begin_src emacs-lisp
724 (defun insert-date ()
726 (insert (format-time-string "%Y-%m-%d")))
730 #+begin_src emacs-lisp
731 (use-package ace-window
732 :bind ("M-o" . ace-window))
734 ** Kill current buffer
735 Makes "C-x k" binding faster.
736 #+begin_src emacs-lisp
737 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
741 Render OpenSCAD files, and add a preview window.
743 Personal fork just merges a PR.
744 #+begin_src emacs-lisp
745 (use-package scad-mode)
746 (use-package scad-preview
747 :straight (scad-preview :type git :host github :repo "Armaanb/scad-preview"))
749 ** Control backup files
750 Stop backup files from spewing everywhere.
751 #+begin_src emacs-lisp
752 (setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
754 ** Make yes/no easier
755 #+begin_src emacs-lisp
756 (defalias 'yes-or-no-p 'y-or-n-p)
758 ** Move customize file
759 No more clogging up init.el.
760 #+begin_src emacs-lisp
761 (setq custom-file "~/.emacs.d/custom.el")
765 #+begin_src emacs-lisp
767 :commands (helpful-callable helpful-variable helpful-command helpful-key)
769 (counsel-describe-function-function #'helpful-callable)
770 (counsel-describe-variable-function #'helpful-variable)
772 ([remap describe-function] . counsel-describe-function)
773 ([remap describe-command] . helpful-command)
774 ([remap describe-variable] . counsel-describe-variable)
775 ([remap describe-key] . helpful-key))
778 #+begin_src emacs-lisp
779 (use-package epa-file
780 :straight (:type built-in)
782 (epa-file-select-keys nil)
783 (epa-file-encrypt-to '("me@armaanb.net"))
784 (password-cache-expiry (* 60 15)))
786 (use-package pinentry
787 :config (pinentry-start))
790 #+begin_src emacs-lisp
792 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
793 :custom (0x0-default-service 'envs)
794 :config (evil-leader/set-key
796 "0f" '0x0-upload-file
797 "0s" '0x0-upload-string
798 "0c" '0x0-upload-kill-ring
799 "0p" '0x0-upload-popup))
804 #+begin_src conf :tangle ~/.spectrwm.conf
809 autorun = ws[1]:/home/armaa/Code/scripts/autostart
812 #+begin_src conf :tangle ~/.spectrwm.conf
813 color_focus = rgb:ff/ff/ff
814 color_focus_maximized = rgb:ee/cc/00
815 color_unfocus = rgb:55/55/55
818 #+begin_src conf :tangle ~/.spectrwm.conf
820 bar_font = xos4 Fira Code:pixelsize=14:antialias=true # any installed font
824 #+begin_src conf :tangle ~/.spectrwm.conf
825 program[lock] = i3lock -c 000000 -ef
826 program[term] = alacritty
827 program[screenshot_all] = flameshot gui
828 program[menu] = rofi -show run # `rofi-dmenu` handles the rest
829 program[switcher] = rofi -show window
830 program[notif] = /home/armaa/Code/scripts/setter status
833 bind[switcher] = MOD+Tab
836 #+begin_src conf :tangle ~/.spectrwm.conf
837 program[paup] = /home/armaa/Code/scripts/setter audio +5
838 program[padown] = /home/armaa/Code/scripts/setter audio -5
839 program[pamute] = /home/armaa/Code/scripts/setter audio
840 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
841 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
842 program[next] = playerctl next
843 program[prev] = playerctl previous
844 program[pause] = playerctl play-pause
846 bind[padown] = XF86AudioLowerVolume
847 bind[paup] = XF86AudioRaiseVolume
848 bind[pamute] = XF86AudioMute
849 bind[brigdown] = XF86MonBrightnessDown
850 bind[brigup] = XF86MonBrightnessUp
851 bind[pause] = XF86AudioPlay
852 bind[next] = XF86AudioNext
853 bind[prev] = XF86AudioPrev
856 #+begin_src conf :tangle ~/.spectrwm.conf
857 program[h] = xdotool keyup h key --clearmodifiers Left
858 program[j] = xdotool keyup j key --clearmodifiers Down
859 program[k] = xdotool keyup k key --clearmodifiers Up
860 program[l] = xdotool keyup l key --clearmodifiers Right
862 bind[h] = Mod1 + Tab + h
863 bind[j] = Mod1 + Tab + j
864 bind[k] = Mod1 + Tab + k
865 bind[l] = Mod1 + Tab + l
868 #+begin_src conf :tangle ~/.spectrwm.conf
869 program[aerc] = alacritty -e aerc
870 program[weechat] = alacritty --hold -e sh -c "while : ; do ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat; sleep 2; done"
871 program[emacs] = emacsclient -c
872 program[emacs-anywhere] = emacsclient --eval "(emacs-everywhere)"
873 program[firefox] = firefox
874 program[thunderbird] = thunderbird
875 program[slack] = slack
877 bind[aerc] = MOD+Control+1
878 bind[weechat] = MOD+Control+2
879 bind[emacs-anywhere] = MOD+Control+3
880 bind[firefox] = MOD+Control+4
881 bind[thunderbird] = MOD+Control+5
882 bind[slack] = MOD+Control+6
883 bind[emacs] = MOD+Control+Return
888 #+begin_src shell :tangle ~/.config/zsh/zshrc
889 autoload -Uz compinit
893 unsetopt glob_complete
896 #+begin_src shell :tangle ~/.config/zsh/zshrc
900 bindkey -M vicmd "^[[3~" delete-char
901 bindkey "^[[3~" delete-char
903 autoload edit-command-line
904 zle -N edit-command-line
905 bindkey -M vicmd ^e edit-command-line
906 bindkey ^e edit-command-line
909 #+begin_src shell :tangle ~/.config/zsh/zshrc
910 setopt extended_history
912 setopt inc_append_history
913 setopt hist_ignore_dups
914 setopt hist_reduce_blanks
918 HISTFILE=~/.local/share/zsh/history
921 I manage plugins using my own plugin manager, ZPE. https://git.sr.ht/~armaan/zpe
923 #+begin_src plain :tangle ~/.config/zpe/repositories
924 https://github.com/Aloxaf/fzf-tab
925 https://github.com/zdharma/fast-syntax-highlighting
926 https://github.com/rupa/z
929 #+begin_src shell :tangle ~/.config/zsh/zshrc
930 source ~/Code/zpe/zpe.sh
931 source ~/Code/admone/admone.zsh
932 source ~/.config/zsh/fzf-bindings.zsh
934 zpe-source fzf-tab/fzf-tab.zsh
935 zstyle ':completion:*:descriptions' format '[%d]'
936 zstyle ':fzf-tab:complete:cd:*' fzf-preview 'exa -1 --color=always $realpath'
937 zstyle ':completion:*' completer _complete
938 zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \
939 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
941 zpe-source fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
942 export _Z_DATA="/home/armaa/.local/share/z"
946 **** Alert after long command
947 #+begin_src shell :tangle ~/.config/zsh/zshrc
949 notify-send --urgency=low -i ${(%):-%(?.terminal.error)} \
950 ${history[$HISTCMD]%[;&|][[:space:]]##alert}
953 **** Time Zsh startup
954 #+begin_src shell :tangle ~/.config/zsh/zshrc
956 for i in $(seq 1 10); do
957 time "zsh" -i -c exit;
961 **** Update all packages
962 #+begin_src shell :tangle ~/.config/zsh/zshrc
963 color=$(tput setaf 5)
967 sudo echo "${color}== upgrading with yay ==${reset}"
970 echo "${color}== checking for pacnew files ==${reset}"
973 echo "${color}== upgrading flatpaks ==${reset}"
976 echo "${color}== upgrading zsh plugins ==${reset}"
979 echo "${color}== updating nvim plugins ==${reset}"
980 nvim +PlugUpdate +PlugUpgrade +qall
981 echo "Updated nvim plugins"
983 echo "${color}You are entirely up to date!${reset}"
986 **** Clean all packages
987 #+begin_src shell :tangle ~/.config/zsh/zshrc
989 sudo echo "${color}== cleaning pacman orphans ==${reset}"
990 (pacman -Qtdq | sudo pacman -Rns - 2> /dev/null) || echo "No orphans"
992 echo "${color}== cleaning flatpaks ==${reset}"
993 flatpak remove --unused
995 echo "${color}== cleaning zsh plugins ==${reset}"
998 echo "${color}== cleaning nvim plugins ==${reset}"
999 nvim +PlugClean +qall
1000 echo "Cleaned nvim plugins"
1002 echo "${color}All orphans cleaned!${reset}"
1006 #+begin_src shell :tangle ~/.config/zsh/zshrc
1009 exa -lh --icons --git --group-directories-first
1013 #+begin_src shell :tangle ~/.config/zsh/zshrc
1015 __conda_setup="$('/opt/anaconda/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
1016 if [ $? -eq 0 ]; then
1017 eval "$__conda_setup"
1019 if [ -f "/opt/anaconda/etc/profile.d/conda.sh" ]; then
1020 . "/opt/anaconda/etc/profile.d/conda.sh"
1022 export PATH="/opt/anaconda/bin:$PATH"
1028 **** Interact with 0x0
1029 #+begin_src shell :tangle ~/.config/zsh/zshrc
1030 zxz="https://envs.sh"
1031 0file() { curl -F"file=@$1" "$zxz" ; }
1032 0pb() { curl -F"file=@-;" "$zxz" ; }
1033 0url() { curl -F"url=$1" "$zxz" ; }
1034 0short() { curl -F"shorten=$1" "$zxz" ; }
1035 0clip() { xclip -out | curl -F"file=@-;" "$zxz" ; }
1038 #+begin_src shell :tangle ~/.config/zsh/zshrc
1047 #+begin_src shell :tangle ~/.config/zsh/zshrc
1048 alias bhoji-drop='ssh -p 23 root@armaanb.net'
1049 alias weechat='ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat'
1050 alias tcf='ssh root@204.48.23.68'
1051 alias ngmun='ssh root@157.245.89.25'
1052 alias prox='ssh root@192.168.1.224'
1053 alias dock='ssh root@192.168.1.225'
1054 alias jenkins='ssh root@192.168.1.226'
1055 alias envs='ssh acheam@envs.net'
1057 **** File management
1058 #+begin_src shell :tangle ~/.config/zsh/zshrc
1059 alias ls='exa -lh --icons --git --group-directories-first'
1060 alias la='exa -lha --icons --git --group-directories-first'
1061 alias df='df -h / /boot'
1063 alias free='free -h'
1068 alias grep='grep -in --exclude-dir=.git --color=auto'
1069 alias mkdir='mkdir -pv'
1070 alias unar='atool -x'
1071 alias wget='wget -e robots=off'
1072 alias lanex='~/.local/share/lxc/lxc'
1075 #+begin_src shell :tangle ~/.config/zsh/zshrc
1076 alias padm='yadm --yadm-repo ~/Code/dotfiles/repo.git'
1077 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1079 alias padu='padm add -u && padm commit && padm push && yadu'
1082 #+begin_src shell :tangle ~/.config/zsh/zshrc
1085 alias vw="nvim ~/Documents/vimwiki/index.md"
1087 **** System management
1088 #+begin_src shell :tangle ~/.config/zsh/zshrc
1089 alias jctl='journalctl -p 3 -xb'
1090 alias pkill='pkill -i'
1092 alias please='sudo $(fc -ln -1)'
1093 alias sudo='sudo ' # allows aliases to be run with sudo
1096 #+begin_src shell :tangle ~/.config/zsh/zshrc
1097 alias ping='ping -c 10'
1098 alias speed='speedtest-cli'
1099 alias ip='ip --color=auto'
1100 alias cip='curl https://armaanb.net/ip'
1101 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1102 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1105 #+begin_src shell :tangle ~/.config/zsh/zshrc
1106 alias dc='docker-compose'
1107 alias dcdu='docker-compose down && docker-compose up -d'
1110 #+begin_src shell :tangle ~/.config/zsh/zshrc
1111 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1112 iflag=fullblock status=progress'
1113 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1114 iflag=fullblock status=progress'
1115 alias ts='gen-shell -c task'
1116 alias ts='gen-shell -c task'
1117 alias tetris='autoload -Uz tetriscurses && tetriscurses'
1118 alias news='newsboat'
1119 alias tilderadio="\mpv https://radio.tildeverse.org/radio/8000/radio.ogg"
1120 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1121 --restrict-filenames -o '%(title)s.%(ext)s'"
1122 alias cal="cal -3 --color=auto"
1124 **** Virtual machines, chroots
1125 #+begin_src shell :tangle ~/.config/zsh/zshrc
1126 alias ckiss="sudo chrooter ~/Virtual/kiss"
1127 alias cdebian="sudo chrooter ~/Virtual/debian bash"
1128 alias cwindows='devour qemu-system-x86_64 \
1133 -device VGA,vgamem_mb=64 \
1135 -device hda-duplex \
1137 -net user,smb=/home/armaa/Public \
1138 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1141 #+begin_src shell :tangle ~/.config/zsh/zshrc
1143 alias zpy="zconda && ipython"
1144 alias math="ipython --profile=math"
1145 alias pypi="python setup.py sdist && twine upload dist/*"
1146 alias pip="python -m pip"
1147 alias black="black -l 79"
1150 #+begin_src shell :tangle ~/.config/zsh/zshrc
1151 alias words='gen-shell -c "words"'
1152 alias words-e='gen-shell -c "words ~E"'
1155 #+begin_src shell :tangle ~/.config/zsh/zshrc
1156 alias zathura='devour zathura'
1157 alias mpv='devour mpv'
1158 alias sql='devour sqlitebrowser'
1159 alias cad='devour openscad'
1160 alias feh='devour feh'
1162 **** Package management (Pacman)
1163 #+begin_src shell :tangle ~/.config/zsh/zshrc
1165 alias api='yay -Syu'
1166 alias apii='sudo pacman -S'
1167 alias app='yay -Rns'
1169 alias apo='yay -Qttd'
1170 alias azf='pacman -Q | fzf'
1171 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1172 alias ufetch='ufetch-arch'
1173 alias reflect='reflector --verbose --sort rate --save \
1174 ~/.local/etc/pacman.d/mirrorlist --download-timeout 60' # Takes ~45m to run
1177 #+begin_src shell :tangle ~/.config/zsh/zshrc
1178 export EDITOR="emacsclient -c"
1179 export VISUAL="$EDITOR"
1180 export TERM=xterm-256color # for compatability
1182 export GPG_TTY="$(tty)"
1183 export MANPAGER='nvim +Man!'
1186 export GTK_USE_PORTAL=1
1188 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
1189 export PATH="$PATH:/home/armaa/Code/scripts"
1190 export PATH="$PATH:/home/armaa/.cargo/bin"
1191 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
1192 export PATH="$PATH:/usr/sbin"
1193 export PATH="$PATH:/opt/FreeTube/freetube"
1195 export LC_ALL="en_US.UTF-8"
1196 export LC_CTYPE="en_US.UTF-8"
1197 export LANGUAGE="en_US.UTF-8"
1199 export KISS_PATH="/home/armaa/kiss/home/armaa/kiss-repo"
1200 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
1201 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
1202 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
1203 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
1204 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
1208 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1211 family: JetBrains Mono Nerd Font
1218 ligatures: true # Requires ligature patch
1225 background_opacity: 1
1228 Send <RET> + modifier through
1229 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1243 Modus vivendi. Source: https://github.com/ishan9299/Nixos/blob/d4bbb7536be95b59466bb9cca4d671be46e04e81/user/alacritty/alacritty.yml#L30-L118
1244 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1248 background: '#000000'
1249 foreground: '#ffffff'
1253 background: '#ffffff'
1255 # Normal colors (except green it is from intense colors)
1266 # Bright colors [all the faint colors in the modus theme]
1277 # dim [all the intense colors in modus theme]
1290 Symlink profile_default/ipython_config.py to profile_math/ipython_config.py
1291 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1292 c.TerminalInteractiveShell.editing_mode = 'vi'
1293 c.InteractiveShell.colors = 'linux'
1294 c.TerminalInteractiveShell.confirm_exit = False
1297 #+begin_src python :tangle ~/.ipython/profile_math/startup.py
1301 return x * (180 / pi)
1304 return x * (pi / 180)
1307 return (x * (pi / 180)) / unit
1319 Make MPV play a little bit smoother.
1320 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1321 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1325 For any GNU Readline programs
1326 #+begin_src plain :tangle ~/.inputrc
1331 #+begin_src conf :tangle ~/.gitconfig
1333 name = Armaan Bhojwani
1334 email = me@armaanb.net
1335 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1338 #+begin_src conf :tangle ~/.gitconfig
1340 defaultBranch = main
1343 #+begin_src conf :tangle ~/.gitconfig
1348 #+begin_src conf :tangle ~/.gitconfig
1350 smtpserver = smtp.mailbox.org
1351 smtpuser = me@armaanb.net
1352 smtpencryption = ssl
1353 smtpserverport = 465
1357 #+begin_src conf :tangle ~/.gitconfig
1362 #+begin_src conf :tangle ~/.gitconfig
1365 sclone = clone --depth 1
1371 subup = submodule update --remote
1372 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1373 mirror = git config --global alias.mirrormirror
1376 #+begin_src conf :tangle ~/.gitconfig
1381 Lightweight notification daemon.
1383 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1385 font = "JetBrains Mono Medium Nerd Font 11"
1387 format = "<b>%s</b>\n%b"
1389 indicate_hidden = yes
1392 show_age_threshold = 60
1395 geometry = "400x5-10+10"
1397 idle_threshold = 120
1399 sticky_history = yes
1401 separator_height = 4
1403 horizontal_padding = 8
1405 separator_color = "#ffffff"
1406 startup_notification = false
1409 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1416 close_all = mod4+shift+c
1417 history = mod4+ctrl+c
1420 background = "#222222"
1421 foreground = "#ffffff"
1422 highlight = "#ffffff"
1426 background = "#222222"
1427 foreground = "#ffffff"
1428 highlight = "#ffffff"
1432 background = "#222222"
1433 foreground = "#a60000"
1434 highlight = "#ffffff"
1438 Modus vivendi theme that extends DarkBlue.
1439 #+begin_src plain :tangle ~/.config/rofi/config.rasi
1440 @import "/usr/share/rofi/themes/DarkBlue.rasi"
1442 white: rgba ( 255, 255, 255, 100 % );
1444 selected-normal-background: @white;
1445 separatorcolor: @white;
1446 background: rgba ( 34, 34, 34, 100 % );
1455 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1457 map <A-b> toggle_statusbar
1458 set selection-clipboard clipboard
1461 set window-title-basename "true"
1462 set selection-clipboard "clipboard"
1465 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1466 set default-bg "#000000"
1467 set default-fg "#ffffff"
1468 set render-loading true
1469 set render-loading-bg "#000000"
1470 set render-loading-fg "#ffffff"
1472 set recolor-lightcolor "#000000" # bg
1473 set recolor-darkcolor "#ffffff" # fg