X-Git-Url: https://git.shemshak.org/~bandali/configs/blobdiff_plain/bc39c78020af68f7f51f4065d27c94b48c4b6179..526ea2c42ae3190eea588843035e39c3b609b1bf:/init.org?ds=sidebyside diff --git a/init.org b/init.org index 8de259e..a6e4d11 100644 --- a/init.org +++ b/init.org @@ -240,10 +240,12 @@ can then be managed with the help of Magit or other tools. (with-eval-after-load 'bind-key (bind-keys :package borg - ("C-c B A" . borg-activate) - ("C-c B a" . borg-assimilate) - ("C-c B b" . borg-build) - ("C-c B c" . borg-clone))) + ("C-c b A" . borg-activate) + ("C-c b a" . borg-assimilate) + ("C-c b b" . borg-build) + ("C-c b c" . borg-clone) + ("C-c b m" . borg-insert-update-message) + ("C-c b r" . borg-remove))) #+end_src *** =use-package= @@ -281,10 +283,9 @@ database, low-level functions for querying the database, and a (use-package epkg :defer t :bind - (("C-c B d" . epkg-describe-package) - ("C-c B p" . epkg-list-packages) - ("C-c B r" . borg-remove) - ("C-c B u" . epkg-update))) + (("C-c b d" . epkg-describe-package) + ("C-c b p" . epkg-list-packages) + ("C-c b u" . epkg-update))) #+end_src ** No littering in =~/.emacs.d= @@ -367,10 +368,11 @@ See [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.htm #+begin_src emacs-lisp (use-package server + :defer 1 :config (or (server-running-p) (server-mode))) #+end_src -** Unicode support +** COMMENT Unicode support Font stack with better unicode support, around =Ubuntu Mono= and =Hack=. @@ -609,7 +611,7 @@ 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) + global-auto-revert-non-file-buffers nil) #+end_src *** Always use space for indentation @@ -643,20 +645,23 @@ Enable =winner-mode=. (cons msg code))) #+end_src -** Bindings +*** Search for non-ASCII characters + +I’d like non-ASCII characters such as ‘’“”«»‹›áⓐ𝒶 to be selected when +I search for their ASCII counterpart. Shoutout to [[http://endlessparentheses.com/new-in-emacs-25-1-easily-search-non-ascii-characters.html][endlessparentheses]] +for this. #+begin_src emacs-lisp -(bind-keys - ("C-c b k" . kill-this-buffer) - ("C-c b s" . save-buffer) - ("C-c S" . save-buffer) - ("C-c o" . other-window) - ("C-c q q" . save-buffers-kill-terminal) +(setq search-default-mode #'char-fold-to-regexp) - ("C-c F m" . make-frame-command) - ("C-c F d" . delete-frame) - ("C-c F D" . delete-other-frames) +;; uncomment to extend this behaviour to query-replace +;; (setq replace-char-fold t) +#+end_src + +** Bindings +#+begin_src emacs-lisp +(bind-keys ("s-c e b" . eval-buffer) ("s-c e r" . eval-region) @@ -688,6 +693,146 @@ customizing it. 'auto-compile-inhibit-compile-detached-git-head)) #+end_src +*** [[https://github.com/noctuid/general.el][general]] + +#+begin_src emacs-lisp +(use-package general + :demand t + :config + (general-evil-setup t) + (general-override-mode) + + (general-create-definer + amin--leader-keys + :keymaps 'override + :states '(emacs normal visual motion insert) + :non-normal-prefix "M-m" + :prefix "SPC")) +#+end_src + +*** [[https://github.com/emacs-evil/evil][evil]] + +#+begin_src emacs-lisp +(use-package evil + :demand t + ;; :hook (org-src-mode . evil-motion-state) + :config + (evil-mode 1) + (general-swap-key nil '(normal motion) ";" ":") + + (setq evil-want-visual-char-semi-exclusive t) + + ;; custom mode state mappings + (dolist (mspair '((ebdb-mode . emacs) + (helpful-mode . motion) + (view-mode . motion))) + (evil-set-initial-state (car mspair) (cdr mspair))) + + ;; fix tab and indentation in src blocks inside org-mode buffer + ;; also see https://git.sr.ht/~bandali/dotfiles/commit/0e2ffd584aafdd4cf256bcdf2473f01c3aaaed55 + (unbind-key "TAB" evil-motion-state-map) + + (unbind-key "C-d" evil-insert-state-map) + (unbind-key "C-v" evil-insert-state-map) + (unbind-key "C-y" evil-insert-state-map) + (unbind-key "C-a" evil-insert-state-map) + (unbind-key "C-e" evil-insert-state-map) + (unbind-key "C-p" evil-insert-state-map) + (unbind-key "C-n" evil-insert-state-map) + (unbind-key "C-k" evil-insert-state-map) + (bind-keys + :map evil-insert-state-map + ("C-k" . kill-line) + ("C-S-k" . evil-insert-digraph) + :map evil-motion-state-map + ([down-mouse-1] . nil))) +#+end_src + +#+begin_src emacs-lisp +(use-package evil-escape + :after evil + :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 + +#+begin_src emacs-lisp +(use-package evil-nerd-commenter + :after evil + :general + (nmap + "gc" 'evilnc-comment-operator + "gy" 'evilnc-copy-and-comment-lines)) +#+end_src + +#+begin_src emacs-lisp +(use-package evil-surround + :after evil + :general + (omap + "s" 'evil-surround-edit + "S" 'evil-Surround-edit) + (vmap + "S" 'evil-surround-region + "gS" 'evil-Surround-region)) +#+end_src + +#+begin_src emacs-lisp +(amin--leader-keys + "/" '(:ignore t :wk "search") + + "a" '(:ignore t :wk "apps") + "a i" 'ielm + + "b" '(:ignore t :wk "buffers") + "b k" 'kill-this-buffer + "b s" 'save-buffer + + "e" '(:ignore t :wk "eval") + "e b" 'eval-buffer + "e r" 'eval-region + + "f" '(:ignore t :wk "files") + + "F" '(:ignore t :wk "frames") + "F m" 'make-frame-command + "F d" 'delete-frame + "F D" 'delete-other-frames + + "h" '(:ignore t :wk "help(ful)") + "h c" 'describe-char + "h f" 'describe-function + "h F" 'describe-face + "h H" 'view-hello-file + "h i" 'info + "h k" 'describe-key + "h l" 'view-lossage + "h v" 'describe-variable + + "o" 'other-window + + "w" '(:ignore t :wk "window") + "w o" 'other-window + "w 0" 'delete-window + "w 1" 'delete-other-windows + "w 2" 'split-window-below + "w 3" 'split-window-right + "w u" 'winner-undo + "w r" 'winner-redo + + "q" '(:ignore t :wk "quit") + "q q" 'save-buffers-kill-terminal) +#+end_src + *** [[https://orgmode.org/][Org mode]] #+begin_quote @@ -700,11 +845,42 @@ In short, my favourite way of life. #+begin_src emacs-lisp (use-package org + :defer 3 + :general + (amin--leader-keys + :states 'normal + :keymaps 'org-mode-map + "'" 'org-edit-special) + (amin--leader-keys + :definer 'minor-mode + :states 'normal + :keymaps 'org-src-mode + "'" 'org-edit-src-exit + "k" 'org-edit-src-abort) + (general-define-key + :definer 'minor-mode + :states 'normal + :keymaps 'org-src-mode + "q" 'org-edit-src-exit) :config (setq org-src-tab-acts-natively t org-src-preserve-indentation nil org-edit-src-content-indentation 0 + org-email-link-description-format "Email %c: %s" ; %.30s org-log-done 'time) + (add-to-list 'org-structure-template-alist '("L" . "src emacs-lisp") t) + (after! org-src + (define-key org-src-mode-map [remap evil-write] 'org-edit-src-save) + (define-key org-src-mode-map [remap evil-save-and-close] + (lambda () (interactive) + (org-edit-src-save) + (org-edit-src-exit))) + (define-key org-src-mode-map [remap evil-save-modified-and-close] + (lambda () (interactive) + (org-edit-src-save) + (org-edit-src-exit))) + (define-key org-src-mode-map [remap evil-quit] 'org-edit-src-abort)) + :bind (:map org-mode-map ("M-L" . org-insert-last-stored-link)) :hook ((org-mode . org-indent-mode) (org-mode . auto-fill-mode) (org-mode . flyspell-mode)) @@ -712,6 +888,7 @@ In short, my favourite way of life. (org-latex-packages-alist '(("" "listings") ("" "color")))) (use-package ox-latex + :after ox :config (setq org-latex-listings 'listings ;; org-latex-prefer-user-labels t @@ -727,9 +904,18 @@ In short, my favourite way of life. ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) t)) -(use-package ox-beamer) +(use-package ox-beamer + :after ox) + +(use-package ob-tangle + :general + (amin--leader-keys + :states 'normal + :keymaps 'org-mode-map + "b t" 'org-babel-tangle)) (use-package orgalist + :after message :hook (message-mode . orgalist-mode)) #+end_src @@ -791,29 +977,20 @@ Not just how I do git, but /the/ way to do git. #+begin_src emacs-lisp (use-package magit - :defer t - :bind - (("s-g" . magit-status) - :prefix-map amin--magit-prefix-map - :prefix "C-c g" - ("SPC" . magit-status) - ("s" . magit-status) - ("S" . magit-status-prefix) - ("B" . magit-blame-addition) - ("C" . magit-clone) - ("f" . magit-fetch-other) - ("F" . magit-pull-branch) - ("P" . magit-push-other) - ("p" . magit-dispatch-popup) - ("c c" . magit-commit-create) - ("c a" . magit-commit-amend) - ("b b" . magit-checkout) - ("b c" . magit-branch-create)) + :defer 2 + :general (amin--leader-keys "g s" 'magit-status) + :bind ("s-g" . magit-status) :config (magit-add-section-hook 'magit-status-sections-hook 'magit-insert-modules 'magit-insert-stashes 'append) + (setq + magit-repository-directories '(("~/.emacs.d/" . 0) + ("~/src/git/" . 1))) + (nconc magit-section-initial-visibility-alist + '(([unpulled status] . show) + ([unpushed status] . show))) :custom-face (magit-diff-file-heading ((t (:weight normal))))) #+end_src @@ -831,9 +1008,9 @@ There's no way I could top that, so I won't attempt to. #+begin_src emacs-lisp (use-package ivy :defer 1 + :general (amin--leader-keys "," 'ivy-switch-buffer) :bind - (("C-c b b" . ivy-switch-buffer) - :map ivy-minibuffer-map + (:map ivy-minibuffer-map ([escape] . keyboard-escape-quit) ([S-up] . ivy-previous-history-element) ([S-down] . ivy-next-history-element) @@ -851,6 +1028,7 @@ There's no way I could top that, so I won't attempt to. #+begin_src emacs-lisp (use-package swiper + :general (:states '(normal motion) "/" 'swiper) :bind (("C-s" . swiper) ("C-r" . swiper))) #+end_src @@ -860,12 +1038,16 @@ There's no way I could top that, so I won't attempt to. #+begin_src emacs-lisp (use-package counsel :defer 1 + :general + (amin--leader-keys + "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) ("C-c x" . counsel-M-x) ("C-c f ." . counsel-find-file) - ("C-c f r" . counsel-recentf) :map minibuffer-local-map ("C-r" . counsel-minibuffer-history)) :config @@ -877,6 +1059,7 @@ There's no way I could top that, so I won't attempt to. #+begin_src emacs-lisp (use-package eshell + :defer t :commands eshell :config (eval-when-compile (defvar eshell-prompt-regexp)) @@ -904,9 +1087,10 @@ There's no way I could top that, so I won't attempt to. #+begin_src emacs-lisp (use-package ibuffer + :defer t + :general (amin--leader-keys "b b" 'ibuffer-other-window) :bind (("C-x C-b" . ibuffer-other-window) - ("C-c b B" . ibuffer-other-window) :map ibuffer-mode-map ("P" . ibuffer-backward-filter-group) ("N" . ibuffer-forward-filter-group) @@ -967,6 +1151,7 @@ There's no way I could top that, so I won't attempt to. #+begin_src emacs-lisp (use-package outline + :defer t :hook (prog-mode . outline-minor-mode) :bind (:map @@ -1008,7 +1193,9 @@ TODO: break this giant source block down into individual org sections. (use-package help :defer t - :config (temp-buffer-resize-mode)) + :config + (temp-buffer-resize-mode) + (setq help-window-select t)) (progn ; `isearch' (setq isearch-allow-scroll t)) @@ -1035,7 +1222,7 @@ TODO: break this giant source block down into individual org sections. (add-hook 'prog-mode-hook #'indicate-buffer-boundaries-left)) (use-package recentf - :demand t + :defer 0.5 :config (add-to-list 'recentf-exclude "^/\\(?:ssh\\|su\\|sudo\\)?:") (setq recentf-max-saved-items 40)) @@ -1062,12 +1249,14 @@ TODO: break this giant source block down into individual org sections. (list (regexp-quote (system-name)) nil nil))) (use-package undo-tree - :bind (("C-?" . undo-tree-undo) - ("M-_" . undo-tree-redo)) :config - (global-undo-tree-mode) - (setq undo-tree-mode-lighter "" - undo-tree-auto-save-history t)) + (global-undo-tree-mode -1)) + ;; :bind (("C-?" . undo-tree-undo) + ;; ("M-_" . undo-tree-redo)) + ;; :config + ;; (global-undo-tree-mode) + ;; (setq undo-tree-mode-lighter "" + ;; undo-tree-auto-save-history t)) #+end_src * Editing @@ -1076,7 +1265,7 @@ TODO: break this giant source block down into individual org sections. #+begin_src emacs-lisp (use-package company - :defer 5 + :defer 2 :bind (:map company-active-map ([tab] . company-complete-common-or-cycle) @@ -1095,6 +1284,7 @@ TODO: break this giant source block down into individual org sections. * Syntax and spell checking #+begin_src emacs-lisp (use-package flycheck + :defer 3 :hook (prog-mode . flycheck-mode) :bind (:map flycheck-mode-map @@ -1109,6 +1299,7 @@ TODO: break this giant source block down into individual org sections. ;; http://endlessparentheses.com/ispell-and-apostrophes.html (use-package ispell + :defer 3 :config ;; ’ can be part of a word (setq ispell-local-dictionary-alist @@ -1138,6 +1329,7 @@ TODO: break this giant source block down into individual org sections. #+begin_src emacs-lisp (use-package alloy-mode + :defer t :config (setq alloy-basic-offset 2)) #+end_src @@ -1145,6 +1337,7 @@ TODO: break this giant source block down into individual org sections. #+begin_src emacs-lisp (use-package proof-site ; Proof General + :defer t :load-path "lib/proof-site/generic/") #+end_src @@ -1153,12 +1346,17 @@ TODO: break this giant source block down into individual org sections. #+begin_src emacs-lisp (eval-when-compile (defvar lean-mode-map)) (use-package lean-mode - :defer 2 + :defer 1 :bind (:map lean-mode-map ("S-SPC" . company-complete)) :config (require 'lean-input) - (setq default-input-method "Lean")) + (setq default-input-method "Lean" + lean-input-tweak-all '(lean-input-compose + (lean-input-prepend "/") + (lean-input-nonempty)) + lean-input-user-translations '(("/" "/"))) + (lean-input-setup)) #+end_src ** Haskell @@ -1167,6 +1365,7 @@ TODO: break this giant source block down into individual org sections. #+begin_src emacs-lisp (use-package haskell-mode + :defer t :config (setq haskell-indentation-layout-offset 4 haskell-indentation-left-offset 4 @@ -1190,6 +1389,7 @@ executable from [[https://github.com/mpickering/apply-refact][apply-refact]]. #+begin_src emacs-lisp (use-package hlint-refactor + :after haskell-mode :bind (:map hlint-refactor-mode-map ("C-c l b" . hlint-refactor-refactor-buffer) ("C-c l r" . hlint-refactor-refactor-at-point)) @@ -1199,7 +1399,8 @@ executable from [[https://github.com/mpickering/apply-refact][apply-refact]]. *** [[https://github.com/flycheck/flycheck-haskell][flycheck-haskell]] #+begin_src emacs-lisp -(use-package flycheck-haskell) +(use-package flycheck-haskell + :after haskell-mode) #+end_src *** [[https://github.com/ndmitchell/hlint/blob/20e116a043f2073c57b17b24ae6364b5e433ba7e/data/hs-lint.el][hs-lint.el]] @@ -1353,6 +1554,7 @@ instead. #+begin_src emacs-lisp (use-package sgml-mode + :defer t :config (setq sgml-basic-offset 2)) #+end_src @@ -1361,6 +1563,7 @@ instead. #+begin_src emacs-lisp (use-package css-mode + :defer t :config (setq css-indent-offset 2)) #+end_src @@ -1369,6 +1572,7 @@ instead. #+begin_src emacs-lisp (use-package web-mode + :defer t :mode "\\.html\\'" :config (setq-every! 2 @@ -1381,6 +1585,7 @@ instead. #+begin_src emacs-lisp (use-package emmet-mode + :after (:any web-mode css-mode sgml-mode) :bind* (("C-)" . emmet-next-edit-point) ("C-(" . emmet-prev-edit-point)) :config @@ -1393,6 +1598,7 @@ instead. #+begin_src emacs-lisp (use-package nix-mode + :defer t :mode "\\.nix\\'") #+end_src @@ -1491,40 +1697,43 @@ Emacs package that displays available keybindings in popup :config (which-key-mode)) #+end_src -** [[https://github.com/seagle0128/doom-modeline][doom-modeline]] +** [[https://github.com/Malabarba/smart-mode-line][smart-mode-line]] #+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/maio/eink-emacs][eink-theme]] - -#+begin_src emacs-lisp -(setq doom-modeline-bar-width 5) -(load-theme 'eink t) +(use-package smart-mode-line + :config + (sml/setup) + ;; (sml/apply-theme 'light) + (remove-hook 'display-time-hook 'sml/propertize-time-string)) #+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) - ("C-c b K" . crux-kill-other-buffers) - ("C-c f c" . crux-copy-file-preserve-attributes) - ("C-c f D" . crux-delete-file-and-buffer) - ("C-c f R" . crux-rename-file-and-buffer) - ("C-S-j" . crux-top-join-line) - ("C-c j" . crux-top-join-line))) + :defer 1 + :general + (amin--leader-keys + "b K" 'crux-kill-other-buffers + "c d" 'crux-duplicate-current-line-or-region + "c D" 'crux-duplicate-and-comment-current-line-or-region + "f c" 'crux-copy-file-preserve-attributes + "f d" 'crux-delete-file-and-buffer + "f r" 'crux-rename-file-and-buffer) + :bind (("C-c d" . crux-duplicate-current-line-or-region) + ("C-c D" . crux-duplicate-and-comment-current-line-or-region) + ("C-S-j" . crux-top-join-line) + ("C-c j" . crux-top-join-line))) #+end_src ** [[https://github.com/alezost/mwim.el][mwim]] #+begin_src emacs-lisp (use-package mwim + :general + (:states '(normal visual) + "0" 'mwim-beginning-of-code-or-line + "$" 'mwim-end-of-code-or-line) :bind (("C-a" . mwim-beginning-of-code-or-line) ("C-e" . mwim-end-of-code-or-line) ("" . mwim-beginning-of-line-or-code) @@ -1535,7 +1744,7 @@ Emacs package that displays available keybindings in popup #+begin_src emacs-lisp (use-package projectile - :defer 5 + :defer 2 :bind-keymap ("C-c p" . projectile-command-map) :config (projectile-mode) @@ -1556,33 +1765,26 @@ Emacs package that displays available keybindings in popup #+begin_src emacs-lisp (use-package helpful - :bind - (;; ("C-h F" . helpful-function) - ("C-h f" . helpful-callable) - ("C-h v" . helpful-variable) - ("C-h k" . helpful-key) - ("C-c C-d" . helpful-at-point) - ("C-h C" . helpful-command) - ("C-h c" . describe-char) - ("C-h F" . describe-face))) - -(use-package help - :bind - (("C-S-h f" . describe-function) - ("C-S-h v" . describe-variable) - ("C-S-h k" . describe-key) - ("C-S-h C" . describe-coding-system) - ("C-S-h c" . describe-key-briefly)) - :config (setq help-window-select t)) + :defer 1 + :general + (amin--leader-keys + "h h" '(:ignore t :wk "helpful") + "h h c" 'helpful-command + "h h f" 'helpful-callable ; helpful-function + "h h v" 'helpful-variable + "h h k" 'helpful-key + "h h p" 'helpful-at-point)) #+end_src ** [[https://github.com/kyagi/shell-pop-el][shell-pop]] #+begin_src emacs-lisp (use-package shell-pop - :custom - (shell-pop-universal-key "C-c e") - (shell-pop-shell-type '("eshell" "*eshell*" (lambda nil (eshell))))) + :defer 1 + :general (amin--leader-keys "a s" 'shell-pop) + :init + (setq shell-pop-universal-key "C-c e" + shell-pop-shell-type '("eshell" "*eshell*" (lambda nil (eshell))))) #+end_src ** [[https://github.com/EricCrosson/unkillable-scratch][unkillable-scratch]] @@ -1591,6 +1793,7 @@ Make =*scratch*= and =*Messages*= unkillable. #+begin_src emacs-lisp (use-package unkillable-scratch + :defer 3 :config (unkillable-scratch 1) :custom @@ -1607,6 +1810,7 @@ Make =*scratch*= and =*Messages*= unkillable. #+begin_src emacs-lisp (use-package boxquote + :defer 3 :bind (:prefix-map amin--boxquote-prefix-map :prefix "C-c q" @@ -1634,11 +1838,11 @@ Make =*scratch*= and =*Messages*= unkillable. Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. -** [[https://github.com/DarthFennec/highlight-indent-guides][highlight-indent-guides]] +** COMMENT [[https://github.com/DarthFennec/highlight-indent-guides][highlight-indent-guides]] :ARCHIVE: #+begin_src emacs-lisp (use-package highlight-indent-guides - :demand t + :defer 3 :hook ((prog-mode . highlight-indent-guides-mode) ;; (org-mode . highlight-indent-guides-mode) ) @@ -1655,6 +1859,7 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. #+begin_src emacs-lisp (use-package pdf-tools + :defer t :magic ("%PDF" . pdf-view-mode) :config (setq pdf-view-resize-factor 1.05) @@ -1679,6 +1884,7 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. #+begin_src emacs-lisp (use-package typo + :defer 2 :config (typo-global-mode 1) :hook (text-mode . typo-mode)) @@ -1719,6 +1925,9 @@ Hopefully temporary. :subscribed-channels '(general) :full-and-display-names t) (add-to-list 'swiper-font-lock-exclude 'slack-message-buffer-mode t) + (setq lui-time-stamp-format "[%Y-%m-%d %H:%M:%S]" + lui-time-stamp-only-when-changed-p t + lui-time-stamp-position 'right) :bind (("C-c s s" . slack-start) ("C-c s u" . slack-select-unread-rooms) @@ -1746,6 +1955,65 @@ Hopefully temporary. (setq alert-default-style 'notifier)) #+end_src +** hl-todo + +#+begin_src emacs-lisp +(use-package hl-todo + :defer 4 + :config + (global-hl-todo-mode)) +#+end_src + +** shrink-path + +#+begin_src emacs-lisp +(use-package shrink-path + :after eshell + :config + (setq eshell-prompt-regexp "\\(.*\n\\)*λ " + eshell-prompt-function #'+eshell/prompt) + + (defun +eshell/prompt () + (let ((base/dir (shrink-path-prompt default-directory))) + (concat (propertize (car base/dir) + 'face 'font-lock-comment-face) + (propertize (cdr base/dir) + 'face 'font-lock-constant-face) + (propertize (+eshell--current-git-branch) + 'face 'font-lock-function-name-face) + "\n" + (propertize "λ" 'face 'eshell-prompt-face) + ;; needed for the input text to not have prompt face + (propertize " " 'face 'default)))) + + (defun +eshell--current-git-branch () + (let ((branch (car (loop for match in (split-string (shell-command-to-string "git branch") "\n") + when (string-match "^\*" match) + collect match)))) + (if (not (eq branch nil)) + (concat " " (substring branch 2)) + "")))) +#+end_src + +** magithub + +For when I /have to/ use GH. + +#+begin_src emacs-lisp +(use-package magithub + :after magit + :config + (magithub-feature-autoinject t) + (setq magithub-clone-default-directory "~/src/git")) +#+end_src + +** [[https://github.com/peterwvj/eshell-up][eshell-up]] + +#+begin_src emacs-lisp +(use-package eshell-up + :after eshell) +#+end_src + * Email #+begin_src emacs-lisp @@ -1757,35 +2025,43 @@ Hopefully temporary. ** Gnus #+begin_src emacs-lisp -(setq amin-gnus-init-file (no-littering-expand-etc-file-name "gnus")) +(setq + amin-gnus-init-file (no-littering-expand-etc-file-name "gnus") + mail-user-agent 'gnus-user-agent + read-mail-command 'gnus) (use-package gnus - :bind ("s-m" . gnus) + :general + (amin--leader-keys + "m" 'gnus + "M" 'gnus-unplugged) + :bind (("s-m" . gnus) + ("s-M" . gnus-unplugged)) :init (setq - gnus-select-method - '(nnimap "amin" + gnus-select-method '(nnnil "") + gnus-secondary-select-methods + '((nnimap "amin" (nnimap-stream plain) (nnimap-address "127.0.0.1") (nnimap-server-port 143) (nnimap-authenticator plain) (nnimap-user "amin@aminb.org")) - gnus-secondary-select-methods - '((nnimap "uwaterloo" + (nnimap "uwaterloo" (nnimap-stream plain) (nnimap-address "127.0.0.1") (nnimap-server-port 143) (nnimap-authenticator plain) (nnimap-user "abandali@uwaterloo.ca"))) - gnus-message-archive-group "nnimap:Sent" + gnus-message-archive-group "nnimap+amin:Sent" gnus-parameters - '(("amin" - (display . 20)) - ("uwaterloo" - (display . 20))) + '(("gnu.*" + (gcc-self . t))) + gnus-large-newsgroup 50 gnus-home-directory (no-littering-expand-var-file-name "gnus/") - gnus-directory (no-littering-expand-var-file-name "gnus/News/") - message-directory amin-maildir + gnus-directory (concat gnus-home-directory "news/") + message-directory (concat gnus-home-directory "mail/") + nndraft-directory (concat gnus-home-directory "drafts/") gnus-save-newsrc-file nil gnus-read-newsrc-file nil gnus-interactive-exit nil @@ -1795,12 +2071,12 @@ Hopefully temporary. :config (setq gnus-visible-headers - (concat gnus-visible-headers "\\|^List-Id:\\|^X-RT-Originator:") + (concat gnus-visible-headers "\\|^List-Id:\\|^X-RT-Originator:\\|^User-Agent:") gnus-sorted-header-list '("^From:" "^Subject:" "^Summary:" "^Keywords:" "^Followup-To:" "^To:" "^Cc:" "X-RT-Originator" "^Newsgroups:" "List-Id:" "^Organization:" - "^Date:") + "^User-Agent:" "^Date:") ;; local-lapsed article dates ;; from https://www.emacswiki.org/emacs/GnusFormatting#toc11 gnus-article-date-headers '(user-defined) @@ -1816,8 +2092,9 @@ Hopefully temporary. (concat local lapsed)))) (bind-keys :map gnus-article-mode-map - ("r" . gnus-article-reply-with-original) - ("R" . gnus-article-wide-reply-with-original))) + ("r" . gnus-article-reply-with-original) + ("R" . gnus-article-wide-reply-with-original) + ("M-L" . org-store-link))) (use-package gnus-sum :bind (:map gnus-summary-mode-map @@ -1827,27 +2104,229 @@ Hopefully temporary. ("w" . gnus-summary-wide-reply) ("v" . gnus-summary-show-raw-article)) :config - (setq gnus-extra-headers (append gnus-extra-headers - '(List-Id X-RT-Originator))) (bind-keys :map gnus-summary-mode-map - ("r" . gnus-summary-reply-with-original) - ("R" . gnus-summary-wide-reply-with-original))) + ("r" . gnus-summary-reply-with-original) + ("R" . gnus-summary-wide-reply-with-original) + ("M-L" . org-store-link))) + +(use-package gnus-msg + :config + (setq gnus-posting-styles + '((".*" + (address "amin@aminb.org") + (body "\nBest,\namin\n")) + ("gnu.*" + (address "bandali@gnu.org")) + ((header "subject" "ThankCRM") + (to "webmasters-comment@gnu.org")) + ("nnimap\\+uwaterloo:.*" + (address "abandali@uwaterloo.ca") + (gcc "\"nnimap+uwaterloo:Sent Items\""))))) + +(use-package gnus-topic + :hook (gnus-group-mode . gnus-topic-mode)) -(use-package nnmail +(use-package gnus-agent :config - (setq nnmail-extra-headers (append nnmail-extra-headers - '(List-Id X-RT-Originator)))) + (setq gnus-agent-synchronize-flags 'ask) + :hook (gnus-group-mode . gnus-agent-mode)) (use-package gnus-group - :hook (gnus-group-mode . gnus-topic-mode)) + :config + (setq gnus-permanently-visible-groups "\\((INBOX\\|gnu$\\)")) (use-package mm-decode :config (setq mm-discouraged-alternatives '("text/html" "text/richtext"))) #+end_src -** gnus-alias +** sendmail + +#+begin_src emacs-lisp +(use-package sendmail + :config + (setq sendmail-program "/usr/bin/msmtp" + ;; message-sendmail-extra-arguments '("-v" "-d") + mail-specify-envelope-from t + mail-envelope-from 'header)) +#+end_src + +** message + +#+begin_src emacs-lisp +(use-package message + :config + (defconst message-cite-style-bandali + '((message-cite-function 'message-cite-original) + (message-citation-line-function 'message-insert-formatted-citation-line) + (message-cite-reply-position 'traditional) + (message-yank-prefix "> ") + (message-yank-cited-prefix ">") + (message-yank-empty-prefix ">") + (message-citation-line-format "Hi %F,\n\nOn %Y-%m-%d %l:%M %p, %N wrote:")) + "Citation style based on Mozilla Thunderbird's. Use with message-cite-style.") + (setq message-cite-style 'message-cite-style-bandali + message-kill-buffer-on-exit t + message-send-mail-function 'message-send-mail-with-sendmail + message-sendmail-envelope-from 'header + message-dont-reply-to-names + "\\(\\(.*@aminb\\.org\\)\\|\\(\\(aminb?\\|mab\\|bandali\\)@gnu\\.org\\)\\|\\(\\(m\\|a\\(min\\.\\)?\\)bandali@uwaterloo\\.ca\\)\\)" + message-user-fqdn "aminb.org") + :hook (;; (message-setup . mml-secure-message-sign-pgpmime) + (message-mode . flyspell-mode) + (message-mode . (lambda () (setq fill-column 65 + message-fill-column 65)))) + :custom-face + (message-header-subject ((t (:foreground "#111" :weight semi-bold)))) + (message-header-to ((t (:foreground "#111" :weight normal)))) + (message-header-cc ((t (:foreground "#333" :weight normal))))) + +(after! mml-sec + (setq mml-secure-openpgp-encrypt-to-self t + mml-secure-openpgp-sign-with-sender t)) +#+end_src + +** footnote + +Convenient footnotes in =message-mode=. + +#+begin_src emacs-lisp +(use-package footnote + :after message + :bind + (:map message-mode-map + :prefix-map amin--footnote-prefix-map + :prefix "C-c f" + ("a" . footnote-add-footnote) + ("b" . footnote-back-to-message) + ("c" . footnote-cycle-style) + ("d" . footnote-delete-footnote) + ("g" . footnote-goto-footnote) + ("r" . footnote-renumber-footnotes) + ("s" . footnote-set-style)) + :config + (setq footnote-start-tag "" + footnote-end-tag "" + footnote-style 'unicode)) +#+end_src + +** COMMENT supercite + +#+begin_src emacs-lisp +(use-package supercite + :after message + :init + (setq sc-nested-citation-p t + ;; sc-cite-blank-lines-p t + sc-citation-leader "" + sc-reference-tag-string "" + sc-preferred-header-style 5 ; (sc-header-author-writes) + sc-auto-fill-region-p nil + sc-confirm-always-p nil) + :config + ;; (defun amin--sc-header-on-wrote () + ;; "\"On , wrote:\" unless: + ;; 1. the \"sc-author\" field cannot be found, in which case nothing is inserted; + ;; 2. the \"date\" field is missing in which case only the from part is printed." + ;; (let ((sc-mumble "") + ;; (whofrom (sc-whofrom))) + ;; (if whofrom + ;; (insert sc-reference-tag-string + ;; (sc-hdr "On " (sc-mail-field "date") ", ") + ;; (sc-hdr "" (sc-mail-field "sc-author")) " wrote:\n")))) + ;; (defun amin--sc-header () + ;; "Hi ,\n\n writes:" + ;; (let ((sc-mumble "") + ;; (whofrom (sc-whofrom))) + ;; (if whofrom + ;; (insert (sc-hdr "Hi " (sc-mail-field "sc-firstname") ",\n\n") + ;; sc-reference-tag-string + ;; whofrom + ;; " writes:\n")))) + ;; (add-to-list 'sc-rewrite-header-list '(amin--sc-header) t) + ;; (add-to-list 'sc-rewrite-header-list '(amin--sc-header-on-wrote) t) + ;; (setq sc-preferred-header-style (1- (length sc-rewrite-header-list))) + (add-hook 'mail-citation-hook 'sc-cite-original)) +#+end_src + +** ebdb + +#+begin_src emacs-lisp +(use-package ebdb + :defer 1 + :bind (:map gnus-group-mode-map ("e" . ebdb)) + :config + (setq ebdb-sources (no-littering-expand-var-file-name "ebdb"))) + +(use-package ebdb-com + :after ebdb) + +(use-package ebdb-complete + :after ebdb + :config + (ebdb-complete-enable)) + +(use-package ebdb-gnus + :after ebdb) + +(use-package ebdb-message + :after ebdb) + +;; (use-package ebdb-vcard +;; :after ebdb) +#+end_src + +** COMMENT bbdb + +#+begin_comment +[submodule "bbdb"] + path = lib/bbdb + url = https://git.savannah.nongnu.org/git/bbdb.git + load-path = lisp/elisp + info-path = doc + build-step = ./autogen.sh + build-step = ./configure --with-lispdir=elisp + build-step = make + build-step = make install +#+end_comment + +#+begin_src emacs-lisp +(use-package bbdb + :init + (bbdb-mua-auto-update-init 'message) + (setq bbdb-mua-auto-update-p 'query) + (add-hook 'gnus-startup-hook 'bbdb-insinuate-gnus)) +#+end_src + +** COMMENT message-x + +#+begin_src emacs-lisp +(use-package message-x + :custom + (message-x-completion-alist + (quote + (("\\([rR]esent-\\|[rR]eply-\\)?[tT]o:\\|[bB]?[cC][cC]:" . gnus-harvest-find-address) + ((if + (boundp + (quote message-newgroups-header-regexp)) + message-newgroups-header-regexp message-newsgroups-header-regexp) + . message-expand-group))))) +#+end_src + +** COMMENT gnus-harvest + +#+begin_src emacs-lisp +(use-package gnus-harvest + :commands gnus-harvest-install + :demand t + :config + (if (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install))) +#+end_src + +** COMMENT gnus-alias :ARCHIVE: #+begin_src emacs-lisp (use-package gnus-alias @@ -1888,95 +2367,6 @@ Hopefully temporary. :hook (message-setup . gnus-alias-determine-identity)) #+end_src -** sendmail - -#+begin_src emacs-lisp -(use-package sendmail - :config - (setq sendmail-program "/usr/bin/msmtp" - ;; message-sendmail-extra-arguments '("-v" "-d") - mail-specify-envelope-from t - mail-envelope-from 'header)) -#+end_src - -** message - -#+begin_src emacs-lisp -(use-package message - :config - (setq message-kill-buffer-on-exit t - message-send-mail-function 'message-send-mail-with-sendmail - message-sendmail-envelope-from 'header - ;; message-directory "drafts" - message-user-fqdn "aminb.org") - ;; (add-hook 'message-mode-hook 'electric-quote-local-mode) - (add-hook 'message-mode-hook - (lambda () (setq fill-column 65 - message-fill-column 65))) - (add-hook 'message-mode-hook - #'flyspell-mode) - ;; (add-hook 'message-setup-hook - ;; #'mml-secure-message-sign-pgpmime) - :custom-face - (message-header-subject ((t (:foreground "navy blue" :weight semi-bold)))) - (message-header-to ((t (:foreground "MidnightBlue" :weight semi-bold))))) - -(after! mml-sec - (setq mml-secure-openpgp-encrypt-to-self t - mml-secure-openpgp-sign-with-sender t)) -#+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 - ** COMMENT [[https://notmuchmail.org][notmuch]] :ARCHIVE: See [[notmuch:id:87muuqsvci.fsf@fencepost.gnu.org][bug follow-up]].