X-Git-Url: https://git.shemshak.org/gitweb.cgi/~bandali/configs/blobdiff_plain/3ea5e792dcaadc84a2b932f7c04d4de264a30553..850dd012bd83fb5d89e31695c4e66df4f1684e87:/init.org?ds=inline diff --git a/init.org b/init.org index 04719f0..b47a513 100644 --- a/init.org +++ b/init.org @@ -105,20 +105,19 @@ file. ** Naming conventions -The conventions below were inspired by [[https://github.com/hlissner/doom-emacs][Doom]]'s conventions, found -[[https://github.com/hlissner/doom-emacs/blob/5dacbb7cb1c6ac246a9ccd15e6c4290def67757c/core/core.el#L3-L17][here]]. Naturally, I use my initials, =ab=, instead of =doom=. +The conventions below were inspired by [[https://github.com/hlissner/doom-emacs][Doom]]'s, found [[https://github.com/hlissner/doom-emacs/blob/5dacbb7cb1c6ac246a9ccd15e6c4290def67757c/core/core.el#L3-L17][here]]. #+begin_src emacs-lisp :comments none ;; Naming conventions: ;; -;; ab-... public variables or non-interactive functions -;; ab--... private anything (non-interactive), not safe for direct use -;; ab/... an interactive function; safe for M-x or keybinding -;; ab:... an evil operator, motion, or command -;; ab|... a hook function -;; ab*... an advising function -;; ab@... a hydra command -;; ...! a macro +;; amin-... public variables or non-interactive functions +;; amin--... private anything (non-interactive), not safe for direct use +;; amin/... an interactive function; safe for M-x or keybinding +;; amin:... an evil operator, motion, or command +;; amin|... a hook function +;; amin*... an advising function +;; amin@... a hydra command +;; ...! a macro #+end_src * Initial setup @@ -137,10 +136,10 @@ let's see how long Emacs takes to start up, before even loading =init.el=, i.e. =user-init-file=: #+begin_src emacs-lisp -(defvar ab--before-user-init-time (current-time) +(defvar amin--before-user-init-time (current-time) "Value of `current-time' when Emacs begins loading `user-init-file'.") (message "Loading Emacs...done (%.3fs)" - (float-time (time-subtract ab--before-user-init-time + (float-time (time-subtract amin--before-user-init-time before-init-time))) #+end_src @@ -150,9 +149,9 @@ frequency. Clearing the ~file-name-handler-alist~ seems to help reduce startup time as well. #+begin_src emacs-lisp -(defvar ab--gc-cons-threshold gc-cons-threshold) -(defvar ab--gc-cons-percentage gc-cons-percentage) -(defvar ab--file-name-handler-alist file-name-handler-alist) +(defvar amin--gc-cons-threshold gc-cons-threshold) +(defvar amin--gc-cons-percentage gc-cons-percentage) +(defvar amin--file-name-handler-alist file-name-handler-alist) (setq gc-cons-threshold (* 400 1024 1024) ; 400 MiB gc-cons-percentage 0.6 file-name-handler-alist nil @@ -167,9 +166,9 @@ done initializing. (add-hook 'after-init-hook (lambda () - (setq gc-cons-threshold ab--gc-cons-threshold - gc-cons-percentage ab--gc-cons-percentage - file-name-handler-alist ab--file-name-handler-alist))) + (setq gc-cons-threshold amin--gc-cons-threshold + gc-cons-percentage amin--gc-cons-percentage + file-name-handler-alist amin--file-name-handler-alist))) #+end_src Increase the number of lines kept in message logs (the =*Messages*= @@ -188,6 +187,13 @@ but for now I've decided to keep them enabled. See documentation for ;; '(not free-vars unresolved noruntime lexical make-local)) #+end_src +** whoami + +#+begin_src emacs-lisp +(setq user-full-name "Amin Bandali" + user-mail-address "amin@aminb.org") +#+end_src + ** Package management *** No =package.el= @@ -241,7 +247,7 @@ and without compromising on performance. #+begin_src emacs-lisp (require 'use-package) -(if nil ; set to t when need to debug init +(if nil ; set to t when need to debug init (setq use-package-verbose t use-package-expand-minimally nil use-package-compute-statistics t @@ -390,7 +396,7 @@ Font stack with better unicode support, around =Ubuntu Mono= and ** Useful utilities #+begin_src emacs-lisp -(defun ab-enlist (exp) +(defun amin-enlist (exp) "Return EXP wrapped in a list, or as-is if already a list." (if (listp exp) exp (list exp))) @@ -400,7 +406,7 @@ Font stack with better unicode support, around =Ubuntu Mono= and compilation." (declare (indent defun) (debug t)) (list (if (or (not (bound-and-true-p byte-compile-current-file)) - (dolist (next (ab-enlist features)) + (dolist (next (amin-enlist features)) (if (symbolp next) (require next nil :no-error) (load next :no-message :no-error)))) @@ -419,7 +425,7 @@ compilation." (setq body `(after! ,next ,@body))) body) ((listp features) - `(after! (:all ,@features) ,@body))))) + `(after! (:all ,@features) ,@body))))) #+end_src * Core @@ -435,7 +441,9 @@ Enable displaying time and battery in the mode-line, since I'm not using the Xfce panel anymore. Also, I don't need to see the load average on a regular basis, so disable that. -#+begin_src emacs-lisp +Note: using =i3status= on sway at the moment, so disabling this. + +#+begin_src emacs-lisp :tangle no (use-package time :ensure nil :init @@ -558,6 +566,25 @@ variable. version-control t) #+end_src +*** Auto revert + +Enable automatic reloading of changed buffers and files. + +#+begin_src emacs-lisp +(global-auto-revert-mode 1) +(setq auto-revert-verbose nil + global-auto-revert-non-file-buffers t) +#+end_src + +*** Always use space for indentation + +#+begin_src emacs-lisp +(setq-default + indent-tabs-mode nil + require-final-newline t + tab-width 4) +#+end_src + ** Packages The packages in this section are absolutely essential to my everyday @@ -574,293 +601,76 @@ customizing it. (auto-compile-on-load-mode) (auto-compile-on-save-mode) (setq auto-compile-display-buffer nil - auto-compile-mode-line-counter t - auto-compile-source-recreate-deletes-dest t - auto-compile-toggle-deletes-nonlib-dest t - auto-compile-update-autoloads t) + auto-compile-mode-line-counter t + auto-compile-source-recreate-deletes-dest t + auto-compile-toggle-deletes-nonlib-dest t + auto-compile-update-autoloads t) (add-hook 'auto-compile-inhibit-compile-hook 'auto-compile-inhibit-compile-detached-git-head)) #+end_src -*** [[https://github.com/noctuid/general.el][general]] +*** [[https://github.com/Kungsgeten/ryo-modal][ryo-modal]] #+begin_quote Roll your own modal mode #+end_quote #+begin_src emacs-lisp -(use-package general - :demand t +(use-package ryo-modal + :commands ryo-modal-mode + :bind ("M-m" . ryo-modal-mode) + :after which-key :config - (general-evil-setup t) - - (general-override-mode) - - (general-create-definer - ab--mode-leader-keys - :keymaps 'override - :states '(emacs normal visual motion insert) - :non-normal-prefix "C-," - :prefix ",") - - (general-create-definer - ab--leader-keys - :keymaps 'override - :states '(emacs normal visual motion insert) - :non-normal-prefix "M-m" - :prefix "SPC")) -#+end_src - -*** evil - -#+begin_src emacs-lisp -(use-package evil - :demand t - :hook (view-mode . evil-motion-state) - :config (evil-mode 1)) -#+end_src - -#+begin_src emacs-lisp -(use-package evil-escape - :demand t - :init - (setq evil-escape-excluded-states '(normal visual multiedit emacs motion) - evil-escape-excluded-major-modes '(neotree-mode) - evil-escape-key-sequence "jk" - evil-escape-delay 0.25) - :general - (:states '(insert replace visual operator) - "C-g" #'evil-escape) - :config - (evil-escape-mode 1) - ;; no `evil-escape' in minibuffer - (push #'minibufferp evil-escape-inhibit-functions)) -#+end_src - -*** [[https://github.com/ch11ng/exwm][EXWM]] (window manager) - -#+begin_src emacs-lisp :tangle no -(use-package exwm - :demand t - :config - (require 'exwm-config) - - ;; Set the initial workspace number. - (setq exwm-workspace-number 4) - - ;; Make class name the buffer name, truncating beyond 50 characters - (defun exwm-rename-buffer () - (interactive) - (exwm-workspace-rename-buffer - (concat exwm-class-name ":" - (if (<= (length exwm-title) 50) exwm-title - (concat (substring exwm-title 0 49) "..."))))) - (add-hook 'exwm-update-class-hook 'exwm-rename-buffer) - (add-hook 'exwm-update-title-hook 'exwm-rename-buffer) - - ;; 's-R': Reset - (exwm-input-set-key (kbd "s-R") #'exwm-reset) - ;; 's-\': Switch workspace - (exwm-input-set-key (kbd "s-\\") #'exwm-workspace-switch) - ;; 's-N': Switch to certain workspace - (dotimes (i 10) - (exwm-input-set-key (kbd (format "s-%d" i)) - (lambda () - (interactive) - (exwm-workspace-switch-create i)))) - ;; 's-SPC': Launch application - ;; (exwm-input-set-key - ;; (kbd "s-SPC") - ;; (lambda (command) - ;; (interactive (list (read-shell-command "➜ "))) - ;; (start-process-shell-command command nil command))) - - (exwm-input-set-key (kbd "M-s-SPC") #'counsel-linux-app) - - ;; Shorten 'C-c C-q' to 'C-q' - (define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key) - - ;; Line-editing shortcuts - (setq exwm-input-simulation-keys - '(;; movement - ([?\C-b] . [left]) - ([?\M-b] . [C-left]) - ([?\C-f] . [right]) - ([?\M-f] . [C-right]) - ([?\C-p] . [up]) - ([?\C-n] . [down]) - ([?\C-a] . [home]) - ([?\C-e] . [end]) - ([?\M-v] . [prior]) - ([?\C-v] . [next]) - ([?\C-d] . [delete]) - ([?\C-k] . [S-end delete]) - ;; cut/copy/paste - ;; ([?\C-w] . [?\C-x]) - ([?\M-w] . [?\C-c]) - ([?\C-y] . [?\C-v]) - ;; search - ([?\C-s] . [?\C-f]))) - - ;; Enable EXWM - (exwm-enable) - - (add-hook 'exwm-init-hook #'exwm-config--fix/ido-buffer-window-other-frame) - - (require 'exwm-systemtray) - (exwm-systemtray-enable) - - (require 'exwm-randr) - (exwm-randr-enable) - - ;; (exwm-input-set-key - ;; (kbd "s-") - ;; (lambda () - ;; (interactive) - ;; (start-process "urxvt" nil "urxvt"))) - - ;; (exwm-input-set-key - ;; (kbd "s-SPC") ;; rofi doesn't properly launch programs when started from emacs - ;; (lambda () - ;; (interactive) - ;; (start-process-shell-command "rofi-run" nil "rofi -show run -display-run '> ' -display-window ' 🗔 '"))) - - ;; (exwm-input-set-key - ;; (kbd "s-/") - ;; (lambda () - ;; (interactive) - ;; (start-process-shell-command "rofi-win" nil "rofi -show window -display-run '> ' -display-window ' 🗔 '"))) - - ;; (exwm-input-set-key - ;; (kbd "M-SPC") - ;; (lambda () - ;; (interactive) - ;; (start-process "rofi-pass" nil "rofi-pass"))) - - ;; (exwm-input-set-key - ;; (kbd "") - ;; (lambda () - ;; (interactive) - ;; (start-process-shell-command "pamixer" nil "pamixer --toggle-mute"))) - - ;; (exwm-input-set-key - ;; (kbd "") - ;; (lambda () - ;; (interactive) - ;; (start-process-shell-command "pamixer" nil "pamixer --allow-boost --decrease 5"))) - - ;; (exwm-input-set-key - ;; (kbd "") - ;; (lambda () - ;; (interactive) - ;; (start-process-shell-command "pamixer" nil "pamixer --allow-boost --increase 5"))) - - ;; (exwm-input-set-key - ;; (kbd "") - ;; (lambda () - ;; (interactive) - ;; (start-process-shell-command "mpc" nil "mpc toggle"))) - - ;; (exwm-input-set-key - ;; (kbd "") - ;; (lambda () - ;; (interactive) - ;; (start-process-shell-command "mpc" nil "mpc prev"))) - - ;; (exwm-input-set-key - ;; (kbd "") - ;; (lambda () - ;; (interactive) - ;; (start-process-shell-command "mpc" nil "mpv next"))) - - (defun ab--exwm-pasystray () - "A command used to start pasystray." - (interactive) - (if (executable-find "pasystray") - (progn - (message "EXWM: starting pasystray ...") - (start-process-shell-command "pasystray" nil "pasystray --notify=all")) - (message "EXWM: pasystray is not installed, abort!"))) - - (add-hook 'exwm-init-hook #'ab--exwm-pasystray) - - (exwm-input-set-key - (kbd "s-t") - (lambda () - (interactive) - (exwm-floating-toggle-floating))) - - (exwm-input-set-key - (kbd "s-f") - (lambda () - (interactive) - (exwm-layout-toggle-fullscreen))) - - (exwm-input-set-key - (kbd "s-w") - (lambda () - (interactive) - (kill-buffer (current-buffer)))) - - (exwm-input-set-key - (kbd "s-q") - (lambda () - (interactive) - (exwm-manage--kill-client)))) -#+end_src - -**** sxhkdrc -:PROPERTIES: -:header-args+: :tangle ~/.config/sxhkd/sxhkdrc :mkdirp yes -:END: - -#+begin_src conf :tangle no -# terminal emulator -super + Return - urxvt - -# program launcher -super + space - rofi -show run -display-run '> ' -display-window ' 🗔 ' - -# window finder -super + slash - rofi -show window -display-run '> ' -display-window ' 🗔 ' - -# password manager -alt + space - rofi-pass - -# make sxhkd reload its configuration files: -super + Escape - pkill -USR1 -x sxhkd - -# volume {up,down} -XF86Audio{Raise,Lower}Volume - pamixer --allow-boost --{in,de}crease 5 - -# mute -XF86AudioMute - pamixer --toggle-mute - -# playback control -XF86Audio{Play,Prev,Next} - mpc {toggle,prev,next} - -# Toggle keyboard layout -# super + F7 -# toggle-layout - -# Toggle Xfce presentation mode -# XF86LaunchB -# toggle-presentation-mode - -# monitor brightness -XF86MonBrightness{Up,Down} - light -{A,U} 5 - -super + apostrophe - rofi-light + (push '((nil . "ryo:.*:") . (nil . "")) which-key-replacement-alist) + (ryo-modal-keys + ("," ryo-modal-repeat) + ("b" backward-char) + ("n" next-line) + ("p" previous-line) + ("f" forward-char) + ("/" undo) + ("i" ryo-modal-mode) + ("l" recenter-top-bottom) + ("v" scroll-up-command) + ("V" scroll-down-command) + ("x" delete-forward-char) + ("SPC" (("b" (("b" ibuffer-list-buffers) + ("k" kill-this-buffer) + ("o" other-window) + ("s" save-buffer))) + ("B" (("A" borg-activate) + ("a" borg-assimilate) + ("b" borg-build) + ("c" borg-clone) + ("r" borg-remove))) + ("h" (("c" describe-char) + ("f" describe-function) + ("F" describe-face) + ("i" info) + ("k" describe-key) + ("l" view-lossage) + ("v" describe-variable))) + ("q" (("q" save-buffers-kill-terminal))))) + ("d" (("w" kill-word) + ("b" backward-kill-word))) + ("c w" kill-word :exit t)) + + (ryo-modal-keys + ;; First argyment to ryo-modal-keys may be a list of keywords. + ;; These keywords will be applied to all keybindings. + (:norepeat t) + ("0" "M-0") + ("1" "M-1") + ("2" "M-2") + ("3" "M-3") + ("4" "M-4") + ("5" "M-5") + ("6" "M-6") + ("7" "M-7") + ("8" "M-8") + ("9" "M-9")) + :hook ((text-mode . ryo-modal-mode) + (prog-mode . ryo-modal-mode))) #+end_src *** [[https://orgmode.org/][Org mode]] @@ -874,10 +684,15 @@ system. In short, my favourite way of life. #+begin_src emacs-lisp -(setq org-src-tab-acts-natively t - org-src-preserve-indentation nil - org-edit-src-content-indentation 0) -(add-hook 'org-mode-hook 'org-indent-mode) +(use-package org + :ryo ("SPC b t" org-babel-tangle) + :config + (setq org-src-tab-acts-natively t + org-src-preserve-indentation nil + org-edit-src-content-indentation 0) + :hook (org-mode . org-indent-mode)) +(use-package org-notmuch + :after (:any org notmuch)) #+end_src *** [[https://magit.vc/][Magit]] @@ -890,10 +705,10 @@ Not just how I do git, but /the/ way to do git. #+begin_src emacs-lisp (use-package magit - :general (ab--leader-keys "g s" 'magit-status) + :ryo ("SPC" (("g s" magit-status))) :defer t :bind (("s-g" . magit-status) - ("C-x g" . magit-status) + ("C-x g" . magit-status) ("C-x M-g" . magit-dispatch-popup)) :config (magit-add-section-hook 'magit-status-sections-hook @@ -924,6 +739,7 @@ There's no way I could top that, so I won't attempt to. ([S-up] . ivy-previous-history-element) ([S-down] . ivy-next-history-element) ("DEL" . ivy-backward-delete-char)) + :ryo ("SPC ," ivy-switch-buffer) :config (setq ivy-wrap t) (ivy-mode 1)) @@ -933,9 +749,11 @@ There's no way I could top that, so I won't attempt to. #+begin_src emacs-lisp (use-package swiper - :general (:states 'normal "/" 'swiper) + :ryo + ("SPC /" swiper) + ("s" swiper) :bind (([remap isearch-forward] . swiper) - ([remap isearch-backward] . swiper))) + ([remap isearch-backward] . swiper))) #+end_src **** Counsel @@ -943,15 +761,15 @@ There's no way I could top that, so I won't attempt to. #+begin_src emacs-lisp (use-package counsel :defer 1 - :general (ab--leader-keys - "f r" 'counsel-recentf - "SPC" 'counsel-M-x - "." 'counsel-find-file) + :ryo + ("SPC" (("f r" counsel-recentf) + ("SPC" counsel-M-x) + ("." counsel-find-file))) :bind (([remap execute-extended-command] . counsel-M-x) ([remap find-file] . counsel-find-file) ("s-r" . counsel-recentf) :map minibuffer-local-map - ("C-r" . counsel-minibuffer-history)) + ("C-r" . counsel-minibuffer-history)) :config (counsel-mode 1) (defalias 'locate #'counsel-locate)) @@ -1033,9 +851,15 @@ TODO: break this giant source block down into individual org sections. (list (regexp-quote (system-name)) nil nil))) (use-package undo-tree + :ryo + ("?" undo-tree-undo) + ("_" undo-tree-redo) + :bind (("C-?" . undo-tree-undo) + ("M-_" . undo-tree-redo)) :config (global-undo-tree-mode) - (setq undo-tree-mode-lighter "")) + (setq undo-tree-mode-lighter "" + undo-tree-auto-save-history t)) #+end_src * Editing @@ -1047,7 +871,7 @@ TODO: break this giant source block down into individual org sections. :defer 5 :bind (:map company-active-map - ([tab] . company-complete-common-or-cycle)) + ([tab] . company-complete-common-or-cycle)) :custom (company-idle-delay 0.3) (company-minimum-prefix-length 1) @@ -1057,16 +881,6 @@ TODO: break this giant source block down into individual org sections. (global-company-mode t)) #+end_src -** Customizations - -#+begin_src emacs-lisp -(ab--leader-keys - "b s" 'save-buffer - "b b" 'ivy-switch-buffer - "b k" 'kill-buffer - "q q" 'evil-save-and-quit) -#+end_src - * Syntax and spell checking #+begin_src emacs-lisp (use-package flycheck @@ -1080,12 +894,26 @@ TODO: break this giant source block down into individual org sections. #+end_src * Programming modes -** [[https://github.com/leanprover/lean-mode][Lean]] +** [[http://alloytools.org][Alloy]] (with [[https://github.com/dwwmmn/alloy-mode][alloy-mode]]) + +#+begin_src emacs-lisp +(use-package alloy-mode + :config (setq alloy-basic-offset 2)) +#+end_src + +** [[https://coq.inria.fr][Coq]] (with [[https://github.com/ProofGeneral/PG][Proof General]]) + +#+begin_src emacs-lisp +(use-package proof-site ; Proof General + :load-path "lib/proof-site/generic/") +#+end_src + +** [[https://leanprover.github.io][Lean]] (with [[https://github.com/leanprover/lean-mode][lean-mode]]) #+begin_src emacs-lisp (use-package lean-mode :bind (:map lean-mode-map - ("S-SPC" . company-complete))) + ("S-SPC" . company-complete))) #+end_src ** Haskell @@ -1097,8 +925,8 @@ TODO: break this giant source block down into individual org sections. :config (setq haskell-indentation-layout-offset 4 haskell-indentation-left-offset 4 - flycheck-checker 'haskell-hlint - flycheck-disabled-checkers '(haskell-stack-ghc haskell-ghc))) + flycheck-checker 'haskell-hlint + flycheck-disabled-checkers '(haskell-stack-ghc haskell-ghc))) #+end_src *** [[https://github.com/jyp/dante][dante]] @@ -1118,8 +946,8 @@ executable from [[https://github.com/mpickering/apply-refact][apply-refact]]. #+begin_src emacs-lisp (use-package hlint-refactor :bind (:map hlint-refactor-mode-map - ("C-c l b" . hlint-refactor-refactor-buffer) - ("C-c l r" . hlint-refactor-refactor-at-point)) + ("C-c l b" . hlint-refactor-refactor-buffer) + ("C-c l r" . hlint-refactor-refactor-at-point)) :hook (haskell-mode . hlint-refactor-mode)) #+end_src @@ -1220,8 +1048,8 @@ instead. (new-old-code "")) (save-excursion (switch-to-buffer (get-file-buffer fname)) - (goto-char (point-min)) - (forward-line (1- fline)) + (goto-char (point-min)) + (forward-line (1- fline)) (beginning-of-line) (setf bline (point)) (when (or hs-lint-replace-without-ask @@ -1286,36 +1114,100 @@ Emacs package that displays available keybindings in popup :defer 1 :config (which-key-mode)) #+end_src + +** [[https://github.com/seagle0128/doom-modeline][doom-modeline]] + +#+begin_src emacs-lisp +(use-package doom-modeline + :demand t + :config (setq doom-modeline-height 32) + :hook (after-init . doom-modeline-init)) +#+end_src + +** [[https://github.com/11111000000/tao-theme-emacs][tao-theme]] + +#+begin_src emacs-lisp :tangle no +(use-package tao-theme + :demand t + :config (load-theme 'tao-yang t)) +#+end_src + +** [[https://github.com/maio/eink-emacs][eink-theme]] + +#+begin_src emacs-lisp +(load-theme 'eink t) +#+end_src + +** [[https://github.com/bbatsov/crux][crux]] + +#+begin_src emacs-lisp +(use-package crux + :bind (("C-c d" . crux-duplicate-current-line-or-region) + ("C-c M-d" . crux-duplicate-and-comment-current-line-or-region)) + :ryo + ("o" crux-smart-open-line :exit t) + ("O" crux-smart-open-line-above :exit t) + ("SPC b K" crux-kill-other-buffers) + ("d d" crux-kill-whole-line) + ("c c" crux-kill-whole-line :then '(crux-smart-open-line-above) :exit t) + ("SPC f" (("c" crux-copy-file-preserve-attributes) + ("D" crux-delete-file-and-buffer) + ("R" crux-rename-file-and-buffer)))) +#+end_src + +** [[https://github.com/alezost/mwim.el][mwim]] + +#+begin_src emacs-lisp +(use-package mwim + :bind (("C-a" . mwim-beginning-of-code-or-line) + ("C-e" . mwim-end-of-code-or-line) + ("" . mwim-beginning-of-line-or-code) + ("" . mwim-end-of-line-or-code)) + :ryo + ("a" mwim-beginning-of-code-or-line) + ("e" mwim-end-of-code-or-line)) +#+end_src + +** [[https://www.emacswiki.org/emacs/KeyChord][key-chord]] + +#+begin_src emacs-lisp +(use-package key-chord + :demand t + :config + (key-chord-mode 1) + (key-chord-define-global "jk" 'ryo-modal-mode) + (setq key-chord-one-key-delay 0 ; i don't need one-key chords for now + key-chord-two-keys-delay 0.005)) +#+end_src + * Email -** notmuch +** [[https://notmuchmail.org][notmuch]] + +See [[notmuch:id:87muuqsvci.fsf@fencepost.gnu.org][bug follow-up]]. #+begin_src emacs-lisp -(defun ab/notmuch () +(defun amin/notmuch () "Delete other windows, then launch `notmuch'." (interactive) (require 'notmuch) (delete-other-windows) (notmuch)) -;; (ab--leader-keys -;; "m" 'ab/notmuch -;; "s" 'save-buffer -;; "SPC" 'counsel-M-x) - ;; (map! ;; :leader -;; :desc "notmuch" :n "m" #'ab/notmuch +;; :desc "notmuch" :n "m" #'amin/notmuch ;; (:desc "search" :prefix "/" ;; :desc "notmuch" :n "m" #'counsel-notmuch)) #+end_src #+begin_src emacs-lisp -(defvar ab-maildir "~/mail") +(defvar amin-maildir "~/mail") (use-package sendmail ;; :ensure nil :config (setq sendmail-program "/usr/bin/msmtp" + ; message-sendmail-extra-arguments '("-v" "-d") mail-specify-envelope-from t mail-envelope-from 'header)) @@ -1326,7 +1218,7 @@ Emacs package that displays available keybindings in popup message-send-mail-function 'message-send-mail-with-sendmail message-sendmail-envelope-from 'header message-directory "drafts" - message-user-fqdn "fencepost.gnu.org") + message-user-fqdn "aminb.org") (add-hook 'message-mode-hook (lambda () (setq fill-column 65 message-fill-column 65))) @@ -1334,12 +1226,12 @@ Emacs package that displays available keybindings in popup #'flyspell-mode) ;; (add-hook 'notmuch-message-mode-hook #'+doom-modeline|set-special-modeline) ;; TODO: is there a way to only run this when replying and not composing? - (add-hook 'notmuch-message-mode-hook - (lambda () (progn - (newline) - (newline) - (forward-line -1) - (forward-line -1)))) + ;; (add-hook 'notmuch-message-mode-hook + ;; (lambda () (progn + ;; (newline) + ;; (newline) + ;; (forward-line -1) + ;; (forward-line -1)))) ;; (add-hook 'message-setup-hook ;; #'mml-secure-message-sign-pgpmime) ) @@ -1349,7 +1241,7 @@ Emacs package that displays available keybindings in popup mml-secure-openpgp-sign-with-sender t)) (use-package notmuch - :general (ab--leader-keys "m" 'ab/notmuch) + :ryo ("SPC m" amin/notmuch) :config (setq notmuch-hello-sections '(notmuch-hello-insert-header @@ -1358,13 +1250,22 @@ Emacs package that displays available keybindings in popup notmuch-hello-insert-alltags) notmuch-search-oldest-first nil notmuch-show-all-tags-list t + notmuch-message-headers ; see bug follow-up above + '("Subject" "To" "Cc" "Date" "List-Id" "X-RT-Originator") notmuch-hello-thousands-separator "," notmuch-fcc-dirs '(("amin@aminb.org" . "amin/Sent") + ("amin@gnu.org" . "gnu/Sent") ("abandali@uwaterloo.ca" . "\"uwaterloo/Sent Items\"") - ("amin.bandali@uwaterloo.ca" . "\"uwaterloo/Sent Items\"") + ("mab@gnu.org" . "gnu/Sent") ("aminb@gnu.org" . "gnu/Sent") - (".*" . "sent"))) + (".*" . "sent")) + notmuch-search-result-format + '(("date" . "%12s ") + ("count" . "%-7s ") + ("authors" . "%-40s ") + ("subject" . "%s ") + ("tags" . "(%s)"))) ;; (add-hook 'visual-fill-column-mode-hook ;; (lambda () ;; (when (string= major-mode 'notmuch-message-mode) @@ -1374,49 +1275,57 @@ Emacs package that displays available keybindings in popup ;; :override #'kill-this-buffer) :bind (:map notmuch-hello-mode-map - ("g" . notmuch-poll-and-refresh-this-buffer) - ("i" . (lambda () - "Search for `inbox' tagged messages" - (interactive) - (notmuch-hello-search "tag:inbox"))) - ("u" . (lambda () - "Search for `unread' tagged messages" - (interactive) - (notmuch-hello-search "tag:unread"))) - ("M" . (lambda () - "Compose new mail and prompt for sender" - (interactive) - (let ((current-prefix-arg t)) - (call-interactively #'notmuch-mua-new-mail))))) + ("g" . notmuch-poll-and-refresh-this-buffer) + ("u" . (lambda () + "Search for `unread' tagged messages" + (interactive) + (notmuch-hello-search "tag:unread"))) + ("i" . (lambda () + "Search for `inbox' tagged messages" + (interactive) + (notmuch-hello-search "tag:inbox"))) + ("l" . (lambda () + "Search for `latest' tagged messages" + (interactive) + (notmuch-hello-search "tag:latest"))) + ("e" . (lambda () + "Search for `encrypted' tagged messages" + (interactive) + (notmuch-hello-search "tag:encrypted"))) + ("M" . (lambda () + "Compose new mail and prompt for sender" + (interactive) + (let ((current-prefix-arg t)) + (call-interactively #'notmuch-mua-new-mail))))) (:map notmuch-search-mode-map - ("g" . notmuch-poll-and-refresh-this-buffer) - ("k" . (lambda () - "Mark message read" - (interactive) - (notmuch-search-tag '("-unread")) - ;; (notmuch-search-archive-thread) - (notmuch-search-next-thread))) - ("u" . (lambda () - "Mark message unread" - (interactive) - (notmuch-search-tag '("+unread")) - (notmuch-search-next-thread))) - ("K" . (lambda () - "Mark message deleted" - (interactive) - (notmuch-search-tag '("-unread" "-inbox" "+deleted")) - (notmuch-search-archive-thread))) - ("S" . (lambda () - "Mark message as spam" - (interactive) - (notmuch-search-tag '("-unread" "-inbox" "-webmasters" "+spam")) - (notmuch-search-archive-thread)))) + ("g" . notmuch-poll-and-refresh-this-buffer) + ("k" . (lambda () + "Mark message read" + (interactive) + (notmuch-search-tag '("-unread")) + ;; (notmuch-search-archive-thread) + (notmuch-search-next-thread))) + ("u" . (lambda () + "Mark message unread" + (interactive) + (notmuch-search-tag '("+unread")) + (notmuch-search-next-thread))) + ("K" . (lambda () + "Mark message deleted" + (interactive) + (notmuch-search-tag '("-unread" "-inbox" "+deleted")) + (notmuch-search-archive-thread))) + ("S" . (lambda () + "Mark message as spam" + (interactive) + (notmuch-search-tag '("-unread" "-inbox" "-webmasters" "+spam")) + (notmuch-search-archive-thread)))) (:map notmuch-tree-mode-map ; TODO: additional bindings - ("S" . (lambda () - "Mark message as spam" - (interactive) - (notmuch-tree-tag '("-unread" "-inbox" "-webmasters" "+spam")) - (notmuch-tree-archive-thread)))) + ("S" . (lambda () + "Mark message as spam" + (interactive) + (notmuch-tree-tag '("-unread" "-inbox" "-webmasters" "+spam")) + (notmuch-tree-archive-thread)))) ) ;; (use-package counsel-notmuch @@ -1432,7 +1341,66 @@ Emacs package that displays available keybindings in popup ;; (notmuch-tree-mode . emacs)))) (after! recentf - (add-to-list 'recentf-exclude (expand-file-name ab-maildir))) + (add-to-list 'recentf-exclude (expand-file-name amin-maildir))) +#+end_src + +** supercite + +#+begin_src emacs-lisp :tangle no +(use-package supercite + :commands sc-cite-original + :init + (add-hook 'mail-citation-hook 'sc-cite-original) + + (defun sc-remove-existing-signature () + (save-excursion + (goto-char (region-beginning)) + (when (re-search-forward message-signature-separator (region-end) t) + (delete-region (match-beginning 0) (region-end))))) + + (add-hook 'mail-citation-hook 'sc-remove-existing-signature) + + (defun sc-remove-if-not-mailing-list () + (unless (assoc "list-id" sc-mail-info) + (setq attribution sc-default-attribution + citation (concat sc-citation-delimiter + sc-citation-separator)))) + + (add-hook 'sc-attribs-postselect-hook 'sc-remove-if-not-mailing-list) + + :config + (defun sc-fill-if-different (&optional prefix) + "Fill the region bounded by `sc-fill-begin' and point. +Only fill if optional PREFIX is different than +`sc-fill-line-prefix'. If `sc-auto-fill-region-p' is nil, do not +fill region. If PREFIX is not supplied, initialize fill +variables. This is useful for a regi `begin' frame-entry." + (if (not prefix) + (setq sc-fill-line-prefix "" + sc-fill-begin (line-beginning-position)) + (if (and sc-auto-fill-region-p + (not (string= prefix sc-fill-line-prefix))) + (let ((fill-prefix sc-fill-line-prefix)) + (unless (or (string= fill-prefix "") + (save-excursion + (goto-char sc-fill-begin) + (or (looking-at ">+ +") + (< (length + (buffer-substring (point) + (line-end-position))) + 65)))) + (fill-region sc-fill-begin (line-beginning-position))) + (setq sc-fill-line-prefix prefix + sc-fill-begin (line-beginning-position))))) +nil)) +#+end_src + +* Blogging +** [[https://ox-hugo.scripter.co][ox-hugo]] + +#+begin_src emacs-lisp +(use-package ox-hugo + :after ox) #+end_src * Post initialization @@ -1445,7 +1413,7 @@ Display how long it took to load the init file. #+begin_src emacs-lisp (message "Loading %s...done (%.3fs)" user-init-file (float-time (time-subtract (current-time) - ab--before-user-init-time))) + amin--before-user-init-time))) #+end_src * Footer