Evie Litherland-Smith
94a20654cd
Ensure it's run before use-package is used or theme is loaded, since nix puts these at the start of the extra config block Run vdirsyncer when khalel first loaded, before importing, to make sure things are up to date. No run at startup so only affects when first opening email/org-agenda
1425 lines
48 KiB
EmacsLisp
1425 lines
48 KiB
EmacsLisp
;;; init.el --- Personal Emacs Config
|
|
;;; Commentary:
|
|
;;; Code:
|
|
(use-package package
|
|
:config
|
|
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
|
|
(package-initialize))
|
|
|
|
(use-package delight
|
|
:demand t)
|
|
|
|
(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-language-environment "UTF-8")
|
|
(set-default-coding-systems 'utf-8)
|
|
(global-auto-revert-mode +1)
|
|
(delete-selection-mode +1)
|
|
|
|
;; (setq warning-minimum-level :error)
|
|
|
|
(keymap-global-set "<mouse-8>" #'previous-buffer)
|
|
(keymap-global-set "<mouse-9>" #'next-buffer)
|
|
|
|
(setq backup-directory-alist '(("." . "~/.local/state/emacs/backups")))
|
|
|
|
(use-package secrets
|
|
:defer t)
|
|
|
|
(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
|
|
tab-bar-show 1
|
|
tab-line-tabs-function 'tab-line-tabs-mode-buffers)
|
|
|
|
(global-prettify-symbols-mode +1)
|
|
(global-tab-line-mode +1)
|
|
(menu-bar-mode +1)
|
|
(tool-bar-mode -1)
|
|
(scroll-bar-mode -1)
|
|
|
|
(use-package nerd-icons
|
|
:demand t)
|
|
|
|
(use-package nerd-icons-dired
|
|
:after (nerd-icons dired)
|
|
:commands nerd-icons-dired-mode
|
|
:hook (dired-mode . (lambda () (nerd-icons-dired-mode +1))))
|
|
|
|
(use-package nerd-icons-ibuffer
|
|
:after nerd-icons
|
|
:commands nerd-icons-ibuffer-mode
|
|
:hook (ibuffer-mode . (lambda () (nerd-icons-ibuffer-mode +1))))
|
|
|
|
(use-package nerd-icons-corfu
|
|
:after nerd-icons)
|
|
|
|
(setopt mode-line-compact 'long)
|
|
|
|
(line-number-mode +1)
|
|
(column-number-mode +1)
|
|
(size-indication-mode -1)
|
|
|
|
(add-hook 'help-mode-hook (lambda () (visual-line-mode +1)))
|
|
|
|
(use-package visual-fill-column
|
|
:functions (visual-fill-column-mode)
|
|
:hook ((prog-mode . (lambda ()
|
|
(visual-line-mode +1)
|
|
(visual-fill-column-mode +1)))
|
|
((Info-mode man-common) . (lambda ()
|
|
(setq-local visual-fill-column-width 80)
|
|
(visual-line-mode +1)
|
|
(visual-fill-column-mode +1))))
|
|
:custom
|
|
(visual-fill-column-width 120)
|
|
(visual-fill-column-center-text t)
|
|
(visual-fill-column-enable-sensible-window-split t)
|
|
:config
|
|
(setopt visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow)))
|
|
|
|
(with-eval-after-load 'mu4e
|
|
(add-hook 'mu4e-view-mode-hook
|
|
#'(lambda ()
|
|
(visual-line-mode +1)
|
|
(visual-fill-column-mode +1)))
|
|
(add-hook 'mu4e-compose-mode-hook
|
|
#'(lambda ()
|
|
(visual-line-mode +1)
|
|
(visual-fill-column-mode +1))))
|
|
|
|
(use-package ligature
|
|
:load-path "external-packages/ligature.el/"
|
|
:functions (ligature-set-ligatures
|
|
global-ligature-mode)
|
|
:config
|
|
(ligature-set-ligatures
|
|
'(prog-mode)
|
|
'(("<" (rx (= 1 "=")))
|
|
(">" (rx (= 1 "=")))
|
|
("-" (rx (* "-") (= 1 ">")))
|
|
("=" (rx (* "=") (? ">")))
|
|
("!" (rx (+ "=")))))
|
|
(global-ligature-mode +1))
|
|
|
|
(setq split-height-threshold nil
|
|
split-width-threshold 160)
|
|
|
|
(setq tab-always-indent 'complete
|
|
completion-cycle-threshold nil
|
|
completions-detailed t)
|
|
|
|
(add-to-list 'directory-abbrev-alist
|
|
'("^/ndrive" . "/smb:elitherl%ccfepc@msrv-cfshare.ccfepc.ccfe.ac.uk:/NDrive/"))
|
|
(add-to-list 'directory-abbrev-alist
|
|
'("^/tdrive" . "/smb:elitherl%ccfepc@msrv-cfshare.ccfepc.ccfe.ac.uk:/NewT/"))
|
|
|
|
(use-package tramp
|
|
:defer t
|
|
:custom
|
|
(tramp-default-method "scp")
|
|
(tramp-backup-directory-alist backup-directory-alist)
|
|
(tramp-auto-save-directory (cdr (assoc "." tramp-backup-directory-alist)))
|
|
(remote-file-name-inhibit-cache 300)
|
|
(remote-file-name-inhibit-locks t)
|
|
:config
|
|
(add-to-list 'tramp-remote-path 'tramp-own-remote-path)
|
|
(add-to-list 'tramp-remote-path "~/.local/bin/")
|
|
(add-to-list 'tramp-remote-path "~/bin")
|
|
(add-to-list 'tramp-default-proxies-alist
|
|
'("legion" "\\`root\\'" "/ssh:%h:")))
|
|
|
|
(connection-local-set-profile-variables
|
|
'remote-no-corfu-auto
|
|
'((corfu-auto . nil)))
|
|
|
|
(connection-local-set-profiles
|
|
'(:application tramp)
|
|
'remote-no-corfu-auto)
|
|
|
|
(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))))))
|
|
|
|
(use-package gnus-icalendar
|
|
:after (calendar mu4e org-agenda)
|
|
:functions (gnus-icalendar-setup)
|
|
:config
|
|
(gnus-icalendar-setup))
|
|
|
|
(use-package khalel
|
|
:after (org-agenda)
|
|
:commands (khalel-run-vdirsyncer khalel-import-events khalel-add-capture-template)
|
|
:custom
|
|
(khalel-default-alarm "10")
|
|
(khalel-default-calendar nil)
|
|
(khalel-import-org-file (expand-file-name "calendar.org" org-directory))
|
|
(khalel-import-org-file-read-only nil)
|
|
(khalel-import-org-file-confirm-overwrite nil)
|
|
(khalel-import-start-date "-365d")
|
|
(khalel-import-end-date "+365d")
|
|
(khalel-import-org-file-header "#+TITLE: khalel imported calendar events\n#+COLUMNS: %ITEM %TIMESTAMP %LOCATION %CALENDAR\n#+CATEGORY: Calendar\n\n")
|
|
:config
|
|
(khalel-run-vdirsyncer)
|
|
(khalel-import-events)
|
|
(khalel-add-capture-template))
|
|
|
|
(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
|
|
: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)
|
|
(require 'mu4e-icalendar)
|
|
(require 'khalel-icalendar))
|
|
|
|
(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")
|
|
(khalel-default-calendar . "personal")
|
|
(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"
|
|
"Email: e.litherlandsmith@proton.me\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")
|
|
(khalel-default-calendar . "other")
|
|
(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"
|
|
"Email: e.litherlandsmith@icloud.com\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")
|
|
(khalel-default-calendar . "work")
|
|
(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 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 'secrets)
|
|
(erc-tls
|
|
:server "irc.libera.chat"
|
|
:password (secrets-get-secret "default" "IRC libera.chat")))
|
|
|
|
(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))
|
|
|
|
;; 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)
|
|
|
|
(use-package savehist
|
|
:demand
|
|
:config
|
|
(savehist-mode +1))
|
|
|
|
(use-package dired
|
|
:hook (dired-mode . (lambda () (dired-omit-mode +1)))
|
|
:custom
|
|
(dired-auto-revert-buffer t)
|
|
(dired-dwim-target t)
|
|
(dired-omit-files "\\`[.]?#\\|\\`[.][.]?.*\\'"))
|
|
|
|
(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:default")))
|
|
|
|
;; 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
|
|
:delight flyspell-mode
|
|
:hook ((text-mode . flyspell-mode)
|
|
(prog-mode . flyspell-prog-mode))
|
|
:custom
|
|
(flyspell-use-meta-tab nil)
|
|
:init
|
|
(require 'ispell))
|
|
|
|
(use-package ibuffer
|
|
:defines ibuffer-filter-groups
|
|
:bind (("C-c b" . ibuffer)))
|
|
|
|
(use-package eshell
|
|
:bind (("C-c 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))
|
|
|
|
(add-hook 'prog-mode-hook #'(lambda () (display-line-numbers-mode +1)))
|
|
|
|
(use-package which-key
|
|
:functions which-key-mode
|
|
:config (which-key-mode +1))
|
|
|
|
(use-package elec-pair
|
|
:hook (prog-mode . (lambda () (electric-pair-local-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)))
|
|
|
|
(dolist (command '(scroll-up-command
|
|
scroll-down-command
|
|
recenter-top-bottom other-window))
|
|
(advice-add command :after #'pulse-line))
|
|
|
|
(use-package whitespace
|
|
:hook prog-mode
|
|
:custom
|
|
(whitespace-action nil)
|
|
(whitespace-style '(face
|
|
trailing
|
|
missing-newline-at-eof
|
|
empty
|
|
indentation
|
|
space-after-tab
|
|
space-before-tab
|
|
tab-mark)))
|
|
|
|
(use-package diff-hl
|
|
:functions (diff-hl-magit-pre-refresh
|
|
diff-hl-magit-post-refresh
|
|
global-diff-hl-mode)
|
|
:custom
|
|
(diff-hl-disable-on-remote nil)
|
|
:init
|
|
(global-diff-hl-mode)
|
|
(add-hook 'magit-pre-refresh-hook #'diff-hl-magit-pre-refresh)
|
|
(add-hook 'magit-post-refresh-hook #'diff-hl-magit-post-refresh))
|
|
|
|
(use-package winner
|
|
:demand
|
|
:config
|
|
(winner-mode))
|
|
|
|
(use-package ediff
|
|
:custom
|
|
(ediff-window-setup-function #'ediff-setup-windows-plain))
|
|
|
|
(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-default-command #'org-archive-to-archive-sibling)
|
|
(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
|
|
:delight org-indent-mode
|
|
: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-preserve-indentation t)
|
|
(org-src-window-setup 'current-window))
|
|
|
|
(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 n n" . org-capture))
|
|
:custom (org-capture-templates
|
|
'(("n" "Note" entry
|
|
(file+olp "notes.org" "Inbox"))
|
|
("t" "Task" entry
|
|
(file+olp "tasks.org" "Inbox")
|
|
"* TODO %?\nDEADLINE: %t\n %i\n %a")))
|
|
:config
|
|
(when (package-installed-p 'khalel)
|
|
(with-eval-after-load 'khalel
|
|
(khalel-add-capture-template))))
|
|
|
|
(use-package org-roam
|
|
:after org
|
|
:defines org-roam-directory
|
|
:functions org-roam-db-autosync-mode
|
|
:bind-keymap ("C-c n d" . org-roam-dailies-map)
|
|
:bind (("C-c n r" . org-roam-capture)
|
|
("C-c n f" . org-roam-node-find)
|
|
:map org-mode-map
|
|
("C-c n i" . org-roam-node-insert)
|
|
("C-c n l" . 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" week)))))
|
|
|
|
(use-package org-clock
|
|
:after org
|
|
:custom
|
|
(org-clock-rounding-minutes 15)
|
|
(org-clock-mode-line-total 'auto))
|
|
|
|
(use-package org-duration
|
|
:after org
|
|
:custom
|
|
(org-duration-format '((special . h:mm))))
|
|
|
|
(use-package org-habit
|
|
:after org
|
|
:custom
|
|
(org-habit-show-habits t)
|
|
(org-habit-show-habits-only-for-today t))
|
|
|
|
(use-package org-agenda
|
|
:after (org appt)
|
|
:bind (("C-c a" . org-agenda))
|
|
: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-inhibit-startup t)
|
|
(org-agenda-tags-column 0)
|
|
(org-agenda-diary-file (expand-file-name "diary.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-clockreport-parameter-plist '(:maxlevel 6 :emphasize t :stepskip0 t :fileskip0 t :properties ("WON")))
|
|
(org-agenda-start-with-log-mode t)
|
|
(org-agenda-start-with-clockreport-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 "roam/journal.org" org-directory)))
|
|
:config
|
|
(appt-activate +1)
|
|
(setq org-agenda-custom-commands
|
|
'(("p" "Personal Agenda" tags "+personal")
|
|
("w" "Work Agenda" tags "+work"))))
|
|
|
|
(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 '("notes.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
|
|
:functions vertico-mode
|
|
:custom
|
|
(vertico-cycle t)
|
|
:init
|
|
(vertico-mode +1)
|
|
:config
|
|
(require 'vertico-directory))
|
|
|
|
(use-package marginalia
|
|
:functions marginalia-mode
|
|
:custom
|
|
(marginalia-annotators '(marginalia-annotators-heavy
|
|
marginalia-annotators-light
|
|
nil))
|
|
:init
|
|
(marginalia-mode +1)
|
|
:config (marginalia-mode +1))
|
|
|
|
(use-package 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 corfu
|
|
:defines (corfu-map
|
|
corfu-mode-map
|
|
corfu-margin-formatters)
|
|
:functions (corfu-mode
|
|
global-corfu-mode
|
|
corfu-history-mode)
|
|
:hook ((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 t)
|
|
(corfu-auto-delay 0.2)
|
|
(corfu-auto-prefix 3)
|
|
(corfu-preselect 'valid)
|
|
:init
|
|
(global-corfu-mode +1)
|
|
: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
|
|
:after (corfu savehist)
|
|
:functions corfu-history
|
|
:config
|
|
(add-to-list 'savehist-additional-variables #'corfu-history))
|
|
|
|
(use-package corfu-popupinfo
|
|
:after 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
|
|
:after corfu
|
|
:functions corfu-terminal-mode)
|
|
|
|
(use-package 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
|
|
: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 c s" . consult-eglot-symbols)))
|
|
|
|
(use-package 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 "+"))
|
|
|
|
(use-package tempel-collection
|
|
:after tempel)
|
|
|
|
(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 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
|
|
:after 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 e" . eglot)
|
|
("C-c c a" . eglot-code-actions)
|
|
("C-c c r" . eglot-rename))
|
|
:hook ((prog-mode . eglot-ensure)
|
|
(eglot-managed-mode . (lambda () (add-hook 'flymake-diagnostic-functions 'eglot-flymake-backend nil t))))
|
|
:custom
|
|
(eglot-menu-string "lsp")
|
|
(eglot-send-changes-idle-time 0.5)
|
|
(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
|
|
'( :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
|
|
:delight apheleia-mode
|
|
:defines (apheleia-formatters
|
|
apheleia-mode-alist)
|
|
:bind (("C-c c f" . apheleia-format-buffer))
|
|
:hook (prog-mode)
|
|
:custom (apheleia-remote-algorithm 'local)
|
|
:config
|
|
(add-to-list 'apheleia-mode-alist '(python-ts-mode . (ruff)))
|
|
(add-to-list 'apheleia-mode-alist '(python-mode . (ruff))))
|
|
|
|
(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 0.5)
|
|
(flymake-show-diagnostics-at-end-of-line 'short))
|
|
|
|
(use-package flymake-shellcheck
|
|
:disabled t
|
|
:functions flymake-shellcheck-load
|
|
:after flymake
|
|
:hook (sh-mode . (lambda () (if (executable-find "shellcheck" t)
|
|
(flymake-shellcheck-load)))))
|
|
|
|
(use-package flymake-yamllint
|
|
:functions flymake-yamllint-setup
|
|
:after flymake
|
|
:hook (yaml-ts-mode . (lambda () (if (executable-find "yamllint" t)
|
|
(flymake-yamllint-setup)))))
|
|
|
|
(use-package flymake-clippy
|
|
:disabled t
|
|
:functions flymake-clippy-setup-backend
|
|
:after flymake
|
|
:hook (rust-mode . (lambda () (if (executable-find "clippy" t)
|
|
(flymake-clippy-setup-backend)))))
|
|
|
|
(use-package flymake-eslint
|
|
:functions flymake-eslint-enable
|
|
:after 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")
|
|
(project-vc-dir "VC Status")
|
|
(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" . magit-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 forge
|
|
:after magit)
|
|
|
|
(use-package 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))
|
|
|
|
(use-package lua-mode
|
|
:mode "\\.lua\\'")
|
|
|
|
(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-interpreter "python3")
|
|
(python-shell-interpreter "python3")
|
|
(python-shell-dedicated nil)
|
|
(python-shell-completion-native-enable nil)
|
|
(python-indent-guess-indent-offset nil)
|
|
(python-indent-offset 4)
|
|
(python-indent-def-block-scale 1)
|
|
:config
|
|
(setq python-ts-mode-hook python-mode-hook))
|
|
|
|
(use-package python-docstring
|
|
:hook python-base-mode)
|
|
|
|
(use-package python-pytest
|
|
:defer t)
|
|
|
|
(use-package files
|
|
:custom
|
|
(view-read-only t)
|
|
(enable-remote-dir-locals t))
|
|
|
|
(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 nil))
|
|
|
|
(use-package auctex
|
|
:defer t)
|
|
|
|
(use-package 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
|
|
:after (markdown-mode)
|
|
:hook (markdown-mode . conditionally-turn-on-pandoc))
|
|
|
|
(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 scad-mode
|
|
:defer t)
|
|
|
|
;; Scratch buffer shortcut
|
|
(keymap-global-set "C-c w x" #'scratch-buffer)
|
|
|
|
;; 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/"))
|
|
(defun my/open-projects-directory ()
|
|
"Open Projects directory."
|
|
(interactive)
|
|
(find-file "~/Projects/"))
|
|
(keymap-global-set "C-c w d" #'my/open-documents-directory)
|
|
(keymap-global-set "C-c w C-d" #'my/open-downloads-directory)
|
|
(keymap-global-set "C-c w p" #'my/open-projects-directory)
|
|
|
|
(defun my/configure-theme ()
|
|
"Load theme and configure some faces."
|
|
(interactive)
|
|
|
|
;; Set some font-lock faces to be italic
|
|
(set-face-attribute 'font-lock-doc-face nil :slant 'italic)
|
|
(set-face-attribute 'font-lock-comment-face nil :slant 'italic)
|
|
(set-face-attribute 'font-lock-comment-delimiter-face nil :slant 'italic)
|
|
|
|
;; Change outline headers to follow rainbow order
|
|
(require 'outline)
|
|
(when (boundp 'base16-stylix-theme-colors)
|
|
(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-stylix-theme-colors (cdr pairing))))
|
|
|
|
(require 'org-faces)
|
|
;; Lighten `org-agenda-clocking' background to be more legible.
|
|
(set-face-attribute 'org-agenda-clocking nil :background
|
|
(plist-get base16-stylix-theme-colors :base01))
|
|
;; Set `org-hide' face to actually match background colour
|
|
(set-face-attribute 'org-hide nil :foreground
|
|
(plist-get base16-stylix-theme-colors :base00))
|
|
(with-eval-after-load 'org-noter
|
|
(set-face-attribute 'org-noter-no-notes-exist-face nil :foreground
|
|
(plist-get base16-stylix-theme-colors :base08))
|
|
(set-face-attribute 'org-noter-notes-exist-face nil :foreground
|
|
(plist-get base16-stylix-theme-colors :base0B))))
|
|
)
|
|
|
|
(with-eval-after-load 'base16-theme
|
|
(require 'server)
|
|
(add-hook 'after-init-hook (lambda () (my/configure-theme)))
|
|
(add-hook 'server-after-make-frame-hook (lambda () (my/configure-theme))))
|
|
|
|
(provide 'init)
|
|
;;; init.el ends here
|