Evie Litherland-Smith
b288d7b018
Start to rearrange some things to appropriate headings Add an empty diary file to stop complaining about file not being found
1536 lines
55 KiB
Org Mode
1536 lines
55 KiB
Org Mode
#+title: Emacs Config
|
|
#+author: Evie Litherland-Smith
|
|
#+email: evie@xenia.me.uk
|
|
#+filetags: :emacs:config:org:
|
|
Personal Emacs configuration. Clone to =~/.config/emacs/= (or
|
|
=~/.emacs.d/=) and install specified plugins.
|
|
* Config
|
|
Customise =use-package= first, configuration must be set before first
|
|
time it's used.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Configure packages archives with priority
|
|
(setopt use-package-check-before-init t
|
|
use-package-enable-imenu-support t)
|
|
|
|
(use-package package
|
|
:custom
|
|
(package-archive-priorities '(("melpa" . 4) ("stable" . 3) ("nongnu" . 2) ("gnu" . 1)))
|
|
(package-selected-packages
|
|
'(
|
|
;; UI
|
|
base16-theme all-the-icons nerd-icons nerd-icons-completion
|
|
nerd-icons-corfu nerd-icons-dired nerd-icons-ibuffer minions
|
|
ligature which-key diff-hl
|
|
|
|
;; Completion
|
|
vertico orderless marginalia cape corfu corfu-terminal
|
|
consult consult-eglot flyspell-correct tempel
|
|
|
|
;; IDE
|
|
treesit-auto magit forge apheleia envrc rainbow-delimiters
|
|
flymake-shellcheck flymake-yamllint flymake-clippy
|
|
flymake-eslint markdown-mode pandoc-mode python-docstring
|
|
nix-mode lua-mode
|
|
|
|
;; Org + LaTeX
|
|
org-roam org-noter citar auctex htmlize
|
|
|
|
;; Other
|
|
password-store emms bbdb ement scad-mode
|
|
|
|
))
|
|
:config
|
|
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
|
|
(add-to-list 'package-archives '("stable" . "https://stable.melpa.org/packages/"))
|
|
(package-initialize))
|
|
#+end_src
|
|
|
|
Add custom function to ensure required packages are installed and
|
|
updated.
|
|
|
|
#+begin_src emacs-lisp
|
|
(defun my/package-ensure ()
|
|
"Ensure packages are installed and updated."
|
|
(interactive)
|
|
(require 'use-package)
|
|
(package-refresh-contents)
|
|
(package-install-selected-packages)
|
|
(package-autoremove)
|
|
(package-upgrade-all))
|
|
#+end_src
|
|
|
|
Load =custom.el= if file exists in default location.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq custom-file (locate-user-emacs-file "custom.el"))
|
|
(when (and custom-file (file-exists-p custom-file))
|
|
(load custom-file nil 'nomessage))
|
|
#+end_src
|
|
** Defaults
|
|
Set some useful defaults. Some of these should be moved to relevant
|
|
section of config.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq user-full-name "Evie Litherland-Smith"
|
|
user-mail-address "evie@xenia.me.uk"
|
|
use-short-answers t
|
|
kill-do-not-save-duplicates t)
|
|
|
|
(set-default-coding-systems 'utf-8)
|
|
(global-auto-revert-mode +1)
|
|
(delete-selection-mode +1)
|
|
|
|
;; 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)
|
|
#+end_src
|
|
** UI and Appearance
|
|
Configure the look and feel of Emacs
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq inhibit-splash-screen t
|
|
initial-frame-alist nil
|
|
default-frame-alist nil)
|
|
|
|
(setq-default truncate-lines t
|
|
truncate-partial-width-windows nil)
|
|
|
|
(setopt indent-tabs-mode nil
|
|
async-shell-command-display-buffer nil
|
|
compilation-scroll-output t)
|
|
|
|
(global-prettify-symbols-mode +1)
|
|
(which-function-mode +1)
|
|
(tool-bar-mode -1)
|
|
(scroll-bar-mode -1)
|
|
#+end_src
|
|
** Completion
|
|
#+begin_src emacs-lisp
|
|
(setq tab-always-indent 'complete
|
|
completion-cycle-threshold nil
|
|
completions-detailed t)
|
|
#+end_src
|
|
** Org Mode
|
|
** Email and Messaging
|
|
*** MU4E
|
|
Configure email with iCalendar event support, to integrate with
|
|
=org-agenda=.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package sendmail
|
|
:custom
|
|
(sendmail-program (executable-find "msmtp"))
|
|
(send-mail-function #'sendmail-send-it))
|
|
|
|
(use-package message
|
|
:custom
|
|
(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))
|
|
|
|
(setq mail-user-agent 'mu4e-user-agent
|
|
read-mail-command 'mu4e)
|
|
|
|
(use-package mm-decode
|
|
:custom
|
|
(mm-discouraged-alternatives '("text/html")))
|
|
|
|
(use-package mu4e
|
|
:if (package-installed-p '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-compose-signature-auto-include nil)
|
|
(mu4e-compose-complete-only-personal nil)
|
|
(mu4e-eldoc-support t)
|
|
(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 "Drafts" :query "flag:draft AND NOT flag:trashed" :key ?d :hide-unread t)
|
|
(:name "Unread" :query "flag:unread AND maildir:/inbox/" :key ?u :hide-unread t)
|
|
(:name "Flagged" :query "flag:flagged AND NOT flag:trashed" :key ?f :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-trash-folder . "/Proton/Trash")
|
|
(mu4e-refile-folder . "/Proton/Archive")
|
|
(message-cite-style . message-cite-style-thunderbird)
|
|
(message-signature . (concat "Evelyn Litherland-Smith (she/they)\n"))
|
|
))
|
|
(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-trash-folder . "/iCloud/Deleted Messages")
|
|
(mu4e-refile-folder . "/iCloud/Archive")
|
|
(message-cite-style . message-cite-style-thunderbird)
|
|
(message-signature . (concat "Evelyn Litherland-Smith (she/they)\n"))
|
|
))
|
|
(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-trash-folder . "/Outlook/Trash")
|
|
(mu4e-refile-folder . "/Outlook/Archive")
|
|
(message-cite-style . message-cite-style-outlook)
|
|
(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))
|
|
|
|
(use-package gnus-icalendar
|
|
:after (org-agenda)
|
|
:custom
|
|
(gnus-icalendar-org-capture-file (expand-file-name "calendar/email.org.gpg" org-directory))
|
|
(gnus-icalendar-org-capture-headline '("Inbox"))
|
|
:config
|
|
(require 'org-agenda)
|
|
(require 'org-capture)
|
|
(gnus-icalendar-org-setup))
|
|
|
|
(use-package mu4e-icalendar
|
|
:after (mu4e org-agenda)
|
|
:custom
|
|
(mu4e-icalendar-trash-after-reply nil)
|
|
:config
|
|
(require 'gnus-icalendar)
|
|
(mu4e-icalendar-setup)
|
|
(gnus-icalendar-org-setup))
|
|
#+end_src
|
|
*** IRC
|
|
** Development Tools
|
|
** Other
|
|
** Initial copy from =init.el=
|
|
#+begin_src emacs-lisp
|
|
(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))
|
|
|
|
;; 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*"))
|
|
(keymap-global-set "C-c g s" #'my/git-sync-all)
|
|
|
|
;; Make shebang (#!) file executable when saved
|
|
(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
|
|
|
|
;; Remap `upcase-word' and `downcase-word' to DWIM versions
|
|
(keymap-global-set "<remap> <upcase-word>" 'upcase-dwim)
|
|
(keymap-global-set "<remap> <downcase-word>" 'downcase-dwim)
|
|
|
|
(setq backup-directory-alist '(("." . "~/.local/state/emacs/backups")))
|
|
|
|
(use-package savehist
|
|
:demand
|
|
:config
|
|
(savehist-mode +1))
|
|
|
|
(use-package dired
|
|
:custom
|
|
(dired-auto-revert-buffer t)
|
|
(dired-dwim-target t))
|
|
|
|
(use-package recentf
|
|
:config
|
|
(run-at-time nil (* 5 60) 'recentf-save-list)
|
|
(recentf-mode +1)
|
|
:custom
|
|
(recentf-max-saved-items 2048))
|
|
|
|
(use-package auth-source
|
|
:custom
|
|
(auth-sources '("secrets:Login")))
|
|
|
|
(use-package auth-source-pass
|
|
:requires auth-source
|
|
:config
|
|
(auth-source-pass-enable))
|
|
|
|
;; 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-use-meta-tab nil))
|
|
|
|
(use-package flyspell-correct
|
|
:if (package-installed-p 'flyspell-correct)
|
|
:after flyspell
|
|
:bind ( :map flyspell-mode-map
|
|
("C-;" . flyspell-correct-wrapper)))
|
|
|
|
(use-package ibuffer
|
|
:defines ibuffer-filter-groups
|
|
:bind (("C-c b" . ibuffer)))
|
|
|
|
(use-package shell
|
|
:bind (("C-c t s" . shell)))
|
|
|
|
(use-package eshell
|
|
:bind (("C-c t e" . eshell))
|
|
:config
|
|
(require 'esh-mode))
|
|
|
|
(use-package esh-mode
|
|
:defines eshell-mode-map
|
|
:bind ( :map eshell-mode-map
|
|
("<remap> <eshell-previous-matching-input>" . consult-history)))
|
|
|
|
(use-package calc
|
|
:bind (("<Calculator>" . calc)))
|
|
|
|
(use-package xref
|
|
:custom
|
|
(xref-show-definitions-function 'xref-show-definitions-completing-read))
|
|
|
|
(use-package appt
|
|
:custom
|
|
(appt-display-diary nil)
|
|
(appt-display-format 'echo))
|
|
|
|
(use-package calendar
|
|
:after appt
|
|
:bind (("C-c >" . calendar))
|
|
:hook ((calendar-today-visible . calendar-mark-today))
|
|
: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)
|
|
:config
|
|
(appt-activate +1)
|
|
(add-to-list 'display-buffer-alist
|
|
'("\\*Calendar\\*"
|
|
(display-buffer-in-side-window)
|
|
(side . bottom)
|
|
(slot . 0)
|
|
(window-height . 0.2)
|
|
(window-parameters . ((no-delete-other-windows . t))))))
|
|
|
|
(add-hook 'prog-mode-hook #'(lambda () (display-line-numbers-mode +1)))
|
|
|
|
(use-package which-key
|
|
:if (package-installed-p 'which-key)
|
|
:functions which-key-mode
|
|
:config (which-key-mode +1))
|
|
|
|
(use-package elec-pair
|
|
:config
|
|
(electric-pair-mode +1))
|
|
|
|
(use-package paren
|
|
:config
|
|
(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)))
|
|
|
|
(use-package base16-theme
|
|
:if (package-installed-p 'base16-theme)
|
|
:demand
|
|
:defines (base16-one-light-theme-colors
|
|
my/load-theme-and-configure)
|
|
:hook (server-after-make-frame . my/load-theme-and-configure)
|
|
:custom
|
|
(base16-theme-distinct-fringe-background nil)
|
|
(base16-theme-highlight-mode-line 'contrast)
|
|
:init
|
|
(defun my/load-theme-and-configure ()
|
|
"Load theme and configure some faces."
|
|
(load-theme 'base16-one-light t)
|
|
|
|
;; Change outline headers to follow rainbow order
|
|
(require 'outline)
|
|
(dolist (pairing '((outline-1 . :base08)
|
|
(outline-2 . :base09)
|
|
(outline-3 . :base0A)
|
|
(outline-4 . :base0B)
|
|
(outline-5 . :base0C)
|
|
(outline-6 . :base0D)
|
|
(outline-7 . :base0E)
|
|
(outline-8 . :base0F)))
|
|
(set-face-attribute (car pairing) nil
|
|
:foreground
|
|
(plist-get base16-one-light-theme-colors (cdr pairing)))))
|
|
:config
|
|
(if (display-graphic-p) (my/load-theme-and-configure)))
|
|
|
|
(use-package nerd-icons
|
|
:if (package-installed-p 'nerd-icons)
|
|
:functions (nerd-icons-octicon))
|
|
|
|
(use-package nerd-icons-dired
|
|
:requires nerd-icons
|
|
:hook (dired-mode))
|
|
|
|
(use-package nerd-icons-ibuffer
|
|
:requires nerd-icons
|
|
:hook (ibuffer-mode))
|
|
|
|
(use-package nerd-icons-completion
|
|
:functions nerd-icons-completion-mode
|
|
:requires nerd-icons
|
|
:hook (after-init . (lambda () (nerd-icons-completion-mode +1))))
|
|
|
|
(use-package minions
|
|
:if (package-installed-p 'minions)
|
|
:functions minions-mode
|
|
:hook (after-init . (lambda () (minions-mode +1)))
|
|
:custom
|
|
(minions-prominent-modes '(envrc-mode flymake-mode)))
|
|
|
|
(use-package ligature
|
|
:if (package-installed-p 'ligature)
|
|
:functions (ligature-set-ligatures
|
|
global-ligature-mode)
|
|
: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)
|
|
|
|
(line-number-mode -1)
|
|
(column-number-mode -1)
|
|
(size-indication-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 time
|
|
:custom
|
|
(display-time-24hr-format t))
|
|
|
|
(use-package diff-hl
|
|
:if (package-installed-p 'diff-hl)
|
|
:functions (diff-hl-magit-pre-refresh
|
|
diff-hl-magit-post-refresh
|
|
global-diff-hl-mode)
|
|
:init
|
|
(add-hook 'magit-pre-refresh-hook #'diff-hl-magit-pre-refresh)
|
|
(add-hook 'magit-post-refresh-hook #'diff-hl-magit-post-refresh)
|
|
:custom
|
|
(diff-hl-disable-on-remote nil)
|
|
(diff-hl-draw-borders t)
|
|
:config
|
|
(global-diff-hl-mode))
|
|
|
|
(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))
|
|
|
|
(use-package emms
|
|
:defines (emms-browser-mode-map
|
|
emms-playlist-mode-map)
|
|
:functions (emms-all
|
|
emms-default-players
|
|
emms-mpris-enable
|
|
emms-cache-enable
|
|
emms-show)
|
|
: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
|
|
:defines org-mode-map
|
|
:hook ((org-mode . turn-on-auto-fill))
|
|
:bind ( :map org-mode-map
|
|
("<remap> <imenu>" . consult-org-heading)
|
|
("<remap> <org-goto>" . consult-org-heading))
|
|
:custom
|
|
(org-directory "~/Documents/org")
|
|
(org-default-notes-file (expand-file-name "notes.org" org-directory))
|
|
(org-archive-location "::* Archived Tasks")
|
|
(org-hide-emphasis-markers t)
|
|
(org-use-sub-superscripts '{})
|
|
(org-pretty-entities t)
|
|
(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-display-remote-inline-images 'cache)
|
|
(org-M-RET-may-split-line '((default . nil)
|
|
(headline . nil)
|
|
(item . nil)
|
|
(table . t))))
|
|
|
|
(use-package ox
|
|
:after org
|
|
:custom
|
|
(org-export-with-sub-superscripts org-use-sub-superscripts))
|
|
|
|
(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))
|
|
(org-attach-dir-relative t)
|
|
(org-attach-use-inheritance nil))
|
|
|
|
(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 . 3))
|
|
(org-agenda-files . (:maxlevel . 3)))))
|
|
|
|
(use-package org-src
|
|
:after org
|
|
:custom
|
|
(org-src-window-setup 'reorganize-frame))
|
|
|
|
(use-package ob-core
|
|
:after org
|
|
:custom
|
|
(org-babel-no-eval-on-ctrl-c-ctrl-c t)
|
|
(org-confirm-babel-evaluate nil)
|
|
:config
|
|
(let (babel-languages)
|
|
(push '(lua . t) babel-languages)
|
|
(push '(python . t) babel-languages)
|
|
(push '(emacs-lisp . t) babel-languages)
|
|
(org-babel-do-load-languages 'org-babel-load-languages babel-languages)))
|
|
|
|
(use-package ob-python
|
|
:after ob-core
|
|
:custom
|
|
(org-babel-python-command "python3"))
|
|
|
|
(use-package org-capture
|
|
:after org
|
|
:bind ("C-c o n" . org-capture)
|
|
:custom (org-capture-templates
|
|
'(("t" "TODO" entry
|
|
(file+olp "tasks.org.gpg" "Inbox")
|
|
"* TODO %?\nDEADLINE: %t\n %i\n %a")
|
|
("#" "used by gnus-icalendar-org" entry
|
|
(file+olp "calendar/email.org.gpg" "Inbox")
|
|
"%i" :immediate-finish t))))
|
|
|
|
(if (executable-find "sqlite3")
|
|
(use-package org-roam
|
|
:if (package-installed-p 'org-roam)
|
|
:after org
|
|
:defines org-roam-directory
|
|
:functions org-roam-db-autosync-mode
|
|
: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)
|
|
("C-c o r j" . org-roam-dailies-capture-today)
|
|
("M-g j" . org-roam-dailies-goto-today)
|
|
("M-g C-j" . org-roam-dailies-goto-date)
|
|
:map org-mode-map
|
|
("C-c o r b" . org-roam-buffer-toggle))
|
|
: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")
|
|
: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-delete-other-windows . t)))))
|
|
(org-roam-db-autosync-mode +1)))
|
|
|
|
(use-package org-roam-dailies
|
|
:after org-roam
|
|
:custom
|
|
(org-roam-dailies-directory "./")
|
|
(org-roam-dailies-capture-templates
|
|
'(("d" "default" entry
|
|
"* %?"
|
|
:target (file+datetree "journal.org.gpg" week)))))
|
|
|
|
(use-package org-clock
|
|
:after org
|
|
:custom
|
|
(org-clock-rounding-minutes 15))
|
|
|
|
(use-package org-agenda
|
|
:after (org appt)
|
|
:bind (("C-c o a" . org-agenda)
|
|
("C-c o C-a" . org-agenda-list))
|
|
:hook (org-agenda-finalize . org-agenda-to-appt)
|
|
:custom
|
|
(org-agenda-span 'day)
|
|
(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 "calendar/diary.org.gpg" 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-clockreport-parameter-plist '(:link t :maxlevel 6 :emphasize t :stepskip0 t :fileskip0 t :filetitle t :properties ("WON")))
|
|
(org-agenda-start-with-clockreport-mode t)
|
|
(org-agenda-start-with-log-mode t)
|
|
(org-agenda-prefix-format '((agenda . " %-12:c%?-12t% s")
|
|
(todo . " %-12:c")
|
|
(tags . " %-12:c")
|
|
(search . " %-12:c")))
|
|
(org-agenda-file-regexp "\\`[^.].*\\.org\\\(\\.gpg\\\)?\\'")
|
|
(org-agenda-files (list
|
|
(expand-file-name org-directory)
|
|
(expand-file-name "calendar" org-directory)
|
|
(expand-file-name "roam/journal.org.gpg" org-directory)
|
|
(expand-file-name "roam/analysis_notes.org" org-directory)))
|
|
:config
|
|
(appt-activate +1))
|
|
|
|
(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-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
|
|
:defines (citar-bibliography
|
|
citar-indicators)
|
|
:functions (citar-indicator-create
|
|
citar-has-files
|
|
citar-has-links
|
|
citar-has-notes
|
|
citar-is-cited)
|
|
:hook
|
|
(LaTeX-mode . citar-capf-setup)
|
|
(org-mode . citar-capf-setup)
|
|
:custom
|
|
(citar-bibliography
|
|
(list
|
|
(expand-file-name "citar/main.bib" org-directory)))
|
|
(citar-notes-paths
|
|
(list
|
|
(expand-file-name "citar/notes/" org-directory)))
|
|
(citar-library-paths
|
|
(list
|
|
(expand-file-name "~/Documents/library/")))
|
|
:config
|
|
(require 'org)
|
|
(require 'nerd-icons)
|
|
(setopt org-cite-insert-processor 'citar
|
|
org-cite-follow-processor 'citar
|
|
org-cite-activate-processor 'citar)
|
|
(dolist (bibfile citar-bibliography)
|
|
(add-to-list 'org-cite-global-bibliography bibfile))
|
|
(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)))
|
|
|
|
(setq org-latex-compiler "lualatex")
|
|
(setq org-preview-latex-default-process 'dvisvgm)
|
|
|
|
(use-package vertico
|
|
:if (package-installed-p 'vertico)
|
|
:functions vertico-mode
|
|
:hook (after-init . (lambda () (vertico-mode +1)))
|
|
:custom
|
|
(vertico-cycle t)
|
|
:config
|
|
(require 'vertico-directory))
|
|
|
|
(use-package marginalia
|
|
:if (package-installed-p 'marginalia)
|
|
:functions marginalia-mode
|
|
:hook (after-init . (lambda () (marginalia-mode +1)))
|
|
:custom
|
|
(marginalia-annotators '(marginalia-annotators-heavy
|
|
marginalia-annotators-light
|
|
nil))
|
|
:config (marginalia-mode +1))
|
|
|
|
(use-package orderless
|
|
:if (package-installed-p 'orderless)
|
|
:custom
|
|
(completion-styles '(orderless basic))
|
|
(completion-category-defaults nil)
|
|
(completion-category-overrides '((file (styles basic partial-completion))
|
|
(eglot (styles orderless))
|
|
(eglot-capf (styles orderless)))))
|
|
|
|
(use-package nerd-icons-corfu
|
|
:functions nerd-icons-corfu-formatter
|
|
:requires nerd-icons)
|
|
|
|
(use-package corfu
|
|
:if (package-installed-p 'corfu)
|
|
:defines (corfu-map
|
|
corfu-mode-map
|
|
corfu-margin-formatters)
|
|
:functions (corfu-mode
|
|
global-corfu-mode
|
|
corfu-history-mode)
|
|
:hook ((after-init . (lambda () (global-corfu-mode +1)))
|
|
(minibuffer-setup . (lambda ()
|
|
"Enable `corfu-mode' for `M-:' and `M-!'."
|
|
(when (local-variable-p 'completion-at-point-functions)
|
|
(corfu-mode +1)))))
|
|
:bind ( :map corfu-map
|
|
("M-SPC" . corfu-insert-separator)
|
|
("RET" . nil)
|
|
("TAB" . corfu-insert)
|
|
([tab] . corfu-insert))
|
|
:custom
|
|
(corfu-cycle t)
|
|
(corfu-auto nil)
|
|
(corfu-preselect 'directory)
|
|
:config
|
|
(require 'corfu-history)
|
|
(when (require 'nerd-icons-corfu nil :noerror)
|
|
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
|
|
(when (require 'corfu-popupinfo nil :noerror)
|
|
(corfu-popupinfo-mode +1))
|
|
(when (and (require 'corfu-terminal nil :noerror)
|
|
(not (display-graphic-p)))
|
|
(corfu-terminal-mode +1)))
|
|
|
|
(use-package corfu-history
|
|
:requires (corfu savehist)
|
|
:functions corfu-history
|
|
:config
|
|
(add-to-list 'savehist-additional-variables #'corfu-history))
|
|
|
|
(use-package corfu-popupinfo
|
|
:requires corfu
|
|
:defines corfu-popupinfo-map
|
|
:functions corfu-popupinfo-mode
|
|
:bind ( :map corfu-popupinfo-map
|
|
("M-d" . corfu-popupinfo-toggle)
|
|
("M-n" . corfu-popupinfo-scroll-up)
|
|
("M-p" . corfu-popupinfo-scroll-down))
|
|
:custom
|
|
(corfu-popupinfo-delay 0.3))
|
|
|
|
(use-package corfu-terminal
|
|
:requires corfu
|
|
:functions corfu-terminal-mode)
|
|
|
|
(use-package cape
|
|
:if (package-installed-p 'cape)
|
|
:after corfu
|
|
:functions (cape-emoji
|
|
cape-file
|
|
cape-dabbrev)
|
|
:hook ((conf-mode prog-mode text-mode) . (lambda ()
|
|
(dolist (cape-fn '(cape-dabbrev
|
|
cape-file
|
|
cape-emoji))
|
|
(add-hook 'completion-at-point-functions cape-fn nil t))))
|
|
:custom
|
|
(cape-dabbrev-min-length (+ corfu-auto-prefix 1)))
|
|
|
|
(use-package consult
|
|
:if (package-installed-p 'consult)
|
|
:functions (consult-org-heading
|
|
consult-history)
|
|
:bind (("<remap> <imenu>" . consult-imenu)
|
|
("<remap> <switch-to-buffer>" . consult-buffer)
|
|
("<remap> <project-switch-to-buffer>" . consult-project-buffer)
|
|
("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
|
|
("<remap> <previous-matching-history-element>" . consult-history)
|
|
:map comint-mode-map
|
|
("<remap> <comint-history-isearch-backward-regexp>" . consult-history)))
|
|
|
|
(use-package consult-eglot
|
|
:after (consult eglot)
|
|
:bind (("C-c s s" . consult-eglot-symbols)))
|
|
|
|
(use-package tempel
|
|
:if (package-installed-p 'tempel)
|
|
:defines tempel-path
|
|
:functions (tempel-expand
|
|
tempel-abbrev-mode)
|
|
:bind (("M-+" . tempel-complete)
|
|
("M-*" . tempel-insert))
|
|
:hook ((conf-mode prog-mode text-mode) . (lambda () (add-hook 'completion-at-point-functions 'tempel-complete nil t)))
|
|
:custom
|
|
(tempel-trigger-prefix "+"))
|
|
|
|
(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
|
|
:if (package-installed-p 'rainbow-delimiters)
|
|
:hook (prog-mode))
|
|
|
|
(use-package envrc
|
|
:if (package-installed-p 'envrc)
|
|
:hook (after-init . envrc-global-mode)
|
|
:custom
|
|
(envrc-show-summary-in-minibuffer t))
|
|
|
|
(use-package gud
|
|
:defer t
|
|
:defines gdb-many-windows
|
|
:config
|
|
(setq gdb-many-windows t))
|
|
|
|
(use-package treesit
|
|
:custom
|
|
(treesit-font-lock-level 3))
|
|
|
|
(use-package treesit-auto
|
|
:if (package-installed-p 'treesit-auto)
|
|
:requires treesit
|
|
:functions (treesit-auto-add-to-auto-mode-alist
|
|
global-treesit-auto-mode)
|
|
:hook (after-init . (lambda () (global-treesit-auto-mode +1)))
|
|
:config
|
|
(treesit-auto-add-to-auto-mode-alist))
|
|
|
|
(use-package eldoc
|
|
:custom
|
|
(eldoc-echo-area-display-truncation-message nil)
|
|
(eldoc-echo-area-prefer-doc-buffer 'maybe)
|
|
(eldoc-echo-area-use-multiline-p 3))
|
|
|
|
(use-package eglot
|
|
: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)))
|
|
(nix-mode . (lambda () (if (and (project-current nil) (executable-find "nixd" t))
|
|
(eglot-ensure))))
|
|
(python-base-mode . (lambda () (if (and (project-current nil) (executable-find "pylsp" t))
|
|
(eglot-ensure))))
|
|
(lua-mode . (lambda () (if (and (project-current nil) (executable-find "lua-language-server" t))
|
|
(eglot-ensure))))
|
|
((rust-ts-mode rust-mode) . (lambda () (if (and (project-current nil) (executable-find "rust-analyzer" t))
|
|
(eglot-ensure))))
|
|
((js-base-mode typescript-ts-base-mode) . (lambda () (if (and (project-current nil) (executable-find "typescript-language-server" t))
|
|
(eglot-ensure))))
|
|
)
|
|
:custom
|
|
(eglot-menu-string "lsp")
|
|
(eglot-send-changes-idle-time 1)
|
|
(eglot-extend-to-xref t)
|
|
(eglot-autoshutdown t)
|
|
(eglot-sync-connect nil)
|
|
(eglot-autoreconnect (* 60 5))
|
|
(eglot-events-buffer-config '(:size 0))
|
|
(eglot-ignored-server-capabilities
|
|
'(:documentHighlightProvider
|
|
:documentFormattingProvider
|
|
:documentRangeFormattingProvider
|
|
:documentOnTypeFormattingProvider
|
|
:documentLinkProvider
|
|
:colorProvider
|
|
:foldingRangeProvider))
|
|
:init
|
|
(setq eglot-stay-out-of '(flymake))
|
|
:config
|
|
(setq-default eglot-workspace-configuration
|
|
'( :nil ( :nix
|
|
( :maxMemoryMB nil
|
|
:flake
|
|
( :autoArchive t
|
|
:nixpkgsInputName "nixpkgs")))
|
|
: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)))))
|
|
)
|
|
|
|
(use-package apheleia
|
|
:if (package-installed-p 'apheleia)
|
|
:defines (apheleia-formatters
|
|
apheleia-mode-alist)
|
|
:bind (("C-c c f" . apheleia-format-buffer))
|
|
:hook (prog-mode)
|
|
:custom (apheleia-remote-algorithm 'cancel)
|
|
:config
|
|
(add-to-list 'apheleia-mode-alist '(python-ts-mode . (ruff ruff-isort)))
|
|
(add-to-list 'apheleia-mode-alist '(python-mode . (ruff ruff-isort))))
|
|
|
|
(use-package flymake
|
|
:bind (("C-c C-." . flymake-goto-next-error)
|
|
("C-c C-," . flymake-goto-prev-error))
|
|
:hook ((prog-mode yaml-ts-mode) . (lambda () (flymake-mode +1)))
|
|
:custom
|
|
(flymake-no-changes-timeout 1)
|
|
(flymake-show-diagnostics-at-end-of-line 'short))
|
|
|
|
(use-package flymake-shellcheck
|
|
:if (package-installed-p 'flymake-shellcheck)
|
|
:functions flymake-shellcheck-load
|
|
:requires flymake
|
|
:hook (sh-mode . (lambda () (if (executable-find "shellcheck" t)
|
|
(flymake-shellcheck-load)))))
|
|
|
|
(use-package flymake-yamllint
|
|
:if (package-installed-p 'flymake-yamllint)
|
|
:functions flymake-yamllint-setup
|
|
:requires flymake
|
|
:hook (yaml-ts-mode . (lambda () (if (executable-find "yamllint" t)
|
|
(flymake-yamllint-setup)))))
|
|
|
|
(use-package flymake-clippy
|
|
:if (package-installed-p 'flymake-clippy)
|
|
:functions flymake-clippy-setup-backend
|
|
:requires flymake
|
|
:hook (rust-mode . (lambda () (if (executable-find "clippy" t)
|
|
(flymake-clippy-setup-backend)))))
|
|
|
|
(use-package flymake-eslint
|
|
:if (package-installed-p 'flymake-eslint)
|
|
:functions flymake-eslint-enable
|
|
:requires flymake
|
|
:hook ((js-base-mode typescript-ts-base-mode) . (lambda () (if (executable-find "eslint" t)
|
|
(flymake-eslint-enable)))))
|
|
|
|
(use-package project
|
|
:functions (project-forget-zombie-projects
|
|
project-remember-projects-under)
|
|
: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-projects-under' for ~/Projects/"
|
|
(interactive)
|
|
(require 'project)
|
|
(project-forget-zombie-projects)
|
|
(project-remember-projects-under user-emacs-directory nil)
|
|
(project-remember-projects-under "/etc/nixos/" nil)
|
|
(project-remember-projects-under "~/Projects" 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 b" . magit-blame-addition)
|
|
("<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-show-long-lines-warning 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 nix-mode
|
|
:if (package-installed-p 'nix-mode)
|
|
:mode "\\.nix\\'"
|
|
:functions nix-prettify-global-mode
|
|
: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 () (setq-local
|
|
python-check-command (cond
|
|
((executable-find "mypy" t) "mypy --check-untyped-defs --warn-unreachable --show-error-codes --ignore-missing-imports")
|
|
(t "pyflakes"))
|
|
python-flymake-command (cond
|
|
((executable-find "ruff" t) '("ruff" "check" "--output-format=concise" "--stdin-filename=stdin" "-"))
|
|
((executable-find "flake8" t) '("flake8" "--max-line-length" "88" "-"))
|
|
(t '("pyflakes")))))))
|
|
:custom
|
|
(python-shell-interpreter "python3")
|
|
(python-shell-dedicated nil)
|
|
(python-shell-completion-native-enable nil)
|
|
(python-indent-def-block-scale 1)
|
|
:config
|
|
(setq python-ts-mode-hook python-mode-hook))
|
|
|
|
(use-package python-docstring
|
|
:if (package-installed-p 'python-docstring)
|
|
:hook python-base-mode)
|
|
|
|
(use-package files
|
|
:custom
|
|
(view-read-only t)
|
|
(enable-remote-dir-locals t))
|
|
|
|
(use-package tramp
|
|
:defer t
|
|
:custom
|
|
(tramp-default-method "scpx")
|
|
(tramp-backup-directory-alist backup-directory-alist)
|
|
(tramp-auto-save-directory (cdr (assoc "." tramp-backup-directory-alist)))
|
|
: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-no-corfu-auto
|
|
'((corfu-auto . nil)))
|
|
|
|
(connection-local-set-profiles
|
|
'(:application tramp)
|
|
'remote-no-corfu-auto)
|
|
|
|
(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
|
|
:if (package-installed-p 'markdown-mode)
|
|
:hook
|
|
((markdown-mode . turn-on-auto-fill))
|
|
: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
|
|
:if (package-installed-p 'pandoc-mode)
|
|
:after (markdown-mode)
|
|
:hook (markdown-mode . conditionally-turn-on-pandoc))
|
|
|
|
(use-package bbdb
|
|
:bind (("M-g b" . bbdb-display-all-records))
|
|
:custom
|
|
(bbdb-file (locate-user-emacs-file "bbdb.gpg")))
|
|
|
|
(use-package erc
|
|
:commands erc-compute-nick
|
|
:custom
|
|
(erc-nick (user-login-name))
|
|
(erc-user-full-name (user-full-name)))
|
|
|
|
(defun my/libera-chat-connect ()
|
|
"Connect to irc.libera.chat directly."
|
|
(interactive)
|
|
(require 'erc)
|
|
(require 'password-store)
|
|
(erc-tls
|
|
:server "irc.libera.chat"
|
|
:password (password-store-get 'social/irc.libera.chat)))
|
|
(defun my/znc-connect ()
|
|
"Connect to my ZNC IRC bouncer."
|
|
(interactive)
|
|
(require 'erc)
|
|
(require 'password-store)
|
|
(erc-tls
|
|
:server "xenia.me.uk"
|
|
:port 6697
|
|
:nick (concat (erc-compute-nick) "/liberachat")
|
|
:password (password-store-get 'local/znc)))
|
|
|
|
(use-package eww
|
|
:defer t
|
|
:custom
|
|
(browse-url-browser-function 'browse-url-default-browser)
|
|
(browse-url-secondary-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 password-store
|
|
:defer t
|
|
:functions password-store-get)
|
|
|
|
;; 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)
|
|
|
|
;; 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 'citar)
|
|
(find-file (car org-cite-global-bibliography)))
|
|
(keymap-global-set "C-c w b" #'my/open-global-bibliography)
|
|
|
|
(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)
|
|
#+end_src
|