diff --git a/early-init.el b/early-init.el index 9f8e7f0..2fcee66 100644 --- a/early-init.el +++ b/early-init.el @@ -224,7 +224,14 @@ package. This macro is not repeatable." :repeatable nil :shorthand (lambda (sexp) (let ((recipe (cadr sexp))) - (if (consp recipe) (car recipe) recipe))))) + (if (consp recipe) (car recipe) recipe)))) + ;; Hotfix + (setup-define :file-match + (lambda (pat) + `(add-to-list 'auto-mode-alist (cons ,pat ',(setup-get 'mode)))) + :documentation "Associate the current mode with files that match PAT." + :debug '(form) + :repeatable t)) ;;; `no-littering' (setup (:straight no-littering) diff --git a/init.el b/init.el index 324430c..b4b692c 100644 --- a/init.el +++ b/init.el @@ -74,7 +74,7 @@ (global-auto-revert-mode +1)) (setup browse-url - (require 'acdw-browse-url) + (:require acdw-browse-url) (setq-default browse-url-secondary-browser-function (if (executable-find "firefox") ; prefer Firefox @@ -116,7 +116,7 @@ (acdw/add-button-url-regexp-protocol "gemini")) (setup buffers - (:global "C-x k" acdw/kill-a-buffer)) + (:global "C-x k" #'acdw/kill-a-buffer)) (setup calendar (:option calendar-week-start-day 1)) @@ -129,7 +129,7 @@ completion-category-overrides '((file (styles . (partial-completion))))) - (:global "M-/" hippie-expand)) + (:global "M-/" #'hippie-expand)) (setup cursor (:option cursor-type 'bar @@ -147,34 +147,43 @@ ;; `Custom-mode-hook' fires /before/ the widgets are built, so I have to ;; install advice after the widgets are made. - (advice-add - 'custom-buffer-create :after - (defun custom-buffer@expand-widgets (&rest _) - "Expand descriptions and values of variables in `Custom-mode' buffers." - (interactive) - ;; "More/Hide" widgets (thanks alphapapa!) - (widget-map-buttons (lambda (widget _) - (pcase (widget-get widget :off) - ("More" (widget-apply-action widget))) - nil)) - ;; "Show Value" widgets (the little triangles) - (widget-map-buttons (lambda (widget _) - (pcase (widget-get widget :off) - ("Show Value" (widget-apply-action widget))) - nil)))) + (:advise custom-buffer-create :after + (defun custom-buffer@expand-widgets (&rest _) + "Expand descriptions in `Custom-mode' buffers." + (interactive) + ;; "More/Hide" widgets (thanks alphapapa!) + (widget-map-buttons (lambda (widget _) + (pcase (widget-get widget :off) + ("More" (widget-apply-action widget))) + nil)) + ;; "Show Value" widgets (the little triangles) + (widget-map-buttons (lambda (widget _) + (pcase (widget-get widget :off) + ("Show Value" + (widget-apply-action widget))) + nil)))) - (add-hook ; thanks u/oantolin! - 'Custom-mode-hook - (defun custom-mode@imenu () - "Build `imenu' for `Custom-mode'." - (setq imenu-generic-expression - '(("Faces" "^\\(?:Show\\|Hide\\) \\(.*\\) face: \\[sample\\]" 1) - ("Variables" "^\\(?:Show Value\\|Hide\\) \\([^:\n]*\\)" 1)))))) + (:with-mode Custom-mode + (:hook (defun custom-mode@imenu () ; thanks u/oantolin! + "Build `imenu' for `Custom-mode'." + (setq + imenu-generic-expression + '(("Faces" (rx (seq bol + (or "Show" "Hide") " " + (group (zero-or-more nonl)) + " face: [sample]")) + 1) + ("Variables" (rx (seq bol + (or "Show Value" "Hide") " " + (group (zero-or-more + (not (any "\n:")))))) + 1))))))) (setup debugger (:hook visual-line-mode)) (setup dired + (:also-load dired-x) (setq-default dired-recursive-copies 'always dired-recursive-deletes 'always delete-by-moving-to-trash t @@ -190,27 +199,26 @@ (:hook dired-hide-details-mode hl-line-mode) - (:global "C-x C-j" dired-jump) - - (acdw/system - (:work (:straight w32-browser) - (autoload 'dired-w32-browser "w32-browser") - (:bind "RET" dired-w32-browser)) - (:home (:straight dired-open) - (require 'dired-open) - (:bind "RET" dired-find-alternate-file))) + (:global "C-x C-j" #'dired-jump) (with-eval-after-load 'dired - (require 'dired-x) + (acdw/system + (:work (:straight w32-browser) + (autoload 'dired-w32-browser "w32-browser") + (:bind "RET" #'dired-w32-browser)) + (:home (:straight dired-open) + (require 'dired-open) + (:bind "RET" #'dired-find-alternate-file))) + (:straight dired-subtree) - (:bind "i" dired-subtree-toggle - "TAB" dired-subtree-cycle) + (:bind "i" #'dired-subtree-toggle + "TAB" #'dired-subtree-cycle) (:straight dired-collapse) (:hook dired-collapse-mode) (:straight dired-git-info) - (:bind ")" dired-git-info-mode) + (:bind ")" #'dired-git-info-mode) (:straight trashed) (:option trashed-action-confirmer #'y-or-n-p))) @@ -263,8 +271,8 @@ cmd)))))) (setup ediff - (:option ediff-window-setup-function 'ediff-setup-windows-plain - ediff-split-window-function 'split-window-horizontally)) + (:option ediff-window-setup-function #'ediff-setup-windows-plain + ediff-split-window-function #'split-window-horizontally)) (setup eldoc (:option eldoc-idle-delay 0.1 @@ -275,31 +283,28 @@ eval-expression-print-level nil lisp-indent-function #'lisp-indent-function) - (add-hook 'emacs-lisp-mode-hook #'checkdoc-minor-mode) + (:with-mode emacs-lisp-mode + (:hook #'checkdoc-minor-mode + #'turn-on-eldoc-mode + + (defun emacs-lisp@enforce-lexical-binding () + (setq-local lexical-binding t)) + + (defun emacs-lisp@imenu-add-setup () + (add-to-list 'imenu-generic-expression + '("Setup" + "\\(^\\s-*(setup +(?\\)\\(\\_<.+\\_>\\)" 2)))) + + ;; Emulate slime's eval binds + (:bind "C-c C-c" #'eval-defun + "C-c C-k" #'acdw/eval-region-or-buffer + "C-c C-z" #'ielm)) - (add-hook 'emacs-lisp-mode-hook - (defun emacs-lisp@enforce-lexical-binding () - (setq-local lexical-binding t))) - - (add-hook 'emacs-lisp-mode-hook - (defun emacs-lisp@imenu-add-setup () - (add-to-list 'imenu-generic-expression - '("Setup" - "\\(^\\s-*(setup +(?\\)\\(\\_<.+\\_>\\)" 2)))) - - ;; Emulate slime's eval binds - (:with-map emacs-lisp-mode-map - (:bind "C-c C-c" eval-defun - "C-c C-k" acdw/eval-region-or-buffer - "C-c C-z" ielm)) - - (add-hook 'emacs-lisp-mode-hook #'turn-on-eldoc-mode) - (add-hook 'ielm-mode-hook #'turn-on-eldoc-mode) - ;; Add advice to pulse evaluated regions - (define-advice eval-region (:around (fn start end &rest args) pulse-region) - (pulse-momentary-highlight-region start end) - (apply fn start end args))) + (:advise eval-region :around + (defun eval-region@pulse (fn beg end &rest args) + (pulse-momentary-highlight-region beg end) + (apply fn start end args)))) (setup encoding (:option locale-coding-system 'utf-8-unix @@ -336,34 +341,28 @@ eshell-smart-space-goes-to-end t eshell-where-to-jump 'begin) - (:global "C-c s" eshell-pop-or-quit) - - (defun eshell-mode@setup () - "Set up `eshell' for use. -Most customizations must go in this function since `eshell' loads -like a dumbass." - ;; Define keys - (dolist (spec '(("C-d" . eshell-quit-or-delete-char))) - (define-key eshell-mode-map (kbd (car spec)) (cdr spec))) - ;; Fix modeline - (when (boundp 'simple-modeline--mode-line) - (setq mode-line-format '(:eval simple-modeline--mode-line))) - ;; Make navigating amongst prompts easier - (setq-local outline-regexp eshell-prompt-regexp - page-delimiter eshell-prompt-regexp)) - (defun eshell-buffer-name () (rename-buffer (concat "*eshell*<" (eshell/pwd) ">") t)) (add-hook 'eshell-directory-change-hook #'eshell-buffer-name) (add-hook 'eshell-prompt-load-hook #'eshell-buffer-name) - (:hook eshell-mode@setup - eshell-arg-hist-mode)) + (:hook eshell-arg-hist-mode + (defun eshell-mode@setup () + ;; Define keys + (dolist (spec '(("C-d" . eshell-quit-or-delete-char))) + (define-key eshell-mode-map (kbd (car spec)) (cdr spec))) + ;; Fix modeline + (when (boundp 'simple-modeline--mode-line) + (setq mode-line-format '(:eval simple-modeline--mode-line))) + ;; Make navigating amongst prompts easier + (setq-local outline-regexp eshell-prompt-regexp + page-delimiter eshell-prompt-regexp)))) (setup eww (:option eww-search-prefix "https://duckduckgo.com/html?q=" url-privacy-level '(email agent cookies lastloc)) + (:hook acdw/reading-mode)) (setup files @@ -381,8 +380,6 @@ like a dumbass." vc-make-backup-files t version-control t) - (:global "C-c i" acdw/find-emacs-dotfiles) - (auto-save-visited-mode +1) (add-hook 'unfocused-hook @@ -404,18 +401,16 @@ like a dumbass." (add-hook 'unfocused-hook #'garbage-collect)) -(setup gnus - (:option gnus-home-directory (acdw/dir "gnus" t) - gnus-directory (acdw/dir "News" t) - gnus-init-file (expand-file-name "gnus.el" user-emacs-directory)) - (:global "C-c n" gnus)) - (setup goto-addr - (add-hook 'after-change-major-mode-hook #'goto-address-mode)) + (if (fboundp #'global-goto-address-mode) + (global-goto-address-mode) + (add-hook 'after-change-major-mode-hook #'goto-address-mode))) (setup ibuffer (:also-load ibuf-ext) - (:option ibuffer-saved-filter-groups + (:option ibuffer-expert t + ibuffer-show-empty-filter-groups nil + ibuffer-saved-filter-groups '(("default" ("dired" (mode . dired-mode)) ("customize" (mode . Custom-mode)) @@ -447,14 +442,13 @@ like a dumbass." (mode . gemini-mode) (mode . eww-mode)))))) - (global-set-key (kbd "C-x C-b") #'ibuffer) + (:global "C-x C-b" #'ibuffer) - (add-hook 'ibuffer-mode-hook - (defun ibuffer@filter-to-default () - (ibuffer-switch-to-saved-filter-groups "default"))) - - (:option ibuffer-show-empty-filter-groups nil - ibuffer-expert t)) + (:hook (defun ibuffer@filter-to-default () + (ibuffer-switch-to-saved-filter-groups "default")))) + +(setup ielm + (:hook #'turn-on-eldoc-mode)) (setup imenu (:option imenu-auto-rescan t)) @@ -478,11 +472,12 @@ like a dumbass." ;; `acdw/kill-line-and-join-advice' cribs from `crux-kill-and-join-forward'. ;; I can't simply advise `kill-line' with an override from crux because crux ;; itself calls `kill-line', leading to a infinite nesting situation. - (define-advice kill-line (:around (fn &rest args) join-killed-line) - (if (and (eolp) - (not (bolp))) - (delete-indentation 1) - (apply fn args)))) + (advice-add 'kill-line :around + (defun kill-line@join (fn &rest args) + (if (and (eolp) + (not (bolp))) + (delete-indentation 1) + (apply fn args))))) (setup minibuffer (:option enable-recursive-minibuffers t @@ -505,7 +500,6 @@ like a dumbass." (fset 'yes-or-no-p #'y-or-n-p)) (setup page - (:option page-delimiter (rx bol (or "\f" ";;;") (not (any "#")) (* not-newline) "\n" @@ -534,62 +528,30 @@ like a dumbass." (put 'backward-page 'repeat-map 'page-navigation-repeat-map)) (setup prog - (:option smie-indent-basic tab-width) - - (add-hook 'prog-mode-hook - (defun prog-mode@auto-fill () - (setq-local comment-auto-fill-only-comments t) - ;; (advice-add 'do-auto-fill :after - ;; (defun auto-fill@set-comment-column (&rest _) - ;; (save-excursion - ;; (when (or (looking-back comment-start-skip) - ;; (progn (backward-word) - ;; (looking-back - ;; comment-start-skip))) - ;; (comment-set-column t))))) - ;; If the above advice is enabled, the below advice also needs to - ;; be set to make `comment-dwim' work... I think. - ;; (advice-add 'comment-dwim :before - ;; (defun comment-dwim@set-comment-column (&rest _) - ;; (setq comment-column 0))) - (turn-on-auto-fill))) - (:option show-paren-delay 0 show-paren-style 'mixed show-paren-when-point-inside-paren t - show-paren-when-point-in-periphery t) - - (defun flymake-mode-except () - "Turn on flymake mode, except in some modes." - (let ((no-flymake-modes '(emacs-lisp-mode))) - (unless (or (member major-mode no-flymake-modes) - (apply #'derived-mode-p no-flymake-modes)) - (flymake-mode-on)))) + show-paren-when-point-in-periphery t + smie-indent-basic tab-width) (:hook show-paren-mode electric-pair-local-mode - flymake-mode-except - acdw/setup-fringes) + acdw/setup-fringes + + (defun flymake-mode-except () + "Turn on flymake mode, except in some modes." + (let ((no-flymake-modes '(emacs-lisp-mode))) + (unless (or (member major-mode no-flymake-modes) + (apply #'derived-mode-p no-flymake-modes)) + (flymake-mode-on)))) + + (defun prog-mode@auto-fill () + (setq-local comment-auto-fill-only-comments t) + (turn-on-auto-fill))) (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)) -;; (setup re-builder -;; (require 'acdw-re) -;; (advice-add 're-builder :before #'acdw/re-builder-save-state) - -;; (add-hook 'reb-mode-hook #'paredit-mode) - -;; (:global "" re-builder) - -;; (dolist (map '(reb-mode-map reb-lisp-mode-map)) -;; (let ((setup-map map)) -;; (:bind "RET" reb-replace-regexp -;; "M-n" reb-next-match -;; "M-p" reb-prev-match -;; "C-g" reb-quit -;; "C-c C-k" reb-quit)))) - (setup repeat ;; new for Emacs 28! (:only-if (fboundp #'repeat-mode)) @@ -697,9 +659,8 @@ like a dumbass." (setup view (:option view-read-only t) - (add-hook 'view-mode-hook - (defun acdw/read-view-mode () - (acdw/reading-mode (if view-mode +1 -1))))) + (:hook (defun acdw/read-view-mode () + (acdw/reading-mode (if view-mode +1 -1))))) (setup w32 (:option w32-allow-system-shell t @@ -717,21 +678,21 @@ like a dumbass." tab-width 4 backward-delete-char-untabify-method 'hungry) - (:global "M-SPC" cycle-spacing)) + (:global "M-SPC" #'cycle-spacing)) (setup windmove (:option windmove-wrap-around t) (:global ;; moving - "C-x 4 " windmove-left - "C-x 4 " windmove-right - "C-x 4 " windmove-up - "C-x 4 " windmove-down + "C-x 4 " #'windmove-left + "C-x 4 " #'windmove-right + "C-x 4 " #'windmove-up + "C-x 4 " #'windmove-down ;; swapping - "C-x 4 S-" windmove-swap-states-left - "C-x 4 S-" windmove-swap-states-right - "C-x 4 S-" windmove-swap-states-up - "C-x 4 S-" windmove-swap-states-down) + "C-x 4 S-" #'windmove-swap-states-left + "C-x 4 S-" #'windmove-swap-states-right + "C-x 4 S-" #'windmove-swap-states-up + "C-x 4 S-" #'windmove-swap-states-down) (when (fboundp 'repeat-mode) (defvar windmove-repeat-map @@ -761,34 +722,29 @@ like a dumbass." (setup window (require 'acdw-bell) - (:option use-dialog-box nil - use-file-dialog nil - tab-bar-show 1 - visible-bell nil - ring-bell-function (lambda () - (acdw-bell/flash-mode-line - (acdw/system :home))) - recenter-positions '(top middle bottom)) - - ;; from FrostyX: - ;; https://github.com/frostyx/dotfiles/blob/master/.emacs.d/frostyx.org#window-management - (:option display-buffer-alist + (:option Man-notify-method 'pushy + display-buffer-alist ; from FrostyX '(("shell.*" (display-buffer-same-window) ()) (".*" (display-buffer-reuse-window display-buffer-same-window) (reusable-frames . t))) - ;; `display-buffer-alist' isn't respected by every command, so we - ;; /also/ need to set some of these. - Man-notify-method 'pushy) - + recenter-positions '(top middle bottom) + ring-bell-function (lambda () + (acdw-bell/flash-mode-line + (acdw/system :home))) + tab-bar-show 1 + use-dialog-box nil + use-file-dialog nil + visible-bell nil) + (tooltip-mode -1)) (setup winner ;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html - (:global "C-x 4 C-/" winner-undo - "C-x 4 /" winner-undo - "C-x 4 C-?" winner-redo - "C-x 4 ?" winner-redo) + (:global "C-x 4 C-/" #'winner-undo + "C-x 4 /" #'winner-undo + "C-x 4 C-?" #'winner-redo + "C-x 4 ?" #'winner-redo) ;; add `winner-undo' and `winner-redo' to `repeat-mode' (when (fboundp 'repeat-mode) @@ -830,13 +786,13 @@ like a dumbass." "A keymap for looking up things.") (global-set-key (kbd "C-c l") lookup-map) - (:global "M-=" count-words - "C-w" kill-region-or-backward-word - "C-c c c" capitalize-dwim - "C-c c t" titlecase-dwim - "C-c c u" upcase-dwim - "C-c c l" downcase-dwim - "C-c d" acdw/insert-iso-date + (:global "M-=" #'count-words + "C-w" #'kill-region-or-backward-word + "C-c c c" #'capitalize-dwim + "C-c c t" #'titlecase-dwim + "C-c c u" #'upcase-dwim + "C-c c l" #'downcase-dwim + "C-c d" #'acdw/insert-iso-date "M-`" nil) ;; toggle bindings @@ -845,9 +801,9 @@ like a dumbass." (global-set-key (kbd "C-c t") toggle-map) (:with-map toggle-map - (:bind "c" column-number-mode - "l" display-line-numbers-mode - "d" toggle-debug-on-error)) + (:bind "c" #'column-number-mode + "l" #'display-line-numbers-mode + "d" #'toggle-debug-on-error)) (defalias 'forward-word-with-case 'forward-word "Alias for `forward-word' for use in `case-repeat-map'.") @@ -921,44 +877,44 @@ like a dumbass." (:global ;; C-c bindings (`mode-specific-map') ;; I don't use any of these right now. - ;; "C-c h" consult-history - ;; "C-c m" consult-mode-command - ;; "C-c b" consult-bookmark - ;; "C-c k" consult-kmacro + ;; "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 + "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 + "M-#" #'consult-register-load + "M-'" #'consult-register-store + "C-M-#" #'consult-register ;; M-g bindings (`goto-map') - "M-g e" consult-compile-error - "M-g g" consult-goto-line - "M-g M-g" consult-goto-line - "M-g o" consult-outline - "M-g m" consult-mark - "M-g k" consult-global-mark - "M-g i" consult-imenu - "M-g I" consult-project-imenu + "M-g e" #'consult-compile-error + "M-g g" #'consult-goto-line + "M-g M-g" #'consult-goto-line + "M-g o" #'consult-outline + "M-g m" #'consult-mark + "M-g k" #'consult-global-mark + "M-g i" #'consult-imenu + "M-g I" #'consult-project-imenu ;; M-s bindings (`search-map') - "M-s g" acdw-consult/sensible-grep - "M-s f" acdw-consult/sensible-find - "M-s l" consult-line - "M-s m" consult-multi-occur - "M-s k" consult-keep-lines - "M-s u" consult-focus-lines + "M-s g" #'acdw-consult/sensible-grep + "M-s f" #'acdw-consult/sensible-find + "M-s l" #'consult-line + "M-s m" #'consult-multi-occur + "M-s k" #'consult-keep-lines + "M-s u" #'consult-focus-lines ;; Other bindings - "M-y" consult-yank-pop - " a" consult-apropos + "M-y" #'consult-yank-pop + " a" #'consult-apropos ;; Isearch integration - "M-s e" consult-isearch) + "M-s e" #'consult-isearch) (:with-map isearch-mode-map - (:bind "M-e" consult-isearch - "M-s e" consult-isearch - "M-s l" consult-line)) + (:bind "M-e" #'consult-isearch + "M-s e" #'consult-isearch + "M-s l" #'consult-line)) ;; see https://github.com/oantolin/completing-history (defmacro consult-history-to-modes (map-hook-alist) @@ -1043,10 +999,10 @@ like a dumbass." elpher-certificate-directory (acdw/dir "elpher/") elpher-gemini-max-fill-width fill-column) - (:bind "n" elpher-next-link - "p" elpher-prev-link - "o" elpher-follow-current-link - "G" elpher-go-current) + (:bind "n" #'elpher-next-link + "p" #'elpher-prev-link + "o" #'elpher-follow-current-link + "G" #'elpher-go-current) (:hook acdw/reading-mode) @@ -1064,7 +1020,7 @@ like a dumbass." (setup (:straight (gemini-mode :host nil :repo "https://git.carcosa.net/jmcbray/gemini.el.git")) - (add-to-list 'auto-mode-alist '("\\.\\(gemini\\|gmi\\)\\'" . gemini-mode)) + (:file-match (rx (seq "." (or "gemini" "gmi") eos))) (:hook turn-off-auto-fill)) (setup (:straight (gemini-write @@ -1076,13 +1032,14 @@ like a dumbass." (setup (:straight (mastodon :host github - :repo "mooseyboots/mastodon.el")) - (:straight request) + :repo "mooseyboots/mastodon.el") + request) (:option mastodon-instance-url "https://writing.exchange" mastodon-auth-source-file (car auth-sources) mastodon-client--token-file (acdw/dir "mastodon.plstore")) - (:hook hl-line-mode - acdw/reading-mode)) + + (:hook #'hl-line-mode + #'acdw/reading-mode)) (setup (:straight (modus-themes :host gitlab @@ -1107,11 +1064,12 @@ like a dumbass." orderless-component-separator #'orderless-escapable-split-on-space orderless-style-dispatchers '(acdw/orderless-dispatch)) - (defun fix-dollar (args) - (if (string-suffix-p "$" (car args)) - (list (concat (substring (car args) 0 -1) "[\x100000-\x10FFFD]*$")) - args)) - (advice-add #'orderless-regexp :filter-args #'fix-dollar) + (:advise orderless-regexp :filter-args + (defun fix-dollar (args) + (if (string-suffix-p "$" (car args)) + (list (concat (substring (car args) 0 -1) + "[\x100000-\x10FFFD]*$")) + args))) (defun acdw/orderless-dispatch (pattern _index _total) "My custom dispatcher for `orderless'." @@ -1174,15 +1132,14 @@ like a dumbass." vertico-count-format nil vertico-cycle t) - (defun up-directory (arg) - "Move up a directory (delete backwards to /)." - (interactive "p") - (if (string-match-p "/." (minibuffer-contents)) - (zap-up-to-char (- arg) ?/) - (backward-kill-word arg))) - - (with-eval-after-load 'vertico - (define-key vertico-map (kbd "") #'up-directory)) + (:with-map vertico-map + (:bind "" + (defun up-directory (arg) + "Move up a directory (delete backwards to /)." + (interactive "p") + (if (string-match-p "/." (minibuffer-contents)) + (zap-up-to-char (- arg) ?/) + (backward-kill-word arg))))) (if (boundp 'comp-deferred-compilation-deny-list) (add-to-list 'comp-deferred-compilation-deny-list "vertico")) @@ -1194,14 +1151,14 @@ like a dumbass." (vertico-mouse-mode +1) ;; Prefix the current candidate with "> ". From Vertico wiki. - (defun vertico-format@add-arrow (orig cand prefix suffix index _start) - (setq cand (funcall orig cand prefix suffix index _start)) - (concat - (if (= vertico--index index) - (propertize "> " 'face 'vertico-current) - " ") - cand)) - (advice-add #'vertico--format-candidate :around #'vertico-format@add-arrow)) + + (:advise vertico--format-candidate :around + (defun vertico-format@add-arrow (orig cand pref suf index start) + (setq cand (funcall orig cand pref suf index start)) + (concat (if (= vertico--index index) + (propertize "> " 'face 'vertico-current) + " ") + cand)))) (setup (:straight alert) (:option alert-default-style (acdw/system @@ -1210,18 +1167,20 @@ like a dumbass." (setup (:straight async) (autoload 'dired-async-mode "dired-async.el" nil t) + (dired-async-mode +1) + (add-hook 'dired-mode (defun dired@disable-dired-async-mode-line () (autoload 'dired-async--modeline-mode "dired-async.el" nil t) (dired-async--modeline-mode -1)))) (setup (:straight avy) - (:global "C-:" avy-goto-char-timer - "C-c C-j" avy-resume) + (:global "C-:" #'avy-goto-char-timer + "C-c C-j" #'avy-resume) - (with-eval-after-load "isearch" - (define-key isearch-mode-map (kbd "C-'") #'avy-isearch))) + (:with-feature isearch + (:bind "C-'" #'avy-isearch))) (setup (:straight circe) (require 'circe) @@ -1234,27 +1193,44 @@ like a dumbass." circe-default-nick "acdw" circe-default-part-message "See You, Space Cowpokes . . ." circe-default-user "acdw" + circe-format-action + (lambda (&rest plist) + (concat + (acdw-irc/margin-format "" "*" "*" t) + " " (plist-get plist :nick) " " (plist-get plist :body))) + circe-format-say + (lambda (&rest plist) + (concat + (acdw-irc/margin-format (plist-get plist :nick) "" " |" t) + " " (plist-get plist :body))) + circe-format-self-action + (lambda (&rest plist) + (concat + (acdw-irc/margin-format "" "-*" " *" t) + " " (plist-get plist :nick) " " (plist-get plist :body))) + circe-format-self-say + (lambda (&rest plist) + (concat + (acdw-irc/margin-format (plist-get plist :nick) "-" " >" t) + " " (plist-get plist :body))) circe-highlight-nick-type 'sender circe-network-options `(("Libera Chat" :channels ("#emacs" "#systemcrafters" "##webpals") - :sasl-username "acdw" + :sasl-username circe-default-nick :sasl-password ,(acdw/make-password-fetcher :host "libera.chat")) - ("Tilde Chat" + ("Tilde Chat" :host "irc.tilde.chat" :port 6697 :use-tls t :channels ("#meta" "#bread" "#dadjokes" "#team") - :host "irc.tilde.chat" :port 6697 :use-tls t - :sasl-username "acdw" + :sasl-username circe-default-nick :sasl-password ,(acdw/make-password-fetcher :host "tilde.chat")) - ("Casa" + ("Casa" :host "m455.casa" :port 6697 :use-tls t :channels ("#basement") - :host "m455.casa" :port 6697 :use-tls t - :sasl-username "acdw" + :sasl-username circe-default-nick :sasl-password ,(acdw/make-password-fetcher :host "m455.casa")) - ("Piss" - :host "piss.hmm.st" :port 6697 :use-tls t)) + ("Piss" :host "piss.hmm.st" :port 6697 :use-tls t)) circe-reduce-lurker-spam t circe-server-auto-join-default-type :after-auth) @@ -1262,13 +1238,15 @@ like a dumbass." ((t (:inherit (modus-themes-hl-line)))) :now)) - (:bind "C-c C-p" circe-command-PART) + (:bind "C-c C-p" #'circe-command-PART) (:advise circe-command-PART :after (defun circe-command-PART@kill-buffer (&rest _) - (kill-buffer))) + (let ((circe-channel-killed-confirmation nil)) + (kill-buffer)))) - (add-hook 'circe-chat-mode-hook + (:with-mode circe-chat-mode + (:hook #'acdw/stop-paren-annoyances (defun circe-chat@setup () (lui-set-prompt (concat (propertize (acdw-irc/margin-format (buffer-name) @@ -1280,70 +1258,37 @@ like a dumbass." " ")) (enable-circe-color-nicks) (enable-circe-display-images) - (enable-circe-new-day-notifier))) - - (add-hook 'circe-chat-mode-hook #'acdw/stop-paren-annoyances) + (enable-circe-new-day-notifier)))) (autoload 'circe-nick-color-reset "circe-color-nicks") (add-hook 'modus-themes-after-load-theme-hook #'circe-nick-color-reset) - (setq circe-format-say - (lambda (&rest plist) - (concat - (acdw-irc/margin-format (plist-get plist :nick) "" " |" t) - " " - (plist-get plist :body))) - - circe-format-self-say - (lambda (&rest plist) - (concat - (acdw-irc/margin-format (plist-get plist :nick) "-" " >" t) - " " - (plist-get plist :body))) - - circe-format-action - (lambda (&rest plist) - (concat - (acdw-irc/margin-format "" "*" "*" t) - " " - (plist-get plist :nick) " " - (plist-get plist :body))) - - circe-format-self-action - (lambda (&rest plist) - (concat - (acdw-irc/margin-format "" "-*" " *" t) - " " - (plist-get plist :nick) " " - (plist-get plist :body))) - - lui-fill-type (repeat-string acdw-irc/left-margin " ")) - - (:option lui-fill-column fill-column - lui-time-stamp-position 'right-margin - lui-time-stamp-format "%H:%M" - lui-track-behavior 'before-switch-to-buffer - lui-track-indicator 'fringe) - - (add-hook 'lui-mode-hook - (defun lui-mode@setup () - (setq-local fringes-outside-margins t - right-margin-width 5 - scroll-margin 0 - word-wrap t - wrap-prefix (repeat-string - acdw-irc/left-margin " ") - line-number-mode nil) - (enable-lui-track)))) + (:with-mode lui-mode + (:option lui-fill-column fill-column + lui-fill-type (repeat-string acdw-irc/left-margin " ") + lui-time-stamp-position 'right-margin + lui-time-stamp-format "%H:%M" + lui-track-behavior 'before-switch-to-buffer + lui-track-indicator 'fringe) + + (:hook (defun lui-mode@setup () + (setq-local fringes-outside-margins t + right-margin-width 5 + scroll-margin 0 + word-wrap t + wrap-prefix (repeat-string + acdw-irc/left-margin " ") + line-number-mode nil) + (enable-lui-track))))) (setup (:straight crux) - (:global "C-x o" acdw/other-window-or-switch-buffer - "C-o" crux-smart-open-line - "M-o" crux-smart-open-line-above - "C-M-\\" crux-cleanup-buffer-or-region - "C-x 4 t" crux-transpose-windows) + (:global "C-x o" #'acdw/other-window-or-switch-buffer + "C-o" #'crux-smart-open-line + "M-o" #'crux-smart-open-line-above + "C-M-\\" #'crux-cleanup-buffer-or-region + "C-x 4 t" #'crux-transpose-windows) (when (fboundp 'repeat-mode) (unless (boundp 'other-window-repeat-map) @@ -1370,9 +1315,9 @@ like a dumbass." (require 'edit-server nil :noerror)) (edit-server-start) - (advice-add 'edit-server-make-frame :before - (defun edit-server@set-a-variable (&rest _) - (setq-local edit-server-frame-p t))))) + (:advise edit-server-make-frame :before + (defun edit-server@set-a-variable (&rest _) + (setq-local edit-server-frame-p t))))) (setup (:straight elfeed elfeed-protocol) @@ -1383,39 +1328,33 @@ like a dumbass." :host "mf.acdw.net")))) (elfeed-protocol-enable) - - (add-hook 'elfeed-show-mode-hook - (defun elfeed-show@setup () - (acdw/reading-mode))) - ;; see https://irreal.org/blog/?p=8885 - ;; Lazy Elfeed (karthinks) - (defun elfeed-scroll-up-command (&optional arg) - "Scroll up or go to next feed item in Elfeed" - (interactive "^P") - (let ((scroll-error-top-bottom nil)) - (condition-case-unless-debug nil - (scroll-up-command arg) - (error (elfeed-show-next))))) + (:with-mode elfeed-show-mode + (:hook (defun elfeed-show@setup () + (acdw/reading-mode))) - (defun elfeed-scroll-down-command (&optional arg) - "Scroll up or go to next feed item in Elfeed" - (interactive "^P") - (let ((scroll-error-top-bottom nil)) - (condition-case-unless-debug nil - (scroll-down-command arg) - (error (elfeed-show-prev))))) - - ;; Turns out, `scroll-up' and `scroll-down' are /backward/ - (define-key elfeed-show-mode-map (kbd "SPC") 'elfeed-scroll-up-command) - (define-key elfeed-show-mode-map (kbd "S-SPC") 'elfeed-scroll-down-command)) + ;; see https://irreal.org/blog/?p=8885 + (:bind "SPC" (defun elfeed-scroll-up-command (&optional arg) + "Scroll up or go to next feed item in Elfeed" + (interactive "^P") + (let ((scroll-error-top-bottom nil)) + (condition-case-unless-debug nil + (scroll-up-command arg) + (error (elfeed-show-next))))) + "S-SPC" (defun elfeed-scroll-down-command (&optional arg) + "Scroll up or go to next feed item in Elfeed" + (interactive "^P") + (let ((scroll-error-top-bottom nil)) + (condition-case-unless-debug nil + (scroll-down-command arg) + (error (elfeed-show-prev)))))))) (setup (:straight elisp-slime-nav) (:hook-into emacs-lisp-mode ielm-mode)) (setup (:straight embark) - (:global "C-." embark-act) + (:global "C-." #'embark-act) (:option prefix-help-command #'embark-prefix-help-command (append display-buffer-alist) '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" @@ -1437,18 +1376,20 @@ like a dumbass." #'consult-preview-at-point-mode))) (setup (:straight epithet) - (add-hook 'Info-selection-hook #'epithet-rename-buffer) - (add-hook 'eww-after-render-hook #'epithet-rename-buffer) - (add-hook 'help-mode-hook #'epithet-rename-buffer) - (add-hook 'occur-mode-hook #'epithet-rename-buffer)) + (dolist (hook '(Info-selection-hook + eww-after-render-hook + help-mode-hook + occur-mode-hook)) + (add-hook hook #'epithet-rename-buffer))) (setup (:straight eros) (:hook-into emacs-lisp-mode)) (setup (:straight expand-region) - - (defun acdw/set-mark-or-expand-region (arg) - "Set mark at point and activate, jump to mark, or expand region. + (:global "C-=" #'er/expand-region + "C-SPC" + (defun acdw/set-mark-or-expand-region (arg) + "Set mark at point and activate, jump to mark, or expand region. See `set-mark-command' and `expand-region'. With no prefix argument, either run `set-mark-command' on first @@ -1458,29 +1399,22 @@ With any prefix argument (e.g., \\[universal-argument] \\[set-mark-command]), act as with `set-mark-command' (i.e., pop the mark). Don't care about successive invocations." - (interactive "P") - (cond - ((or arg - (and set-mark-command-repeat-pop - (eq last-command 'pop-to-mark-command))) - (setq this-command 'set-mark-command) - (set-mark-command arg)) - ((eq last-command 'acdw/set-mark-or-expand-region) - (er/expand-region 1)) - (t (set-mark-command arg)))) - - (:global "C-=" er/expand-region - "C-SPC" acdw/set-mark-or-expand-region)) + (interactive "P") + (cond + ((or arg + (and set-mark-command-repeat-pop + (eq last-command 'pop-to-mark-command))) + (setq this-command 'set-mark-command) + (set-mark-command arg)) + ((eq last-command 'acdw/set-mark-or-expand-region) + (er/expand-region 1)) + (t (set-mark-command arg)))))) (setup (:straight flyspell-correct) - (add-hook 'flyspell-mode-hook - (defun flyspell-mode@flyspell-correct () - (dolist (keybind '(("C-;" . flyspell-correct-wrapper) - ("C-," . nil) - ("C-." . nil) - ("C-M-i" . nil))) - (define-key flyspell-mode-map - (kbd (car keybind)) (cdr keybind)))))) + (:with-mode flyspell-mode + (:hook (defun flyspell@correct () + (:bind "C-;" #'flyspell-correct-wrapper) + (:unbind "C-," "C-." "C-M-i"))))) (setup (:straight gcmh) (:option gcmh-idle-delay 'auto) @@ -1489,40 +1423,40 @@ successive invocations." ;; TODO: figure out a popper.el / shackle.el ... thing to fix this (setup (:straight helpful) (:option helpful-max-buffers 5) - (:global " f" helpful-callable - " v" helpful-variable - " k" helpful-key - " o" helpful-symbol - "C-c C-d" helpful-at-point)) + (:global " f" #'helpful-callable + " v" #'helpful-variable + " k" #'helpful-key + " o" #'helpful-symbol)) (setup (:straight hungry-delete) - - (with-eval-after-load 'paredit - (define-key paredit-mode-map [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)))) - - (define-key paredit-mode-map [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))))) - (:option hungry-delete-chars-to-skip " \t" hungry-delete-join-reluctantly nil) - (global-hungry-delete-mode +1)) + + (global-hungry-delete-mode +1) + + (:with-feature paredit + (:bind [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)))))) (setup (:straight iscroll) - (define-globalized-minor-mode global-iscroll-mode - iscroll-mode - (lambda () (iscroll-mode +1)))) + (define-globalized-minor-mode global-iscroll-mode iscroll-mode + (lambda () (iscroll-mode +1))) + + (global-iscroll-mode +1)) (setup (:straight lacarte) - (:global "" lacarte-execute-menu-command)) + (:global "" #'lacarte-execute-menu-command)) (setup (:straight link-hint) ;; Browse web URLs with a browser with a prefix argument. @@ -1541,31 +1475,30 @@ successive invocations." (link-hint-define-type type :open-secondary browse-url-secondary-browser-function)) - (defun acdw/link-hint-open-link (arg) - "Open a link using `link-hint-open-link', but like `browse-url-at-point'. + (:option link-hint-avy-style 'at) + (:global "C-;" + (defun acdw/link-hint-open-link (arg) + "Open a link using `link-hint-open-link', prefix-aware. That is, a prefix argument (\\[universal-argument]) will open the browser defined in `browse-url-secondary-browser-function'." - (interactive "P") - (avy-with link-hint-open-link - (link-hint--one (if arg :open-secondary :open)))) - - (setq link-hint-avy-style 'at) - (:global "C-;" acdw/link-hint-open-link)) + (interactive "P") + (avy-with link-hint-open-link + (link-hint--one (if arg :open-secondary :open)))))) (setup (:straight lua-mode) - (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode))) + (:file-match (rx ".lua" eos))) (setup (:straight macrostep) - (define-key emacs-lisp-mode-map (kbd "C-c e") #'macrostep-expand)) + (:with-mode emacs-lisp-mode + (:bind "C-c e" #'macrostep-expand))) (setup (:straight magit) - (:global "C-c g" magit-status) + (:global "C-c g" #'magit-status) - (defun magit-display-buffer-same-window (buffer) - "Display BUFFER in the selected window like God intended." - (display-buffer buffer '(display-buffer-same-window))) - - (:option magit-display-buffer-function #'magit-display-buffer-same-window + (:option magit-display-buffer-function + (defun magit-display-buffer-same-window (buffer) + "Display BUFFER in the selected window like God intended." + (display-buffer buffer '(display-buffer-same-window))) magit-popup-display-buffer-action '((display-buffer-same-window)) magit-refresh-status-buffer nil)) @@ -1587,33 +1520,32 @@ browser defined in `browse-url-secondary-browser-function'." (append apheleia-mode-alist) '(gfm-mode . markdownfmt))))) (setup (:straight mwim) - (:global "C-a" mwim-beginning - "C-e" mwim-end)) + (:global "C-a" #'mwim-beginning + "C-e" #'mwim-end)) (setup (:straight nov) (:option nov-text-width fill-column) - (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))) + (:file-match (rx ".epub" eos))) (setup (:straight olivetti) (:option olivetti-body-width (+ fill-column 4) olivetti-minimum-body-width fill-column) - (add-hook 'olivetti-mode-hook - (defun acdw/olivetti-mode-hook () - (if olivetti-mode - (setq-local indicate-empty-lines nil - indicate-buffer-boundaries nil) - (acdw/setup-fringes))))) + (:hook (defun olivetti-mode@setup () + (if olivetti-mode + (setq-local indicate-empty-lines nil + indicate-buffer-boundaries nil) + (acdw/setup-fringes))))) (setup (:straight org org-contrib) - (require 'acdw-org) ; so I don't clutter up init.el + (:also-load 'acdw-org) ; so I don't clutter up init.el (:option org-adapt-indentation nil org-agenda-files nil ; only until I set this up org-catch-invisible-edits 'smart org-clock-clocked-in-display 'mode-line - org-clock-string-limit 7 ; gives time and not title + org-clock-string-limit 7 ; gives time and not title org-confirm-babel-evaluate nil org-directory "~/org" org-ellipsis " …" @@ -1643,39 +1575,35 @@ browser defined in `browse-url-secondary-browser-function'." org-tags-column 0 ; (- 0 fill-column -3) ) - (:bind "RET" acdw-org/return-dwim - "" acdw-org/org-table-copy-down - "M-SPC M-SPC" insert-zero-width-space - "C-c C-l" org-insert-link-dwim - "M-w" acdw/copy-region-plain - "C-c C-n" acdw/org-next-heading-widen - "C-c C-p" acdw/org-previous-heading-widen) + (:bind "RET" #'acdw-org/return-dwim + "" #'acdw-org/org-table-copy-down + "M-SPC M-SPC" #'insert-zero-width-space + "C-c C-l" #'org-insert-link-dwim + "M-w" #'acdw/copy-region-plain + "C-c C-n" #'acdw/org-next-heading-widen + "C-c C-p" #'acdw/org-previous-heading-widen) (with-eval-after-load 'org-export (add-to-list 'org-export-filter-final-output-functions #'org-export-remove-zero-width-spaces)) - (defun acdw/org-fix-lines-before-save () - (add-hook 'before-save-hook #'acdw-org/fix-blank-lines-in-buffer 0 :local)) - (:hook variable-pitch-mode olivetti-mode - acdw/org-fix-lines-before-save) + (defun acdw/org-fix-lines-before-save () + (add-hook 'before-save-hook + #'acdw-org/fix-blank-lines-in-buffer 0 :local)) + (defun org-mode@wc-stupid () + (unless (and wc-mode + (> 0 (+ (or wc-orig-words 0) + (or wc-words-delta 0))))) + (setq-local + wc-count-words-function + (lambda (start end) "Count words stupidly with a limit." + (acdw-org/count-words-stupidly start + end + 999))))) - (advice-add 'org-delete-backward-char - :override #'acdw-org/delete-backward-char) - - (add-hook 'org-mode-hook - (defun org-mode@wc-stupid () - (unless (and wc-mode - (> 0 (+ (or wc-orig-words 0) - (or wc-words-delta 0))))) - (setq-local - wc-count-words-function - (lambda (start end) "Count words stupidly with a limit." - (acdw-org/count-words-stupidly start - end - 999)))))) + (:advise org-delete-backward-char :override #'acdw-org/delete-backward-char)) (setup (:straight org-appear) (:hook-into org-mode)) @@ -1686,24 +1614,24 @@ browser defined in `browse-url-secondary-browser-function'." (setup (:straight page-break-lines) (global-page-break-lines-mode +1)) -(setup (:straight paredit) +(setup (:straight paredit) ;; I don't use paredit-splice-sexp much, and it stomps on isearch. (:unbind "M-s") (defun paredit@setup () "Correct weirdnesses and set up paredit mode." (:with-map lisp-mode-shared-map - (:bind "DEL" paredit-backward-delete - "C-M-;" comment-or-uncomment-sexp - "C-" paredit-backward-kill-word)) + (:bind "DEL" #'paredit-backward-delete + "C-M-;" #'comment-or-uncomment-sexp + "C-" #'paredit-backward-kill-word)) (paredit-mode +1)) - + (dolist (mode lispy-modes) (add-hook (intern (concat (symbol-name mode) "-hook")) #'paredit@setup)) - (require 'eldoc) + (:also-load 'eldoc) (eldoc-add-command 'paredit-backward-delete 'paredit-close-round)) (setup (:straight paren-face) @@ -1723,53 +1651,54 @@ browser defined in `browse-url-secondary-browser-function'." (buffer-list))) (setup (:straight powerthesaurus) - (:global (kbd "C-c l t") #'powerthesaurus-lookup-word-dwim)) + (:global "C-c l t" #'powerthesaurus-lookup-word-dwim)) (setup (:straight restart-emacs) (defun emacs-upgrade (&optional update-packages) "Pull config, upgrade packages, restart Emacs." (interactive "P") - (when update-packages - (straight-pull-all)) (emacs-git-pull-config) + (when update-packages + (require 'straight) + (straight-pull-all)) (restart-emacs))) -(setup (:straight simple-modeline) - (setup (:straight minions)) - (require 'acdw-modeline) - (:option - simple-modeline-segments '(;; left - (acdw-modeline/modified - acdw-modeline/buffer-name - acdw-modeline/vc-branch - acdw-modeline/winum - acdw-modeline/position) - ;; right - (acdw-modeline/track - simple-modeline-segment-misc-info - acdw-modeline/wc - acdw-modeline/text-scale - simple-modeline-segment-process - acdw-modeline/god-mode-indicator - acdw-modeline/minions - acdw-modeline/narrowed - acdw-modeline/major-mode))) +(setup (:straight simple-modeline + minions) + (:also-load acdw-modeline) + (:option simple-modeline-segments + '(;; left + (acdw-modeline/modified + acdw-modeline/buffer-name + acdw-modeline/vc-branch + acdw-modeline/winum + acdw-modeline/position) + ;; right + (acdw-modeline/track + simple-modeline-segment-misc-info + acdw-modeline/wc + acdw-modeline/text-scale + simple-modeline-segment-process + acdw-modeline/god-mode-indicator + acdw-modeline/minions + acdw-modeline/narrowed + acdw-modeline/major-mode))) ;; I've put in a pull request to add the (- 0 right-margin) bit here. - (advice-add 'simple-modeline--format :override - (defun simple-modeline@format (lefts rights) - (let* ((left (simple-modeline--format-segments lefts)) - (right (simple-modeline--format-segments rights)) - (reserve (length right))) - (concat - left - (propertize " " - 'display `((space :align-to - (- right - (- 0 right-margin) - ,reserve))) - 'face '(:inherit simple-modeline-space)) - right)))) + (:advise simple-modeline--format :override + (defun simple-modeline@format (lefts rights) + (let* ((left (simple-modeline--format-segments lefts)) + (right (simple-modeline--format-segments rights)) + (reserve (length right))) + (concat + left + (propertize " " + 'display `((space :align-to + (- right + (- 0 right-margin) + ,reserve))) + 'face '(:inherit simple-modeline-space)) + right)))) (simple-modeline-mode +1)) @@ -1780,7 +1709,7 @@ browser defined in `browse-url-secondary-browser-function'." ("/authorized_keys2?\\'" . ssh-authorized-keys-mode))) (add-to-list 'auto-mode-alist spec)) - (add-hook 'ssh-config-mode-hook #'turn-on-font-lock)) + (:hook #'turn-on-font-lock)) (setup (:straight typo) @@ -1799,28 +1728,24 @@ browser defined in `browse-url-secondary-browser-function'." (or (buffer-name) ""))) (typo-mode +1)))) - (with-eval-after-load 'typo - ;; jlf & cvandusen on #emacs make a great point: ’ (RIGHT SINGLE QUOTATION - ;; MARK) is /not/ an apostrophe. Making it curly is a typographical - ;; consideration, not an input consideration. (I suppose you could make - ;; the argument that all of these are typographical considerations, but - ;; .. bleh.) - (define-typo-cycle typo-cycle-apostrophe - "Cycle through apostrophe-like graphemes. + ;; jlf & cvandusen on #emacs make a great point: ’ (RIGHT SINGLE QUOTATION + ;; MARK) is /not/ an apostrophe. Making it curly is a typographical + ;; consideration, not an input consideration. (I suppose you could make + ;; the argument that all of these are typographical considerations, but + ;; .. bleh.) + + (:bind "'" (define-typo-cycle typo-cycle-apostrophe + "Cycle through apostrophe-like graphemes. If used with a numeric prefix argument N, N apostrophes will be inserted." - ("'" "′" "″" "’")) - - (define-typo-cycle typo-cycle-backtick - "Cycle through backtick and left single quotation mark. + ("'" "′" "″" "’")) + "`" (define-typo-cycle typo-cycle-backtick + "Cycle through backtick and left single quotation mark. If used with a numeric prefix argument N, N backticks will be inserted." - ("`" "‘")) - - (:bind "'" typo-cycle-apostrophe - "`" typo-cycle-backtick))) + ("`" "‘")))) (setup (:straight undo-fu) - (:global "C-/" undo-fu-only-undo - "C-?" undo-fu-only-redo)) + (:global "C-/" #'undo-fu-only-undo + "C-?" #'undo-fu-only-redo)) (setup (:straight undo-fu-session) (:option undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'" @@ -1833,38 +1758,33 @@ If used with a numeric prefix argument N, N backticks will be inserted." (setup (:straight unfill)) (setup (:straight visual-regexp) - (:global "M-%" vr/query-replace)) + (:global "M-%" #'vr/query-replace)) (setup (:straight wc-mode) ; TODO: move some of this stuff around (:option wc-modeline-format "[%tww]" wc-idle-wait 2) - (:hook-into text-mode) - - (defun acdw-modeline/wc () - "Display current `wc-buffer-stats'." - (when (bound-and-true-p wc-mode) - (or wc-buffer-stats "[w]")))) + (:hook-into text-mode)) (setup (:straight web-mode) (:option css-level-offset 2 js-indent-level 2 sgml-indent-offset 2) - - (dolist (ext '("\\.\\(p\\|dj\\)?html\\'" - "\\.html?\\'" - "\\.\\(tpl\\.\\)?php\\'" - "\\.[agj]sp\\'" - "\\.as[cp]x\\'" - "\\.erb\\'" - "\\.mustache\\'")) - (add-to-list 'auto-mode-alist `(,ext . web-mode)))) + + (:file-match "\\.\\(p\\|dj\\)?html\\'" + "\\.html?\\'" + "\\.\\(tpl\\.\\)?php\\'" + "\\.[agj]sp\\'" + "\\.as[cp]x\\'" + "\\.erb\\'" + "\\.mustache\\'")) (setup (:straight which-key) (:option which-key-show-early-on-C-h t which-key-idle-delay 1 - which-key-idle-secondary-delay 0.5) + which-key-idle-secondary-delay 0.5 + which-key-sort-order 'which-key-prefix-then-key-order) (:global "C-h m" #'which-key-show-major-mode) @@ -1886,16 +1806,16 @@ If used with a numeric prefix argument N, N backticks will be inserted." (when (and (not winum--keys-mapped) (display-graphic-p)) (:with-map winum-keymap - (:bind "M-0" winum-select-window-0-or-10 - "M-1" winum-select-window-1 - "M-2" winum-select-window-2 - "M-3" winum-select-window-3 - "M-4" winum-select-window-4 - "M-5" winum-select-window-5 - "M-6" winum-select-window-6 - "M-7" winum-select-window-7 - "M-8" winum-select-window-8 - "M-9" winum-select-window-9)) + (:bind "M-0" #'winum-select-window-0-or-10 + "M-1" #'winum-select-window-1 + "M-2" #'winum-select-window-2 + "M-3" #'winum-select-window-3 + "M-4" #'winum-select-window-4 + "M-5" #'winum-select-window-5 + "M-6" #'winum-select-window-6 + "M-7" #'winum-select-window-7 + "M-8" #'winum-select-window-8 + "M-9" #'winum-select-window-9)) (setq winum--keys-mapped t))) (winum-mode +1)) @@ -1903,21 +1823,20 @@ If used with a numeric prefix argument N, N backticks will be inserted." (setup (:straight xr)) (setup (:straight zzz-to-char) - (defun acdw/zzz-up-to-char (prefix) - "Call `zzz-up-to-char', unless issued a PREFIX, in which case -call `zzz-to-char'." - (interactive "P") - (if prefix - (call-interactively #'zzz-to-char) - (call-interactively #'zzz-up-to-char))) - - (:global "M-z" acdw/zzz-up-to-char)) + + (:global "M-z" + (defun acdw/zzz-up-to-char (prefix) + "Call `zzz-up-to-char' or `zzz-to-char', PREFIX-depending." + (interactive "P") + (if prefix + (call-interactively #'zzz-to-char) + (call-interactively #'zzz-up-to-char))))) (setup (:straight-if (pdf-tools :host github :repo "vedang/pdf-tools") (acdw/system :home)) - (add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-view-mode)) + (:file-match (rx ".pdf" eos)) (pdf-loader-install)) (setup (:straight-if affe @@ -1925,11 +1844,10 @@ call `zzz-to-char'." (executable-find "find")) (executable-find "rg"))) ;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find' - (defun affe-orderless-regexp-compiler (input _type) - (setq input (orderless-pattern-compiler input)) - (cons input (lambda (str) (orderless--highlight input str)))) - - (:option affe-regexp-compiler #'affe-orderless-regexp-compiler)) + (:option affe-regexp-compiler + (defun affe-orderless-regexp-compiler (input _type) + (setq input (orderless-pattern-compiler input)) + (cons input (lambda (str) (orderless--highlight input str)))))) (setup (:straight-if ahk-mode (acdw/system :work))) @@ -1969,9 +1887,9 @@ call `zzz-to-char'." "https://radio.tildeverse.org/radio/8000/radio.ogg") ("vantaradio" . "https://vantaa.black/radio"))) - (:global "C-c r r" eradio-play ; mnemonic: radio - "C-c r s" eradio-stop ; mnemonic: stop - "C-c r p" eradio-toggle ; mnemonic: play/pause + (:global "C-c r r" #'eradio-play ; mnemonic: radio + "C-c r s" #'eradio-stop ; mnemonic: stop + "C-c r p" #'eradio-toggle ; mnemonic: play/pause )) (setup (:straight-if exec-path-from-shell @@ -1982,17 +1900,17 @@ call `zzz-to-char'." (setup (:straight-if fennel-mode (executable-find "fennel")) (autoload 'fennel-repl "fennel-mode" nil t) - (add-to-list 'auto-mode-alist '("\\.fnl\\'" . fennel-mode))) + (:file-match (rx ".fnl" eos))) (setup (:straight-if geiser (progn (defvar acdw/schemes - (let (schemes) ; these binaries should be checked... + (let (schemes) (dolist (scheme '(("scheme" . geiser-chez) ; chez ("petite" . geiser-chez) ; petite ("csi" . geiser-chez) ; chicken - ("gsi" . geiser-gambit) ; gambit - ("gosh" . geiser-gauche) ; gauche + ("gsi" . geiser-gambit) + ("gosh" . geiser-gauche) ("guile" . geiser-guile) ("kawa" . geiser-kawa) ("mit-scheme" . geiser-mit) @@ -2003,31 +1921,32 @@ call `zzz-to-char'." ;; and install the proper helper package (straight-use-package (cdr scheme)))) (nreverse schemes))) - acdw/schemes))) + acdw/schemes)) + (:file-match (rx ".rkt" eos) + (rx ".scm" eos))) (setup (:straight-if ledger-mode (executable-find "ledger"))) (setup (:straight-if pkgbuild-mode - (executable-find "makepkg"))) + (executable-find "makepkg")) + (:file-match "PKGBUILD")) (setup (:straight-if sly - (progn (defvar acdw/lisp-bin - (or (executable-find "sbcl") - (executable-find "clisp") - "")) - (executable-find acdw/lisp-bin))) - + (progn + (defvar acdw/lisps + (let (lisps) + (dolist (lisp '("sbcl" ; TODO: add more lisps + "clisp")) + (when-let (binary (executable-find lisp)) + (push binary lisps))) + (nreverse lisps))) + acdw/lisps)) + (:also-load sly-autoloads) + (:straight clhs) + (:option inferior-lisp-program acdw/lisp-bin sly-kill-without-query-p t) - - (:also-load sly-autoloads) - (setup (:straight clhs)) - - (:with-feature sly-mrepl - (dolist (key '("RET" "")) - (:bind key sly-mrepl-return-at-end)) - (:bind "C-c C-c" sly-mrepl-return)) (defun sly-mrepl-return-at-end () (interactive) @@ -2035,7 +1954,12 @@ call `zzz-to-char'." (sly-mrepl-return) (if (bound-and-true-p paredit-mode) (paredit-newline) - (electric-newline-and-maybe-indent))))) + (electric-newline-and-maybe-indent)))) + + (:with-feature sly-mrepl + (dolist (key '("RET" "")) + (:bind key #'sly-mrepl-return-at-end)) + (:bind "C-c C-c" #'sly-mrepl-return))) (setup (:straight-if systemd (executable-find "systemd"))) diff --git a/lisp/acdw-modeline.el b/lisp/acdw-modeline.el index 44bb889..5aa0a18 100644 --- a/lisp/acdw-modeline.el +++ b/lisp/acdw-modeline.el @@ -173,6 +173,11 @@ is, if point < mark." (if-let ((backend (vc-backend buffer-file-name))) (substring vc-mode (+ (if (eq backend 'Hg) 2 3) 2)))) +(defun acdw-modeline/wc () + "Display current `wc-buffer-stats'." + (when (bound-and-true-p wc-mode) + (or wc-buffer-stats "[w]"))) + (defun acdw-modeline/winum () "Show the `winum' number of the current window in the modeline. Only shows if there is more than one window."