Evie Litherland-Smith
178456df06
Add black profile option to isort formatter call Keep option for flake8 as checker if ruff not available (e.g. on another machine)
1431 lines
48 KiB
EmacsLisp
1431 lines
48 KiB
EmacsLisp
;;; init.el -- My emacs config -*- lexical-binding: t -*-
|
|
;;; Commentary:
|
|
;; Moving my Emacs config from separate directory
|
|
;; To install packages on non-NixOS systems run `install.el'
|
|
;;; Code:
|
|
;; Stop popups for warning messages, keep in log buffer
|
|
(setopt warning-minimum-level :error)
|
|
|
|
;; Configure packages archives with priority
|
|
(load-file (locate-user-emacs-file "package-config.el"))
|
|
|
|
(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
|
|
even-window-sizes t
|
|
global-auto-revert-non-file-buffers t
|
|
dired-auto-revert-buffer t
|
|
dired-dwim-target t
|
|
tab-always-indent t
|
|
completion-cycle-threshold nil
|
|
completions-detailed t
|
|
xref-show-definitions-function #'xref-show-definitions-completing-read
|
|
kill-do-not-save-duplicates t)
|
|
|
|
(setopt scroll-conservatively 101)
|
|
|
|
(use-package pixel-scroll
|
|
:init
|
|
(pixel-scroll-precision-mode +1))
|
|
|
|
(use-package mwheel
|
|
:custom
|
|
(mouse-wheel-scroll-amount '(1 ((shift) . 1)))
|
|
(mouse-wheel-progressive-speed nil)
|
|
(mouse-wheel-follow-mouse t))
|
|
|
|
;; Bind normal forward/back buttons on mouse to next/previous buffer respectively
|
|
(keymap-global-set "<mouse-8>" #'previous-buffer)
|
|
(keymap-global-set "<mouse-9>" #'next-buffer)
|
|
|
|
;; Quick bind for calling `git-sync-all'
|
|
(defun my/git-sync-all ()
|
|
"Run shell command `git-sync-all' asynchronously."
|
|
(interactive)
|
|
(async-shell-command "git-sync-all" "*git-sync-all*" "*git-sync-errors*")
|
|
(when (require 'org-journal nil :noerror)
|
|
(org-journal-invalidate-cache)))
|
|
(keymap-global-set "C-c g s" #'my/git-sync-all)
|
|
|
|
(set-default-coding-systems 'utf-8)
|
|
(set-terminal-coding-system 'utf-8)
|
|
(set-keyboard-coding-system 'utf-8)
|
|
|
|
(global-auto-revert-mode +1)
|
|
(delete-selection-mode +1)
|
|
|
|
(setopt
|
|
;; No tabs
|
|
indent-tabs-mode nil
|
|
;; Only display async output buffer when there's something to show
|
|
async-shell-command-display-buffer nil
|
|
;; Scroll compilation buffer output
|
|
compilation-scroll-output t)
|
|
|
|
;; Make shebang (#!) file executable when saved
|
|
(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
|
|
|
|
(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)))
|
|
|
|
(savehist-mode +1)
|
|
|
|
(use-package recentf
|
|
:config
|
|
(run-at-time nil (* 5 60) 'recentf-save-list)
|
|
(recentf-mode +1)
|
|
:custom
|
|
(recentf-max-saved-items 2048))
|
|
|
|
(when (require 'auth-source nil :noerror)
|
|
(setq auth-sources '("secrets:Login"))
|
|
(when (require 'auth-source-pass nil :noerror)
|
|
(auth-source-pass-enable)))
|
|
|
|
;; Make `describe-*' screens more helpful
|
|
(use-package helpful
|
|
: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)
|
|
|
|
;; turn on spell checking, if available.
|
|
(use-package ispell
|
|
:custom
|
|
(ispell-dictionary "en_GB"))
|
|
|
|
(use-package flyspell
|
|
:hook ((text-mode . flyspell-mode)
|
|
(prog-mode . flyspell-prog-mode))
|
|
:init
|
|
(require 'ispell)
|
|
:custom
|
|
(flyspell-mode-line-string nil)
|
|
(flyspell-use-meta-tab nil)
|
|
:config
|
|
(require 'flyspell-correct)
|
|
(require 'consult-flyspell))
|
|
|
|
(use-package flyspell-correct
|
|
:after flyspell
|
|
:bind ( :map flyspell-mode-map
|
|
("C-;" . flyspell-correct-wrapper)))
|
|
|
|
(use-package consult-flyspell
|
|
:after (consult flyspell)
|
|
:bind ( :map flyspell-mode-map
|
|
("C-c s ;" . consult-flyspell))
|
|
:config
|
|
(setq consult-flyspell-always-check-buffer t))
|
|
|
|
(use-package ibuffer
|
|
:bind (("C-c b" . ibuffer)))
|
|
|
|
(use-package ibuffer-project
|
|
:after (ibuffer project)
|
|
: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))))))
|
|
|
|
(use-package link-hint
|
|
: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)))
|
|
|
|
(use-package avy
|
|
:bind (("C-c j j" . avy-goto-char-2)
|
|
("C-c j w" . avy-goto-word-0)
|
|
("C-c j c" . avy-goto-char)
|
|
("C-c j l" . avy-goto-line)))
|
|
|
|
(use-package which-func
|
|
:init (which-function-mode))
|
|
|
|
(use-package shell
|
|
:bind (("C-c t s" . shell)))
|
|
|
|
(use-package eshell
|
|
:bind (("C-c t e" . eshell)))
|
|
|
|
(use-package eww
|
|
:defer t
|
|
:custom
|
|
(browse-url-browser-function 'browse-url-default-browser)
|
|
(browse-url-new-window-flag t)
|
|
(eww-default-download-directory "~/Downloads/")
|
|
(eww-auto-rename-buffer 'title)
|
|
(eww-browse-url-new-window-is-tab nil))
|
|
|
|
(use-package vertico
|
|
:custom
|
|
(vertico-cycle t)
|
|
:init
|
|
(vertico-mode)
|
|
:config
|
|
(require 'vertico-directory))
|
|
|
|
(use-package marginalia
|
|
:custom
|
|
(marginalia-annotators '(marginalia-annotators-heavy
|
|
marginalia-annotators-light
|
|
nil))
|
|
:config (marginalia-mode +1))
|
|
|
|
(use-package orderless
|
|
:custom
|
|
(completion-styles '(orderless basic))
|
|
(completion-category-defaults nil)
|
|
(completion-category-overrides '((file (styles . (partial-completion)))
|
|
(eglot (styles . (styles orderless)))
|
|
(eglot-capf (styles . (styles orderless))))))
|
|
|
|
(use-package corfu
|
|
:demand
|
|
:custom
|
|
(corfu-cycle t)
|
|
(corfu-auto t)
|
|
(corfu-auto-delay 0.2)
|
|
(corfu-auto-prefix 2)
|
|
(corfu-quit-no-match 'separator)
|
|
(corfu-quit-at-boundary 'separator)
|
|
(corfu-preview-current nil)
|
|
(corfu-preselect 'directory)
|
|
:bind ( :map corfu-map
|
|
("M-SPC" . corfu-insert-separator)
|
|
("RET" . nil)
|
|
("TAB" . corfu-insert)
|
|
([tab] . corfu-insert))
|
|
:init
|
|
(global-corfu-mode +1)
|
|
(corfu-history-mode +1)
|
|
:config
|
|
(when (require 'corfu-popupinfo nil :noerror)
|
|
(setq corfu-popupinfo-delay 0.3)
|
|
(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)
|
|
|
|
(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)))
|
|
|
|
(use-package corfu-terminal
|
|
:after corfu
|
|
:demand
|
|
:config
|
|
(corfu-terminal-mode +1))
|
|
|
|
(use-package cape
|
|
:demand
|
|
:init
|
|
(add-to-list 'completion-at-point-functions #'cape-emoji)
|
|
(add-to-list 'completion-at-point-functions #'cape-file)
|
|
(add-to-list 'completion-at-point-functions #'cape-dabbrev)
|
|
:custom
|
|
(cape-dabbrev-min-length (+ corfu-auto-prefix 1)))
|
|
|
|
(use-package consult
|
|
:bind (("<remap> <imenu>" . consult-imenu)
|
|
("<remap> <switch-to-buffer>" . consult-buffer)
|
|
("<remap> <project-switch-to-buffer>" . consult-project-buffer)
|
|
("<remap> <org-goto>" . consult-org-heading)
|
|
("C-c s l" . consult-line)
|
|
("C-c s o" . consult-outline)
|
|
("C-c s f" . consult-fd)
|
|
("C-c s g" . consult-ripgrep)
|
|
("C-c s e" . consult-flymake)
|
|
("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
|
|
:after (consult eglot)
|
|
:bind (("C-c s s" . consult-eglot-symbols)))
|
|
|
|
(use-package embark
|
|
:bind (("<remap> <describe-bindings>" . embark-bindings)
|
|
("C-." . embark-act))
|
|
:config (setq prefix-help-command #'embark-prefix-help-command))
|
|
|
|
(use-package embark-consult
|
|
:after (embark consult)
|
|
:hook (embark-collect-mode . consult-preview-at-point-mode))
|
|
|
|
;; Configure Tempel
|
|
(use-package tempel
|
|
;; Require trigger prefix before template name when completing.
|
|
;; :custom
|
|
;; (tempel-trigger-prefix "<")
|
|
|
|
:bind (("M-+" . tempel-complete) ;; Alternative tempel-expand
|
|
("M-*" . tempel-insert))
|
|
|
|
:init
|
|
|
|
;; Setup completion at point
|
|
(defun tempel-setup-capf ()
|
|
;; Add the Tempel Capf to `completion-at-point-functions'.
|
|
;; `tempel-expand' only triggers on exact matches. Alternatively use
|
|
;; `tempel-complete' if you want to see all matches, but then you
|
|
;; should also configure `tempel-trigger-prefix', such that Tempel
|
|
;; does not trigger too often when you don't expect it. NOTE: We add
|
|
;; `tempel-expand' *before* the main programming mode Capf, such
|
|
;; that it will be tried first.
|
|
(setq-local completion-at-point-functions
|
|
(cons #'tempel-expand
|
|
completion-at-point-functions)))
|
|
|
|
(add-hook 'conf-mode-hook 'tempel-setup-capf)
|
|
(add-hook 'prog-mode-hook 'tempel-setup-capf)
|
|
(add-hook 'text-mode-hook 'tempel-setup-capf)
|
|
|
|
;; Optionally make the Tempel templates available to Abbrev,
|
|
;; either locally or globally. `expand-abbrev' is bound to C-x '.
|
|
(add-hook 'prog-mode-hook #'tempel-abbrev-mode)
|
|
(global-tempel-abbrev-mode))
|
|
|
|
;; Scratch buffer shortcut
|
|
(keymap-global-set "C-c w x" #'scratch-buffer)
|
|
|
|
;; Config file shortcut
|
|
(defun my/open-init-file ()
|
|
"Open Emacs init file."
|
|
(interactive)
|
|
(find-file (locate-user-emacs-file "init.el")))
|
|
(keymap-global-set "C-c w e" #'my/open-init-file)
|
|
|
|
;; NixOS flake shortcut
|
|
(defun my/open-nixos-flake ()
|
|
"Open NixOS system config flake."
|
|
(interactive)
|
|
(let ((flake "/etc/nixos/flake.nix"))
|
|
(if (file-exists-p flake)
|
|
(find-file flake)
|
|
(warn (concat flake " not found")))))
|
|
(keymap-global-set "C-c w n" #'my/open-nixos-flake)
|
|
|
|
;; home-manager flake shortcut
|
|
(defun my/open-home-manager-flake ()
|
|
"Open home-manager config flake."
|
|
(interactive)
|
|
(let ((flake "~/.config/home-manager/flake.nix"))
|
|
(if (file-exists-p flake)
|
|
(find-file flake)
|
|
(warn (concat flake " not found")))))
|
|
(keymap-global-set "C-c w h" #'my/open-home-manager-flake)
|
|
|
|
;; Tempel template file shortcut
|
|
(defun my/open-template-file ()
|
|
"Open `tempel' template file."
|
|
(interactive)
|
|
(require 'tempel)
|
|
(find-file tempel-path))
|
|
(keymap-global-set "C-c w t" #'my/open-template-file)
|
|
|
|
;; Org directory shortcut
|
|
(defun my/open-org-directory ()
|
|
"Open base `org-mode' directory in Dired."
|
|
(interactive)
|
|
(require 'org)
|
|
(find-file org-directory))
|
|
(keymap-global-set "C-c w o" #'my/open-org-directory)
|
|
|
|
(defun my/open-global-bibliography ()
|
|
"Open `org-cite-global-bibliography'."
|
|
(interactive)
|
|
(require 'org)
|
|
(find-file (car org-cite-global-bibliography)))
|
|
(keymap-global-set "C-c w b" #'my/open-global-bibliography)
|
|
|
|
;; Elfeed feeds directory shortcut
|
|
(defun my/open-feeds-file ()
|
|
"Open elfeed org source file."
|
|
(interactive)
|
|
(require 'elfeed)
|
|
(require 'elfeed-org)
|
|
(find-file (car rmh-elfeed-org-files)))
|
|
(keymap-global-set "C-c w f" #'my/open-feeds-file)
|
|
|
|
(defun my/open-documents-directory ()
|
|
"Open Documents directory."
|
|
(interactive)
|
|
(find-file "~/Documents/"))
|
|
(defun my/open-downloads-directory ()
|
|
"Open Downloads directory."
|
|
(interactive)
|
|
(find-file "~/Downloads/"))
|
|
(keymap-global-set "C-c w d" #'my/open-documents-directory)
|
|
(keymap-global-set "C-c w C-d" #'my/open-downloads-directory)
|
|
|
|
(use-package calendar
|
|
:bind (("C-c >" . calendar))
|
|
:custom
|
|
(calendar-date-style 'iso)
|
|
(calendar-mark-holidays-flag t)
|
|
(calendar-mark-diary-entries-flag nil)
|
|
(calendar-view-holidays-initially-flag nil)
|
|
(calendar-view-diary-initially-flag nil))
|
|
|
|
(use-package appt
|
|
:custom
|
|
(appt-display-diary nil)
|
|
(appt-display-format 'echo)
|
|
(appt-display-interval 5)
|
|
(appt-message-warning-time 15)
|
|
:init
|
|
(appt-activate +1))
|
|
|
|
(setq inhibit-splash-screen t
|
|
use-dialog-box nil
|
|
minibuffer-follows-selected-frame nil
|
|
truncate-lines nil
|
|
truncate-partial-width-windows nil)
|
|
|
|
(global-prettify-symbols-mode +1)
|
|
(global-display-line-numbers-mode -1)
|
|
(tool-bar-mode -1)
|
|
|
|
(add-hook 'prog-mode-hook #'(lambda () (display-line-numbers-mode +1)))
|
|
|
|
(use-package which-key
|
|
:config (which-key-mode +1))
|
|
|
|
(use-package page-break-lines
|
|
:config (global-page-break-lines-mode +1))
|
|
|
|
(electric-pair-mode +1)
|
|
(show-paren-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))
|
|
|
|
(use-package base16-theme
|
|
:demand
|
|
:custom
|
|
(base16-theme-distinct-fringe-background nil)
|
|
(base16-theme-highlight-mode-line 'contrast)
|
|
:config
|
|
(load-theme 'base16-catppuccin-mocha t))
|
|
|
|
(use-package nerd-icons
|
|
:config (nerd-icons-set-font "Symbols Nerd Font Mono-12"))
|
|
|
|
(use-package nerd-icons-dired
|
|
:after nerd-icons
|
|
:hook (dired-mode))
|
|
|
|
(use-package nerd-icons-ibuffer
|
|
:after nerd-icons
|
|
:hook (ibuffer-mode))
|
|
|
|
(use-package nerd-icons-completion
|
|
:after nerd-icons
|
|
:config (nerd-icons-completion-mode +1))
|
|
|
|
(use-package nerd-icons-corfu
|
|
:after (corfu nerd-icons)
|
|
:config (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
|
|
|
|
(keymap-global-set "C-c i n" #'nerd-icons-insert)
|
|
|
|
(use-package ligature
|
|
:config
|
|
(ligature-set-ligatures
|
|
'(text-mode prog-mode org-mode)
|
|
'("-<<" "-<" "-<-" "<--" "<---" "<<-" "<-" "->" "->>" "-->" "--->" "->-" ">-" ">>-"
|
|
"=<<" "=<" "=<=" "<==" "<===" "<<=" "<=" "=>" "=>>" "==>" "===>" "=>=" ">=" ">>="
|
|
"<->" "<-->" "<--->" "<---->" "<=>" "<==>" "<===>" "<====>" "::" ":::" "__"
|
|
"<~~" "</" "</>" "/>" "~~>" "==" "!=" "/=" "~=" "<>" "===" "!==" "!===" "=/=" "=!="
|
|
"<:" ":=" "*=" "*+" "<*" "<*>" "*>" "<|" "<|>" "|>" "<." "<.>" ".>" "+*" "=*" "=:" ":>"
|
|
"(*" "*)" "/*" "*/" "[|" "|]" "{|" "|}" "++" "+++" "\\/" "/\\" "|-" "-|" "<!--" "<!---"))
|
|
(global-ligature-mode +1))
|
|
|
|
(use-package whitespace
|
|
:custom
|
|
(whitespace-style '(face
|
|
empty
|
|
trailing
|
|
tab-mark
|
|
indentation::space))
|
|
(whitespace-action '(report-on-bogus
|
|
cleanup
|
|
auto-cleanup)))
|
|
|
|
(setq mode-line-compact 'long)
|
|
|
|
(use-package doom-modeline
|
|
:demand
|
|
:custom
|
|
(doom-modeline-checker-simple-format nil)
|
|
(doom-modeline-enable-word-count t)
|
|
(doom-modeline-env-version t)
|
|
(doom-modeline-github nil)
|
|
(doom-modeline-gnus t)
|
|
(doom-modeline-mu4e nil) ; Built-in implementation looks nicer
|
|
(doom-modeline-icon t)
|
|
(doom-modeline-irc t)
|
|
(doom-modeline-lsp t)
|
|
(doom-modeline-project-detection 'project)
|
|
(doom-modeline-continuous-word-count-modes '(org-mode
|
|
markdown-mode
|
|
gfm-mode))
|
|
:config
|
|
(set-face-attribute 'doom-modeline nil :weight 'normal)
|
|
(doom-modeline-mode +1))
|
|
|
|
(line-number-mode +1)
|
|
(column-number-mode +1)
|
|
(size-indication-mode +1)
|
|
(display-time-mode +1)
|
|
|
|
(require 'battery)
|
|
(when (and battery-status-function
|
|
(not ( string-match-p "unknown"
|
|
( battery-format "%B"
|
|
(funcall battery-status-function)))))
|
|
(display-battery-mode +1))
|
|
|
|
(use-package zone
|
|
:config
|
|
(zone-when-idle (* 60 60 2))) ; 2 hours
|
|
|
|
(use-package diff-hl
|
|
:init
|
|
(add-hook 'magit-pre-refresh-hook #'diff-hl-magit-pre-refresh)
|
|
(add-hook 'magit-post-refresh-hook #'diff-hl-magit-post-refresh)
|
|
:config
|
|
(global-diff-hl-mode)
|
|
:custom
|
|
(diff-hl-disable-on-remote t)
|
|
(diff-hl-draw-borders nil))
|
|
|
|
(setq split-height-threshold nil
|
|
split-width-threshold 160)
|
|
|
|
(use-package winner
|
|
:demand
|
|
:config
|
|
(winner-mode))
|
|
|
|
(use-package ediff
|
|
: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))
|
|
|
|
(setq emms-mode-line-icon-enabled-p nil)
|
|
(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)
|
|
(emms-cache-enable)
|
|
(add-hook 'emms-player-started-hook #'emms-show))
|
|
|
|
(use-package org
|
|
:demand
|
|
:hook ((org-mode . turn-on-auto-fill))
|
|
:custom
|
|
(org-directory "~/Documents/org")
|
|
(org-default-notes-file (expand-file-name "notes.org" org-directory))
|
|
(org-hide-emphasis-markers nil)
|
|
(org-pretty-entities-include-sub-superscripts t)
|
|
(org-fontify-done-headline t)
|
|
(org-fontify-todo-headline t)
|
|
(org-fontify-emphasized-text t)
|
|
(org-fontify-quote-and-verse-blocks t)
|
|
(org-tags-column 0)
|
|
(org-enforce-todo-dependencies t)
|
|
(org-enforce-todo-checkbox-dependencies t)
|
|
(org-yank-folded-subtrees nil)
|
|
(org-yank-adjusted-subtrees t)
|
|
(org-M-RET-may-split-line '((default . nil)
|
|
(headline . nil)
|
|
(item . nil)
|
|
(table . t)))
|
|
(org-babel-load-languages '((emacs-lisp . t)
|
|
(lua . t)
|
|
(python . t))))
|
|
|
|
(use-package org-faces
|
|
:after org
|
|
:config
|
|
;; Ensure tables and src blocks use fixed-pitch font.
|
|
(set-face-attribute 'org-block nil :inherit 'fixed-pitch)
|
|
(set-face-attribute 'org-code nil :inherit 'fixed-pitch)
|
|
(set-face-attribute 'org-table nil :inherit 'fixed-pitch)
|
|
(set-face-attribute 'org-verbatim nil :inherit 'org-code)
|
|
;; Let quote and verse blocks use variable-pitch font, if configured
|
|
(set-face-attribute 'org-quote nil :inherit 'variable-pitch)
|
|
(set-face-attribute 'org-verse nil :inherit 'variable-pitch))
|
|
|
|
(use-package org-keys
|
|
:after org
|
|
:custom
|
|
(org-return-follows-link t)
|
|
(org-mouse-1-follows-link t))
|
|
|
|
(use-package org-indent
|
|
:after org
|
|
:hook org-mode)
|
|
|
|
(use-package org-attach
|
|
:after org
|
|
:custom
|
|
(org-attach-id-dir (expand-file-name "data/" org-directory)))
|
|
|
|
(use-package org-refile
|
|
:after (org org-agenda)
|
|
:custom
|
|
(org-outline-path-complete-in-steps nil)
|
|
(org-refile-use-outline-path t)
|
|
(org-refile-allow-creating-parent-nodes t)
|
|
(org-refile-use-outline-path 'file)
|
|
(org-refile-targets '((nil . (:maxlevel . 2))
|
|
(org-agenda-files . (:maxlevel . 2)))))
|
|
|
|
(use-package org-src
|
|
:after org
|
|
:custom
|
|
(org-src-window-setup 'current-window))
|
|
|
|
(use-package org-capture
|
|
:after org
|
|
:bind
|
|
(("C-c n" . org-capture)
|
|
("C-c C-n" . org-capture-goto-last-stored))
|
|
:custom
|
|
(org-capture-templates '(("n" "Note" entry
|
|
(file+datetree "notes.org")
|
|
"* %?")
|
|
("t" "Task" entry
|
|
(file+datetree "tasks.org")
|
|
"* TODO [#B] %?")
|
|
("r" "Reading List" entry
|
|
(file+olp+datetree "reading.org" "Inbox")
|
|
"* %?")
|
|
)))
|
|
|
|
(use-package org-roam
|
|
:after org
|
|
:bind (("C-c r i" . org-roam-node-insert)
|
|
("C-c r f" . org-roam-node-find)
|
|
("C-c r n" . org-roam-capture))
|
|
:custom
|
|
(org-roam-directory (expand-file-name "roam" org-directory))
|
|
(org-roam-completion-everywhere nil)
|
|
(org-roam-node-display-template (concat
|
|
"${title:*} "
|
|
(propertize "${tags:24}" 'face 'org-tag)))
|
|
;; (org-roam-capture-templates '(("d" "default" plain "%?"
|
|
;; :target
|
|
;; (file+head "${slug}.org" "#+title: ${title}\n#+author: %n")
|
|
;; :unnarrowed t)))
|
|
:config
|
|
(mkdir org-roam-directory t)
|
|
(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))
|
|
|
|
(use-package org-agenda
|
|
:after org
|
|
:bind (("C-c a" . org-agenda))
|
|
:hook (org-agenda-mode . org-agenda-to-appt)
|
|
:custom
|
|
(org-agenda-span 'week)
|
|
(org-agenda-start-on-weekday 1)
|
|
(org-agenda-sticky nil)
|
|
(org-agenda-window-setup 'current-window)
|
|
(org-agenda-tags-column 0)
|
|
(org-agenda-diary-file (expand-file-name "agenda/calendar.org" org-directory))
|
|
(org-agenda-include-diary nil)
|
|
(org-agenda-include-deadlines t)
|
|
(org-agenda-todo-ignore-scheduled 'future)
|
|
(org-agenda-todo-ignore-deadlines 'far)
|
|
(org-agenda-prefix-format '((agenda . " %-12:c%?-12t% s")
|
|
(todo . " %-12:c")
|
|
(tags . " %-12:c")
|
|
(search . " %-12:c")))
|
|
(org-agenda-files (list
|
|
(expand-file-name org-directory)
|
|
(expand-file-name "agenda" org-directory)
|
|
(expand-file-name "citar" org-directory)
|
|
(expand-file-name "journal" org-directory)
|
|
(expand-file-name "roam" org-directory))))
|
|
|
|
(use-package ox-icalendar
|
|
:after org
|
|
:custom
|
|
(org-icalendar-store-UID t)
|
|
(org-icalendar-alarm-time 15)
|
|
(org-icalendar-include-body t)
|
|
(org-icalendar-include-sexps t)
|
|
(org-icalendar-include-todo t)
|
|
(org-icalendar-combined-name "org-mode")
|
|
(org-icalendar-combined-description "Emacs org-mode combined export"))
|
|
|
|
(use-package org-journal
|
|
:after org
|
|
:custom
|
|
(org-journal-dir (expand-file-name "journal" org-directory))
|
|
(org-journal-enable-cache t)
|
|
(org-journal-file-type 'monthly)
|
|
(org-journal-file-format "%Y-%m.org"))
|
|
|
|
(use-package org-noter
|
|
:after (org doc-view citar)
|
|
:commands (org-noter)
|
|
: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 '("noter.org"))
|
|
(org-noter-doc-property-in-notes t)
|
|
(org-noter-notes-search-path (list (expand-file-name "notes" org-directory)
|
|
(car citar-notes-paths)))
|
|
(org-noter-prefer-root-as-file-level nil))
|
|
|
|
(use-package citar
|
|
:after org
|
|
:custom
|
|
(org-cite-global-bibliography (list
|
|
(expand-file-name "citar/main.bib" org-directory)))
|
|
(org-cite-insert-processor 'citar)
|
|
(org-cite-follow-processor 'citar)
|
|
(org-cite-activate-processor 'citar)
|
|
(citar-bibliography org-cite-global-bibliography)
|
|
(citar-library-paths (list
|
|
(expand-file-name "citar/library/" org-directory)))
|
|
(citar-notes-paths (list
|
|
(expand-file-name "citar/notes/" org-directory)))
|
|
:hook
|
|
(LaTeX-mode . citar-capf-setup)
|
|
(org-mode . citar-capf-setup)
|
|
:bind ( :map org-mode-map
|
|
("C-c c" . citar-open))
|
|
:config
|
|
(require 'nerd-icons)
|
|
(require 'citar-embark)
|
|
(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
|
|
:padding " " ; need this because the default padding is too low for these icons
|
|
: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
|
|
:padding " " ; need this because the default padding is too low for these icons
|
|
: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
|
|
:padding " " ; need this because the default padding is too low for these icons
|
|
:tag "is:cited"))
|
|
(setq citar-indicators (list citar-indicator-files-icons
|
|
citar-indicator-links-icons
|
|
citar-indicator-notes-icons
|
|
citar-indicator-cited-icons)))
|
|
|
|
(use-package citar-embark
|
|
:after (citar embark)
|
|
:init
|
|
(citar-embark-mode +1))
|
|
|
|
(setq org-latex-compiler "lualatex")
|
|
(setq org-preview-latex-default-process 'dvisvgm)
|
|
|
|
(require 'tramp)
|
|
(setq org-publish-project-alist
|
|
`(("xenia.me.uk"
|
|
:base-directory ,(expand-file-name "www/xenia.me.uk" "~/Projects/")
|
|
:base-extension "org"
|
|
:exclude "setup.org"
|
|
:recursive t
|
|
:publishing-function org-html-publish-to-html
|
|
:publishing-directory "/sshx:pixelifytica@legion:/var/www/xenia.me.uk"
|
|
:auto-sitemap t
|
|
:sitemap-title "Sitemap"
|
|
:section-numbers nil
|
|
:with-author t
|
|
:with-email t
|
|
:with-toc nil
|
|
:html-link-home "/"
|
|
:html-link-up "../"
|
|
;; :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"css/style.css\"/>"
|
|
)))
|
|
|
|
(use-package rainbow-delimiters
|
|
:hook (prog-mode))
|
|
|
|
(use-package direnv
|
|
:custom (direnv-always-show-summary nil)
|
|
:config (direnv-mode +1))
|
|
|
|
(with-eval-after-load 'gud
|
|
(setopt gdb-many-windows t))
|
|
|
|
(use-package treesit
|
|
:custom
|
|
(treesit-font-lock-level 3))
|
|
|
|
(use-package treesit-auto
|
|
:after (treesit)
|
|
:config
|
|
(treesit-auto-add-to-auto-mode-alist)
|
|
(global-treesit-auto-mode +1))
|
|
|
|
(with-eval-after-load 'rust-mode
|
|
(setq rust-ts-mode-hook rust-mode-hook))
|
|
|
|
(use-package eldoc
|
|
:custom
|
|
(eldoc-echo-area-display-truncation-message nil)
|
|
(eldoc-echo-area-prefer-doc-buffer t)
|
|
(eldoc-echo-area-use-multiline-p nil))
|
|
|
|
(use-package eglot
|
|
:demand
|
|
:bind ( :map prog-mode-map
|
|
("C-c c a" . eglot-code-actions)
|
|
("C-c c r" . eglot-rename))
|
|
:hook ((eglot-managed-mode . (lambda () (add-hook 'flymake-diagnostic-functions 'eglot-flymake-backend nil t))))
|
|
:custom
|
|
(eglot-extend-to-xref t)
|
|
(eglot-autoshutdown t)
|
|
(eglot-autoreconnect nil)
|
|
:init
|
|
(setq eglot-stay-out-of '(flymake))
|
|
:config
|
|
(setq-default eglot-workspace-configuration
|
|
'( :pylsp ( :plugins
|
|
( :autopep8 (:enabled nil)
|
|
:flake8 (:enabled nil)
|
|
:jedi_completion ( :enabled t
|
|
:include_params t
|
|
:include_class_objects t
|
|
:include_function_objects t
|
|
:fuzzy t)
|
|
:jedi_definition (:enabled t)
|
|
:jedi_hover (:enabled t)
|
|
:mccabe (:enabled nil)
|
|
:preload (:enabled nil)
|
|
:pycodestyle (:enabled nil)
|
|
:pydocstyle (:enabled nil)
|
|
:pyflakes (:enabled nil)
|
|
:pylint (:enabled nil)
|
|
:rope_autoimport ( :completions (:enabled t)
|
|
:code_actions (:enabled t))
|
|
:rope_completion (:enabled t)
|
|
:yapf (:enabled nil)))
|
|
:nil ( :nix
|
|
( :maxMemoryMB nil
|
|
:flake
|
|
( :autoArchive t
|
|
:nixpkgsInputName "nixpkgs")))))
|
|
(with-eval-after-load 'cape
|
|
(advice-add 'eglot-completion-at-point :around #'cape-wrap-buster)
|
|
(defun my/eglot-capf ()
|
|
(setq-local completion-at-point-functions
|
|
(list (cape-capf-super
|
|
#'eglot-completion-at-point
|
|
#'tempel-expand
|
|
#'cape-file))))
|
|
(add-hook 'eglot-managed-mode-hook #'my/eglot-capf)))
|
|
|
|
(use-package apheleia
|
|
:bind (("C-c c f" . apheleia-format-buffer))
|
|
:hook (prog-mode)
|
|
:custom (apheleia-remote-algorithm 'local)
|
|
:config
|
|
(add-to-list 'apheleia-formatters '(alejandra . ("alejandra")))
|
|
(add-to-list 'apheleia-formatters '(isort . ("isort" "--profile" "black" "-")))
|
|
(add-to-list 'apheleia-mode-alist '(nix-mode . alejandra))
|
|
(add-to-list 'apheleia-mode-alist '(python-mode . (ruff isort)))
|
|
(add-to-list 'apheleia-mode-alist '(python-ts-mode . (ruff isort))))
|
|
|
|
(use-package flymake
|
|
:bind (("C-c C-." . flymake-goto-next-error)
|
|
("C-c C-," . flymake-goto-prev-error))
|
|
:hook (prog-mode . (lambda () (flymake-mode +1)))
|
|
:config (require 'flymake-collection))
|
|
|
|
(use-package flymake-popon
|
|
:after flymake
|
|
:init
|
|
(global-flymake-popon-mode +1))
|
|
|
|
(use-package flymake-collection
|
|
:after flymake
|
|
:custom
|
|
;; Extra mypy config
|
|
(flymake-collection-mypy-args '("--ignore-missing-imports"
|
|
"--follow-imports=skip"
|
|
"--check-untyped-defs"
|
|
"--warn-unreachable"
|
|
"--show-error-codes"
|
|
"--no-color-output")))
|
|
|
|
(use-package flymake-shellcheck
|
|
:after flymake
|
|
:hook (sh-mode . flymake-shellcheck-load))
|
|
|
|
(use-package project
|
|
:custom
|
|
(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-eshell "Eshell")
|
|
(magit-project-status "Magit")))
|
|
:config
|
|
(defun my/project-find-common-projects ()
|
|
"Search and remember common project directories.
|
|
|
|
Calls `project-remember-project-under' for ~/.config/,
|
|
~/Projects/, and ~/Documents/"
|
|
(interactive)
|
|
(require 'project)
|
|
(project-forget-zombie-projects)
|
|
(dolist
|
|
(dir
|
|
'("~/.config/" "~/Projects/"))
|
|
(project-remember-projects-under dir t))
|
|
))
|
|
|
|
(use-package magit
|
|
: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
|
|
(magit-display-buffer-function 'magit-display-buffer-same-window-except-diff-v1)
|
|
(magit-define-global-key-bindings nil)
|
|
(magit-clone-default-directory "~/Projects/")
|
|
(magit-clone-set-remote.pushDefault t)
|
|
(magit-commit-show-diff t)
|
|
(magit-commit-diff-inhibit-same-window t)
|
|
(magit-diff-adjust-tab-width t)
|
|
(magit-diff-refine-hunk 'all)
|
|
(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"))))
|
|
|
|
(use-package aggressive-indent
|
|
:hook (elisp-mode
|
|
lisp-mode
|
|
lisp-data-mode
|
|
rust-mode))
|
|
|
|
(use-package nix-mode
|
|
:mode "\\.nix\\'"
|
|
:config
|
|
(require 'nix)
|
|
(require 'nix-flake)
|
|
(require 'nix-repl)
|
|
(require 'nix-store)
|
|
(nix-prettify-global-mode +1))
|
|
|
|
(defun my/enable-fill-column (col)
|
|
"Set and enable fill column to `COL'."
|
|
(set-fill-column col)
|
|
(display-fill-column-indicator-mode +1))
|
|
|
|
(use-package python
|
|
:hook ((python-base-mode . (lambda () (my/enable-fill-column 88)))
|
|
(python-base-mode . (lambda () (add-hook 'flymake-diagnostic-functions 'flymake-collection-mypy nil t))))
|
|
:custom
|
|
(python-flymake-command
|
|
(cond ((executable-find "ruff") ("ruff" "check" "--output-format" "pylint" "-"))
|
|
((executable-find "flake8") ("flake8" "--max-line-length" "88" "-"))
|
|
(t ("pyflakes"))))
|
|
(python-check-command
|
|
(cond ((executable-find "ruff") "ruff check --output-format pylint")
|
|
((executable-find "flake8") "flake8 --max-line-length 88")
|
|
(t "pyflakes")))
|
|
:config
|
|
(setq python-ts-mode-hook python-mode-hook))
|
|
|
|
(use-package python-docstring
|
|
:hook python-base-mode)
|
|
|
|
(use-package tramp
|
|
:defer t
|
|
:config
|
|
(add-to-list 'tramp-remote-path 'tramp-own-remote-path)
|
|
(add-to-list 'tramp-remote-path "~/.local/bin/"))
|
|
|
|
(connection-local-set-profile-variables
|
|
'remote-disable-apheleia
|
|
'((apheleia-mode . nil)
|
|
(apheleia-inhibit . t)))
|
|
|
|
(connection-local-set-profile-variables
|
|
'remote-no-corfu-auto
|
|
'((corfu-auto . nil)))
|
|
|
|
(connection-local-set-profiles
|
|
'(:application tramp)
|
|
'remote-no-corfu-auto)
|
|
|
|
(connection-local-set-profiles
|
|
'(:application tramp :machine "heimdall")
|
|
'remote-disable-apheleia)
|
|
|
|
(connection-local-set-profiles
|
|
'(:application tramp :machine "freia")
|
|
'remote-disable-apheleia)
|
|
|
|
(use-package doc-view
|
|
:defer t
|
|
:bind ( :map doc-view-mode-map
|
|
("<mouse-8>" . doc-view-previous-page)
|
|
("<mouse-9>" . doc-view-next-page))
|
|
:custom
|
|
(doc-view-resolution 200)
|
|
(doc-view-imenu-enabled t)
|
|
(doc-view-scale-internally t)
|
|
(doc-view-image-width 850))
|
|
|
|
(use-package markdown-mode
|
|
:custom
|
|
(markdown-enable-math t)
|
|
(markdown-enable-html t)
|
|
:config
|
|
(set-face-attribute 'markdown-code-face nil :inherit 'fixed-pitch)
|
|
(set-face-attribute 'markdown-inline-code-face nil :inherit 'fixed-pitch)
|
|
(set-face-attribute 'markdown-table-face nil :inherit 'fixed-pitch)
|
|
(set-face-attribute 'markdown-blockquote-face nil :inherit 'variable-pitch)
|
|
(set-face-attribute 'markdown-comment-face nil :inherit 'variable-pitch))
|
|
|
|
(use-package pandoc-mode
|
|
:after (markdown-mode)
|
|
:hook (markdown-mode . conditionally-turn-on-pandoc))
|
|
|
|
(setq sendmail-program (executable-find "msmtp")
|
|
send-mail-function #'sendmail-send-it
|
|
message-send-mail-function #'message-send-mail-with-sendmail
|
|
message-sendmail-f-is-evil t
|
|
message-sendmail-extra-arguments '("--read-envelope-from")
|
|
message-auto-save-directory nil
|
|
message-kill-buffer-on-exit t
|
|
mail-user-agent 'mu4e-user-agent
|
|
read-mail-command 'mu4e)
|
|
|
|
(use-package mu4e
|
|
:bind
|
|
(("C-c m" . mu4e)
|
|
:map mu4e-view-mode-map
|
|
("o n" . mu4e-org-store-and-capture))
|
|
:custom
|
|
(mu4e-read-option-use-builtin nil)
|
|
(mu4e-completing-read-function #'completing-read)
|
|
(mu4e-split-view 'horizontal)
|
|
(mu4e-attachment-dir "~/Downloads")
|
|
(mu4e-get-mail-command "mbsync -a")
|
|
(mu4e-update-interval (* 5 60)) ; Every 5 minutes
|
|
(mu4e-headers-auto-update nil)
|
|
(mu4e-sent-messages-behavior 'sent)
|
|
(mu4e-change-filenames-when-moving t)
|
|
(mu4e-context-policy 'pick-first)
|
|
(mu4e-compose-context-policy 'ask)
|
|
(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)))
|
|
(mu4e-bookmarks '((:name "Inbox" :query "maildir:/inbox/" :key ?i :favorite t)
|
|
(:name "Today" :query "date:today..now AND maildir:/inbox/" :key ?t)
|
|
(:name "Flagged" :query "flag:flagged AND NOT flag:trashed AND NOT maildir:/spam/ AND NOT maildir:/junk/" :key ?f)
|
|
(:name "Unread" :query "flag:unread AND NOT flag:trashed AND NOT maildir:/archive/ AND NOT maildir:/spam/ AND NOT maildir:/junk/" :key ?u :hide-unread t)
|
|
(:name "Spam" :query "maildir:/spam/ OR maildir:/junk/" :key ?s :hide-unread t)))
|
|
(mu4e-headers-visible-lines 3)
|
|
(mu4e-headers-fields
|
|
'((:human-date . 8)
|
|
(:flags . 10)
|
|
(:from . 22)
|
|
(:subject)))
|
|
(mu4e-headers-visible-flags
|
|
'(draft
|
|
flagged
|
|
unread
|
|
passed
|
|
replied
|
|
trashed
|
|
attach
|
|
calendar
|
|
encrypted
|
|
signed
|
|
list
|
|
personal))
|
|
:config
|
|
(setq mu4e-use-fancy-chars t)
|
|
|
|
)
|
|
|
|
(with-eval-after-load 'mu4e
|
|
(require 'mu4e-context)
|
|
(setq mu4e-contexts
|
|
(list
|
|
(make-mu4e-context
|
|
:name "Personal"
|
|
: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")
|
|
(gnus-icalendar-org-capture-headline . ("Email" "Personal"))
|
|
))
|
|
(make-mu4e-context
|
|
:name "Alternate"
|
|
: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")
|
|
(gnus-icalendar-org-capture-headline . ("Email" "Personal"))
|
|
))
|
|
(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")
|
|
(gnus-icalendar-org-capture-headline . ("Email" "Work"))
|
|
(message-signature . (concat "Evelyn Litherland-Smith (she/they)\n"
|
|
"Spectroscopy Diagnostic Physicist\n"
|
|
"Plasma Science and Fusion Operations\n"
|
|
"UK Atomic Energy Authority"))
|
|
)))))
|
|
|
|
(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))
|
|
|
|
(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 '(" " . " ")
|
|
mu4e-headers-thread-single-orphan-prefix '("─>" . "─>")
|
|
mu4e-headers-thread-orphan-prefix '("┬>" . "┬>")
|
|
mu4e-headers-thread-connection-prefix '("│ " . "│ ")
|
|
mu4e-headers-thread-first-child-prefix '("├>" . "├>")
|
|
mu4e-headers-thread-child-prefix '("├>" . "├>")
|
|
mu4e-headers-thread-last-child-prefix '("└>" . "╰>")))
|
|
|
|
(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")))))
|
|
|
|
(with-eval-after-load 'mu4e
|
|
(require 'mu4e-notification)
|
|
(setq mu4e-notification-support t))
|
|
|
|
(with-eval-after-load 'mu4e
|
|
(require 'mu4e-org))
|
|
|
|
(use-package gnus-icalendar
|
|
:after mu4e
|
|
:custom
|
|
(gnus-icalendar-org-capture-file (expand-file-name "agenda/invited.org" org-directory))
|
|
(gnus-icalendar-org-capture-headline '("Email" "Inbox"))
|
|
:config
|
|
(require 'org-agenda)
|
|
(require 'org-capture)
|
|
(gnus-icalendar-org-setup))
|
|
|
|
(use-package mu4e-icalendar
|
|
:after mu4e
|
|
:custom
|
|
(mu4e-icalendar-trash-after-reply nil)
|
|
:config
|
|
(require 'gnus-icalendar)
|
|
(mu4e-icalendar-setup)
|
|
(gnus-icalendar-org-setup))
|
|
|
|
(use-package elfeed
|
|
:bind (("C-c f" . elfeed))
|
|
:hook (elfeed-search-mode . elfeed-update)
|
|
:custom
|
|
(elfeed-search-filter "@2-months-ago +unread")
|
|
:config
|
|
(require 'elfeed-db)
|
|
(require 'elfeed-org))
|
|
|
|
(use-package elfeed-db
|
|
:after (elfeed org)
|
|
:custom
|
|
(elfeed-db-directory (expand-file-name "elfeed" org-directory)))
|
|
|
|
(use-package elfeed-org
|
|
:after (elfeed elfeed-db org)
|
|
:custom
|
|
(rmh-elfeed-org-files (list
|
|
(expand-file-name "feeds.org" elfeed-db-directory)))
|
|
:config
|
|
(elfeed-org))
|
|
|
|
(use-package elfeed-tube
|
|
:after elfeed
|
|
:bind ( :map elfeed-show-mode-map
|
|
("F" . elfeed-tube-fetch)
|
|
([remap save-buffer] . elfeed-tube-save)
|
|
:map elfeed-search-mode-map
|
|
("F" . elfeed-tube-fetch)
|
|
([remap save-buffer] . elfeed-tube-save))
|
|
:custom
|
|
(elfeed-tube-auto-save-p nil)
|
|
(elfeed-tube-auto-fetch-p t)
|
|
:config
|
|
(elfeed-tube-setup))
|
|
|
|
(use-package password-store
|
|
:defer t)
|
|
|
|
(use-package password-store-otp
|
|
:defer t)
|
|
|
|
(use-package pass
|
|
:defer t
|
|
:bind (("C-c P" . pass))
|
|
:custom
|
|
(pass-show-keybindings nil)
|
|
(pass-username-field "login"))
|
|
|
|
(provide 'init)
|
|
;;; init.el ends here
|