;;; init.el --- Emacs initiation file -*- lexical-binding: t -*- ;; Author: Case Duckworth ;; Created: Sometime during Covid-19, 2020 ;; Keywords: configuration ;; URL: https://tildegit.org/acdw/emacs ;; Bankruptcy: 8 ;;; License: ;; Everyone is permitted to do whatever they like with this software ;; without limitation. This software comes without any warranty ;; whatsoever, but with two pieces of advice: ;; - Be kind to yourself. ;; - Make good choices. ;;; Code: (dolist (feature `((early-init . ,(locate-user-emacs-file "early-init")) private _work)) (require (or (car-safe feature) feature) (cdr-safe feature) :noerror)) (setq debug-on-error t) (setup (:require +emacs) (:also-load +lisp) ;; +emacs.el contains super-basic defaults that are basically necessary for ;; good functioning. In this block, I add extra things or more "experimental" ;; ones that might not belong in a separate file. (:option sentence-end-double-space nil) ; I can't believe I'm doing this... ;; Setting `sentence-end-double-space' to nil means that `fill-paragraph' ;; fills single-spaced sentences, which I /don't/ like. This advice will fix ;; that. (define-advice fill-region (:around (fn &rest r)) (dlet ((sentence-end-double-space t)) (apply fn r))) ;; Bindings (:global "C-x C-k" #'kill-current-buffer "C-x 4 n" #'clone-buffer "C-c v" #'visible-mode "C-M-;" #'+lisp-comment-or-uncomment-sexp) ;; Unbind stuff, too. (dolist (key '("C-M-j" "M-j")) (global-set-key (kbd key) nil)) ;; C-h deletes backward - see https://idiomdrottning.org/bad-emacs-defaults (global-set-key (kbd "C-h") 'delete-backward-char) (keyboard-translate ?\C-h ?\C-?) ;; https://old.reddit.com/r/emacs/comments/rlli0u/whats_your_favorite_defadvice/hph14un/ (define-advice keyboard-escape-quit (:around (fn &rest r)) "Don't close splits on `keyboard-escape-quit'." (let ((buffer-quit-function #'ignore)) (apply fn r)))) (setup (:require +init) (:bind "C-c s" #'+init-sort-then-save) (:hook #'+init-add-setup-to-imenu)) (setup (:require +key) (+key-setup)) (setup (:require auth-source) (:option auth-sources (list (private/ "authinfo") (private/ "authinfo.gpg") "~/.authinfo" "~/.authinfo.gpg"))) (setup (:require goto-addr) (if (fboundp #'global-goto-address-mode) (global-goto-address-mode) (add-hook 'after-change-major-mode-hook #'goto-address-mode))) (setup (:require pulse) (:also-load +pulse) (:option pulse-flag nil pulse-delay 0.5 pulse-iterations 1) (+pulse-location-mode +1)) (setup (:require reading) (:global "C-c C-r" #'reading-mode)) (setup Info (:hook #'reading-mode)) (setup abbrev (:option abbrev-file-name (sync/ "abbrev.el") save-abbrevs 'silent) (:hook-into text-mode circe-chat-mode)) (setup autorevert (:option global-auto-revert-non-file-buffers t auto-revert-verbose nil) (global-auto-revert-mode +1)) (setup browse-url (:require +browse-url) (:option browse-url-secondary-browser-function (if (executable-find "firefox") #'browse-url-firefox #'browse-url-default-browser) browse-url-new-window-flag nil browse-url-firefox-arguments '("--new-tab") browse-url-firefox-new-window-is-tab t) ;; Set up URL handlers. (+browse-url-set-handlers (list (cons (rx ; images "." (or "jpeg" "jpg" "png") eos) (lambda (&rest args) (apply (cond ((executable-find "mpv") #'+browse-image-with-mpv) (t #'eww-browse-url)) args))) (cons (rx ; videos (or "youtube.com" "youtu.be" "yewtu.be" (seq "." (or "mp4" "gif" "mov" "MOV") eos))) (lambda (&rest args) (apply (if (executable-find "mpv") #'+browse-url-with-mpv browse-url-secondary-browser-function) args))) (cons (rx ; non-eww-friendly websites (or "github.com" "gitlab.com" "google.com" "imgur.com" "pixelfed" "instagram.com" "bibliogram.art" "reddit.com" "teddit.net" "tildes.net" "taskiq" "twitter.com" "nitter.net" )) browse-url-secondary-browser-function) (cons "." ; everything else #'eww-browse-url))) ;; Transform URLs before passing to `browse-url' (:option +browse-url-transformations `((,(rx "//" (or "youtube.com" "youtu.be")) . "//yewtu.be") ("twitter\\.com" . "nitter.net") ("instagram\\.com" . "bibilogram.art") (,(rx (or "reddit.com" "old.reddit.com")) . "teddit.net") ("medium\\.com" . "scribe.rip"))) (+browse-url-transform-url-global-mode +1)) (setup calendar (require '_location) (:option calendar-location-name _location-name calendar-latitude _location-latitude calendar-longitude _location-longitude)) (setup cus-edit ;; I don't use Custom to actually /make/ any customizations, but it's handy to ;; (A) see what options are available and (B) persist some changes across ;; restarts, for example, `safe-local-variables'. (:require +cus-edit) (:option custom-file (private/ "custom.el") custom-magic-show nil custom-magic-show-button t custom-raised-buttons nil custom-unlispify-tag-names nil custom-variable-default-form 'lisp +custom-variable-allowlist '(safe-local-variable-values warning-suppress-types)) (when (file-exists-p custom-file) (+custom-load-ignoring-most-customizations t)) (advice-add #'custom-buffer-create-internal :after #'+cus-edit-expand-widgets) (:with-mode Custom-mode (:local-set imenu-generic-expression +cus-edit-imenu-generic-expression))) (setup dired (:also-load dired-x) (:also-straight dired-subtree dired-collapse dired-git-info dired+) (:option dired-recursive-copies 'top dired-recursive-deletes 'top dired-create-destination-dirs 'ask delete-by-moving-to-trash t dired-listing-switches "-Al" ls-lisp-dirs-first t dired-ls-F-marks-symlinks t dired-no-confirm '(byte-compile load chgrp chmod chown copy move hardlink symlink shell touch) dired-dwim-target t) (:bind "" #'dired-up-directory "TAB" #'dired-subtree-cycle "i" #'dired-subtree-toggle ")" #'dired-git-info-mode) (:hook #'dired-collapse-mode #'dired-hide-details-mode #'hl-line-mode) (:+key "C-x C-j" #'dired-jump) (with-eval-after-load 'dired (pcase system-type ((or 'ms-dos 'windows-nt) (:straight w32-browser)) ((or 'gnu/linux) (:straight dired-open) (:option dired-listing-switches (concat dired-listing-switches " -F"))))) (with-eval-after-load 'frowny (add-to-list 'frowny-inhibit-modes #'dired-mode))) (setup eldoc (:hook-into elisp-mode lisp-interaction-mode)) (setup elisp-mode (:also-load +elisp) (:option eval-expression-print-length nil eval-expression-print-level nil) (:with-map (emacs-lisp-mode-map lisp-interaction-mode-map) (:bind "C-c C-c" #'eval-defun "C-c C-k" #'+elisp-eval-region-or-buffer "C-c C-z" #'ielm)) (advice-add #'eval-region :around #'+eval-region@pulse)) (setup eshell (:also-load +eshell em-smart em-tramp) (:option eshell-aliases-file (.etc "eshell/aliases" t) eshell-destroy-buffer-when-process-dies t eshell-directory-name (.etc "eshell/" t) eshell-error-if-no-glob t eshell-hist-ignore-dups t eshell-kill-on-exit nil eshell-prefer-lisp-functions t eshell-prefer-lisp-variables t eshell-review-quick-commands nil eshell-save-history-on-exit t eshell-scroll-to-bottom-on-input 'all eshell-smart-space-goes-to-end t eshell-where-to-jump 'begin) (:local-set outline-regexp eshell-prompt-regexp page-delimiter eshell-prompt-regexp) (:bind "C-d" #'+eshell-quit-or-delete-char) (:when-loaded (setenv "PAGER" "cat"))) (setup eww (:also-load +eww) (:option eww-search-prefix "https://duckduckgo.com/html?q=" url-privacy-level '(email agent cookies lastloc)) (add-hook 'eww-after-render-hook #'reading-mode) (:hook #'+eww-bookmark-setup #'+eww-track-readable-mode) (:bind "b" #'bookmark-set "B" #'bookmark-jump "M-n" nil "M-p" nil)) (setup hideshow (:also-load +hideshow) (:with-mode hs-minor-mode (:hook-into prog-mode) (:bind "C-" #'+hs-cycle "C-S-" #'+hs-global-cycle ;; but y tho "C-S-" #'+hs-global-cycle))) (setup ibuffer (:also-load ibuf-ext) (:option ibuffer-expert t ibuffer-show-empty-filter-groups nil ibuffer-saved-filter-groups '(("default" ("Org" (mode . org-mode)) ("emacs" (or (name . "^\\*scratch\\*$") (name . "^\\*Messages\\*$") (name . "^\\*Warnings\\*$") (name . "^\\*straight-process\\*$") (name . "^\\*Calendar\\*$"))) ("customize" (mode . Custom-mode)) ("emacs-config" (or (filename . ".emacs.d") (mode . +init-mode))) ("git" (or (name . "^\*magit") (name . "^\magit"))) ("help" (or (mode . help-mode) (mode . Info-mode) (mode . helpful-mode))) ("irc" (or (mode . erc-mode) (mode . circe-server-mode) (mode . circe-channel-mode))) ("shell" (or (mode . eshell-mode) (mode . shell-mode) (mode . vterm-mode))) ("web" (or (mode . elpher-mode) (mode . eww-mode)))))) (:hook (defun ibuffer@filter-to-default () (ibuffer-auto-mode +1) (ibuffer-switch-to-saved-filter-groups "default")))) (setup kmacro (:also-load +kmacro) (with-eval-after-load '+kmacro (+kmacro-recording-indicator-mode +1) (+kmacro-block-undo-mode +1))) (setup magit ;; This setup is weird because of dependency issues (:straight (transient :host github :repo "magit/transient" :branch "master") (magit :host github :repo "magit/magit") (git-modes :host github :repo "magit/git-modes")) (when (eq system-type 'gnu/linux) (:straight (forge :host github :repo "magit/forge")) (with-eval-after-load 'magit (require 'forge) (add-to-list 'forge-alist '("tildegit.org" "tildegit.org/api/v1" "tildegit.org" forge-gitea-repository))))) (setup minibuffer (:require +minibuffer) (:with-map minibuffer-local-map (:bind "M-/" #'+minibuffer-complete-history))) (setup mouse ;; Brand new for Emacs 28: see https://ruzkuku.com/texts/emacs-mouse.html ;; Actually, look at this as well: https://www.emacswiki.org/emacs/Mouse3 (when (fboundp 'context-menu-mode) ;; (:option context-menu-functions ;; '(context-menu-ffap ;; context-menu-region ;; context-menu-undo ;; context-menu-dictionary)) (context-menu-mode +1))) (setup org-agenda (:option org-agenda-skip-deadline-if-done t) (:+leader "a" #'org-agenda "C-a" #'org-agenda)) (setup prog (:local-set comment-auto-fill-only-comments t) (:hook #'prettify-symbols-mode #'display-fill-column-indicator-mode #'turn-on-auto-fill)) (setup scratch (:require +scratch) (:option initial-major-mode #'lisp-interaction-mode initial-scratch-message ";; ABANDON ALL HOPE YE WHO ENTER HERE\n\n") (add-hook 'kill-buffer-query-functions #'+scratch-immortal)) (setup text (:hook #'turn-on-auto-fill)) (setup (:straight 0x0) (:option 0x0-default-server 'ttm) (with-eval-after-load 'embark (define-key embark-region-map (kbd "U") #'0x0-dwim))) (setup (:straight ace-window) (:require +ace-window) (:option aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l) aw-display-mode-overlay nil) (:+key "M-o" #'+ace-window-or-switch-buffer) (:face aw-mode-line-face ((t (:foreground "red")))) (+ace-window-display-mode +1)) (setup (:straight (actually-selected-window :host github :repo "duckwork/actually-selected-window.el")) (actually-selected-window-mode +1)) (setup (:straight anzu) (:option anzu-cons-mode-line-p nil) (:+key [remap query-replace] #'anzu-query-replace-regexp [remap query-replace-regexp] #'anzu-query-replace-regexp) (global-anzu-mode +1) (:bind-into isearch [remap isearch-query-replace] #'anzu-isearch-query-replace [remap isearch-query-replace-regexp] #'anzu-isearch-query-replace-regexp)) (setup (:straight avy) (:also-load +avy) (:+key "M-j" #'avy-goto-char-timer) (:bind-into isearch "M-j" #'avy-isearch) (:when-loaded (setf (alist-get ?. avy-dispatch-alist) #'avy-action-embark))) (setup (:straight (cape :host github :repo "minad/cape")) (dolist (fn ;; All available cape capfs listed here. Add them to the front since ;; they're reversed with `add-to-list'. '(;;cape-dict cape-ispell cape-abbrev cape-keyword cape-dabbrev cape-file)) (add-to-list 'completion-at-point-functions fn))) (setup (:straight (capf-autosuggest :host nil :repo "https://repo.or.cz/emacs-capf-autosuggest.git")) (:hook-into eshell-mode comint-mode)) (setup (:straight circe) (:require _circe +circe) (:also-load circe-chanop) ;; Formatting options (:option circe-format-action (format (format "%%%ds* {nick} {body}" (- +circe-left-margin 2)) " ") circe-format-say (format "{nick:%1$d.%1$ds} | {body}" (- +circe-left-margin 3)) circe-format-self-action circe-format-action circe-format-self-say (replace-regexp-in-string "|" ">" circe-format-say) circe-format-server-part (+circe-format-meta "PART {channel}: {reason}") circe-format-server-quit (+circe-format-meta "QUIT: {reason}") circe-format-server-quit-channel (+circe-format-meta "QUIT {channel}: {reason}") circe-format-server-join (+circe-format-meta "JOIN: {userinfo}") circe-format-server-rejoin (+circe-format-meta (concat "REJOIN: {userinfo} " "after {departuredelta}")) circe-format-server-topic (+circe-format-meta "TOPIC: {new-topic}") circe-prompt-string (format (format "%%%ds> " (- +circe-left-margin 2)) " ")) (:option +circe-server-buffer-action (lambda (buf) (message "Connected to %s" buf)) +circe-network-inhibit-autoconnect _circe-network-inhibit-autoconnect circe-network-options _circe-network-options circe-color-nicks-everywhere t circe-default-part-message "See You, Space Cowpokes . . ." circe-default-user user-real-login-name circe-reduce-lurker-spam t circe-server-auto-join-default-type :after-auth) (:bind "C-c C-p" #'circe-command-PART "C-c C-t" #'+circe-current-topic "C-l" #'lui-track-jump-to-indicator "C-" #'+circe-chat@set-prompt) (advice-add #'circe-command-PART :after #'+circe-kill-buffer) (advice-add #'circe-command-QUIT :after #'+circe-quit@kill-buffer) (advice-add #'circe-command-GQUIT :after #'+circe-gquit@kill-buffer) (:with-mode circe-chat-mode (:hook #'enable-circe-color-nicks #'enable-circe-new-day-notifier #'+circe-chat@set-prompt) (:bind "C-c C-s" #'circe-command-SLAP)) (:with-mode lui-mode (:option lui-fill-column (+ fill-column +circe-left-margin) lui-fill-type nil lui-time-stamp-position 'right-margin lui-time-stamp-format "[ %H:%M" lui-track-behavior 'before-switch-to-buffer lui-track-indicator 'fringe lui-fill-remove-face-from-newline nil lui-formatting-list `((,(+lui-make-formatting-list-rx "*") 1 lui-strong-face) (,(+lui-make-formatting-list-rx "_") 1 lui-emphasis-face) (,(+lui-make-formatting-list-rx "/") 1 lui-emphasis-face)) (append +pulse-location-commands) 'lui-track-jump-to-indicator) (:hook #'visual-line-mode #'enable-lui-track #'visual-fill-column-mode) (:local-set fringes-outside-margins t right-margin-width (length lui-time-stamp-format) scroll-margin 0 word-wrap t wrap-prefix (+string-repeat +circe-left-margin " ") line-number-mode nil column-number-mode nil file-percentage-mode nil visual-fill-column-extra-text-width (cons +circe-left-margin 0))) (with-eval-after-load 'topsy (:option (append topsy-mode-functions) '(circe-channel-mode . +circe-current-topic))) (with-eval-after-load 'circe-color-nicks (add-hook 'modus-themes-after-load-theme-hook #'circe-nick-color-reset)) (add-hook 'kill-emacs-hook #'+circe-quit-all@kill-emacs)) (setup (:straight consult) (:also-load +consult) ;; from Consult wiki (:option register-preview-delay 0 register-preview-function 'consult-register-format xref-show-xrefs-function 'consult-xref xref-show-definitions-function 'consult-xref tab-always-indent 'complete completion-in-region-function 'consult-completion-in-region) (advice-add #'register-preview :override #'consult-register-window) (advice-add #'completing-read-multiple :override #'consult-completing-read-multiple) (dolist (binding '(;; C-c bindings (mode-specific-map) ("C-c h" . consult-history) ("C-c m" . consult-mode-command) ("C-c b" . consult-bookmark) ("C-c k" . consult-kmacro) ;; C-x bindings (ctl-x-map) ("C-x M-:" . consult-complex-command) ("C-x b" . consult-buffer) ("C-x 4 b" . consult-buffer-other-window) ("C-x 5 b" . consult-buffer-other-frame) ;; Custom M-# bindings for fast register access ("M-#" . consult-register-load) ("M-'" . consult-register-store) ("C-M-#" . consult-register) ;; Other custom bindings ("M-y" . consult-yank-pop) (" a" . consult-apropos) ;; M-g bindings (goto-map) ("M-g e" . consult-compile-error) ("M-g f" . consult-flymake) ; or consult-flycheck ("M-g g" . consult-goto-line) ("M-g M-g" . consult-goto-line) ("M-g o" . consult-outline) ; or consult-org-heading ("M-g m" . consult-mark) ("M-g k" . consult-global-mark) ("M-g i" . consult-imenu) ("M-g I" . consult-imenu-multi) ;; M-s bindings (search-map) ("M-s f" . consult-find) ("M-s F" . consult-locate) ("M-s g" . consult-grep) ("M-s G" . consult-git-grep) ("M-s r" . consult-ripgrep) ("M-s l" . consult-line) ("M-s L" . consult-line-multi) ("M-s m" . consult-multi-occur) ("M-s k" . consult-keep-lines) ("M-s u" . consult-focus-lines) ;; Isearch integration ("M-s e" . consult-isearch-history))) (define-key +key-mode-map (kbd (car binding)) (cdr binding))) (with-eval-after-load 'isearch-mode (dolist (binding '(("M-e" . consult-isearch-history) ("M-s e" . consult-isearch-history) ("M-s l" . consult-line) ("M-s L" . consult-line-multi))) (define-key isearch-mode-map (car binding) (cdr binding)))) (with-eval-after-load 'org-mode (define-key org-mode-map "M-g o" 'consult-org-heading)) (advice-add 'consult-yank-pop :after '+yank@indent) (with-eval-after-load 'consult (:option consult-narrow-key "<" consult-project-root-function '+consult-project-root) (consult-customize consult-theme :preview-key '(:debounce 0.2 any) consult-ripgrep consult-git-grep consult-grep consult-bookmark consult-recent-file consult-xref consult--source-file consult--source-project-file consult--source-bookmark :preview-key (kbd "M-.")) (consult-history-to-modes ((minibuffer-local-map . nil) (shell-mode-map . shell-mode-hook) (term-mode-map . term-mode-hook) (term-raw-map . term-mode-hook) (comint-mode-map . comint-mode-hook) (sly-mrepl-mode-map . sly-mrepl-hook))) (with-eval-after-load 'orderless (:option consult--regexp-compiler 'consult--orderless-regexp-compiler)))) (setup (:straight crux) (:+key "C-o" #'crux-smart-open-line "C-x 4 t" #'crux-transpose-windows) (el-patch-feature crux) (with-eval-after-load 'crux (el-patch-defun crux-reopen-as-root () "Find file as root if necessary. Meant to be used as `find-file-hook'. See also `crux-reopen-as-root-mode'." (unless (or ;; This helps fix for `nov-mode', and possibly others. (el-patch-add (null buffer-file-name)) (tramp-tramp-file-p buffer-file-name) (equal major-mode 'dired-mode) (not (file-exists-p (file-name-directory buffer-file-name))) (file-writable-p buffer-file-name) (crux-file-owned-by-user-p buffer-file-name)) (crux-find-alternate-file-as-root buffer-file-name)))) (crux-reopen-as-root-mode +1)) (setup (:straight dictionary) (:option dictionary-use-single-buffer t) (autoload 'dictionary-search "dictionary" "Ask for a word and search it in all dictionaries" t) (autoload 'dictionary-match-words "dictionary" "Ask for a word and search all matching words in the dictionaries" t) (autoload 'dictionary-lookup-definition "dictionary" "Unconditionally lookup the word at point." t) (autoload 'dictionary "dictionary" "Create a new dictionary buffer" t) (autoload 'dictionary-mouse-popup-matching-words "dictionary" "Display entries matching the word at the cursor" t) (autoload 'dictionary-popup-matching-words "dictionary" "Display entries matching the word at the point" t) (autoload 'dictionary-tooltip-mode "dictionary" "Display tooltips for the current word" t) (autoload 'global-dictionary-tooltip-mode "dictionary" "Enable/disable dictionary-tooltip-mode for all buffers" t) (:hook #'reading-mode)) (setup (:straight (discord :host github :repo "davep/discord.el" :fork (:repo "duckwork/discord.el")))) (setup (:straight electric-cursor) (electric-cursor-mode +1)) (setup (:straight elfeed) (:also-load +elfeed) (:option elfeed-use-curl t elfeed-curl-extra-arguments '("--insecure") elfeed-show-unique-buffers t elfeed-db-directory (sync/ "elfeed/db/" t)) ;; https://old.reddit.com/r/emacs/comments/rlli0u/whats_your_favorite_defadvice/hphfh4e/ (advice-add #'elfeed-search-update--force :after #'elfeed-db-save) (:with-mode elfeed-show-mode (:bind "SPC" #'+elfeed-scroll-up-command "S-SPC" #'+elfeed-scroll-down-command) (:hook #'reading-mode))) (setup (:straight elfeed-org) (:option rmh-elfeed-org-files (list (sync/ "elfeed/elfeed.org" t))) (elfeed-org)) (setup (:straight embark) (:option prefix-help-command 'embark-prefix-help-command) (:+key "C-." #'embark-act "M-." #'embark-dwim " B" #'embark-bindings) (:bind-into minibuffer "C-." #'embark-act)) (setup (:straight embark-consult) (:load-after consult embark) (add-hook 'embark-collect-mode-hook #'consult-preview-at-point-mode)) (setup (:straight eros) (:hook-into emacs-lisp-mode lisp-interaction-mode)) (setup (:straight eshell-syntax-highlighting) (:hook-into eshell-mode)) (setup (:straight-when exec-path-from-shell (eq system-type 'gnu/linux)) (when (daemonp) (exec-path-from-shell-initialize)) (exec-path-from-shell-copy-envs '("XDG_CONFIG_HOME" "XDG_CONFIG_DIRS" "XDG_DATA_HOME" "XDG_DATA_DIRS" "XDG_CACHE_HOME"))) (setup (:straight expand-region) (:+key "C-=" #'er/expand-region)) (setup (:straight (fill-sentences-correctly :host github :repo "duckwork/fill-sentences-correctly.el")) (fill-sentences-correctly-mode +1)) (setup (:straight (filldent :host github :repo "duckwork/filldent.el")) (:+key "M-q" #'filldent-dwim)) (setup (:straight (frowny :host github :repo "duckwork/frowny.el")) (global-frowny-mode +1)) (setup (:straight gcmh) (:option gcmh-idle-delay 'auto) (gcmh-mode +1)) (setup (:straight-when geiser (progn (defvar +schemes (let (schemes) (dolist (scheme '(("scheme" . geiser-chez) ; chez ("petite" . geiser-chez) ; petite ("csi" . geiser-chicken) ; chicken ("gsi" . geiser-gambit) ("gosh" . geiser-gauche) ("guile" . geiser-guile) ("kawa" . geiser-kawa) ("mit-scheme" . geiser-mit) ("racket" . geiser-racket) ("stklos" . geiser-stklos))) (when-let (binary (executable-find (car scheme))) (push binary schemes) ;; and install the proper helper package (straight-use-package (cdr scheme)))) (nreverse schemes))) +schemes)) (:file-match (rx ".rkt" eos) (rx ".scm" eos))) (setup (:straight helpful) (run-with-idle-timer 0.5 nil 'require 'helpful) (:+key " f" #'helpful-callable " v" #'helpful-variable " k" #'helpful-key "C-c C-d" #'helpful-at-point)) (setup (:straight (hippie-completing-read :host github :repo "duckwork/hippie-completing-read")) (:+key "M-/" #'hippie-completing-read)) (setup (:straight hungry-delete) (:option hungry-delete-chars-to-skip " \t" hungry-delete-join-reluctantly nil) (:bind-into paredit ;; I define these functions here because they really require both packages ;; to make any sense. So, would I put them in `+hungry-delete' or ;; `+paredit' ? There's no satisfactory answer. [remap paredit-backward-delete] (defun acdw/paredit-hungry-delete-backward (arg) (interactive "P") (if (looking-back "[ \t]" 1) (hungry-delete-backward (or arg 1)) (paredit-backward-delete arg))) [remap paredit-forward-delete] (defun acdw/paredit-hungry-delete-forward (arg) (interactive "P") (if (looking-at "[ \t]") (hungry-delete-forward (or arg 1)) (paredit-forward-delete arg)))) (global-hungry-delete-mode +1)) (setup (:straight isearch-mb) ;; This complicatedness is an attempt to make it easier to add and ;; subtract `isearch-mb' bindings using the suggestions in the ;; project's README. (with-eval-after-load 'isearch-mb (dolist (spec '((isearch-mb--with-buffer ("M-e" . consult-isearch) ("C-o" . loccur-isearch)) (isearch-mb--after-exit ("M-%" . anzu-isearch-query-replace) ("M-s l" . consult-line)))) (let ((isearch-mb-list (car spec)) (isearch-mb-binds (cdr spec))) (dolist (cell isearch-mb-binds) (let ((key (car cell)) (command (cdr cell))) (when (fboundp command) (add-to-list isearch-mb-list command) (define-key isearch-mb-minibuffer-map (kbd key) command))))))) (isearch-mb-mode +1)) (setup (:straight lacarte) (:+key "" #'lacarte-execute-menu-command)) (setup (:straight (lin :host gitlab :repo "protesilaos/lin")) (require 'lin) (:hook-into dired-mode elfeed-search-mode git-rebase-mode ibuffer-mode ledger-report-mode log-view-mode magit-log-mode notmuch-search-mode notmuch-tree-mode org-agenda-mode tabulated-list-mode)) (setup (:straight marginalia) (marginalia-mode +1)) (setup (:straight minions) (:option minions-prominent-modes '(tracking-mode)) (minions-mode +1)) (setup (:straight mode-line-bell) (:option mode-line-bell-flash-time 0.1) (mode-line-bell-mode +1)) (setup (:straight (modus-themes :host gitlab :repo "protesilaos/modus-themes")) (require 'modus-themes (.etc "straight/build/modus-themes/modus-themes")) (:option modus-themes-bold-constructs t modus-themes-italic-constructs t modus-themes-headings '((t . (background)))) (+sunrise-sunset 'modus-themes-load-operandi 'modus-themes-load-vivendi)) (setup (:straight mwim) (:+key "C-a" #'mwim-beginning "C-e" #'mwim-end)) (setup (:straight orderless) (:option completion-styles '(orderless))) (setup (:straight (org :type git :host nil :repo "https://git.savannah.gnu.org/git/emacs/org-mode.git" :local-repo "org" :depth full :pre-build (straight-recipes-org-elpa--build) :build (:not autoloads) :files (:defaults "lisp/*.el" ("etc/styles/" "etc/styles/*"))) (org-contrib :type git :host nil :repo "https://git.sr.ht/~bzg/org-contrib")) ;; DO NOT load system-installed org !!! (setq load-path (cl-remove-if (lambda (path) (string-match-p "lisp/org\\'" path)) load-path)) (:also-load +org ox-md) (:option org-adapt-indentation nil org-archive-mark-done t org-catch-invisible-edits 'show-and-error org-clock-clocked-in-display 'mode-line org-clock-frame-title-format (cons '(t org-mode-line-string) (cons " --- " frame-title-format)) org-clock-string-limit 7 ; just the clock bit ;; org-clock-string-limit 25 ; gives enough information org-clock-persist t org-confirm-babel-evaluate nil org-cycle-separator-lines 0 org-directory "~/org" org-ellipsis "…" org-export-coding-system 'utf-8-unix org-export-headline-levels 8 org-export-with-section-numbers nil org-export-with-smart-quotes t org-export-with-sub-superscripts t org-export-with-toc nil org-fontify-done-headline t org-fontify-quote-and-verse-blocks t org-fontify-whole-heading-line t org-hide-emphasis-markers t org-html-coding-system 'utf-8-unix org-image-actual-width (list (* (window-font-width) (- fill-column 8))) org-imenu-depth 3 org-list-demote-modify-bullet '(("-" . "+") ("+" . "*") ("*" . "-")) org-log-done 'time org-log-into-drawer t org-outline-path-complete-in-steps nil org-pretty-entities t org-pretty-entities-include-sub-superscripts nil org-refile-use-outline-path 'file org-special-ctrl-a/e t org-special-ctrl-k t org-src-fontify-natively t org-src-tab-acts-natively t org-src-window-setup 'current-window org-startup-truncated nil org-startup-with-inline-images t org-tags-column (- (- fill-column (length org-ellipsis)))) (:bind "RET" #'+org-return-dwim "" #'+org-table-copy-down "C-c C-l" #'+org-insert-link-dwim "C-c C-n" #'+org-next-heading-widen "C-c C-p" #'+org-previous-heading-widen) (:+leader "c" #'org-capture "C-c" #'org-capture) (:local-hook before-save-hook #'+org-before-save@prettify-buffer) (advice-add #'org-delete-backward-char :override #'+org-delete-backward-char) (with-eval-after-load 'org (org-clock-persistence-insinuate) (org-link-set-parameters "tel" :follow #'+org-tel-open))) (setup (:straight org-appear) (:option org-appear-autoemphasis t org-appear-autoentities t org-appear-autokeywords t org-appear-autolinks nil org-appear-autosubmarkers t org-appear-delay 0) (:hook-into org-mode)) (setup (:straight org-sticky-header) (:hook-into org-mode)) (setup (:straight package-lint)) (setup (:straight paredit) (:bind "DEL" #'paredit-backward-delete "C-" #'paredit-backward-kill-word) (dolist (hook '(emacs-lisp-mode-hook eval-expression-minibuffer-setup-hook ielm-mode-hook lisp-interaction-mode-hook lisp-mode-hook scheme-mode-hook)) (add-hook hook #'enable-paredit-mode)) (:also-load eldoc) (eldoc-add-command #'paredit-backward-delete #'paredit-close-round)) (setup (:straight paren-face) (:hook-into emacs-lisp-mode ielm-mode sly-repl-mode lisp-mode lisp-interaction-mode scheme-mode)) (setup (:straight-when pdf-tools (eq system-type 'gnu/linux)) (pdf-tools-install)) (setup (:straight (shell-command+ :host nil :repo "https://git.sr.ht/~pkal/shell-command-plus")) (:option shell-command-prompt "$ ") (:bind-into dired "M-!" 'shell-command+) (:+key "M-!" #'shell-command+)) (setup (:straight sicp)) (setup (:straight (simple-modeline :fork (:host github :repo "duckwork/simple-modeline"))) (:also-load +modeline) (:option simple-modeline-segments `((;; left +modeline-ace-window-display +modeline-modified ,(+modeline-concat '(+modeline-reading-mode +modeline-narrowed) ",") +modeline-buffer-name +modeline-position +modeline-anzu ) (;; right +modeline-track +modeline-vc simple-modeline-segment-misc-info simple-modeline-segment-process +modeline-text-scale +modeline-minions +modeline-major-mode ))) (simple-modeline-mode +1)) (setup (:straight smartscan) (:hook-into prog-mode)) (setup (:straight ssh-config-mode) (:file-match (rx "/.ssh/config" eos) (rx "/ssh" (? "d") "_config" eos)) (:with-mode ssh-known-hosts-mode (:file-match (rx "/knownhosts" eos))) (:with-mode ssh-authorized-keys-mode (:file-match (rx "/authorized_keys" (? "2") eos)))) (setup (:straight super-save) (:option auto-save-default nil super-save-auto-save-when-idle t super-save-idle-duration 60 super-save-exclude '(".gpg") super-save-remote-files nil) (auto-save-visited-mode -1) (super-save-mode +1)) (setup (:straight (titlecase :host github :repo "duckwork/titlecase.el" :files ("*")))) (setup (:straight topsy) (:hook-into prog-mode circe-chat-mode) (:when-loaded (:option topsy-header-line-format '(:eval (list (propertize " " 'display `((space :align-to ,(unless (bound-and-true-p visual-fill-column-mode) 0)))) (funcall topsy-fn)))))) (setup (:straight transpose-frame)) (setup (:straight trashed) (:option trashed-action-confirmer #'y-or-n-p)) (setup (:straight undo-fu) (:+key "C-/" #'undo-fu-only-undo "C-?" #'undo-fu-only-redo)) (setup (:straight undo-fu-session) (:option undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'" "/git-rebase-todo\\'") undo-fu-session-directory (.etc "undo/" t) undo-fu-session-compression (eq system-type 'gnu/linux)) (global-undo-fu-session-mode +1)) (setup (:straight (vertico :host github :repo "minad/vertico" :files ("*" "extensions/*" (:exclude ".git")))) (:also-load +vertico) (:option resize-mini-windows 'grow-only vertico-count-format nil vertico-cycle t) (advice-add #'vertico-next :around #'+vertico-ding-wrap) (when (boundp 'native-comp-deferred-compilation-deny-list) (add-to-list 'native-comp-deferred-compilation-deny-list "vertico")) (vertico-mode +1) ;; Extensions (:also-load vertico-directory) (:with-map vertico-map (:bind "RET" #'vertico-directory-enter "DEL" #'vertico-directory-delete-char "M-DEL" #'vertico-directory-delete-word)) (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy)) (setup (:straight visual-fill-column) (:option visual-fill-column-center-text t (append reading-modes) '(visual-fill-column-mode . +1)) (:hook #'visual-line-mode) (:hook-into org-mode) (advice-add #'text-scale-adjust :after #'visual-fill-column-adjust)) (setup (:straight vlf) (:require vlf-setup)) (setup (:straight whitespace-cleanup-mode) (:option whitespace-cleanup-mode-preserve-point t) (global-whitespace-cleanup-mode +1)) (setup (:straight zoom-frm)) (setup (:straight zzz-to-char) (:+key "M-z" (lambda (prefix) "Call `zzz-to-char' or `zzz-up-to-char' with PREFIX arg." (interactive "P") (call-interactively (if prefix #'zzz-up-to-char #'zzz-to-char)))))