2024-01-09 14:30:20 +00:00
#+title : Emacs Config
#+author : Evie Litherland-Smith
#+email : evie@xenia.me.uk
#+filetags : :emacs:config:org:
#+property : header-args:emacs-lisp :tangle yes :mkdirp yes :results output silent
2023-12-11 12:07:35 +00:00
2023-12-11 12:19:43 +00:00
* Setup
2024-01-16 08:23:26 +00:00
Loading this file is handled automatically on my [[https://git.xenia.me.uk/xenia/nixos/src/branch/main/home/emacs.nix ][NixOS config ]], otherwise add ~(org-babel-load-file "~ /.emacs/README.org")~ to init file.
2023-12-11 12:19:43 +00:00
2023-12-11 12:07:35 +00:00
* Common defaults
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp :results output silent
2023-12-11 12:07:35 +00:00
(setq custom-file (locate-user-emacs-file "custom.el"))
(when (and custom-file (file-exists-p custom-file))
(load custom-file nil 'nomessage))
(setq user-full-name "Evie Litherland-Smith"
user-mail-address "evie@xenia.me.uk"
use-short-answers t
load-prefer-newer t
indent-tabs-mode nil
2024-01-09 07:30:14 +00:00
even-window-sizes t
2023-12-11 12:07:35 +00:00
global-auto-revert-non-file-buffers t
dired-auto-revert-buffer t
dired-dwim-target t
2024-01-09 07:30:14 +00:00
tab-always-indent t
completion-cycle-threshold nil
2023-12-11 12:07:35 +00:00
completions-detailed t
xref-show-definitions-function #'xref-show-definitions-completing-read
kill-do-not-save-duplicates t
auto-window-vscroll nil
fast-but-imprecise-scrolling t
scroll-conservatively 101
scroll-margin 0
scroll-preserve-screen-position 1)
2024-01-29 08:44:54 +00:00
;; Scratch buffer shortcut
(keymap-global-set "C-c w x" #'scratch-buffer)
2024-01-19 16:32:18 +00:00
;; Bind normal forward/back buttons on mouse to next/previous buffer respectively
2024-01-14 06:49:58 +00:00
(keymap-global-set "<mouse-8 >" #'previous-buffer)
(keymap-global-set "<mouse-9 >" #'next-buffer)
2023-12-11 12:07:35 +00:00
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(global-auto-revert-mode +1)
2023-12-15 09:51:24 +00:00
(delete-selection-mode +1)
2023-12-11 12:07:35 +00:00
2024-01-25 08:53:58 +00:00
;; No tabs
(customize-set-variable 'indent-tabs-mode nil)
2023-12-11 12:07:35 +00:00
;; Make shebang (#!) file executable when saved
(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
2024-01-30 10:12:57 +00:00
;; Scroll compilation buffer output
(customize-set-variable 'compilation-scroll-output t)
2024-01-09 14:30:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** Auto-save file settings
#+begin_src emacs-lisp :tangle yes
(setq backup-directory-alist '(("." . "~/.local/state/emacs/backups"))
tramp-backup-directory-alist backup-directory-alist
tramp-auto-save-directory (cdr (assoc "." tramp-backup-directory-alist)))
2023-12-15 14:02:08 +00:00
(savehist-mode +1)
2023-12-11 12:07:35 +00:00
#+end_src
2023-12-15 10:01:40 +00:00
** Recent files
#+begin_src emacs-lisp
(use-package recentf
:config
2023-12-15 14:02:08 +00:00
(run-at-time nil (* 5 60) 'recentf-save-list)
(recentf-mode +1)
2023-12-15 10:01:40 +00:00
:custom
(recentf-max-saved-items 2048))
#+end_src
2023-12-11 12:07:35 +00:00
** package-archive with priorities
#+begin_src emacs-lisp :results output silent
(when (require 'package nil :noerror)
(add-to-list 'package-archives '("stable" . "https://stable.melpa.org/packages/ "))
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/ "))
(setq package-archive-priorities '(("gnu" . 99)
("nongnu" . 80)
("stable" . 70)
("melpa" . 0))))
#+end_src
2024-01-09 07:30:14 +00:00
** diminish modes
#+begin_src emacs-lisp
(use-package diminish :ensure t)
#+end_src
2023-12-11 12:07:35 +00:00
** Authentication
#+begin_src emacs-lisp
(when (require 'auth-source nil :noerror)
(setq auth-sources '("secrets:Login"))
(when (require 'auth-source-pass nil :noerror)
(auth-source-pass-enable)))
#+end_src
** Helpful
#+begin_src emacs-lisp
;; Make `describe-*' screens more helpful
(use-package helpful
:ensure t
:bind (("<remap > <describe-command >" . helpful-command)
("<remap > <describe-function >" . helpful-callable)
("<remap > <describe-key >" . helpful-key)
("<remap > <describe-symbol >" . helpful-symbol)
("<remap > <describe-variable >" . helpful-variable)
("C-h F" . helpful-function)
:map helpful-mode-map
("<remap > <revert-buffer >" . helpful-update)))
;; Bind extra `describe-*' commands
(keymap-global-set "C-h K" #'describe-keymap)
#+end_src
2024-01-10 15:36:19 +00:00
** Spell checking
#+begin_src emacs-lisp
;; turn on spell checking, if available.
(when (and (require 'ispell nil :noerror) (executable-find ispell-program-name))
(use-package flyspell
:ensure t
:diminish
:hook ((text-mode . flyspell-mode)
(prog-mode . flyspell-prog-mode))
:custom
(flyspell-mode-line-string nil)
(flyspell-use-meta-tab nil))
(use-package flyspell-correct
:ensure t
:diminish
2024-01-10 15:40:09 +00:00
:after flyspell
2024-01-10 15:36:19 +00:00
:bind ( :map flyspell-mode-map
("C-;" . flyspell-correct-wrapper)))
(use-package consult-flyspell
:ensure t
:diminish
2024-01-10 15:40:09 +00:00
:after (consult flyspell)
:bind ( :map flyspell-mode-map
2024-01-10 15:48:34 +00:00
("C-c s ;" . consult-flyspell))
:config
(setq consult-flyspell-always-check-buffer t)))
2024-01-10 15:36:19 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** ibuffer
#+begin_src emacs-lisp
(use-package ibuffer
:ensure t
:bind (("C-c b" . ibuffer)))
(use-package ibuffer-project
:ensure t
:after ibuffer
:hook ((ibuffer . (lambda ()
(setq ibuffer-filter-groups (ibuffer-project-generate-filter-groups))
(unless (eq ibuffer-sorting-mode 'project-file-relative)
(ibuffer-do-sort-by-project-file-relative))))))
#+end_src
** Link hint keymaps
#+begin_src emacs-lisp
(use-package link-hint
:ensure t
:bind (("C-c l o" . link-hint-open-link)
("C-c l c" . link-hint-copy-link)
("C-c l C-o" . link-hint-open-all-link)
("C-c l C-c" . link-hint-copy-all-link)))
#+end_src
** Avy keymaps
#+begin_src emacs-lisp
(use-package avy
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2024-01-10 14:20:58 +00:00
:bind (("C-c j j" . avy-goto-char-2)
("C-c j w" . avy-goto-word-0)
2023-12-11 12:07:35 +00:00
("C-c j c" . avy-goto-char)
2024-01-10 14:20:58 +00:00
("C-c j l" . avy-goto-line)))
2023-12-11 12:07:35 +00:00
#+end_src
** which-func config
#+begin_src emacs-lisp
(use-package which-func
:ensure t
:init (which-function-mode))
#+end_src
2023-12-19 15:13:08 +00:00
** Shells and terminals
#+begin_src emacs-lisp
(use-package shell
:bind (("C-c t s" . shell)))
(use-package eshell
:bind (("C-c t e" . eshell)))
#+end_src
2024-01-29 13:47:17 +00:00
** Web browser
#+begin_src emacs-lisp :tangle yes
(use-package eww
:defer t
:diminish
:custom
(browse-url-browser-function 'eww-browse-url)
(browse-url-new-window-flag t)
(eww-default-download-directory "~/Downloads/ ")
(eww-auto-rename-buffer 'title)
(eww-browse-url-new-window-is-tab nil))
#+end_src
2023-12-11 12:07:35 +00:00
* UI
#+begin_src emacs-lisp
(setq use-dialog-box nil
truncate-lines nil
truncate-partial-width-windows nil)
2024-01-09 07:30:14 +00:00
(menu-bar-mode +1)
(global-prettify-symbols-mode +1)
2024-01-09 14:26:32 +00:00
(global-display-line-numbers-mode -1)
2023-12-11 12:07:35 +00:00
(tool-bar-mode -1)
2024-01-09 07:30:14 +00:00
2024-01-09 14:26:32 +00:00
(add-hook 'prog-mode-hook #'(lambda () (display-line-numbers-mode +1)))
2024-01-11 14:59:56 +00:00
(with-eval-after-load 'diminish
(diminish 'visual-line-mode))
2024-01-14 11:01:27 +00:00
(global-visual-line-mode -1)
(add-hook 'text-mode-hook #'(lambda () (visual-line-mode +1)))
(add-hook 'prog-mode-hook #'(lambda () (visual-line-mode +1)))
2023-12-11 12:07:35 +00:00
(use-package which-key
:ensure t
2024-01-09 07:30:14 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:config (which-key-mode +1))
(use-package page-break-lines
:ensure t
2024-01-09 07:30:14 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:config (global-page-break-lines-mode +1))
;; add visual pulse when changing focus, like beacon but built-in
;; from from https://karthinks.com/software/batteries-included-with-emacs/
(defun pulse-line (&rest _)
"Pulse the current line."
(pulse-momentary-highlight-one-line (point)))
(dolist (command '(scroll-up-command
scroll-down-command
recenter-top-bottom
other-window))
(advice-add command :after #'pulse-line))
#+end_src
** Theme, font and nerd-icons
#+begin_src emacs-lisp
2024-01-10 09:40:13 +00:00
(add-to-list 'initial-frame-alist '(width . 120))
(add-to-list 'initial-frame-alist '(height . 80))
2023-12-11 12:07:35 +00:00
;; Theme
2024-01-09 11:52:59 +00:00
(use-package modus-themes
2023-12-11 12:07:35 +00:00
:ensure t
2023-12-18 07:07:12 +00:00
:custom
2024-01-09 11:52:59 +00:00
(modus-themes-disable-other-themes t)
(modus-themes-to-toggle '(modus-operandi-tinted modus-vivendi-tinted))
2024-01-16 13:52:39 +00:00
(modus-themes-bold-constructs t)
(modus-themes-italic-constructs t)
2024-01-09 11:52:59 +00:00
(modus-themes-org-blocks 'gray-background)
(modus-themes-completions '((matches . (extrabold underline))
(selection . (semibold italic))))
(modus-themes-headings '((1 . (1.4))
(2 . (1.3))
(3 . (1.2))
(agenda-date . (1.3))
(agenda-structure . (light 1.8))
(t . (1.1))))
2023-12-18 07:07:12 +00:00
:config
2024-01-09 11:52:59 +00:00
(modus-themes-load-theme 'modus-vivendi-tinted))
2023-12-11 12:07:35 +00:00
;; Nerd-Icons modes
(use-package nerd-icons
:ensure t
2024-01-11 07:06:11 +00:00
:diminish
2024-01-11 15:51:10 +00:00
:config (nerd-icons-set-font "Symbols Nerd Font Mono-12"))
2023-12-11 12:07:35 +00:00
(use-package nerd-icons-dired
:ensure t
2023-12-14 09:25:25 +00:00
:after nerd-icons
2024-01-11 07:06:11 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:hook (dired-mode))
(use-package nerd-icons-ibuffer
:ensure t
2023-12-14 09:25:25 +00:00
:after nerd-icons
2024-01-11 07:06:11 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:hook (ibuffer-mode))
(use-package nerd-icons-completion
:ensure t
2023-12-14 09:25:25 +00:00
:after nerd-icons
2024-01-11 07:06:11 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:config (nerd-icons-completion-mode +1))
(use-package nerd-icons-corfu
:ensure t
2023-12-14 09:25:25 +00:00
:after (corfu nerd-icons)
2024-01-11 07:06:11 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:config (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
(keymap-global-set "C-c i n" #'nerd-icons-insert)
#+end_src
2024-01-17 05:56:03 +00:00
*** TODO Font ligatures
#+begin_src emacs-lisp
(use-package ligature
:ensure t
:diminish
:config
(ligature-set-ligatures
'(text-mode prog-mode org-mode)
'("<--" "<---" "<<-" "<-" "- >" "->>" "-->" "--->"
"<==" "<= ==" "<<= " "<=" "= >" "=>>" "= =>" "= ==>"
"<- >" "<-- >" "<--- >" "<---- >" "<= >" "<== >" "<=== >" "<==== >" "::" ":::"
"<~~" "</" "</>" "/>" "~ ~>" "==" "!= " "<>" "===" "!= =" "!= =="
"<:" ":=" "*= " "*+" "<* " "<* >" "*>" "<|" "<|>" "|>" "+* " "=*" "= :" ":>"
"/*" "*/ " "+++" "<!--" "<!---"))
(global-ligature-mode +1))
#+end_src
2023-12-11 12:07:35 +00:00
** Window management
2024-01-03 09:39:47 +00:00
*** windmove
#+begin_src emacs-lisp
(use-package windmove
:ensure t
:demand
2024-01-10 10:30:52 +00:00
:diminish
2024-01-03 09:39:47 +00:00
:config (windmove-mode +1)
2024-01-03 10:35:49 +00:00
:bind (("C-c w k" . windmove-up)
("C-c w C-k" . windmove-display-up)
("C-c w K" . windmove-swap-states-up)
("C-c w j" . windmove-down)
("C-c w C-j" . windmove-display-down)
("C-c w J" . windmove-swap-states-down)
("C-c w h" . windmove-left)
("C-c w C-h" . windmove-display-left)
("C-c w H" . windmove-swap-states-left)
("C-c w l" . windmove-right)
("C-c w C-l" . windmove-display-right)
("C-c w L" . windmove-swap-states-right)))
2024-01-03 09:39:47 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
*** winner
#+begin_src emacs-lisp
(use-package winner
:ensure t
:demand
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:bind (("C-c w u" . winner-undo)
("C-c w r" . winner-redo))
:config
(winner-mode))
#+end_src
*** ediff
#+begin_src emacs-lisp :tangle yes
(use-package ediff
2024-01-10 10:30:52 +00:00
:ensure t
:diminish
2023-12-11 12:07:35 +00:00
:bind (("C-c d f" . ediff-files)
("C-c d b" . ediff-buffers)
("C-c d 3 f" . ediff-files3)
("C-c d 3 b" . ediff-buffers3))
:custom
(ediff-window-setup-function #'ediff-setup-windows-plain))
#+end_src
2023-12-20 10:59:20 +00:00
** Notifications
#+begin_src emacs-lisp
(use-package alert
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-20 10:59:20 +00:00
:custom
(alert-default-style 'libnotify))
#+end_src
2023-12-11 12:07:35 +00:00
** Modeline
#+begin_src emacs-lisp
2024-01-09 07:30:14 +00:00
(line-number-mode -1)
(column-number-mode -1)
(size-indication-mode -1)
2023-12-17 17:43:41 +00:00
(display-battery-mode -1)
2023-12-11 12:07:35 +00:00
(display-time-mode -1)
2024-01-09 07:30:14 +00:00
(setq mode-line-compact 'long)
2023-12-20 10:30:35 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** Zone
#+begin_src emacs-lisp :tangle yes
(use-package zone
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:config (zone-when-idle (* 60 60 2))) ; 2 hours
#+end_src
** Git status in fringe
#+begin_src emacs-lisp
(use-package diff-hl
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:init
2024-01-11 14:59:56 +00:00
(add-hook 'magit-pre-refresh-hook #'diff-hl-magit-pre-refresh)
(add-hook 'magit-post-refresh-hook #'diff-hl-magit-post-refresh)
2023-12-11 12:07:35 +00:00
:config
(global-diff-hl-mode)
:custom
(diff-hl-disable-on-remote t)
(diff-hl-draw-borders nil))
#+end_src
2023-12-14 09:25:46 +00:00
2023-12-11 12:07:35 +00:00
* Org-mode
For reference information, see [[https://orgmode.com ][Org-mode website ]]
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp :results output silent
2024-01-14 08:23:27 +00:00
(setq org-directory "~/Documents/Org"
2023-12-11 12:07:35 +00:00
org-default-notes-file (expand-file-name "notes.org" org-directory)
org-pretty-entities-include-sub-superscripts t
org-pretty-entities-include-sub-superscripts t
org-tags-column 0
org-outline-path-complete-in-steps nil
org-return-follows-link t
org-mouse-1-follows-link t
org-link-descriptive t
org-refile-use-outline-path t
org-refile-allow-creating-parent-nodes t
org-refile-use-outline-path 'file
2024-01-14 15:00:56 +00:00
org-refile-targets '((nil :maxlevel . 2)
(org-agenda-files :maxlevel . 1)
;; ((expand-file-name "journal" org-directory) :maxlevel . 1)
;; ((expand-file-name "roam" org-directory) :maxlevel . 1)
(org-agenda-files :tag . "inbox")))
2023-12-11 12:07:35 +00:00
;; Visually indent org-mode files to a given header level
(add-hook 'org-mode-hook #'org-indent-mode)
(use-package org
:ensure t
:custom
(org-babel-load-languages '((emacs-lisp . t)
(python . t))))
2024-01-09 14:30:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** Keymaps
#+begin_src emacs-lisp :results output silent
(keymap-global-set "C-c o ." #'calendar)
(keymap-global-set "C-c o e" #'org-edit-src-code)
(keymap-global-set "C-c o a" #'org-agenda)
(keymap-global-set "C-c o n" #'org-capture)
(keymap-global-set "C-c o l" #'org-capture-goto-last-stored)
#+end_src
2024-01-29 10:10:03 +00:00
** org-roam
#+begin_src emacs-lisp
(use-package org-roam
:ensure t
:after org
:diminish
:bind (("C-c o r i" . org-roam-node-insert)
("C-c o r f" . org-roam-node-find)
("C-c o r n" . org-roam-capture))
:custom
(org-roam-directory (expand-file-name "roam" org-directory))
(org-roam-node-display-template (concat "${title:*} "
(propertize "${tags:10}" 'face 'org-tag)))
2024-02-05 14:41:35 +00:00
:config
2024-02-02 06:49:40 +00:00
(mkdir org-roam-directory t)
2024-01-29 10:10:03 +00:00
(add-to-list 'display-buffer-alist
'("\\*org-roam\\* "
(display-buffer-in-side-window)
(side . right)
(slot . 0)
(window-width . 0.33)
(window-parameters . ((no-other-window . t)
(no-delete-other-windows . t)))))
(org-roam-db-autosync-mode +1))
#+end_src
2023-12-11 12:07:35 +00:00
** org-agenda
#+begin_src emacs-lisp :results output silent
2024-01-31 14:54:23 +00:00
(setq org-agenda-span 'week
2023-12-11 12:07:35 +00:00
org-agenda-start-on-weekday 1
2024-02-02 10:23:53 +00:00
org-agenda-sticky nil
2023-12-11 12:07:35 +00:00
org-agenda-window-setup 'current-window
2023-12-15 09:47:08 +00:00
org-agenda-tags-column 0
2024-01-29 09:07:44 +00:00
org-agenda-todo-ignore-scheduled 'future
org-agenda-todo-ignore-deadlines 'far
2023-12-11 12:07:35 +00:00
org-agenda-prefix-format '((agenda . " %-12:c%?-12t% s")
(todo . " %-12:c")
(tags . " %-12:c")
(search . " %-12:c")))
2024-01-10 14:19:42 +00:00
(let ((agenda-file (expand-file-name ".agenda" org-directory)))
(if (file-exists-p agenda-file)
(setq org-agenda-files agenda-file)))
2023-12-11 12:07:35 +00:00
#+end_src
2023-12-20 10:59:20 +00:00
** org-alert
#+begin_src emacs-lisp
(use-package org-alert
:ensure t
2024-01-08 07:59:34 +00:00
:after alert
:config
2024-01-12 14:43:24 +00:00
(setq org-alert-notification-title "org-mode agenda"
org-alert-notify-cutoff 30
2024-01-14 17:35:59 +00:00
org-alert-notify-after-event-cutoff 5)
2024-01-08 07:59:34 +00:00
(org-alert-enable))
2023-12-20 10:59:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** org-journal
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp :results output silent
2023-12-11 12:07:35 +00:00
(use-package org-journal
:bind (("C-c o j" . org-journal-new-entry))
:custom
(org-journal-dir (expand-file-name "journal" org-directory))
(org-journal-file-type 'monthly)
(org-journal-file-format "%Y-%m.org"))
2024-01-09 14:30:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** Capture templates
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp :results output silent
2023-12-11 12:07:35 +00:00
(setq org-capture-templates
'(("n" "Note" entry
2024-01-14 15:02:14 +00:00
(file+headline "notes.org" "Inbox")
2024-01-05 08:06:12 +00:00
"* %?")
2023-12-11 12:07:35 +00:00
("t" "Task" entry
2024-01-05 08:06:12 +00:00
(file+headline "tasks.org" "Inbox")
2023-12-11 12:07:35 +00:00
"* TODO %?"
2024-01-05 08:06:12 +00:00
:prepend t)
("r" "Reading List" entry
2024-01-08 07:59:34 +00:00
(file+headline "reading.org" "Inbox")
2024-01-05 08:06:12 +00:00
"* %?")
2023-12-11 12:07:35 +00:00
("m" "Email Workflow")
("mf" "Follow Up" entry (file+olp "mail.org" "Follow Up")
"* TODO Follow up with %:fromname on %a\nSCHEDULED:%t\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i")
("mr" "Read Later" entry (file+olp "mail.org" "Read Later")
"* TODO Read %:subject\nSCHEDULED:%t\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%a\n\n%i")
))
2024-01-09 14:30:20 +00:00
#+end_src
2024-01-09 15:10:53 +00:00
** org-noter
#+begin_src emacs-lisp
(use-package org-noter
:ensure t
:diminish
2024-01-09 15:12:22 +00:00
:after (org doc-view)
:commands (org-noter)
2024-01-09 15:10:53 +00:00
:custom
(org-noter-always-create-frame nil)
(org-noter-kill-frame-at-session-end nil)
(org-noter-auto-save-last-location t)
(org-noter-default-notes-file-names '("notes.org"))
(org-noter-doc-property-in-notes t)
(org-noter-notes-search-path (list
(expand-file-name org-directory)
2024-01-14 08:23:27 +00:00
(expand-file-name "~/Documents/References/library/ ")))
2024-01-09 15:10:53 +00:00
(org-noter-prefer-root-as-file-level nil))
#+end_src
2023-12-11 12:07:35 +00:00
2024-01-02 17:12:18 +00:00
** Citar
2023-12-11 12:07:35 +00:00
#+begin_src emacs-lisp :results output silent
(use-package citar
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2024-01-17 10:42:00 +00:00
:custom
(org-cite-global-bibliography '("~/Documents/References/main.bib"))
(org-cite-insert-processor 'citar)
(org-cite-follow-processor 'citar)
(org-cite-activate-processor 'citar)
(citar-bibliography org-cite-global-bibliography)
(citar-library-paths '("~/Documents/References/library/ "))
(citar-notes-paths '("~/Documents/References/notes/ "))
:hook
(LaTeX-mode . citar-capf-setup)
(org-mode . citar-capf-setup)
2024-01-02 17:12:18 +00:00
:bind (("C-c r r" . citar-open)
2024-01-17 10:42:00 +00:00
:map org-mode-map :package org
("C-c r i" . #'org-cite-insert))
2023-12-11 12:07:35 +00:00
:config
(defvar citar-indicator-files-icons
(citar-indicator-create
:symbol (nerd-icons-octicon
"nf-oct-file"
:face 'nerd-icons-green
:v-adjust -0.1)
:function #'citar-has-files
:padding " " ; need this because the default padding is too low for these icons
:tag "has:files"))
(defvar citar-indicator-links-icons
(citar-indicator-create
:symbol (nerd-icons-octicon
"nf-oct-link"
:face 'nerd-icons-orange
:v-adjust 0.01)
:function #'citar-has-links
2024-01-02 17:12:18 +00:00
:padding " " ; need this because the default padding is too low for these icons
2023-12-11 12:07:35 +00:00
:tag "has:links"))
(defvar citar-indicator-notes-icons
(citar-indicator-create
:symbol (nerd-icons-octicon
"nf-oct-note"
:face 'nerd-icons-blue
:v-adjust -0.3)
:function #'citar-has-notes
2024-01-02 17:12:18 +00:00
:padding " " ; need this because the default padding is too low for these icons
2023-12-11 12:07:35 +00:00
:tag "has:notes"))
(defvar citar-indicator-cited-icons
(citar-indicator-create
:symbol (nerd-icons-octicon
"nf-oct-circle"
:face 'nerd-icon-green)
:function #'citar-is-cited
2024-01-02 17:12:18 +00:00
:padding " " ; need this because the default padding is too low for these icons
2023-12-11 12:07:35 +00:00
:tag "is:cited"))
(setq citar-indicators (list citar-indicator-files-icons
citar-indicator-links-icons
citar-indicator-notes-icons
citar-indicator-cited-icons)))
#+end_src
2024-01-08 11:26:39 +00:00
*** Citar Embark integration
#+begin_src emacs-lisp
(use-package citar-embark
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2024-01-08 11:26:39 +00:00
:after (citar embark)
:config
(citar-embark-mode +1))
#+end_src
2024-01-29 06:15:42 +00:00
*** LaTeX
#+begin_src emacs-lisp
(setq org-latex-compiler "lualatex")
(setq org-preview-latex-default-process 'dvisvgm)
#+end_src
2023-12-11 12:07:35 +00:00
** TODO Crafted config
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp
2023-12-11 12:07:35 +00:00
;; Disable auto-pairing of "<" in org-mode with electric-pair-mode
(defun crafted-org-enhance-electric-pair-inhibit-predicate ()
"Disable auto-pairing of \"<\" in `org-mode' when using `electric-pair-mode'."
(when (and electric-pair-mode (eql major-mode #'org-mode))
(setq-local electric-pair-inhibit-predicate
`(lambda (c)
(if (char-equal c ?<)
t
(,electric-pair-inhibit-predicate c))))))
;; Add hook to both electric-pair-mode-hook and org-mode-hook
;; This ensures org-mode buffers don't behave weirdly,
;; no matter when electric-pair-mode is activated.
(add-hook 'electric-pair-mode-hook #'crafted-org-enhance-electric-pair-inhibit-predicate)
(add-hook 'org-mode-hook #'crafted-org-enhance-electric-pair-inhibit-predicate)
2024-01-09 14:30:20 +00:00
#+end_src
2023-12-19 14:40:15 +00:00
* Password Store
#+begin_src emacs-lisp
(use-package password-store
:ensure t
2024-01-10 10:30:52 +00:00
:defer t
:diminish)
2023-12-11 12:07:35 +00:00
2023-12-19 14:40:15 +00:00
(use-package password-store-otp
:ensure t
2024-01-10 10:30:52 +00:00
:defer t
:diminish)
2023-12-19 14:40:15 +00:00
(use-package pass
:ensure t
:defer t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-20 09:43:15 +00:00
:bind (("C-c P" . pass))
:custom
(pass-show-keybindings nil)
(pass-username-field "login"))
2023-12-19 14:40:15 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
* Remote Editing
** TRAMP
#+begin_src emacs-lisp :tangle yes
(use-package tramp
:defer t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:config
(add-to-list 'tramp-remote-path 'tramp-own-remote-path))
#+end_src
2024-01-03 12:00:42 +00:00
*** Connection variables
#+begin_src emacs-lisp
(connection-local-set-profile-variables
'remote-disable-apheleia
'((apheleia-mode . nil)
(apheleia-inhibit . t)))
2024-01-12 13:06:57 +00:00
(connection-local-set-profile-variables
'remote-no-corfu-auto
'((corfu-auto . nil)))
2024-01-03 12:00:42 +00:00
(connection-local-set-profiles
2024-01-15 08:20:20 +00:00
'(:application tramp)
2024-01-12 13:06:57 +00:00
'remote-no-corfu-auto)
2024-01-15 08:20:20 +00:00
(connection-local-set-profiles
'(:application tramp :machine "heimdall")
'remote-disable-apheleia)
(connection-local-set-profiles
'(:application tramp :machine "freia")
'remote-disable-apheleia)
2024-01-03 12:00:42 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
* Development Environment
2024-02-01 13:31:02 +00:00
** Miscellaneous
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp
2023-12-11 12:07:35 +00:00
(use-package rainbow-delimiters
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:hook (prog-mode))
(use-package direnv
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:custom (direnv-always-show-summary nil)
:config (direnv-mode +1))
2024-01-09 14:30:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
2024-02-01 13:31:02 +00:00
** Grand Unified Debugger
#+begin_src emacs-lisp
(with-eval-after-load 'gud
(customize-set-variable 'gdb-many-windows t))
#+end_src
2023-12-31 09:03:20 +00:00
** Tree-sitter
Set treesit to fontify all elements, default was 3 (out of 4)
#+begin_src emacs-lisp
(use-package treesit
2024-01-10 10:30:52 +00:00
:diminish
2023-12-31 09:03:20 +00:00
:custom
2024-01-14 06:46:44 +00:00
(treesit-font-lock-level 3))
2023-12-31 09:03:20 +00:00
(use-package treesit-auto
2024-01-10 10:30:52 +00:00
:diminish
2024-01-10 10:33:39 +00:00
:after (treesit)
2023-12-31 09:31:52 +00:00
:config
2024-01-10 10:34:50 +00:00
(treesit-auto-add-to-auto-mode-alist)
(global-treesit-auto-mode +1))
2023-12-31 09:03:20 +00:00
(setq python-ts-mode-hook python-mode-hook)
2024-01-09 07:30:14 +00:00
(with-eval-after-load 'rust-mode
(setq rust-ts-mode-hook rust-mode-hook))
2023-12-31 09:03:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** Eldoc
#+begin_src emacs-lisp :tangle yes
(use-package eldoc
:ensure t
2024-01-09 07:30:14 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:custom
(eldoc-echo-area-display-truncation-message nil)
(eldoc-echo-area-prefer-doc-buffer t)
(eldoc-echo-area-use-multiline-p nil))
#+end_src
** Eglot LSP
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp
2023-12-11 12:07:35 +00:00
(use-package eglot
:ensure t
2024-01-09 07:30:14 +00:00
:diminish
2023-12-22 12:58:06 +00:00
:demand
2023-12-11 12:07:35 +00:00
:bind (("C-c c e" . eglot)
("C-c c C-e" . eglot-reconnect)
("C-c c a" . eglot-code-actions)
("C-c c r" . eglot-rename))
2024-01-28 12:54:14 +00:00
:hook (((nix-mode fortran-mode f90-mode lua-mode python-base-mode rust-ts-mode) . eglot-ensure)
(eglot-managed-mode . (lambda () (add-to-list 'flymake-diagnostic-functions #'eglot-flymake-backend))))
2023-12-11 12:07:35 +00:00
:custom
(eglot-extend-to-xref t)
(eglot-autoshutdown t)
(eglot-autoreconnect nil)
:config
2024-01-28 12:54:14 +00:00
(setq eglot-stay-out-of '(flymake))
2024-01-13 08:17:50 +00:00
(add-to-list 'eglot-server-programs
2024-01-19 16:32:18 +00:00
`((nix-mode)
. ("nil"
:initializationOptions
(:nil (:nix ( :maxMemoryMB 3000
:flake ( :autoArchive t
:autoEvalInputs t)))))))
2023-12-11 12:07:35 +00:00
(add-to-list 'eglot-server-programs
2024-01-19 16:32:18 +00:00
`((rust-ts-mode rust-mode)
. ("rust-analyzer"
:initializationOptions
( :check (:command "clippy")
:procMacro (:enable t)
:cargo ( :buildScripts (:enable t)
2024-01-28 12:54:14 +00:00
:features "all")))))
(add-to-list 'eglot-server-programs
`((python-ts-mode python-mode)
. ("jedi-language-server"
:initializationOptions
( :diagnostics ( :enable nil)
:hover ( :enable t)
:jediSettings ( :autoImportModules ["numpy"]))))))
2024-01-09 14:30:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
2023-12-21 09:43:35 +00:00
** Apheleia formatting
#+begin_src emacs-lisp
(use-package apheleia
:ensure t
2024-01-09 07:30:14 +00:00
:diminish
2023-12-21 09:43:35 +00:00
:bind (("C-c c f" . apheleia-format-buffer))
2023-12-21 10:20:15 +00:00
:hook (prog-mode)
2023-12-21 09:43:35 +00:00
:custom (apheleia-remote-algorithm 'local)
:config
2024-01-30 16:23:31 +00:00
(add-to-list 'apheleia-formatters '(alejandra . ("alejandra")))
(add-to-list 'apheleia-mode-alist '(nix-mode . alejandra))
(add-to-list 'apheleia-mode-alist '(python-ts-mode . ruff))
2023-12-21 10:20:15 +00:00
(add-to-list 'apheleia-mode-alist '(python-mode . ruff)))
2023-12-21 09:43:35 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** Flymake
#+begin_src emacs-lisp :tangle yes
(use-package flymake
:ensure t
:bind (("C-c C-." . flymake-goto-next-error)
2024-01-28 10:01:53 +00:00
("C-c C-," . flymake-goto-prev-error))
:hook (prog-mode . flymake-mode))
2023-12-11 12:07:35 +00:00
#+end_src
*** Diagnostics in popup
#+begin_src emacs-lisp :tangle yes
(use-package flymake-popon
:ensure t
:after flymake
2024-01-10 11:15:29 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:config
(global-flymake-popon-mode +1))
#+end_src
2024-01-28 10:01:53 +00:00
*** shellcheck
#+begin_src emacs-lisp
(use-package flymake-shellcheck
:ensure t
:after flymake
:diminish
:hook (sh-mode . flymake-shellcheck-load))
#+end_src
2024-01-28 12:54:14 +00:00
*** ruff
#+begin_src emacs-lisp
(use-package flymake-ruff
:ensure t
:after (flymake eglot)
:diminish
:hook (python-base-mode . flymake-ruff-load))
#+end_src
2023-12-11 12:07:35 +00:00
** Project
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp
2023-12-11 12:07:35 +00:00
(setq project-switch-use-entire-map t
project-switch-commands '((project-find-file "Find file")
(project-find-regexp "Find regexp")
(project-find-dir "Find directory")
(project-vc-dir "VC-Dir")
(project-eshell "Eshell")))
2024-01-09 14:30:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** Version control
*** Magit
#+begin_src emacs-lisp
(use-package magit
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:bind (("C-c g g" . magit-status)
("C-c g d" . magit-dispatch)
("C-c g f" . magit-file-dispatch)
("C-c g p" . magit-pull)
("C-c g P" . magit-push)
("<remap > <project-vc-dir" . magit-project-status)
:map project-prefix-map
("m" . magit-project-status))
:custom
2024-01-26 07:34:15 +00:00
(magit-display-buffer-function 'magit-display-buffer-same-window-except-diff-v1)
2023-12-11 12:07:35 +00:00
(magit-define-global-key-bindings nil)
(magit-clone-default-directory "~/Projects/ ")
2023-12-15 07:23:42 +00:00
(magit-clone-set-remote.pushDefault t)
2023-12-11 12:07:35 +00:00
(magit-commit-show-diff nil)
2023-12-31 09:24:46 +00:00
(magit-commit-diff-inhibit-same-window t)
(magit-diff-adjust-tab-width t)
(magit-diff-refine-hunk 'all)
2024-01-26 07:12:40 +00:00
(magit-diff-refine-ignore-whitespace t)
(magit-clone-name-alist '(("\\`\\(?:github:\\|gh:\\)?\\([^:]+\\)\\'" "github.com" "github.user")
("\\`\\(?:gitlab:\\|gl:\\)\\([^:]+\\)\\'" "gitlab.com" "gitlab.user")
("\\`\\(?:sourcehut:\\|sh:\\)\\([^:]+\\)\\'" "git.sr.ht" "sourcehut.user")
("\\`\\(?:gitea:\\|gt:\\)\\([^:]+\\)\\'" "git.xenia.me.uk" "gitea.user"))))
2023-12-11 12:07:35 +00:00
#+end_src
** Completion
*** Vertico
#+begin_src emacs-lisp
(use-package vertico
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:custom
(vertico-cycle t)
:init
(vertico-mode)
:config
(require 'vertico-directory))
#+end_src
*** Marginalia
#+begin_src emacs-lisp
(use-package marginalia
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:custom
(marginalia-annotators '(marginalia-annotators-heavy
marginalia-annotators-light
nil))
:config (marginalia-mode +1))
#+end_src
*** Orderless
#+begin_src emacs-lisp
(use-package orderless
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:custom
(completion-styles '(orderless basic))
(completion-category-defaults nil)
(completion-category-overrides '((file (styles . (partial-completion))))))
#+end_src
*** Corfu and Cape
#+begin_src emacs-lisp
(use-package corfu
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2024-01-08 21:15:35 +00:00
:demand
2023-12-11 12:07:35 +00:00
:custom
(corfu-cycle t)
2024-01-12 13:06:42 +00:00
(corfu-auto t)
(corfu-auto-delay 0.2)
(corfu-auto-prefix 3)
2023-12-11 12:07:35 +00:00
(corfu-quit-no-match 'separator)
(corfu-quit-at-boundary 'separator)
2024-01-08 22:03:29 +00:00
(corfu-preview-current nil)
2023-12-11 12:07:35 +00:00
(corfu-preselect 'directory)
2024-01-08 21:15:35 +00:00
:bind ( :map corfu-map
("M-SPC" . corfu-insert-separator)
("RET" . nil)
2024-01-09 09:04:49 +00:00
("TAB" . corfu-insert)
([tab] . corfu-insert))
2023-12-11 12:07:35 +00:00
:init
(global-corfu-mode +1)
2024-01-08 21:15:35 +00:00
(corfu-history-mode +1)
2023-12-11 12:07:35 +00:00
:config
(when (require 'corfu-popupinfo nil :noerror)
(corfu-popupinfo-mode +1)
(keymap-set corfu-map "M-p" #'corfu-popupinfo-scroll-down)
(keymap-set corfu-map "M-n" #'corfu-popupinfo-scroll-up)
(keymap-set corfu-map "M-d" #'corfu-popupinfo-toggle))
(defun corfu-enable-always-in-minibuffer ()
"Enable Corfu in the minibuffer if Vertico is not active."
(unless (or (bound-and-true-p vertico--input)
(eq (current-local-map) read-passwd-map))
(setq-local corfu-echo-delay nil ;; Disable automatic echo and popup
corfu-auto nil ;; Enable/disable auto completion
corfu-popupinfo-delay nil)
(corfu-mode +1)))
(add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1)
2024-02-01 13:26:29 +00:00
(defun my/local-corfu-no-auto () (setq-local corfu-auto nil))
(with-eval-after-load 'eshell (add-hook 'eshell-mode-hook 'my/local-corfu-no-auto))
(with-eval-after-load 'shell (add-hook 'shell-mode-hook 'my/local-corfu-no-auto))
(with-eval-after-load 'gud (add-hook 'gud-mode-hook 'my/local-corfu-no-auto)))
2023-12-11 12:07:35 +00:00
(use-package cape
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2024-01-08 21:15:35 +00:00
:demand
2023-12-21 12:17:08 +00:00
:init
2023-12-24 07:28:05 +00:00
(add-to-list 'completion-at-point-functions #'cape-emoji)
2023-12-21 12:17:08 +00:00
(add-to-list 'completion-at-point-functions #'cape-file)
2023-12-24 07:28:05 +00:00
(add-to-list 'completion-at-point-functions #'cape-dabbrev))
2023-12-11 12:07:35 +00:00
#+end_src
*** Consult
#+begin_src emacs-lisp
(use-package consult
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2024-01-12 13:20:20 +00:00
:bind (("<remap > <imenu >" . consult-imenu)
2023-12-11 12:07:35 +00:00
("<remap > <switch-to-buffer >" . consult-buffer)
("<remap > <project-switch-to-buffer >" . consult-project-buffer)
("<remap > <org-goto >" . consult-org-heading)
2023-12-21 11:41:46 +00:00
("C-c s l" . consult-line)
2023-12-15 09:51:24 +00:00
("C-c s r" . consult-recent-file)
2023-12-11 12:07:35 +00:00
("C-c s f" . consult-fd)
("C-c s g" . consult-ripgrep)
("C-c s e" . consult-flymake)
2024-01-12 13:20:20 +00:00
("C-c s j" . consult-imenu)
2023-12-11 12:07:35 +00:00
("C-c s i" . consult-info)
:map minibuffer-local-map
("C-r" . consult-history))
:config (setq completion-in-region-function #'consult-completion-in-region))
(use-package consult-eglot
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-21 12:17:08 +00:00
:after (consult eglot)
2023-12-11 12:07:35 +00:00
:bind (("C-c s s" . consult-eglot-symbols)))
2023-12-21 12:17:08 +00:00
(use-package consult-yasnippet
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-21 12:17:08 +00:00
:after (consult yasnippet)
:bind (("C-c s y" . consult-yasnippet)))
2023-12-11 12:07:35 +00:00
#+end_src
*** Embark
#+begin_src emacs-lisp
(use-package embark
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:bind (("<remap > <describe-bindings >" . embark-bindings)
("C-." . embark-act))
:config (setq prefix-help-command #'embark-prefix-help-command))
(use-package embark-consult
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:after (embark consult)
:hook (embark-collect-mode . consult-preview-at-point-mode))
#+end_src
** Snippets
#+begin_src emacs-lisp
2024-01-09 07:30:14 +00:00
(use-package yasnippet-snippets :ensure t)
2023-12-21 12:17:08 +00:00
(use-package yasnippet
2023-12-11 12:07:35 +00:00
:ensure t
2024-01-09 07:30:14 +00:00
:diminish
2023-12-21 12:17:08 +00:00
:hook ((prog-mode org-mode) . yas-minor-mode)
:config
(require 'yasnippet-snippets)
(yas-reload-all))
2023-12-11 12:07:35 +00:00
2023-12-21 12:17:08 +00:00
(use-package yasnippet-capf
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-21 12:17:08 +00:00
:after yasnippet
:init (add-to-list 'completion-at-point-functions #'yasnippet-capf))
2023-12-11 12:07:35 +00:00
#+end_src
** Aggressive Indent
#+begin_src emacs-lisp
(use-package aggressive-indent
:ensure t
2024-01-10 10:30:52 +00:00
:diminish
2023-12-11 12:07:35 +00:00
:hook (elisp-mode
lisp-mode
lisp-data-mode
rust-mode))
#+end_src
** Language-specific settings
2024-01-03 13:49:50 +00:00
*** Nix
#+begin_src emacs-lisp
(use-package nix-mode
:mode "\\.nix\\'"
:config
(require 'nix)
(require 'nix-flake))
#+end_src
2024-02-04 09:48:00 +00:00
*** Nushell
#+begin_src emacs-lisp
(use-package nushell-ts-mode
:mode "\\.nu\\'")
#+end_src
2023-12-11 12:07:35 +00:00
*** Python
Set fill column to 88 and enable display in python buffers
#+begin_src emacs-lisp :tangle yes
(defun my/enable-fill-column (col)
"Set and enable fill column"
(set-fill-column col)
(display-fill-column-indicator-mode +1))
2024-01-24 10:23:24 +00:00
(use-package python
2024-02-04 09:48:00 +00:00
:defer t
2024-01-24 10:23:24 +00:00
:custom
(python-check-command "mypy")
:config
(add-hook 'python-base-mode-hook (lambda () (my/enable-fill-column 88))))
2023-12-11 12:07:35 +00:00
#+end_src
2024-02-04 09:48:00 +00:00
2023-12-31 09:26:20 +00:00
*** Rust
#+begin_src emacs-lisp
(use-package cargo
:hook (rust-ts-mode . cargo-minor-mode))
#+end_src
2023-12-11 12:07:35 +00:00
* Internet
** TODO Gnus
#+begin_src emacs-lisp :tangle yes
(setq gnus-select-method '(nnrss "http://www.fsf.org/static/fsforg/rss/news.xml"))
#+end_src
** Email
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp
2023-12-11 12:07:35 +00:00
(setq sendmail-program (executable-find "msmtp")
send-mail-function #'smtpmail-send-it
message-sendmail-f-is-evil t
message-sendmail-extra-arguments '("--read-envelope-from")
message-send-mail-function #'message-send-mail-with-sendmail
message-auto-save-directory nil
message-kill-buffer-on-exit t
2024-01-03 13:10:32 +00:00
mail-user-agent 'mu4e-user-agent)
(set-variable read-mail-command 'mu4e)
2023-12-11 12:07:35 +00:00
(use-package mu4e
2024-01-08 17:50:36 +00:00
:bind
(("C-c m" . mu4e)
:map mu4e-view-mode-map
("o n" . mu4e-org-store-and-capture))
2024-01-14 11:01:27 +00:00
:hook (((mu4e-view-mode mu4e-compose-mode mu4e-org-mode) . (lambda () (visual-line-mode +1))))
2023-12-11 12:07:35 +00:00
:custom
(mu4e-completing-read-function #'completing-read-default)
2024-01-26 08:11:00 +00:00
(mu4e-split-view nil)
2023-12-11 12:07:35 +00:00
(mu4e-attachment-dir "~/Downloads")
2023-12-27 10:42:47 +00:00
(mu4e-get-mail-command "mbsync -a")
2023-12-11 12:07:35 +00:00
(mu4e-update-interval (* 5 60)) ; Every 5 minutes
(mu4e-headers-auto-update nil)
(mu4e-sent-messages-behavior 'sent)
(mu4e-change-filenames-when-moving t)
2024-01-15 13:44:24 +00:00
(mu4e-context-policy 'pick-first)
(mu4e-compose-context-policy 'ask)
2023-12-11 12:07:35 +00:00
(mu4e-search-full nil)
(mu4e-search-include-related t)
(mu4e-search-threads t)
(mu4e-search-skip-duplicates t)
(mu4e-maildir-shortcuts '((:maildir "/Proton/Inbox/ " :key ?p)
(:maildir "/iCloud/Inbox/ " :key ?i)
(:maildir "/Outlook/Inbox/ " :key ?w)))
2024-01-19 06:25:34 +00:00
(mu4e-bookmarks '((:name "Inbox" :query "maildir:/inbox/ " :key ?i :favorite t)
(:name "Today" :query "date:today..now AND maildir:/inbox/ " :key ?t)
2024-01-19 06:45:06 +00:00
(:name "Flagged" :query "flag:flagged AND NOT flag:trashed AND NOT maildir:/spam/ AND NOT maildir:/junk/ " :key ?f)
2024-01-19 10:45:39 +00:00
(:name "Spam" :query "maildir:/spam/ OR maildir:/junk/ " :key ?s :hide-unread t)))
2023-12-11 12:07:35 +00:00
(mu4e-headers-fields
'((:human-date . 8)
2023-12-22 12:58:06 +00:00
(:from . 24)
(:subject . 64)
2023-12-11 12:07:35 +00:00
(:flags)))
(mu4e-headers-visible-flags
'(draft
flagged
unread
passed
replied
trashed
attach
calendar
encrypted
signed
list
personal))
:config
2024-01-03 13:10:32 +00:00
(setq mu4e-use-fancy-chars t)
)
2024-01-09 14:30:20 +00:00
#+end_src
2024-01-03 13:10:32 +00:00
*** Account contexts
#+begin_src emacs-lisp
(with-eval-after-load 'mu4e
(require 'mu4e-context)
2023-12-11 12:07:35 +00:00
(setq mu4e-contexts
(list
(make-mu4e-context
:name "Xenia"
:vars '((user-mail-address . "evie@xenia.me.uk")
(mu4e-sent-folder . "/Proton/Sent")
(mu4e-drafts-folder . "/Proton/Drafts")
(mu4e-trash-folder . "/Proton/Trash")
(mu4e-refile-folder . "/Proton/Archive")))
(make-mu4e-context
:name "Proton"
:match-func (lambda (msg) (when msg (string-prefix-p "/Proton" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "e.litherlandsmith@proton.me")
(mu4e-sent-folder . "/Proton/Sent")
(mu4e-drafts-folder . "/Proton/Drafts")
(mu4e-trash-folder . "/Proton/Trash")
(mu4e-refile-folder . "/Proton/Archive")))
(make-mu4e-context
:name "iCloud"
:match-func (lambda (msg) (when msg (string-prefix-p "/iCloud" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "e.litherlandsmith@icloud.com")
(mu4e-sent-folder . "/iCloud/Sent Messages")
(mu4e-drafts-folder . "/iCloud/Drafts")
(mu4e-trash-folder . "/iCloud/Deleted Messages")
(mu4e-refile-folder . "/iCloud/Archive")))
(make-mu4e-context
:name "Work"
:match-func (lambda (msg) (when msg (string-prefix-p "/Outlook" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "evie.litherland-smith@ukaea.uk")
(mu4e-sent-folder . "/Outlook/Sent")
(mu4e-drafts-folder . "/Outlook/Drafts")
(mu4e-trash-folder . "/Outlook/Trash")
(mu4e-refile-folder . "/Outlook/Archive"))))))
2024-01-03 13:10:32 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
2024-01-03 13:10:32 +00:00
*** Modeline configuration
#+begin_src emacs-lisp
(with-eval-after-load 'mu4e
(require 'mu4e-modeline)
(setq mu4e-modeline-all-read '("R:" . " ")
mu4e-modeline-all-clear '("C:" . " ")
mu4e-modeline-new-items '("N:" . " ")
mu4e-modeline-unread-items '("U:" . " "))
(mu4e-modeline-mode +1))
#+end_src
2023-12-11 12:07:35 +00:00
2024-01-03 13:10:32 +00:00
*** Headers mode glyphs
#+begin_src emacs-lisp
(with-eval-after-load 'mu4e
(setq mu4e-search-full-label '("F" . " ")
mu4e-search-hide-label '("H" . " ")
mu4e-search-related-label '("R" . " ")
mu4e-search-skip-duplicates-label '("D" . " ")
mu4e-search-threaded-label'("T" . " ")
mu4e-headers-draft-mark '("D" . " ")
mu4e-headers-flagged-mark '("F" . " ")
mu4e-headers-unread-mark '("u" . " ")
mu4e-headers-passed-mark '("P" . " ")
mu4e-headers-replied-mark '("R" . " ")
mu4e-headers-trashed-mark '("T" . " ")
mu4e-headers-attach-mark '("a" . " ")
mu4e-headers-calendar-mark '("c" . " ")
mu4e-headers-encrypted-mark '("x" . " ")
mu4e-headers-signed-mark '("s" . " ")
mu4e-headers-list-mark '("l" . " ")
mu4e-headers-personal-mark '("p" . " ")
mu4e-headers-seen-mark '("S" . " ")
mu4e-headers-new-mark '("N" . " ")
mu4e-headers-from-or-to-prefix '(" " . "To ")
mu4e-headers-thread-root-prefix '("* " . "* ")
mu4e-headers-thread-duplicate-prefix '("= " . "= ")
mu4e-headers-thread-blank-prefix '(" " . " ")
2024-01-17 15:14:13 +00:00
mu4e-headers-thread-single-orphan-prefix '("─>" . "─>")
mu4e-headers-thread-orphan-prefix '("┬>" . "┬>")
2024-01-03 13:10:32 +00:00
mu4e-headers-thread-connection-prefix '("│ " . "│ ")
2024-01-17 15:14:13 +00:00
mu4e-headers-thread-first-child-prefix '("├>" . "├>")
mu4e-headers-thread-child-prefix '("├>" . "├>")
mu4e-headers-thread-last-child-prefix '("└>" . "╰>")))
2024-01-03 13:10:32 +00:00
#+end_src
**** Custom marks
#+begin_src emacs-lisp
(with-eval-after-load 'mu4e
(setq mu4e-marks '((refile :char
("r" . " ")
:prompt "refile" :dyn-target
(lambda
(target msg)
(mu4e-get-refile-folder msg))
:action
(lambda
(docid msg target)
(mu4e--server-move docid
(mu4e--mark-check-target target)
"-N")))
(delete :char
("D" . " ")
:prompt "Delete" :show-target
(lambda
(target)
"delete")
:action
(lambda
(docid msg target)
(mu4e--server-remove docid)))
(flag :char
("+" . " ")
:prompt "+flag" :show-target
(lambda
(target)
"flag")
:action
(lambda
(docid msg target)
(mu4e--server-move docid nil "+F-u-N")))
(move :char
("m" . " ")
:prompt "move" :ask-target mu4e--mark-get-move-target :action
(lambda
(docid msg target)
(mu4e--server-move docid
(mu4e--mark-check-target target)
"-N")))
(read :char
("!" . " ")
:prompt "!read" :show-target
(lambda
(target)
"read")
:action
(lambda
(docid msg target)
(mu4e--server-move docid nil "+S-u-N")))
(trash :char
("d" . " ")
:prompt "dtrash" :dyn-target
(lambda
(target msg)
(mu4e-get-trash-folder msg))
:action
(lambda
(docid msg target)
(mu4e--server-move docid
(mu4e--mark-check-target target)
"+T-N")))
(unflag :char
("-" . " ")
:prompt "-unflag" :show-target
(lambda
(target)
"unflag")
:action
(lambda
(docid msg target)
(mu4e--server-move docid nil "-F-N")))
(untrash :char
("=" . " ")
:prompt "=untrash" :show-target
(lambda
(target)
"untrash")
:action
(lambda
(docid msg target)
(mu4e--server-move docid nil "-T")))
(unread :char
("?" . " ")
:prompt "?unread" :show-target
(lambda
(target)
"unread")
:action
(lambda
(docid msg target)
(mu4e--server-move docid nil "-S+u-N")))
(unmark :char " " :prompt "unmark" :action
(mu4e-error "No action for unmarking"))
(action :char
("a" . " ")
:prompt "action" :ask-target
(lambda nil
(mu4e-read-option "Action: " mu4e-headers-actions))
:action
(lambda
(docid msg actionfunc)
(save-excursion
(when
(mu4e~headers-goto-docid docid)
(mu4e-headers-action actionfunc)))))
(something :char
("*" . " ")
:prompt "*something" :action
(mu4e-error "No action for deferred mark")))))
#+end_src
*** Desktop notifications
#+begin_src emacs-lisp
(with-eval-after-load 'mu4e
(require 'mu4e-notification)
(setq mu4e-notification-support t))
#+end_src
*** Org-mode integration
#+begin_src emacs-lisp
(with-eval-after-load 'mu4e
(require 'mu4e-org))
#+end_src
*** iCalendar integration
#+begin_src emacs-lisp
(with-eval-after-load 'mu4e
(require 'mu4e-icalendar)
(mu4e-icalendar-setup)
2024-01-11 15:00:15 +00:00
(setq mu4e-icalendar-trash-after-reply t)
2024-01-08 16:43:15 +00:00
(require 'gnus-icalendar)
(setq gnus-icalendar-org-capture-file (expand-file-name "calendar.org" org-directory))
(setq gnus-icalendar-org-capture-headline '("Inbox"))
(gnus-icalendar-org-setup))
2024-01-03 13:10:32 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
** TODO Feeds
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp
2023-12-11 12:07:35 +00:00
(let ((elfeed-base-directory "~/.elfeed"))
(setq elfeed-db-directory (expand-file-name "db" elfeed-base-directory)
elfeed-enclosure-default-dir (expand-file-name "enclosures" elfeed-base-directory)
rmh-elfeed-org-files (list (expand-file-name "feeds.org" elfeed-base-directory))))
(use-package elfeed
:bind (("C-c f f" . elfeed)
("C-c f u" . elfeed-update))
:hook (elfeed-search-mode . elfeed-update)
:config
(use-package elfeed-org
:ensure t
:config (elfeed-org))
(use-package elfeed-tube
:ensure t
:config (elfeed-tube-setup)))
2024-01-09 14:30:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
* Media
** EMMS
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp
2023-12-11 12:07:35 +00:00
(setq emms-mode-line-icon-enabled-p nil)
2024-01-14 08:23:03 +00:00
(use-package emms
:bind (("C-c e e" . emms-smart-browse)
("C-c e p" . emms-pause)
("C-c e s" . emms-stop)
("C-c e z" . emms-toggle-repeat-track)
("C-c e C-r" . emms-toggle-repeat-playlist)
("C-c e C-b" . emms-browser)
("C-c e C-p" . emms-playlist-mode-go)
("<XF86AudioPlay >" . emms-pause)
("<XF86AudioPrev >" . emms-previous)
("<XF86AudioNext >" . emms-next)
:map emms-browser-mode-map
("e" . emms-smart-browse)
("P" . emms-pause)
("S" . emms-stop)
("z" . emms-toggle-repeat-track)
:map emms-playlist-mode-map
("e" . emms-smart-browse))
:custom
(emms-source-file-default-directory "~/Music/ ")
(emms-lyrics-dir (expand-file-name "lyrics" "~/Music/ "))
(emms-browser-covers #'emms-browser-cache-thumbnail-async)
(emms-browser-default-covers (list (expand-file-name "placeholder.jpg" "~/Music/ ")))
(emms-repeat-playlist t)
:config
(emms-all)
(emms-default-players)
(emms-mpris-enable)
(add-hook 'emms-player-started-hook #'emms-show))
2024-01-09 14:30:20 +00:00
#+end_src
2023-12-11 12:07:35 +00:00
* Writing
** Doc-view
#+begin_src emacs-lisp :tangle yes
(use-package doc-view
:defer t
:ensure t
2024-01-21 11:32:17 +00:00
:bind ( :map doc-view-mode-map
("<mouse-8 >" . doc-view-previous-page)
("<mouse-9 >" . doc-view-next-page))
2023-12-11 12:07:35 +00:00
:custom
(doc-view-resolution 200)
(doc-view-imenu-enabled t)
(doc-view-scale-internally t)
(doc-view-image-width 850))
#+end_src
** TODO Crafted Config
2024-01-09 14:30:20 +00:00
#+begin_src emacs-lisp
2023-12-11 12:07:35 +00:00
;;; Whitespace
(defun crafted-writing-configure-whitespace (use-tabs &optional use-globally &rest enabled-modes)
"Helper function to configure `whitespace' mode.
Enable using TAB characters if USE-TABS is non-nil. If
USE-GLOBALLY is non-nil, turn on `global-whitespace-mode'. If
ENABLED-MODES is non-nil, it will be a list of modes to activate
whitespace mode using hooks. The hooks will be the name of the
mode in the list with `-hook' appended. If USE-GLOBALLY is
non-nil, ENABLED-MODES is ignored.
Configuring whitespace mode is not buffer local. So calling this
function twice with different settings will not do what you
think. For example, if you wanted to use spaces instead of tabs
globally except for in Makefiles, doing the following won't work:
;; turns on global-whitespace-mode to use spaces instead of tabs
(crafted-writing-configure-whitespace nil t)
;; overwrites the above to turn to use tabs instead of spaces,
;; does not turn off global-whitespace-mode, adds a hook to
;; makefile-mode-hook
(crafted-writing-configure-whitespace t nil 'makefile-mode)
Instead, use a configuration like this:
;; turns on global-whitespace-mode to use spaces instead of tabs
(crafted-writing-configure-whitespace nil t)
;; turn on the buffer-local mode for using tabs instead of spaces.
(add-hook 'makefile-mode-hook #'indent-tabs-mode)
For more information on `indent-tabs-mode', See the info
node `(emacs)Just Spaces'
Example usage:
;; Configuring whitespace mode does not turn on whitespace mode
;; since we don't know which modes to turn it on for.
;; You will need to do that in your configuration by adding
;; whitespace mode to the appropriate mode hooks.
(crafted-writing-configure-whitespace nil)
;; Configure whitespace mode, but turn it on globally.
(crafted-writing-configure-whitespace nil t)
;; Configure whitespace mode and turn it on only for prog-mode
;; and derived modes.
(crafted-writing-configure-whitespace nil nil 'prog-mode)"
(if use-tabs
(customize-set-variable 'whitespace-style
'(face empty trailing indentation::tab
space-after-tab::tab
space-before-tab::tab))
;; use spaces instead of tabs
(customize-set-variable 'whitespace-style
'(face empty trailing tab-mark
indentation::space)))
(if use-globally
(global-whitespace-mode 1)
(when enabled-modes
(dolist (mode enabled-modes)
(add-hook (intern (format "%s-hook" mode)) #'whitespace-mode))))
;; cleanup whitespace
(customize-set-variable 'whitespace-action '(cleanup auto-cleanup)))
;;; parentheses
(electric-pair-mode 1) ; auto-insert matching bracket
(show-paren-mode 1) ; turn on paren match highlighting
;;; LaTeX configuration
(with-eval-after-load 'latex
(customize-set-variable 'TeX-auto-save t)
(customize-set-variable 'TeX-parse-self t)
(setq-default TeX-master nil)
;; compile to pdf
(tex-pdf-mode)
;; correlate the source and the output
(TeX-source-correlate-mode)
;; set a correct indentation in a few additional environments
(add-to-list 'LaTeX-indent-environment-list '("lstlisting" current-indentation))
(add-to-list 'LaTeX-indent-environment-list '("tikzcd" LaTeX-indent-tabular))
(add-to-list 'LaTeX-indent-environment-list '("tikzpicture" current-indentation))
;; add a few macros and environment as verbatim
(add-to-list 'LaTeX-verbatim-environments "lstlisting")
(add-to-list 'LaTeX-verbatim-environments "Verbatim")
(add-to-list 'LaTeX-verbatim-macros-with-braces "lstinline")
(add-to-list 'LaTeX-verbatim-macros-with-delims "lstinline")
;; electric pairs in auctex
(customize-set-variable 'TeX-electric-sub-and-superscript t)
(customize-set-variable 'LaTeX-electric-left-right-brace t)
(customize-set-variable 'TeX-electric-math (cons "$" "$"))
;; open all buffers with the math mode and auto-fill mode
(add-hook 'LaTeX-mode-hook #'auto-fill-mode)
(add-hook 'LaTeX-mode-hook #'LaTeX-math-mode)
;; add support for references
(add-hook 'LaTeX-mode-hook #'turn-on-reftex)
(customize-set-variable 'reftex-plug-into-AUCTeX t)
;; to have the buffer refresh after compilation
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer))
;; message the user if the latex executable is not found
(defun crafted-writing-tex-warning-if-no-latex-executable ()
"Print a message to the minibuffer if the \"latex\" executable cannot be found."
(unless (executable-find "latex")
(message "latex executable not found")))
(add-hook 'tex-mode-hook #'crafted-writing-tex-warning-if-no-latex-executable)
(when (and (executable-find "latex")
(executable-find "latexmk"))
(with-eval-after-load 'latex
(when (require 'auctex-latexmk nil 'noerror)
(with-eval-after-load 'auctex-latexmk
(auctex-latexmk-setup)
(customize-set-variable 'auctex-latexmk-inherit-TeX-PDF-mode t))
(defun crafted-writing-tex-make-latexmk-default-command ()
"Set `TeX-command-default' to \"LatexMk\"."
(setq TeX-command-default "LatexMk"))
(add-hook 'TeX-mode-hook #'crafted-writing-tex-make-latexmk-default-command))))
;;; Markdown
(when (fboundp 'markdown-mode)
;; because the markdown-command variable may not be loaded (yet),
;; check manually for the other markdown processors. If it is
;; loaded, the others are superfluous but `or' fails fast, so they
;; are not checked if `markdown-command' is set and the command is
;; indeed found.
(unless (or (and (boundp 'markdown-command)
(executable-find markdown-command))
(executable-find "markdown")
(executable-find "pandoc"))
(message "No markdown processor found, preview may not possible."))
(with-eval-after-load 'markdown-mode
(customize-set-variable 'markdown-enable-math t)
(customize-set-variable 'markdown-enable-html t)
(add-hook 'markdown-mode-hook #'conditionally-turn-on-pandoc)))
2024-01-09 14:30:20 +00:00
#+end_src