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 Show a ruler at a certain number of chars depending on mode.
134 #+begin_src emacs-lisp
135 (global-display-fill-column-indicator-mode)
138 Whenever starting a key chord, show possible future steps.
139 #+begin_src emacs-lisp
140 (use-package which-key
141 :config (which-key-mode)
142 :custom (which-key-idle-delay 0.3))
144 ** Visual highlights of changes
145 Highlight when changes are made.
146 #+begin_src emacs-lisp
147 (use-package evil-goggles
148 :config (evil-goggles-mode)
149 (evil-goggles-use-diff-faces))
151 ** Highlight TODOs in comments
152 #+begin_src emacs-lisp
154 :straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
155 :config (global-hl-todo-mode 1))
158 #+begin_src emacs-lisp
162 Soft wrap words and do operations by visual lines.
163 #+begin_src emacs-lisp
164 (add-hook 'text-mode-hook 'turn-on-visual-line-mode)
166 ** Display number of matches in search
167 #+begin_src emacs-lisp
169 :config (global-anzu-mode))
172 Inverts modeline instead of audible bell or the standard visual bell.
173 #+begin_src emacs-lisp
174 (setq visible-bell nil
175 ring-bell-function 'flash-mode-line)
176 (defun flash-mode-line ()
177 (invert-face 'mode-line)
178 (run-with-timer 0.1 nil #'invert-face 'mode-line))
182 #+begin_src emacs-lisp
184 :custom (select-enable-clipboard nil)
187 (fset 'evil-visual-update-x-selection 'ignore) ;; Keep clipboard and register seperate
188 ;; Use visual line motions even outside of visual-line-mode buffers
189 (evil-global-set-key 'motion "j" 'evil-next-visual-line)
190 (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
191 (global-set-key (kbd "<escape>") 'keyboard-escape-quit))
194 #+begin_src emacs-lisp
195 (use-package evil-collection
197 :init (evil-collection-init)
198 :custom (evil-collection-setup-minibuffer t))
202 #+begin_src emacs-lisp
203 (use-package evil-surround
204 :config (global-evil-surround-mode))
207 #+begin_src emacs-lisp
208 (use-package evil-leader
209 :straight (evil-leader :type git :host github :repo "cofi/evil-leader")
211 (evil-leader/set-leader "<SPC>")
212 (global-evil-leader-mode))
215 #+begin_src emacs-lisp
217 (use-package evil-nerd-commenter
218 :bind (:map evil-normal-state-map
219 ("gc" . evilnc-comment-or-uncomment-lines))
220 :custom (evilnc-invert-comment-line-by-line nil))
223 Fix the oopsies! Maybe replace with undo-fu or Emacs 28 built in undo-redo.
224 #+begin_src emacs-lisp
225 (use-package undo-tree
227 (undo-tree-auto-save-history t)
228 (undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo-tree")))
230 (global-undo-tree-mode)
231 (evil-set-undo-system 'undo-tree))
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)
270 (org-ellipsis " â–¾")
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")))
300 Simple, but not too simple autocompletion.
301 #+begin_src emacs-lisp
303 :bind (("C-s" . swiper)
304 :map ivy-minibuffer-map
305 ("TAB" . ivy-alt-done)
306 :map ivy-switch-buffer-map
307 ("M-d" . ivy-switch-buffer-kill))
311 #+begin_src emacs-lisp
312 (use-package ivy-rich
314 :config (ivy-rich-mode))
318 #+begin_src emacs-lisp
320 :bind (("C-M-j" . 'counsel-switch-buffer)
321 :map minibuffer-local-map
322 ("C-r" . 'counsel-minibuffer-history))
323 :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
324 :config (counsel-mode))
326 ** Remember frequent commands
327 #+begin_src emacs-lisp
328 (use-package ivy-prescient
331 (ivy-prescient-enable-filtering nil)
333 (prescient-persist-mode)
334 (ivy-prescient-mode))
337 Better search utility.
338 #+begin_src emacs-lisp
343 Use elfeed for RSS. I have another file with all the feeds in it.
344 #+begin_src emacs-lisp
346 :bind (("C-c e" . elfeed))
348 (load "~/.emacs.d/feeds.el")
349 (add-hook 'elfeed-new-entry-hook
350 (elfeed-make-tagger :feed-url "youtube\\.com"
352 :bind (:map elfeed-search-mode-map ("C-c C-o" . 'elfeed-show-visit)))
354 (use-package elfeed-goodies
356 :config (elfeed-goodies/setup))
359 Use mu4e for reading emails.
361 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.
363 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.
364 #+begin_src emacs-lisp
365 (use-package smtpmail
366 :straight (:type built-in))
368 :load-path "/usr/share/emacs/site-lisp/mu4e"
369 :bind (("C-c m" . mu4e))
371 (setq user-full-name "Armaan Bhojwani"
372 smtpmail-local-domain "armaanb.net"
373 smtpmail-stream-type 'ssl
374 smtpmail-smtp-service '465
375 mu4e-change-filenames-when-moving t
376 message-kill-buffer-on-exit t
377 mu4e-get-mail-command "offlineimap -q"
378 message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n"
379 message-citation-line-function 'message-insert-formatted-citation-line
380 mu4e-context-policy "pick-first"
382 `( ,(make-mu4e-context
384 :enter-func (lambda () (mu4e-message "Entering school context"))
385 :leave-func (lambda () (mu4e-message "Leaving school context"))
386 :match-func (lambda (msg)
388 (string-match-p "^/school" (mu4e-message-field msg :maildir))))
389 :vars '( (user-mail-address . "abhojwani22@nobles.edu")
390 (mu4e-sent-folder . "/school/Sent")
391 (mu4e-drafts-folder . "/school/Drafts")
392 (mu4e-trash-folder . "/school/Trash")
393 (mu4e-refile-folder . "/school/Archive")
394 (user-mail-address . "abhojwani22@nobles.edu")
395 (smtpmail-smtp-user . "abhojwani22@nobles.edu")
396 (smtpmail-smtp-server . "smtp.gmail.com")))
399 :enter-func (lambda () (mu4e-message "Entering personal context"))
400 :leave-func (lambda () (mu4e-message "Leaving personal context"))
401 :match-func (lambda (msg)
403 (string-match-p "^/personal" (mu4e-message-field msg :maildir))))
405 (mu4e-sent-folder . "/personal/Sent")
406 (mu4e-drafts-folder . "/personal/Drafts")
407 (mu4e-trash-folder . "/personal/Trash")
408 (mu4e-refile-folder . "/personal/Archive")
409 (user-mail-address . "me@armaanb.net")
410 (smtpmail-smtp-user . "me@armaanb.net")
411 (smtpmail-smtp-server "smtp.mailbox.org")
412 (mu4e-drafts-folder . "/school/Drafts")
413 (mu4e-trash-folder . "/school/Trash")))))
414 (add-to-list 'mu4e-bookmarks
415 '(:name "Unified inbox"
416 :query "maildir:\"/personal/INBOX\" or maildir:\"/school/INBOX\""
420 #+begin_src emacs-lisp
422 (use-package calfw-org)
423 (use-package calfw-ical)
425 (defun acheam-calendar ()
428 (shell-command "vdirsyncer sync")
429 (let ((default-directory "~/.local/share/vdirsyncer/"))
430 (cfw:open-calendar-buffer
433 (cfw:ical-create-source "School" (expand-file-name "school/abhojwani22@nobles.edu.ics") "Green")
434 (cfw:ical-create-source "Personal" (expand-file-name "mailbox/Y2FsOi8vMC8zMQ.ics") "Blue")
435 (cfw:ical-create-source "Birthdays" (expand-file-name "mailbox/Y2FsOi8vMS8w.ics") "Gray")
439 Another file has more specific network configuration.
440 #+begin_src emacs-lisp
442 :config (load-file "~/.emacs.d/irc.el"))
444 (use-package circe-chanop
445 :straight (:type built-in)
448 (use-package circe-color-nicks
449 :straight (:type built-in)
453 Set EWW as default browser except for videos.
454 #+begin_src emacs-lisp
455 (defun browse-url-mpv (url &optional new-window)
457 (start-process "mpv" "*mpv*" "mpv" url))
459 (setq browse-url-handlers
461 (("youtu\\.?be" . browse-url-mpv)
462 ("." . eww-browse-url)
466 Some EWW enhancements.
467 *** Give buffer a useful name
468 #+begin_src emacs-lisp
469 ;; From https://protesilaos.com/dotemacs/
470 (defun prot-eww--rename-buffer ()
471 "Rename EWW buffer using page title or URL.
472 To be used by `eww-after-render-hook'."
473 (let ((name (if (eq "" (plist-get eww-data :title))
474 (plist-get eww-data :url)
475 (plist-get eww-data :title))))
476 (rename-buffer (format "*%s # eww*" name) t)))
478 (add-hook 'eww-after-render-hook #'prot-eww--rename-buffer)
480 *** Better entrypoint
481 #+begin_src emacs-lisp
482 ;; From https://protesilaos.com/dotemacs/
483 (defun prot-eww-browse-dwim (url &optional arg)
484 "Visit a URL, maybe from `eww-prompt-history', with completion.
486 With optional prefix ARG (\\[universal-argument]) open URL in a
489 If URL does not look like a valid link, run a web query using
492 When called from an eww buffer, provide the current link as
496 (completing-read "Query:" eww-prompt-history
497 nil nil (plist-get eww-data :url) 'eww-prompt-history)
499 (eww url (if arg 4 nil)))
501 (global-set-key (kbd "C-c w") 'prot-eww-browse-dwim)
504 Use Emacs globally. Use the Emacs daemon and bind a key in your wm to
505 "emacsclient --eval "(emacs-everywhere)".
506 #+begin_src emacs-lisp
507 (use-package emacs-everywhere)
512 #+begin_src emacs-lisp
513 (use-package lsp-mode
514 :commands (lsp lsp-deferred)
515 :custom (lsp-keymap-prefix "C-c l")
516 :hook ((lsp-mode . lsp-enable-which-key-integration)))
518 (use-package lsp-ivy)
521 :commands lsp-ui-mode
522 :custom (lsp-ui-doc-position 'bottom))
523 (use-package lsp-ui-flycheck
525 :straight (:type built-in))
528 Company-box adds icons.
529 #+begin_src emacs-lisp
532 :hook (lsp-mode . company-mode)
533 :bind (:map company-active-map
534 ("<tab>" . company-complete-selection))
536 ("<tab>" . company-indent-or-complete-common))
538 (company-minimum-prefix-length 1)
539 (setq company-dabbrev-downcase 0)
540 (company-idle-delay 0.0))
542 (use-package company-box
543 :hook (company-mode . company-box-mode))
547 #+begin_src emacs-lisp
548 (use-package lsp-pyright
549 :hook (python-mode . (lambda ()
550 (use-package lsp-pyright
551 :straight (:type built-in))
555 #+begin_src emacs-lisp
557 :hook (python-mode . blacken-mode)
559 (setq blacken-line-length 79))
562 (use-package ws-butler
564 (ws-butler-global-mode))
567 #+begin_src emacs-lisp
568 (use-package flycheck
570 (global-flycheck-mode))
572 ** Project management
573 #+begin_src emacs-lisp
574 (use-package projectile
575 :config (projectile-mode)
576 :custom ((projectile-completion-system 'ivy))
578 ("C-c p" . projectile-command-map)
580 (when (file-directory-p "~/Code")
581 (setq projectile-project-search-path '("~/Code")))
582 (setq projectile-switch-project-action #'projectile-dired))
584 (use-package counsel-projectile
586 :config (counsel-projectile-mode))
589 #+begin_src emacs-lisp
591 :straight (:type built-in)
592 :commands (dired dired-jump)
593 :custom ((dired-listing-switches "-agho --group-directories-first"))
595 (evil-collection-define-key 'normal 'dired-mode-map
596 "h" 'dired-single-up-directory
597 "l" 'dired-single-buffer))
599 (use-package dired-single
600 :commands (dired dired-jump))
602 (use-package dired-open
603 :commands (dired dired-jump)
605 (dired-open-extensions '(("png" . "feh")
608 (use-package dired-hide-dotfiles
609 :hook (dired-mode . dired-hide-dotfiles-mode)
611 (evil-collection-define-key 'normal 'dired-mode-map
612 "H" 'dired-hide-dotfiles-mode))
616 # TODO: Write a command that commits hunk, skipping staging step.
617 #+begin_src emacs-lisp
619 :hook (magit-mode-hook. pinentry-start))
621 *** Colored diff in line number area
622 #+begin_src emacs-lisp
624 :straight (diff-hl :type git :host github :repo "dgutov/diff-hl")
625 :hook ((magit-pre-refresh-hook . diff-hl-magit-pre-refresh)
626 (magit-post-refresh-hook . diff-hl-magit-post-refresh))
627 :config (global-diff-hl-mode))
629 * General text editing
631 Indent after every change.
632 #+begin_src emacs-lisp
633 (use-package aggressive-indent
634 :config (global-aggressive-indent-mode))
637 Spell check in text mode, and in prog-mode comments.
638 #+begin_src emacs-lisp
639 (dolist (hook '(text-mode-hook))
640 (add-hook hook (lambda () (flyspell-mode))))
641 (dolist (hook '(change-log-mode-hook log-edit-mode-hook))
642 (add-hook hook (lambda () (flyspell-mode -1))))
643 (add-hook 'prog-mode (lambda () (flyspell-prog mode)))
645 ** Expand tabs to spaces
646 #+begin_src emacs-lisp
647 (setq-default tab-width 2)
649 ** Copy kill ring to clipboard
650 #+begin_src emacs-lisp
651 (setq x-select-enable-clipboard t)
652 (defun copy-kill-ring-to-xorg ()
653 "Copy the current kill ring to the xorg clipboard."
655 (x-select-text (current-kill 0)))
658 #+begin_src emacs-lisp
659 (use-package browse-kill-ring)
662 Opens file where you left it.
663 #+begin_src emacs-lisp
667 Distraction free writing a la junegunn/goyo.
668 #+begin_src emacs-lisp
669 (use-package olivetti
671 (evil-leader/set-key "o" 'olivetti-mode))
675 #+begin_src emacs-lisp
676 (setq abbrev-file-name "~/.emacs.d/abbrevs")
677 (setq save-abbrevs 'silent)
678 (setq-default abbrev-mode t)
681 ** Easily convert splits
682 Converts splits from horizontal to vertical and vice versa. Lifted from EmacsWiki.
683 #+begin_src emacs-lisp
684 (defun toggle-window-split ()
686 (if (= (count-windows) 2)
687 (let* ((this-win-buffer (window-buffer))
688 (next-win-buffer (window-buffer (next-window)))
689 (this-win-edges (window-edges (selected-window)))
690 (next-win-edges (window-edges (next-window)))
691 (this-win-2nd (not (and (<= (car this-win-edges)
692 (car next-win-edges))
693 (<= (cadr this-win-edges)
694 (cadr next-win-edges)))))
696 (if (= (car this-win-edges)
697 (car (window-edges (next-window))))
698 'split-window-horizontally
699 'split-window-vertically)))
700 (delete-other-windows)
701 (let ((first-win (selected-window)))
703 (if this-win-2nd (other-window 1))
704 (set-window-buffer (selected-window) this-win-buffer)
705 (set-window-buffer (next-window) next-win-buffer)
706 (select-window first-win)
707 (if this-win-2nd (other-window 1))))))
709 (define-key ctl-x-4-map "t" 'toggle-window-split)
712 #+begin_src emacs-lisp
713 (defun insert-date ()
715 (insert (format-time-string "%Y-%m-%d")))
719 #+begin_src emacs-lisp
720 (use-package ace-window
721 :bind ("M-o" . ace-window))
723 ** Kill current buffer
724 Makes "C-x k" binding faster.
725 #+begin_src emacs-lisp
726 (substitute-key-definition 'kill-buffer 'kill-buffer-and-window global-map)
730 Render OpenSCAD files, and add a preview window.
732 Personal fork just merges a PR.
733 #+begin_src emacs-lisp
734 (use-package scad-mode)
735 (use-package scad-preview
736 :straight (scad-preview :type git :host github :repo "Armaanb/scad-preview"))
738 ** Control backup files
739 Stop backup files from spewing everywhere.
740 #+begin_src emacs-lisp
741 (setq backup-directory-alist `(("." . "~/.emacs.d/backups")))
743 ** Make yes/no easier
744 #+begin_src emacs-lisp
745 (defalias 'yes-or-no-p 'y-or-n-p)
747 ** Move customize file
748 No more clogging up init.el.
749 #+begin_src emacs-lisp
750 (setq custom-file "~/.emacs.d/custom.el")
754 #+begin_src emacs-lisp
756 :commands (helpful-callable helpful-variable helpful-command helpful-key)
758 (counsel-describe-function-function #'helpful-callable)
759 (counsel-describe-variable-function #'helpful-variable)
761 ([remap describe-function] . counsel-describe-function)
762 ([remap describe-command] . helpful-command)
763 ([remap describe-variable] . counsel-describe-variable)
764 ([remap describe-key] . helpful-key))
767 #+begin_src emacs-lisp
768 (use-package epa-file
769 :straight (:type built-in))
770 (setq epa-file-select-keys nil
771 epa-file-encrypt-to '("me@armaanb.net")
772 password-cache-expiry (* 60 15))
774 (use-package pinentry)
777 #+begin_src emacs-lisp
779 :straight (0x0 :type git :repo "https://git.sr.ht/~zge/nullpointer-emacs")
780 :custom (0x0-default-service 'envs)
781 :config (evil-leader/set-key
783 "0f" '0x0-upload-file
784 "0s" '0x0-upload-string
785 "0c" '0x0-upload-kill-ring
786 "0p" '0x0-upload-popup))
791 #+begin_src conf :tangle ~/.spectrwm.conf
797 autorun = ws[1]:/home/armaa/Code/scripts/autostart
801 #+begin_src conf :tangle ~/.spectrwm.conf
802 color_focus = rgb:83/a5/98
803 color_focus_maximized = rgb:d6/5d/0e
804 color_unfocus = rgb:58/58/58
807 #+begin_src conf :tangle ~/.spectrwm.conf
809 bar_font = xos4 Fira Code:pixelsize=14:antialias=true # any installed font
813 #+begin_src conf :tangle ~/.spectrwm.conf
814 program[lock] = i3lock -c 000000 -ef
815 program[term] = alacritty
816 program[screenshot_all] = flameshot gui
817 program[menu] = rofi -show run # `rofi-dmenu` handles the rest
818 program[switcher] = rofi -show window
819 program[notif] = /home/armaa/Code/scripts/setter status
822 bind[switcher] = MOD+Tab
825 #+begin_src conf :tangle ~/.spectrwm.conf
826 program[paup] = /home/armaa/Code/scripts/setter audio +5
827 program[padown] = /home/armaa/Code/scripts/setter audio -5
828 program[pamute] = /home/armaa/Code/scripts/setter audio
829 program[brigup] = /home/armaa/Code/scripts/setter brightness +10%
830 program[brigdown] = /home/armaa/Code/scripts/setter brightness 10%-
831 program[next] = playerctl next
832 program[prev] = playerctl previous
833 program[pause] = playerctl play-pause
835 bind[padown] = XF86AudioLowerVolume
836 bind[paup] = XF86AudioRaiseVolume
837 bind[pamute] = XF86AudioMute
838 bind[brigdown] = XF86MonBrightnessDown
839 bind[brigup] = XF86MonBrightnessUp
840 bind[pause] = XF86AudioPlay
841 bind[next] = XF86AudioNext
842 bind[prev] = XF86AudioPrev
845 #+begin_src conf :tangle ~/.spectrwm.conf
846 program[h] = xdotool keyup h key --clearmodifiers Left
847 program[j] = xdotool keyup j key --clearmodifiers Down
848 program[k] = xdotool keyup k key --clearmodifiers Up
849 program[l] = xdotool keyup l key --clearmodifiers Right
851 bind[h] = MOD + Control + h
852 bind[j] = MOD + Control + j
853 bind[k] = MOD + Control + k
854 bind[l] = MOD + Control + l
857 #+begin_src conf :tangle ~/.spectrwm.conf
858 program[aerc] = alacritty -e aerc
859 program[weechat] = alacritty --hold -e sh -c "while : ; do ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat; sleep 2; done"
860 program[emacs] = emacsclient -c
861 program[emacs-anywhere] = emacsclient --eval "(emacs-everywhere)"
862 program[firefox] = firefox
863 program[thunderbird] = thunderbird
864 program[slack] = slack
866 bind[aerc] = MOD+Control+s
867 bind[weechat] = MOD+Control+d
868 bind[emacs] = MOD+Control+f
869 bind[emacs-anywhere] = MOD+f
870 bind[firefox] = MOD+Control+u
871 bind[thunderbird] = MOD+Control+i
872 bind[slack] = MOD+Control+o
877 #+begin_src shell :tangle ~/.config/zsh/zshrc
878 autoload -Uz compinit
882 unsetopt glob_complete
885 #+begin_src shell :tangle ~/.config/zsh/zshrc
889 bindkey -M vicmd "^[[3~" delete-char
890 bindkey "^[[3~" delete-char
892 autoload edit-command-line
893 zle -N edit-command-line
894 bindkey -M vicmd ^e edit-command-line
895 bindkey ^e edit-command-line
898 #+begin_src shell :tangle ~/.config/zsh/zshrc
899 setopt extended_history
901 setopt inc_append_history
902 setopt hist_ignore_dups
903 setopt hist_reduce_blanks
907 HISTFILE=~/.local/share/zsh/history
910 I manage plugins using my own plugin manager, ZPE. https://git.sr.ht/~armaan/zpe
912 #+begin_src plain :tangle ~/.config/zpe/repositories
913 https://github.com/Aloxaf/fzf-tab
914 https://github.com/zdharma/fast-syntax-highlighting
915 https://github.com/rupa/z
918 #+begin_src shell :tangle ~/.config/zsh/zshrc
919 source ~/Code/zpe/zpe.sh
920 source ~/Code/admone/admone.zsh
921 source ~/.config/zsh/fzf-bindings.zsh
923 zpe-source fzf-tab/fzf-tab.zsh
924 zstyle ':completion:*:descriptions' format '[%d]'
925 zstyle ':fzf-tab:complete:cd:*' fzf-preview 'exa -1 --color=always $realpath'
926 zstyle ':completion:*' completer _complete
927 zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \
928 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
930 zpe-source fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
931 export _Z_DATA="/home/armaa/.local/share/z"
935 **** Alert after long command
936 #+begin_src shell :tangle ~/.config/zsh/zshrc
938 notify-send --urgency=low -i ${(%):-%(?.terminal.error)} \
939 ${history[$HISTCMD]%[;&|][[:space:]]##alert}
942 **** Time Zsh startup
943 #+begin_src shell :tangle ~/.config/zsh/zshrc
945 for i in $(seq 1 10); do
946 time "zsh" -i -c exit;
950 **** Update all packages
951 #+begin_src shell :tangle ~/.config/zsh/zshrc
952 color=$(tput setaf 5)
956 sudo echo "${color}== upgrading with yay ==${reset}"
959 echo "${color}== checking for pacnew files ==${reset}"
962 echo "${color}== upgrading flatpaks ==${reset}"
965 echo "${color}== upgrading zsh plugins ==${reset}"
968 echo "${color}== updating nvim plugins ==${reset}"
969 nvim +PlugUpdate +PlugUpgrade +qall
970 echo "Updated nvim plugins"
972 echo "${color}You are entirely up to date!${reset}"
975 **** Clean all packages
976 #+begin_src shell :tangle ~/.config/zsh/zshrc
978 sudo echo "${color}== cleaning pacman orphans ==${reset}"
979 (pacman -Qtdq | sudo pacman -Rns - 2> /dev/null) || echo "No orphans"
981 echo "${color}== cleaning flatpaks ==${reset}"
982 flatpak remove --unused
984 echo "${color}== cleaning zsh plugins ==${reset}"
987 echo "${color}== cleaning nvim plugins ==${reset}"
988 nvim +PlugClean +qall
989 echo "Cleaned nvim plugins"
991 echo "${color}All orphans cleaned!${reset}"
995 #+begin_src shell :tangle ~/.config/zsh/zshrc
998 exa -lh --icons --git --group-directories-first
1002 #+begin_src shell :tangle ~/.config/zsh/zshrc
1004 __conda_setup="$('/opt/anaconda/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
1005 if [ $? -eq 0 ]; then
1006 eval "$__conda_setup"
1008 if [ -f "/opt/anaconda/etc/profile.d/conda.sh" ]; then
1009 . "/opt/anaconda/etc/profile.d/conda.sh"
1011 export PATH="/opt/anaconda/bin:$PATH"
1017 **** Interact with 0x0
1018 #+begin_src shell :tangle ~/.config/zsh/zshrc
1019 zxz="https://envs.sh"
1020 0file() { curl -F"file=@$1" "$zxz" ; }
1021 0pb() { curl -F"file=@-;" "$zxz" ; }
1022 0url() { curl -F"url=$1" "$zxz" ; }
1023 0short() { curl -F"shorten=$1" "$zxz" ; }
1024 0clip() { xclip -out | curl -F"file=@-;" "$zxz" ; }
1027 #+begin_src shell :tangle ~/.config/zsh/zshrc
1036 #+begin_src shell :tangle ~/.config/zsh/zshrc
1037 alias bhoji-drop='ssh -p 23 root@armaanb.net'
1038 alias weechat='ssh -p 23 -t root@armaanb.net tmux attach-session -t weechat'
1039 alias tcf='ssh root@204.48.23.68'
1040 alias ngmun='ssh root@157.245.89.25'
1041 alias prox='ssh root@192.168.1.224'
1042 alias dock='ssh root@192.168.1.225'
1043 alias jenkins='ssh root@192.168.1.226'
1044 alias envs='ssh acheam@envs.net'
1046 **** File management
1047 #+begin_src shell :tangle ~/.config/zsh/zshrc
1048 alias ls='exa -lh --icons --git --group-directories-first'
1049 alias la='exa -lha --icons --git --group-directories-first'
1050 alias df='df -h / /boot'
1052 alias free='free -h'
1057 alias grep='grep -in --exclude-dir=.git --color=auto'
1058 alias mkdir='mkdir -pv'
1059 alias unar='atool -x'
1060 alias wget='wget -e robots=off'
1061 alias lanex='~/.local/share/lxc/lxc'
1064 #+begin_src shell :tangle ~/.config/zsh/zshrc
1065 alias padm='yadm --yadm-repo ~/Code/dotfiles/repo.git'
1066 alias yadu='yadm add -u && yadm commit -m "Updated `date -Iseconds`" && \
1068 alias padu='padm add -u && padm commit && padm push && yadu'
1071 #+begin_src shell :tangle ~/.config/zsh/zshrc
1074 alias vw="nvim ~/Documents/vimwiki/index.md"
1076 **** System management
1077 #+begin_src shell :tangle ~/.config/zsh/zshrc
1078 alias jctl='journalctl -p 3 -xb'
1079 alias pkill='pkill -i'
1081 alias please='sudo $(fc -ln -1)'
1082 alias sudo='sudo ' # allows aliases to be run with sudo
1085 #+begin_src shell :tangle ~/.config/zsh/zshrc
1086 alias ping='ping -c 10'
1087 alias speed='speedtest-cli'
1088 alias ip='ip --color=auto'
1089 alias cip='curl https://armaanb.net/ip'
1090 alias gps='gpg --keyserver keyserver.ubuntu.com --search-keys'
1091 alias gpp='gpg --keyserver keyserver.ubuntu.com --recv-key'
1094 #+begin_src shell :tangle ~/.config/zsh/zshrc
1095 alias dc='docker-compose'
1096 alias dcdu='docker-compose down && docker-compose up -d'
1099 #+begin_src shell :tangle ~/.config/zsh/zshrc
1100 alias bigrandomfile='dd if=/dev/urandom of=1GB-urandom bs=1M count=1024 \
1101 iflag=fullblock status=progress'
1102 alias bigboringfile='dd if=/dev/zero of=1GB-zero bs=1M count=1024 \
1103 iflag=fullblock status=progress'
1104 alias ts='gen-shell -c task'
1105 alias ts='gen-shell -c task'
1106 alias tetris='autoload -Uz tetriscurses && tetriscurses'
1107 alias news='newsboat'
1108 alias tilderadio="\mpv https://radio.tildeverse.org/radio/8000/radio.ogg"
1109 alias ytmusic="youtube-dl -x --add-metadata --audio-format aac \
1110 --restrict-filenames -o '%(title)s.%(ext)s'"
1111 alias cal="cal -3 --color=auto"
1113 **** Virtual machines, chroots
1114 #+begin_src shell :tangle ~/.config/zsh/zshrc
1115 alias ckiss="sudo chrooter ~/Virtual/kiss"
1116 alias cdebian="sudo chrooter ~/Virtual/debian bash"
1117 alias cwindows='devour qemu-system-x86_64 \
1122 -device VGA,vgamem_mb=64 \
1124 -device hda-duplex \
1126 -net user,smb=/home/armaa/Public \
1127 -drive format=qcow2,file=/home/armaa/Virtual/windows.qcow2'
1130 #+begin_src shell :tangle ~/.config/zsh/zshrc
1132 alias zpy="zconda && ipython"
1133 alias math="ipython --profile=math"
1134 alias pypi="python setup.py sdist && twine upload dist/*"
1135 alias pip="python -m pip"
1136 alias black="black -l 79"
1139 #+begin_src shell :tangle ~/.config/zsh/zshrc
1140 alias words='gen-shell -c "words"'
1141 alias words-e='gen-shell -c "words ~E"'
1144 #+begin_src shell :tangle ~/.config/zsh/zshrc
1145 alias zathura='devour zathura'
1146 alias mpv='devour mpv'
1147 alias sql='devour sqlitebrowser'
1148 alias cad='devour openscad'
1149 alias feh='devour feh'
1151 **** Package management (Pacman)
1152 #+begin_src shell :tangle ~/.config/zsh/zshrc
1154 alias api='yay -Syu'
1155 alias app='yay -Rns'
1157 alias apo='yay -Qttd'
1158 alias azf='pacman -Q | fzf'
1159 alias favorites='pacman -Qe | cut -d " " -f 1 > ~/Documents/favorites'
1160 alias ufetch='ufetch-arch'
1161 alias reflect='reflector --verbose --sort rate --save \
1162 ~/.local/etc/pacman.d/mirrorlist --download-timeout 60' # Takes ~45m to run
1165 #+begin_src shell :tangle ~/.config/zsh/zshrc
1166 export EDITOR="emacsclient -c" # $EDITOR opens in terminal
1167 export VISUAL="emacsclient -c -a emacs" # $VISUAL opens in GUI mode
1168 export TERM=xterm-256color # for compatability
1170 export GPG_TTY="$(tty)"
1171 export MANPAGER='nvim +Man!'
1174 # generated with "vivid generate gruvbox"
1175 export LS_COLORS="$(cat ~/.local/share/zsh/gruvbox)"
1177 export GTK_USE_PORTAL=1
1179 export PATH="/home/armaa/.local/bin:$PATH" # prioritize .local/bin
1180 export PATH="$PATH:/home/armaa/Code/scripts"
1181 export PATH="$PATH:/home/armaa/.cargo/bin"
1182 export PATH="$PATH:/home/armaa/.local/share/gem/ruby/2.7.0/bin"
1183 export PATH="$PATH:/usr/sbin"
1184 export PATH="$PATH:/opt/FreeTube/freetube"
1186 export LC_ALL="en_US.UTF-8"
1187 export LC_CTYPE="en_US.UTF-8"
1188 export LANGUAGE="en_US.UTF-8"
1190 export KISS_PATH="/home/armaa/kiss/home/armaa/kiss-repo"
1191 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/core"
1192 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/extra"
1193 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/xorg"
1194 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-main/testing"
1195 export KISS_PATH="$KISS_PATH:/home/armaa/Clone/repo-community/community"
1199 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1202 family: JetBrains Mono Nerd Font
1209 ligatures: true # Requires ligature patch
1216 background_opacity: 0.6
1219 Send <RET> + modifier through
1220 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1235 #+begin_src yml :tangle ~/.config/alacritty/alacritty.yml
1239 background: '#000000'
1240 foreground: '#ebdbb2'
1266 Symlink profile_default/ipython_config.py to profile_math/ipython_config.py
1267 #+begin_src python :tangle ~/.ipython/profile_default/ipython_config.py
1268 c.TerminalInteractiveShell.editing_mode = 'vi'
1269 c.InteractiveShell.colors = 'linux'
1270 c.TerminalInteractiveShell.confirm_exit = False
1273 #+begin_src python :tangle ~/.ipython/profile_math/startup.py
1277 return x * (180 / pi)
1280 return x * (pi / 180)
1283 return (x * (pi / 180)) / unit
1295 Make MPV play a little bit smoother.
1296 #+begin_src conf :tangle ~/.config/mpv/mpv.conf
1297 ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
1302 #+begin_src conf :tangle ~/.config/picom/picom.conf
1305 shadow-offset-x = -5;
1306 shadow-offset-y = -5;
1309 #+begin_src conf :tangle ~/.config/picom/picom.conf
1314 #+begin_src conf :tangle ~/.config/picom/picom.conf
1317 method = "gaussian";
1323 Needs picom to be run with "--experimental-backends"
1324 #+begin_src conf :tangle ~/.config/picom/picom.conf
1328 For any GNU Readline programs
1329 #+begin_src plain :tangle ~/.inputrc
1333 https://github.com/sharkdp/vivid
1335 #+begin_src yml :tangle ~/.config/vivid/gruvbox.yml
1337 background_color: '282A36'
1349 #+begin_src yml :tangle ~/.config/vivid/gruvbox.yml
1366 missing_symlink_target:
1392 sticky_other_writable:
1425 continuous-integration:
1436 font-style: underline
1447 #+begin_src plain :tangle ~/.gitconfig
1449 name = Armaan Bhojwani
1450 email = me@armaanb.net
1451 signingkey = 0FEB9471E19C49C60CFBEB133C9ED82FFE788E4A
1454 #+begin_src plain :tangle ~/.gitconfig
1456 defaultBranch = main
1459 #+begin_src plain :tangle ~/.gitconfig
1464 #+begin_src plain :tangle ~/.gitconfig
1466 smtpserver = smtp.mailbox.org
1467 smtpuser = me@armaanb.net
1468 smtpencryption = ssl
1469 smtpserverport = 465
1473 #+begin_src plain :tangle ~/.gitconfig
1478 #+begin_src plain :tangle ~/.gitconfig
1481 sclone = clone --depth 1
1487 subup = submodule update --remote
1488 loc = diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Empty hash
1489 mirror = git config --global alias.mirrormirror
1492 #+begin_src plain :tangle ~/.gitconfig
1497 Lightweight notification daemon. Gruvbox colors, based on https://github.com/a-schaefers/i3-wm-gruvbox-theme/
1499 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1501 font = "JetBrains Mono Medium Nerd Font 11"
1503 format = "<b>%s</b>\n%b"
1505 indicate_hidden = yes
1508 show_age_threshold = 60
1511 geometry = "400x5-20+20"
1513 idle_threshold = 120
1515 sticky_history = yes
1517 separator_height = 4
1519 horizontal_padding = 8
1521 separator_color = "#585858"
1522 startup_notification = false
1525 #+begin_src conf :tangle ~/.config/dunst/dunstrc
1532 close_all = mod4+shift+c
1533 history = mod4+ctrl+c
1536 background = "#282828"
1537 foreground = "#ebdbb2"
1538 highlight = "#ebdbb2"
1542 background = "#282828"
1543 foreground = "#ebdbb2"
1544 highlight = "#ebdbb2"
1548 background = "#282828"
1549 foreground = "#cc241d"
1550 highlight = "#ebdbb2"