1 #+TITLE: System Configuration
2 #+DESCRIPTION: Armaan's system configuration.
5 Welcome to my system configuration! This file contains my Emacs configuration, but also my config files for many of the other programs on my system!
7 I am currently using GCCEmacs 28 from the feature/native-comp branch, so some settings may not be available for older versions of Emacs. This is a purely personal configuration, so while I can garuntee that it works on my setup, I can't for anything else.
9 I chose to create a powerful, yet not overly heavy Emacs configuration. Things like LSP mode are important to my workflow and help me be productive, so despite its weight, it is kept. Things like a fancy modeline or icons on the other hand, do not increase my productivity, and create visual clutter, and thus have been excluded.
11 Another important choice has been to integrate Emacs into a large part of my computing environment (see [[*EmacsOS]]). I use Email, IRC, et cetera, all through Emacs which simplifies my workflow.
13 Lastly, I use Evil mode. I think modal keybindings are simple and more ergonomic than standard Emacs style, and Vim keybindings are what I'm comfortable with and are pervasive throughout computing.
15 *** TODO Turn keybinding and hook declarations into use-package declarations where possible
16 *** TODO Put configs with passwords in here with some kind of authentication
20 Released under the [[https://opensource.org/licenses/MIT][MIT license]] by Armaan Bhojwani, 2021. Note that many snippets are taken from online, and other sources, who are credited for their work at the snippet.
22 ** Bootstrap straight.el
23 straight.el is really nice for managing package, and it integrates nicely with use-package. It uses the bootstrapping system defined here for installation.
24 #+begin_src emacs-lisp
25 (defvar bootstrap-version)
27 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
28 (bootstrap-version 5))
29 (unless (file-exists-p bootstrap-file)
31 (url-retrieve-synchronously
32 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
33 'silent 'inhibit-cookies)
34 (goto-char (point-max))
35 (eval-print-last-sexp)))
36 (load bootstrap-file nil 'nomessage))
38 ** Replace use-package with straight
39 #+begin_src emacs-lisp
40 (straight-use-package 'use-package)
41 (setq straight-use-package-by-default t)
45 Very nice high contrast theme.
47 Its fine to set this here because I run Emacs in daemon mode, but if I were not, then putting it in early-init.el would be a better choice to eliminate the window being white before the theme is loaded.
48 #+begin_src emacs-lisp
49 (setq modus-themes-slanted-constructs t
50 modus-themes-bold-constructs t
51 modus-themes-org-blocks 'grayscale
52 modus-themes-mode-line '3d
53 modus-themes-scale-headings t
54 modus-themes-region 'no-extend
55 modus-themes-diffs 'desaturated)
56 (load-theme 'modus-vivendi t)
60 Great programming font with ligatures.
61 #+begin_src emacs-lisp
62 (add-to-list 'default-frame-alist '(font . "JetBrainsMonoNF-12"))
65 #+begin_src emacs-lisp
67 :straight (ligature :type git :host github :repo "mickeynp/ligature.el")
69 (ligature-set-ligatures
70 '(prog-mode text-mode)
71 '("-|" "-~" "---" "-<<" "-<" "--" "->" "->>" "-->" "/=" "/=="
72 "/>" "//" "/*" "*>" "*/" "<-" "<<-" "<=>" "<=" "<|" "<||"
73 "<|||" "<|>" "<:" "<>" "<-<" "<<<" "<==" "<<=" "<=<" "<==>"
74 "<-|" "<<" "<~>" "<=|" "<~~" "<~" "<$>" "<$" "<+>" "<+" "</>"
75 "</" "<*" "<*>" "<->" "<!--" ":>" ":<" ":::" "::" ":?" ":?>"
76 ":=" "::=" "=>>" "==>" "=/=" "=!=" "=>" "===" "=:=" "==" "!=="
77 "!!" "!=" ">]" ">:" ">>-" ">>=" ">=>" ">>>" ">-" ">=" "&&&"
78 "&&" "|||>" "||>" "|>" "|]" "|}" "|=>" "|->" "|=" "||-" "|-"
79 "||=" "||" ".." ".?" ".=" ".-" "..<" "..." "+++" "+>" "++"
80 "[||]" "[<" "[|" "{|" "??" "?." "?=" "?:" "##" "###" "####"
81 "#[" "#{" "#=" "#!" "#:" "#_(" "#_" "#?" "#(" ";;" "_|_" "__"
82 "~~" "~~>" "~>" "~-" "~@" "$>" "^=" "]#"))
83 (global-ligature-mode t))
86 #+begin_src emacs-lisp
88 :config (global-emojify-mode))
90 ;; http://ergoemacs.org/emacs/emacs_list_and_set_font.html
95 ((member "Twitter Color Emoji" (font-family-list)) "Twitter Color Emoji")
96 ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
97 ((member "Noto Emoji" (font-family-list)) "Noto Emoji")))
100 Display relative line numbers except in some modes
101 #+begin_src emacs-lisp
102 (global-display-line-numbers-mode)
103 (setq display-line-numbers-type 'relative)
104 (dolist (no-line-num '(term-mode-hook
109 (add-hook no-line-num (lambda () (display-line-numbers-mode 0))))
111 ** Highlight matching parenthesis
112 #+begin_src emacs-lisp
114 :config (show-paren-mode)
115 :custom (show-paren-style 'parenthesis))
118 *** Show current function
119 #+begin_src emacs-lisp
120 (which-function-mode)
122 *** Make position in file more descriptive
123 Show current column and file size.
124 #+begin_src emacs-lisp
126 (size-indication-mode)
129 #+begin_src emacs-lisp
131 :config (minions-mode))
134 #+begin_src emacs-lisp
136 :straight (wc-mode :type git :host github :repo "bnbeckwith/wc-mode")
137 :hook (text-mode-hook . wc-mode))
140 Show a ruler at a certain number of chars depending on mode.
141 #+begin_src emacs-lisp
142 (global-display-fill-column-indicator-mode)
145 Whenever starting a key chord, show possible future steps.
146 #+begin_src emacs-lisp
147 (use-package which-key
148 :config (which-key-mode)
149 :custom (which-key-idle-delay 0.3))
151 ** Visual highlights of changes
152 Highlight when changes are made.
153 #+begin_src emacs-lisp
154 (use-package evil-goggles
155 :config (evil-goggles-mode)
156 (evil-goggles-use-diff-faces))
158 ** Highlight TODOs in comments
159 #+begin_src emacs-lisp
161 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
162 :config (global-hl-todo-mode 1))
165 #+begin_src emacs-lisp
169 Soft wrap words and do operations by visual lines.
170 #+begin_src emacs-lisp
171 (add-hook 'text-mode-hook 'turn-on-visual-line-mode)
173 ** Display number of matches in search
174 #+begin_src emacs-lisp
176 :config (global-anzu-mode))
179 Inverts modeline instead of audible bell or the standard visual bell.
180 #+begin_src emacs-lisp
181 (setq visible-bell nil
182 ring-bell-function 'flash-mode-line)
183 (defun flash-mode-line ()
184 (invert-face 'mode-line)
185 (run-with-timer 0.1 nil #'invert-face 'mode-line))
189 #+begin_src emacs-lisp
191 :custom (select-enable-clipboard nil)
194 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
195 ;; Use visual line motions even outside of visual-line-mode buffers
196 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
197 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
198 (global-set-key (kbd "<escape>") 'keyboard-escape-quit))
201 #+begin_src emacs-lisp
202 (use-package evil-collection
204 :init (evil-collection-init)
205 :custom (evil-collection-setup-minibuffer t))
209 #+begin_src emacs-lisp
210 (use-package evil-surround
211 :config (global-evil-surround-mode))
214 #+begin_src emacs-lisp
215 (use-package evil-leader
216 :straight (evil-leader :type git :host github :repo "cofi/evil-leader")
218 (evil-leader/set-leader "<SPC>")
219 (global-evil-leader-mode))
222 #+begin_src emacs-lisp
224 (use-package evil-nerd-commenter
225 :bind (:map evil-normal-state-map
226 ("gc" . evilnc-comment-or-uncomment-lines))
227 :custom (evilnc-invert-comment-line-by-line nil))
231 #+begin_src emacs-lisp
232 (evil-set-undo-system 'undo-redo)
234 ** Number incrementing
236 #+begin_src emacs-lisp
237 (use-package evil-numbers
238 :straight (evil-numbers :type git :host github :repo "juliapath/evil-numbers")
239 :bind (:map evil-normal-state-map
240 ("C-M-a" . evil-numbers/inc-at-pt)
241 ("C-M-x" . evil-numbers/dec-at-pt)))
245 #+begin_src emacs-lisp
246 (use-package evil-org
248 :hook (org-mode . evil-org-mode)
250 (evil-org-set-key-theme '(textobjects insert navigation shift todo)))
251 (use-package evil-org-agenda
252 :straight (:type built-in)
255 (evil-org-agenda-set-keys))
258 #+begin_src emacs-lisp
259 (evil-leader/set-key-for-mode 'org-mode
260 "T" 'org-show-todo-tree
262 "c" 'org-archive-subtree)
266 #+begin_src emacs-lisp
268 :straight (:type built-in)
269 :commands (org-capture org-agenda)
272 (org-agenda-start-with-log-mode t)
273 (org-agenda-files (quote ("~/Org/tasks.org" "~/Org/break.org")))
275 (org-log-into-drawer t)
276 (org-src-tab-acts-natively t)
277 (org-src-fontify-natively t)
278 (org-startup-indented t)
279 (org-hide-emphasis-markers t)
280 (org-fontify-whole-block-delimiter-line nil)
281 :bind ("C-c a" . org-agenda))
284 #+begin_src emacs-lisp
285 (use-package org-tempo
287 :straight (:type built-in)
289 ;; TODO: There's gotta be a more efficient way to write this
290 (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
291 (add-to-list 'org-structure-template-alist '("sp" . "src conf :tangle ~/.spectrwm.conf"))
292 (add-to-list 'org-structure-template-alist '("zsh" . "src shell :tangle ~/.config/zsh/zshrc"))
293 (add-to-list 'org-structure-template-alist '("al" . "src yml :tangle ~/.config/alacritty/alacritty.yml"))
294 (add-to-list 'org-structure-template-alist '("ipy" . "src python :tangle ~/.ipython/"))
295 (add-to-list 'org-structure-template-alist '("pi" . "src conf :tangle ~/.config/picom/picom.conf"))
296 (add-to-list 'org-structure-template-alist '("git" . "src conf :tangle ~/.gitconfig"))
297 (add-to-list 'org-structure-template-alist '("du" . "src conf :tangle ~/.config/dunst/dunstrc"))
298 (add-to-list 'org-structure-template-alist '("ro" . "src plain :tangle ~/.config/rofi/config.rasi"))
299 (add-to-list 'org-structure-template-alist '("za" . "src plain :tangle ~/.config/zathura/zathurarc")))
303 Simple, but not too simple autocompletion.
304 #+begin_src emacs-lisp
306 :bind (("C-s" . swiper)
307 :map ivy-minibuffer-map
308 ("TAB" . ivy-alt-done)
309 :map ivy-switch-buffer-map
310 ("M-d" . ivy-switch-buffer-kill))
314 #+begin_src emacs-lisp
315 (use-package ivy-rich
317 :config (ivy-rich-mode))
321 #+begin_src emacs-lisp
323 :bind (("C-M-j" . 'counsel-switch-buffer)
324 :map minibuffer-local-map
325 ("C-r" . 'counsel-minibuffer-history))
326 :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
327 :config (counsel-mode))
329 ** Remember frequent commands
330 #+begin_src emacs-lisp
331 (use-package ivy-prescient
334 (ivy-prescient-enable-filtering nil)
336 (prescient-persist-mode)
337 (ivy-prescient-mode))
340 Better search utility.
341 #+begin_src emacs-lisp
346 Use elfeed for RSS. I have another file with all the feeds in it.
347 #+begin_src emacs-lisp
349 :bind (("C-c e" . elfeed))
351 (load "~/.emacs.d/feeds.el")
352 (add-hook 'elfeed-new-entry-hook
353 (elfeed-make-tagger :feed-url "youtube\\.com"
355 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
357 (use-package elfeed-goodies
359 :config (elfeed-goodies/setup))
362 Use mu4e for reading emails.
364 I use `offlineimap` to sync my maildirs. It is slower than mbsync, but is fast enough for me, especially when ran with the =-q= option.
366 Contexts are a not very well known feature of mu4e that makes it super easy to manage multiple accounts. Much better than some of the hacky methods and external packages that I've seen.
367 #+begin_src emacs-lisp
368 (use-package smtpmail
369 :straight (:type built-in))
371 :load-path "/usr/share/emacs/site-lisp/mu4e"
372 :bind (("C-c m" . mu4e))
374 (setq user-full-name "Armaan Bhojwani"
375 smtpmail-local-domain "armaanb.net"
376 smtpmail-stream-type 'ssl
377 smtpmail-smtp-service '465
378 mu4e-change-filenames-when-moving t
379 mu4e-get-mail-command "offlineimap -q"
380 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
381 message-citation-line-function 'message-insert-formatted-citation-line
382 mu4e-completing-read-function 'ivy-completing-read
383 mu4e-confirm-quit nil
384 mail-user-agent 'mu4e-user-agent
386 `( ,(make-mu4e-context
388 :enter-func (lambda () (mu4e-message "Entering school context"))
389 :leave-func (lambda () (mu4e-message "Leaving school context"))
390 :match-func (lambda (msg)
392 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
393 :vars '((user-mail-address . "abhojwani22@nobles.edu")
394 (mu4e-sent-folder . "/school/Sent")
395 (mu4e-drafts-folder . "/school/Drafts")
396 (mu4e-trash-folder . "/school/Trash")
397 (mu4e-refile-folder . "/school/Archive")
398 (user-mail-address . "abhojwani22@nobles.edu")
399 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
400 (smtpmail-smtp-server . "smtp.gmail.com")))
403 :enter-func (lambda () (mu4e-message "Entering personal context"))
404 :leave-func (lambda () (mu4e-message "Leaving personal context"))
405 :match-func (lambda (msg)
407 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
408 :vars '((mu4e-sent-folder . "/personal/Sent")
409 (mu4e-drafts-folder . "/personal/Drafts")
410 (mu4e-trash-folder . "/personal/Trash")
411 (mu4e-refile-folder . "/personal/Archive")
412 (user-mail-address . "me@armaanb.net")
413 (smtpmail-smtp-user . "me@armaanb.net")
414 (smtpmail-smtp-server "smtp.mailbox.org")
415 (mu4e-drafts-folder . "/school/Drafts")
416 (mu4e-trash-folder . "/school/Trash")))))
417 (add-to-list 'mu4e-bookmarks
418 '(:name "Unified inbox"
419 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
421 :hook ((mu4e-compose-mode . flyspell-mode)
422 (mu4e-view-mode-hook . turn-on-visual-line-mode)))
425 #+begin_src emacs-lisp
427 (use-package calfw-org)
428 (use-package calfw-ical)
430 (defun acheam-calendar ()
433 (shell-command "vdirsyncer sync")
434 (let ((default-directory "~/.local/share/vdirsyncer/"))
435 (cfw:open-calendar-buffer
438 (cfw:ical-create-source "School" (expand-file-name "school/abhojwani22@nobles.edu.ics") "Green")
439 (cfw:ical-create-source "Personal" (expand-file-name "mailbox/Y2FsOi8vMC8zMQ.ics") "Blue")
440 (cfw:ical-create-source "Birthdays" (expand-file-name "mailbox/Y2FsOi8vMS8w.ics") "Gray")
444 Another file has more specific network configuration.
445 #+begin_src emacs-lisp
447 :config (load-file "~/.emacs.d/irc.el"))
449 (use-package circe-chanop
450 :straight (:type built-in)
453 (use-package circe-color-nicks
454 :straight (:type built-in)
458 Set EWW as default browser except for videos.
459 #+begin_src emacs-lisp
460 (defun browse-url-mpv (url &optional new-window)
462 (start-process "mpv" "*mpv*" "mpv" url))
464 (setq browse-url-handlers
466 (("youtu\\.?be" . browse-url-mpv)
467 ("." . eww-browse-url)
471 Some EWW enhancements.
472 *** Give buffer a useful name
473 #+begin_src emacs-lisp
474 ;; From https://protesilaos.com/dotemacs/
475 (defun prot-eww--rename-buffer ()
476 "Rename EWW buffer using page title or URL.
477 To be used by `eww-after-render-hook'."
478 (let ((name (if (eq "" (plist-get eww-data :title))
479 (plist-get eww-data :url)
480 (plist-get eww-data :title))))
481 (rename-buffer (format "*%s # eww*" name) t)))
483 (add-hook 'eww-after-render-hook #'prot-eww--rename-buffer)
485 *** Better entrypoint
486 #+begin_src emacs-lisp
487 ;; From https://protesilaos.com/dotemacs/
488 (defun prot-eww-browse-dwim (url &optional arg)
489 "Visit a URL, maybe from `eww-prompt-history', with completion.
491 With optional prefix ARG (\\[universal-argument]) open URL in a
494 If URL does not look like a valid link, run a web query using
497 When called from an eww buffer, provide the current link as
501 (completing-read "Query:" eww-prompt-history
502 nil nil (plist-get eww-data :url) 'eww-prompt-history)
504 (eww url (if arg 4 nil)))
506 (global-set-key (kbd "C-c w") 'prot-eww-browse-dwim)
509 Use Emacs globally. Use the Emacs daemon and bind a key in your wm to
510 =emacsclient --eval "(emacs-everywhere)"=.
511 #+begin_src emacs-lisp
512 (use-package emacs-everywhere)
517 #+begin_src emacs-lisp
518 (use-package lsp-mode
519 :commands (lsp lsp-deferred)
520 :custom (lsp-keymap-prefix "C-c l")
521 :hook ((lsp-mode . lsp-enable-which-key-integration)))
523 (use-package lsp-ivy)
526 :commands lsp-ui-mode
527 :custom (lsp-ui-doc-position 'bottom))
528 (use-package lsp-ui-flycheck
530 :straight (:type built-in))
533 Company-box adds icons.
534 #+begin_src emacs-lisp
537 :hook (lsp-mode . company-mode)
538 :bind (:map company-active-map
539 ("<tab>" . company-complete-selection))
541 ("<tab>" . company-indent-or-complete-common))
543 (company-minimum-prefix-length 1)
544 (setq company-dabbrev-downcase 0)
545 (company-idle-delay 0.0))
547 (use-package company-box
548 :hook (company-mode . company-box-mode))
552 #+begin_src emacs-lisp
553 (use-package lsp-pyright
554 :hook (python-mode . (lambda ()
555 (use-package lsp-pyright
556 :straight (:type built-in))
560 #+begin_src emacs-lisp
562 :hook (python-mode . blacken-mode)
564 (setq blacken-line-length 79))
567 (use-package ws-butler
569 (ws-butler-global-mode))
572 #+begin_src emacs-lisp
573 (use-package flycheck
575 (global-flycheck-mode))
577 ** Project management
578 #+begin_src emacs-lisp
579 (use-package projectile
580 :config (projectile-mode)
581 :custom ((projectile-completion-system 'ivy))
583 ("C-c p" . projectile-command-map)
585 (when (file-directory-p "~/Code")
586 (setq projectile-project-search-path '("~/Code")))
587 (setq projectile-switch-project-action #'projectile-dired))
589 (use-package counsel-projectile
591 :config (counsel-projectile-mode))
594 #+begin_src emacs-lisp
596 :straight (:type built-in)
597 :commands (dired dired-jump)
598 :custom ((dired-listing-switches "-agho --group-directories-first"))
600 (evil-collection-define-key 'normal 'dired-mode-map
601 "h" 'dired-single-up-directory
602 "l" 'dired-single-buffer))
604 (use-package dired-single
605 :commands (dired dired-jump))
607 (use-package dired-open
608 :commands (dired dired-jump)
610 (dired-open-extensions '(("png" . "feh")
613 (use-package dired-hide-dotfiles
614 :hook (dired-mode . dired-hide-dotfiles-mode)
616 (evil-collection-define-key 'normal 'dired-mode-map
617 "H" 'dired-hide-dotfiles-mode))
621 # TODO: Write a command that commits hunk, skipping staging step.
622 #+begin_src emacs-lisp
625 *** Colored diff in line number area
626 #+begin_src emacs-lisp
628 :straight (diff-hl :type git :host github :repo "dgutov/diff-hl")
629 :hook ((magit-pre-refresh-hook . diff-hl-magit-pre-refresh)
630 (magit-post-refresh-hook . diff-hl-magit-post-refresh))
631 :config (global-diff-hl-mode))
633 * General text editing
635 Indent after every change.
636 #+begin_src emacs-lisp
637 (use-package aggressive-indent
638 :config (global-aggressive-indent-mode))
641 Spell check in text mode, and in prog-mode comments.
642 #+begin_src emacs-lisp
643 (dolist (hook '(text-mode-hook))
644 (add-hook hook (lambda () (flyspell-mode))))
645 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
646 (add-hook hook (lambda () (flyspell-mode -1))))
647 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
649 ** Expand tabs to spaces
650 #+begin_src emacs-lisp
651 (setq-default tab-width 2)
653 ** Copy kill ring to clipboard
654 #+begin_src emacs-lisp
655 (setq x-select-enable-clipboard t)
656 (defun copy-kill-ring-to-xorg ()
657 "Copy the current kill ring to the xorg clipboard."
659 (x-select-text (current-kill 0)))
662 #+begin_src emacs-lisp
663 (use-package browse-kill-ring)
666 Opens file where you left it.
667 #+begin_src emacs-lisp
671 Distraction free writing a la junegunn/goyo.
672 #+begin_src emacs-lisp
673 (use-package olivetti
675 (evil-leader/set-key "o" 'olivetti-mode))
679 #+begin_src emacs-lisp
680 (setq abbrev-file-name "~/.emacs.d/abbrevs")
681 (setq save-abbrevs 'silent)
682 (setq-default abbrev-mode t)
685 #+begin_src emacs-lisp
686 (setq tramp-default-method "ssh")
688 ** Don't ask about following symlinks in vc
689 #+begin_src emacs-lisp
690 (setq vc-follow-symlinks t)
693 ** Easily convert splits
694 Converts splits from horizontal to vertical and vice versa. Lifted from EmacsWiki.
695 #+begin_src emacs-lisp
696 (defun toggle-window-split ()
698 (if (= (count-windows) 2)
699 (let* ((this-win-buffer (window-buffer))
700 (next-win-buffer (window-buffer (next-window)))
701 (this-win-edges (window-edges (selected-window)))
702 (next-win-edges (window-edges (next-window)))
703 (this-win-2nd (not (and (<= (car this-win-edges)
704 (car next-win-edges))
705 (<= (cadr this-win-edges)
706 (cadr next-win-edges)))))
708 (if (= (car this-win-edges)
709 (car (window-edges (next-window))))
710 'split-window-horizontally
711 'split-window-vertically)))
712 (delete-other-windows)
713 (let ((first-win (selected-window)))
715 (if this-win-2nd (other-window 1))
716 (set-window-buffer (selected-window) this-win-buffer)
717 (set-window-buffer (next-window) next-win-buffer)
718 (select-window first-win)
719 (if this-win-2nd (other-window 1))))))
721 (define-key ctl-x-4-map "t" 'toggle-window-split)
724 #+begin_src emacs-lisp
725 (defun insert-date ()
727 (insert (format-time-string "%Y-%m-%d")))
731 #+begin_src emacs-lisp
732 (use-package ace-window
733 :bind ("M-o" . ace-window))
735 ** Kill current buffer
736 Makes "C-x k" binding faster.
737 #+begin_src emacs-lisp
738 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
742 Render OpenSCAD files, and add a preview window.
744 Personal fork just merges a PR.
745 #+begin_src emacs-lisp
746 (use-package scad-mode)
747 (use-package scad-preview
748 :straight (scad-preview :type git :host github :repo "Armaanb/scad-preview"))
750 ** Control backup files
751 Stop backup files from spewing everywhere.
752 #+begin_src emacs-lisp
753 (setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
755 ** Make yes/no easier
756 #+begin_src emacs-lisp
757 (defalias 'yes-or-no-p 'y-or-n-p)
759 ** Move customize file
760 No more clogging up init.el.
761 #+begin_src emacs-lisp
762 (setq custom-file "~/.emacs.d/custom.el")
766 #+begin_src emacs-lisp
768 :commands (helpful-callable helpful-variable helpful-command helpful-key)
770 (counsel-describe-function-function #'helpful-callable)
771 (counsel-describe-variable-function #'helpful-variable)
773 ([remap describe-function] . counsel-describe-function)
774 ([remap describe-command] . helpful-command)
775 ([remap describe-variable] . counsel-describe-variable)
776 ([remap describe-key] . helpful-key))
779 #+begin_src emacs-lisp
780 (use-package epa-file
781 :straight (:type built-in)
783 (epa-file-select-keys nil)
784 (epa-file-encrypt-to '("me@armaanb.net"))
785 (password-cache-expiry (* 60 15)))
787 (use-package pinentry
788 :config (pinentry-start))
791 #+begin_src emacs-lisp
793 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
794 :custom (0x0-default-service 'envs)
795 :config (evil-leader/set-key
797 "0f" '0x0-upload-file
798 "0s" '0x0-upload-string
799 "0c" '0x0-upload-kill-ring
800 "0p" '0x0-upload-popup))
805 #+begin_src conf :tangle ~/.spectrwm.conf
810 autorun = ws[1]:/home/armaa/Code/scripts/autostart
813 #+begin_src conf :tangle ~/.spectrwm.conf
814 color_focus = rgb:ff/ff/ff
815 color_focus_maximized = rgb:ee/cc/00
816 color_unfocus = rgb:55/55/55
819 #+begin_src conf :tangle ~/.spectrwm.conf
821 bar_font = xos4 Fira Code:pixelsize=14:antialias=true # any installed font
825 #+begin_src conf :tangle ~/.spectrwm.conf
826 program[lock] = i3lock -c 000000 -ef
827 program[term] = alacritty
828 program[screenshot_all] = flameshot gui
829 program[menu] = rofi -show run # `rofi-dmenu` handles the rest
830 program[switcher] = rofi -show window
831 program[notif] = /home/armaa/Code/scripts/setter status
834 bind[switcher] = MOD+Tab
837 #+begin_src conf :tangle ~/.spectrwm.conf
838 program[paup] = /home/armaa/Code/scripts/setter audio +5
839 program[padown] = /home/armaa/Code/scripts/setter audio -5
840 program[pamute] = /home/armaa/Code/scripts/setter audio
841 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
842 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
843 program[next] = playerctl next
844 program[prev] = playerctl previous
845 program[pause] = playerctl play-pause
847 bind[padown] = XF86AudioLowerVolume
848 bind[paup] = XF86AudioRaiseVolume
849 bind[pamute] = XF86AudioMute
850 bind[brigdown] = XF86MonBrightnessDown
851 bind[brigup] = XF86MonBrightnessUp
852 bind[pause] = XF86AudioPlay
853 bind[next] = XF86AudioNext
854 bind[prev] = XF86AudioPrev
857 #+begin_src conf :tangle ~/.spectrwm.conf
858 program[h] = xdotool keyup h key --clearmodifiers Left
859 program[j] = xdotool keyup j key --clearmodifiers Down
860 program[k] = xdotool keyup k key --clearmodifiers Up
861 program[l] = xdotool keyup l key --clearmodifiers Right
863 bind[h] = Mod1 + Tab + h
864 bind[j] = Mod1 + Tab + j
865 bind[k] = Mod1 + Tab + k
866 bind[l] = Mod1 + Tab + l
869 #+begin_src conf :tangle ~/.spectrwm.conf
870 program[aerc] = alacritty -e aerc
871 program[weechat] = alacritty --hold -e sh -c "while : ; do ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat; sleep 2; done"
872 program[emacs] = emacsclient -c
873 program[emacs-anywhere] = emacsclient --eval "(emacs-everywhere)"
874 program[firefox] = firefox
875 program[thunderbird] = thunderbird
876 program[slack] = slack
878 bind[aerc] = MOD+Control+1
879 bind[weechat] = MOD+Control+2
880 bind[emacs-anywhere] = MOD+Control+3
881 bind[firefox] = MOD+Control+4
882 bind[thunderbird] = MOD+Control+5
883 bind[slack] = MOD+Control+6
884 bind[emacs] = MOD+Control+Return
889 #+begin_src shell :tangle ~/.config/zsh/zshrc
890 autoload -Uz compinit
894 unsetopt glob_complete
897 #+begin_src shell :tangle ~/.config/zsh/zshrc
901 bindkey -M vicmd "^[[3~" delete-char
902 bindkey "^[[3~" delete-char
904 autoload edit-command-line
905 zle -N edit-command-line
906 bindkey -M vicmd ^e edit-command-line
907 bindkey ^e edit-command-line
910 #+begin_src shell :tangle ~/.config/zsh/zshrc
911 setopt extended_history
913 setopt inc_append_history
914 setopt hist_ignore_dups
915 setopt hist_reduce_blanks
919 HISTFILE=~/.local/share/zsh/history
922 I manage plugins using my own plugin manager, ZPE. https://git.sr.ht/~armaan/zpe
924 #+begin_src plain :tangle ~/.config/zpe/repositories
925 https://github.com/Aloxaf/fzf-tab
926 https://github.com/zdharma/fast-syntax-highlighting
927 https://github.com/rupa/z
930 #+begin_src shell :tangle ~/.config/zsh/zshrc
931 source ~/Code/zpe/zpe.sh
932 source ~/Code/admone/admone.zsh
933 source ~/.config/zsh/fzf-bindings.zsh
935 zpe-source fzf-tab/fzf-tab.zsh
936 zstyle ':completion:*:descriptions' format '[%d]'
937 zstyle ':fzf-tab:complete:cd:*' fzf-preview 'exa -1 --color=always $realpath'
938 zstyle ':completion:*' completer _complete
939 zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \
940 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
942 zpe-source fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
943 export _Z_DATA="/home/armaa/.local/share/z"
947 **** Alert after long command
948 #+begin_src shell :tangle ~/.config/zsh/zshrc
950 notify-send --urgency=low -i ${(%):-%(?.terminal.error)} \
951 ${history[$HISTCMD]%[;&|][[:space:]]##alert}
954 **** Time Zsh startup
955 #+begin_src shell :tangle ~/.config/zsh/zshrc
957 for i in $(seq 1 10); do
958 time "zsh" -i -c exit;
962 **** Update all packages
963 #+begin_src shell :tangle ~/.config/zsh/zshrc
964 color=$(tput setaf 5)
968 sudo echo "${color}== upgrading with yay ==${reset}"
971 echo "${color}== checking for pacnew files ==${reset}"
974 echo "${color}== upgrading flatpaks ==${reset}"
977 echo "${color}== upgrading zsh plugins ==${reset}"
980 echo "${color}== updating nvim plugins ==${reset}"
981 nvim +PlugUpdate +PlugUpgrade +qall
982 echo "Updated nvim plugins"
984 echo "${color}You are entirely up to date!${reset}"
987 **** Clean all packages
988 #+begin_src shell :tangle ~/.config/zsh/zshrc
990 sudo echo "${color}== cleaning pacman orphans ==${reset}"
991 (pacman -Qtdq | sudo pacman -Rns - 2> /dev/null) || echo "No orphans"
993 echo "${color}== cleaning flatpaks ==${reset}"
994 flatpak remove --unused
996 echo "${color}== cleaning zsh plugins ==${reset}"
999 echo "${color}== cleaning nvim plugins ==${reset}"
1000 nvim +PlugClean +qall
1001 echo "Cleaned nvim plugins"
1003 echo "${color}All orphans cleaned!${reset}"
1007 #+begin_src shell :tangle ~/.config/zsh/zshrc
1010 exa -lh --icons --git --group-directories-first
1014 #+begin_src shell :tangle ~/.config/zsh/zshrc
1016 __conda_setup="$('/opt/anaconda/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
1017 if [ $? -eq 0 ]; then
1018 eval "$__conda_setup"
1020 if [ -f "/opt/anaconda/etc/profile.d/conda.sh" ]; then
1021 . "/opt/anaconda/etc/profile.d/conda.sh"
1023 export PATH="/opt/anaconda/bin:$PATH"
1029 **** Interact with 0x0
1030 #+begin_src shell :tangle ~/.config/zsh/zshrc
1031 zxz="https://envs.sh"
1032 0file() { curl -F"file=@$1" "$zxz" ; }
1033 0pb() { curl -F"file=@-;" "$zxz" ; }
1034 0url() { curl -F"url=$1" "$zxz" ; }
1035 0short() { curl -F"shorten=$1" "$zxz" ; }
1036 0clip() { xclip -out | curl -F"file=@-;" "$zxz" ; }
1039 #+begin_src shell :tangle ~/.config/zsh/zshrc
1048 #+begin_src shell :tangle ~/.config/zsh/zshrc
1049 alias bhoji-drop='ssh -p 23 root@armaanb.net'
1050 alias weechat='ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat'
1051 alias tcf='ssh root@204.48.23.68'
1052 alias ngmun='ssh root@157.245.89.25'
1053 alias prox='ssh root@192.168.1.224'
1054 alias dock='ssh root@192.168.1.225'
1055 alias jenkins='ssh root@192.168.1.226'
1056 alias envs='ssh acheam@envs.net'
1058 **** File management
1059 #+begin_src shell :tangle ~/.config/zsh/zshrc
1060 alias ls='exa -lh --icons --git --group-directories-first'
1061 alias la='exa -lha --icons --git --group-directories-first'
1062 alias df='df -h / /boot'
1064 alias free='free -h'
1069 alias grep='grep -in --exclude-dir=.git --color=auto'
1070 alias mkdir='mkdir -pv'
1071 alias unar='atool -x'
1072 alias wget='wget -e robots=off'
1073 alias lanex='~/.local/share/lxc/lxc'
1076 #+begin_src shell :tangle ~/.config/zsh/zshrc
1077 alias padm='yadm --yadm-repo ~/Code/dotfiles/repo.git'
1078 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1080 alias padu='padm add -u && padm commit && padm push && yadu'
1083 #+begin_src shell :tangle ~/.config/zsh/zshrc
1086 alias vw="nvim ~/Documents/vimwiki/index.md"
1088 **** System management
1089 #+begin_src shell :tangle ~/.config/zsh/zshrc
1090 alias jctl='journalctl -p 3 -xb'
1091 alias pkill='pkill -i'
1093 alias please='sudo $(fc -ln -1)'
1094 alias sudo='sudo ' # allows aliases to be run with sudo
1097 #+begin_src shell :tangle ~/.config/zsh/zshrc
1098 alias ping='ping -c 10'
1099 alias speed='speedtest-cli'
1100 alias ip='ip --color=auto'
1101 alias cip='curl https://armaanb.net/ip'
1102 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1103 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1106 #+begin_src shell :tangle ~/.config/zsh/zshrc
1107 alias dc='docker-compose'
1108 alias dcdu='docker-compose down && docker-compose up -d'
1111 #+begin_src shell :tangle ~/.config/zsh/zshrc
1112 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1113 iflag=fullblock status=progress'
1114 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1115 iflag=fullblock status=progress'
1116 alias ts='gen-shell -c task'
1117 alias ts='gen-shell -c task'
1118 alias tetris='autoload -Uz tetriscurses && tetriscurses'
1119 alias news='newsboat'
1120 alias tilderadio="\mpv https://radio.tildeverse.org/radio/8000/radio.ogg"
1121 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1122 --restrict-filenames -o '%(title)s.%(ext)s'"
1123 alias cal="cal -3 --color=auto"
1125 **** Virtual machines, chroots
1126 #+begin_src shell :tangle ~/.config/zsh/zshrc
1127 alias ckiss="sudo chrooter ~/Virtual/kiss"
1128 alias cdebian="sudo chrooter ~/Virtual/debian bash"
1129 alias cwindows='devour qemu-system-x86_64 \
1134 -device VGA,vgamem_mb=64 \
1136 -device hda-duplex \
1138 -net user,smb=/home/armaa/Public \
1139 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1142 #+begin_src shell :tangle ~/.config/zsh/zshrc
1144 alias zpy="zconda && ipython"
1145 alias math="ipython --profile=math"
1146 alias pypi="python setup.py sdist && twine upload dist/*"
1147 alias pip="python -m pip"
1148 alias black="black -l 79"
1151 #+begin_src shell :tangle ~/.config/zsh/zshrc
1152 alias words='gen-shell -c "words"'
1153 alias words-e='gen-shell -c "words ~E"'
1156 #+begin_src shell :tangle ~/.config/zsh/zshrc
1157 alias zathura='devour zathura'
1158 alias mpv='devour mpv'
1159 alias sql='devour sqlitebrowser'
1160 alias cad='devour openscad'
1161 alias feh='devour feh'
1163 **** Package management (Pacman)
1164 #+begin_src shell :tangle ~/.config/zsh/zshrc
1166 alias api='yay -Syu'
1167 alias apii='sudo pacman -S'
1168 alias app='yay -Rns'
1170 alias apo='yay -Qttd'
1171 alias azf='pacman -Q | fzf'
1172 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1173 alias ufetch='ufetch-arch'
1174 alias reflect='reflector --verbose --sort rate --save \
1175 ~/.local/etc/pacman.d/mirrorlist --download-timeout 60' # Takes ~45m to run
1178 #+begin_src shell :tangle ~/.config/zsh/zshrc
1179 export EDITOR="emacsclient -c"
1180 export VISUAL="$EDITOR"
1181 export TERM=xterm-256color # for compatability
1183 export GPG_TTY="$(tty)"
1184 export MANPAGER='nvim +Man!'
1187 export GTK_USE_PORTAL=1
1189 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
1190 export PATH="$PATH:/home/armaa/Code/scripts"
1191 export PATH="$PATH:/home/armaa/.cargo/bin"
1192 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
1193 export PATH="$PATH:/usr/sbin"
1194 export PATH="$PATH:/opt/FreeTube/freetube"
1196 export LC_ALL="en_US.UTF-8"
1197 export LC_CTYPE="en_US.UTF-8"
1198 export LANGUAGE="en_US.UTF-8"
1200 export KISS_PATH="/home/armaa/kiss/home/armaa/kiss-repo"
1201 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
1202 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
1203 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
1204 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
1205 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
1209 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1212 family: JetBrains Mono Nerd Font
1219 ligatures: true # Requires ligature patch
1226 background_opacity: 1
1229 Send <RET> + modifier through
1230 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1244 Modus vivendi. Source: https://github.com/ishan9299/Nixos/blob/d4bbb7536be95b59466bb9cca4d671be46e04e81/user/alacritty/alacritty.yml#L30-L118
1245 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1249 background: '#000000'
1250 foreground: '#ffffff'
1254 background: '#ffffff'
1256 # Normal colors (except green it is from intense colors)
1267 # Bright colors [all the faint colors in the modus theme]
1278 # dim [all the intense colors in modus theme]
1291 Symlink profile_default/ipython_config.py to profile_math/ipython_config.py
1292 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1293 c.TerminalInteractiveShell.editing_mode = 'vi'
1294 c.InteractiveShell.colors = 'linux'
1295 c.TerminalInteractiveShell.confirm_exit = False
1298 #+begin_src python :tangle ~/.ipython/profile_math/startup.py
1302 return x * (180 / pi)
1305 return x * (pi / 180)
1308 return (x * (pi / 180)) / unit
1320 Make MPV play a little bit smoother.
1321 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1322 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1326 For any GNU Readline programs
1327 #+begin_src plain :tangle ~/.inputrc
1332 #+begin_src conf :tangle ~/.gitconfig
1334 name = Armaan Bhojwani
1335 email = me@armaanb.net
1336 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1339 #+begin_src conf :tangle ~/.gitconfig
1341 defaultBranch = main
1344 #+begin_src conf :tangle ~/.gitconfig
1349 #+begin_src conf :tangle ~/.gitconfig
1351 smtpserver = smtp.mailbox.org
1352 smtpuser = me@armaanb.net
1353 smtpencryption = ssl
1354 smtpserverport = 465
1358 #+begin_src conf :tangle ~/.gitconfig
1363 #+begin_src conf :tangle ~/.gitconfig
1366 sclone = clone --depth 1
1372 subup = submodule update --remote
1373 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1374 mirror = git config --global alias.mirrormirror
1377 #+begin_src conf :tangle ~/.gitconfig
1382 Lightweight notification daemon.
1384 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1386 font = "JetBrains Mono Medium Nerd Font 11"
1388 format = "<b>%s</b>\n%b"
1390 indicate_hidden = yes
1393 show_age_threshold = 60
1396 geometry = "400x5-10+10"
1398 idle_threshold = 120
1400 sticky_history = yes
1402 separator_height = 4
1404 horizontal_padding = 8
1406 separator_color = "#ffffff"
1407 startup_notification = false
1410 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1417 close_all = mod4+shift+c
1418 history = mod4+ctrl+c
1421 background = "#222222"
1422 foreground = "#ffffff"
1423 highlight = "#ffffff"
1427 background = "#222222"
1428 foreground = "#ffffff"
1429 highlight = "#ffffff"
1433 background = "#222222"
1434 foreground = "#a60000"
1435 highlight = "#ffffff"
1439 Modus vivendi theme that extends DarkBlue.
1440 #+begin_src plain :tangle ~/.config/rofi/config.rasi
1441 @import "/usr/share/rofi/themes/DarkBlue.rasi"
1443 white: rgba ( 255, 255, 255, 100 % );
1445 selected-normal-background: @white;
1446 separatorcolor: @white;
1447 background: rgba ( 34, 34, 34, 100 % );
1456 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1458 map <A-b> toggle_statusbar
1459 set selection-clipboard clipboard
1462 set window-title-basename "true"
1463 set selection-clipboard "clipboard"
1466 #+begin_src plain :tangle ~/.config/zathura/zathurarc
1467 set default-bg "#000000"
1468 set default-fg "#ffffff"
1469 set render-loading true
1470 set render-loading-bg "#000000"
1471 set render-loading-fg "#ffffff"
1473 set recolor-lightcolor "#000000" # bg
1474 set recolor-darkcolor "#ffffff" # fg