From 4cf60c3fea16b60eb18c9a7d8403b75c89aeffef Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Fri, 21 Oct 2022 21:37:30 -0500 Subject: blhe --- init.el | 479 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 399 insertions(+), 80 deletions(-) (limited to 'init.el') diff --git a/init.el b/init.el index 3cbf3cc..101e220 100644 --- a/init.el +++ b/init.el @@ -10,57 +10,189 @@ ;; - Make good choices. (yoke +emacs (locate-user-emacs-file "lisp/") - (require '+emacs) + (require* '+emacs '+window) ;; Settings - (setq truncate-string-ellipsis "…" - ring-bell-function #'ignore - read-file-name-completion-ignore-case t) + (setf truncate-string-ellipsis "…" + ring-bell-function #'ignore + read-file-name-completion-ignore-case t + comment-auto-fill-only-comments t + password-cache t + password-cache-expiry (* 60 60)) + ;; "Safe" variables + (dolist (var+pred + '((browse-url-browser-function + ;; All types defined by custom are safe. + . (lambda (f) + ;; Whooooo boy + (memq f (mapcar (lambda (i) + (plist-get (cdr i) :value)) + (seq-filter + (lambda (i) + (eq (car i) 'function-item)) + (cdr (get 'browse-url-browser-function + 'custom-type))))))))) + (put (car var+pred) 'safe-local-variable (cdr var+pred))) ;; Keys - (define-keys (current-global-map) + (define-key* (current-global-map) "C-x C-k" #'kill-current-buffer "C-/" #'undo-only "C-?" #'undo-redo "C-x C-c" #'+save-buffers-quit "M-SPC" #'+cycle-spacing - "M-/" #'hippie-expand + ;; "M-/" #'hippie-expand ; `hippie-completing-read' "M-=" #'count-words "C-x C-b" #'ibuffer "C-x 4 n" #'clone-buffer "S-" #'mouse-set-mark "C-x 0" #'+delete-window-or-bury-buffer "M-j" nil - "" nil) + "" nil + "M-o" #'other-window|switch-buffer) + (define-key* text-mode-map + "C-M-k" #'kill-paragraph) ;; Hooks - (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) + (add-hook 'after-save-hook + #'executable-make-buffer-file-executable-if-script-p) (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) (add-hook 'find-file-not-found-functions #'+auto-create-missing-dirs) + (add-hook 'text-mode-hook #'abbrev-mode) + (add-hook 'find-file-hook #'+vc-off-when-remote) ;; Advice - (add-function :after after-focus-change-function #'+save-some-buffers-debounce) - (advice-add 'keyboard-escape-quit :around #'keyboard-escape-quit-keep-window-open) + (add-function :after after-focus-change-function + #'+save-some-buffers-debounce) + (advice-add 'keyboard-escape-quit :around + #'keyboard-escape-quit-keep-window-open) (define-advice keyboard-escape-quit (:around (fn &rest r)) "Don't close quits on `keyboard-escape-quit'." (let ((buffer-quit-function #'ignore)) (apply fn r))) + (advice-add 'indent-region :before #'with-region-or-buffer) ;; Themes (load-theme 'modus-operandi) (set-face-attribute 'default nil :family "Comic Code" :height 100) - (set-face-attribute 'variable-pitch nil :family "Comic Code" :height 100)) + (set-face-attribute 'bold nil :family "Comic Code" :weight 'bold) + (set-face-attribute 'variable-pitch nil :family "Comic Code") + ;; Modes + (winner-mode)) + +(yoke whitespace nil + (setf whitespace-line-column nil + whitespace-style '( face trailing + tabs tab-mark + indentation + space-after-tab space-before-tab)) + (defun +whitespace-mode-for-writable-buffers () + "Turn on `whitespace-mode' if the buffer is writable, off otherwise." + (whitespace-mode (if buffer-read-only -1 t))) + (add-hook* '(text-mode-hook + prog-mode-hook + read-only-mode-hook) + #'+whitespace-mode-for-writable-buffers) + (add-hook 'before-save-hook #'whitespace-cleanup) + (define-advice whitespace-cleanup (:around (fn &rest r) preserve-point) + (let ((col (current-column))) + (apply fn r) + (move-to-column col t) + (set-buffer-modified-p nil)))) + +(yoke elisp-mode nil + (setf eval-expression-print-length nil + eval-expression-print-level nil) + (define-key* '(emacs-lisp-mode-map lisp-interaction-mode-map) + "C-c C-c" #'eval-defun + "C-c C-k" (defun +elisp-eval-region-or-buffer () + (interactive) + (cond + ((region-active-p) + (eval-region (region-beginning) (region-end)) + (message "Region evaluated.")) + (t + (eval-buffer) + (message "Buffer %s evaluated." (buffer-name))))) + "C-c C-z" #'ielm) + (define-advice eval-region (:around (fn beg end &rest args) pulse) + (apply fn beg end args) + (pulse-momentary-highlight-region beg end))) (yoke isearch nil - (define-keys (current-global-map) + (define-key* (current-global-map) "C-s" #'isearch-forward-regexp "C-r" #'isearch-backward-regexp "C-M-s" #'isearch-forward "C-M-r" #'isearch-backward)) +(yoke ispell nil + (eval-after ispell + (require '+ispell) + (add-hook 'before-save-hook #'+ispell-move-buffer-words-to-dir-locals-hook)) + (setf ispell-program-name (or (executable-find "ispell") + (executable-find "aspell"))) + (put 'ispell-buffer-session-localwords + 'safe-local-variable #'+ispell-safe-local-p)) + + +(yoke mouse nil + ;; 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) + (setf context-menu-functions '(context-menu-ffap + context-menu-region + context-menu-undo + ;; context-menu-dictionary + )) + (context-menu-mode +1)) + (dolist (click '(;; Fix scrolling in the margin + wheel-down double-wheel-down triple-wheel-down + wheel-up double-wheel-up triple-wheel-up)) + (global-set-key (vector 'right-margin click) 'mwheel-scroll) + (global-set-key (vector 'left-margin click) 'mwheel-scroll))) + +(yoke dired nil + (require 'dired-x) + (setf dired-recursive-copies 'always + dired-recursive-deletes 'always + dired-create-destination-dirs 'always + dired-do-revert-buffer t + dired-hide-details-hide-symlink-targets nil + dired-isearch-filenames 'dwim + delete-by-moving-to-trash t + dired-auto-revert-buffer t + dired-listing-switches "-AlF" + ls-lisp-dirs-first t + dired-ls-F-marks-symlinks t + dired-clean-confirm-killing-deleted-buffers nil + dired-no-confirm '(byte-compile + load chgrp chmod chown + copy move hardlink symlink + shell touch) + dired-dwim-target t) + (setq-local-hook dired-mode-hook + truncate-lines t) + (define-key* (current-global-map) + "C-x C-j" #'dired-jump) + (eval-after dired + (define-key* dired-mode-map + "" #'dired-up-directory + "C-j" #'dired-up-directory)) + (add-hook* 'dired-mode-hook + #'dired-hide-details-mode + #'hl-line-mode)) + +(yoke dired-hacks "https://github.com/Fuco1/dired-hacks" + (define-key* dired-mode-map + "TAB" #'dired-subtree-sycle + "i" #'dired-subtree-toggle) + (add-hook* 'dired-mode-hook + #'dired-collapse-mode)) + (yoke auth-source nil - (setq auth-sources `(default "secrets:passwords")) + (setf auth-sources `(default "secrets:passwords")) (setq-local-hook authinfo-mode-hook truncate-lines t)) (yoke consult "https://github.com/minad/consult" (require 'consult) - (setq register-preview-delay 0 + (setf register-preview-delay 0 register-preview-function #'consult-register-format xref-show-xrefs-function #'consult-xref tab-always-indent 'complete @@ -68,7 +200,7 @@ consult-narrow-key "<" consult--regexp-compiler #'consult--default-regexp-compiler) (advice-add #'register-preview :override #'consult-register-window) - (define-keys (current-global-map) + (define-key* (current-global-map) ;; C-c bindings (mode-specific-map) "C-c h" #'consult-history "C-c m" #'consult-mode-command @@ -111,89 +243,123 @@ ;; Isearch integration "M-s e" #'consult-isearch-history) (eval-after isearch-mode - (define-keys isearch-mode-map + (define-key* isearch-mode-map "M-e" #'consult-isearch-history "M-s e" #'consult-isearch-history "M-s l" #'consult-line "M-s L" #'consult-line-multi)) (eval-after org - (define-key org-mode-map (kbd "M-g o") #'consult-org-heading))) + (define-key org-mode-map (kbd "M-g o") #'consult-org-heading)) + (setf (alist-get ?y (plist-get (alist-get 'emacs-lisp-mode + consult-imenu-config) + :types)) + '("Yoke"))) (yoke orderless "https://github.com/oantolin/orderless" (require 'orderless) - (setq completion-styles '(substring orderless basic) + (setf completion-styles '(substring orderless basic) completion-category-defaults nil - completion-category-overrides '((file (styles basic partial-completion))) + completion-category-overrides + '((file (styles basic partial-completion))) orderless-component-separator #'orderless-escapable-split-on-space)) (yoke vertico "https://github.com/minad/vertico" (require 'vertico) - (setq resize-mini-windows 'grow-only + (setf resize-mini-windows 'grow-only vertico-count-format nil vertico-cycle t) (vertico-mode)) +(yoke embark "https://github.com/oantolin/embark" + (require 'embark) + (setf prefix-help-command #'embark-prefix-help-command + embar-keymap-prompter-key ";") + (define-key* (list (current-global-map) + 'minibuffer-local-map) + "C-." #'embark-act + "M-." #'embark-dwim + " B" #'embark-bindings) + (define-key* embark-file-map + "l" #'vlf) + (eval-after (embark consult) + (require 'embark-consult) + (add-hook 'embark-collect-mode-hook #'consult-preview-at-point-mode))) + (yoke marginalia "https://github.com/minad/marginalia/" (marginalia-mode)) +(yoke wgrep "https://github.com/mhayashi1120/Emacs-wgrep" + (require 'wgrep)) + (yoke slime "https://github.com/slime/slime" ;; r7rs-swank (let ((r7rsloc (yoke-git "https://github.com/ecraven/r7rs-swank"))) (cond ((executable-find "chibi-scheme") (defun chibi-scheme-start-swank (file encoding) - (format "%S\n\n" `(start-swank ,file))) + (format "%S\n\n" `(start-swank ,file))) (setq slime-lisp-implementations - (cons `(chibi-scheme - ("chibi-scheme" ,(format "-A%s" r7rsloc) - "-m" "(chibi-swank)") - :init chibi-scheme-start-swank) - (bound-and-true-p slime-lisp-implementations))))))) + (cons `(chibi-scheme + ("chibi-scheme" ,(format "-A%s" r7rsloc) + "-m" "(chibi-swank)") + :init chibi-scheme-start-swank) + (bound-and-true-p slime-lisp-implementations))))))) (yoke puni "https://github.com/amaikinono/puni" - (puni-global-mode) - (electric-pair-mode) - (define-keys puni-mode-map + (define-key* puni-mode-map "C-)" #'puni-slurp-forward "C-(" #'puni-slurp-backward "C-}" #'puni-barf-forward - "C-{" #'puni-barf-backward)) + "C-{" #'puni-barf-backward + "M-(" (defun +puni-open-then-slurp-forward (&optional n) + (interactive "p") + (insert "()") + (backward-char) + (puni-slurp-forward n))) + (electric-pair-mode) + (add-hook* '(prog-mode-hook + ielm-mode-hook) + #'puni-mode)) (yoke hungry-delete "https://github.com/nflath/hungry-delete" (setq hungry-delete-chars-to-skip " \t" - hungry-delete-join-reluctantly nil) + hungry-delete-join-reluctantly nil) (eval-after hungry-delete (add-to-list* 'hungry-delete-except-modes - 'eshell-mode - 'nim-mode - 'python-mode)) + #'eshell-mode + #'nim-mode + #'python-mode)) (defun +hungry-delete-or (hd-fn fn arg) (funcall (if (looking-back (format "[%s]" hungry-delete-chars-to-skip) arg) - hd-fn - fn) - arg)) - (define-keys puni-mode-map + hd-fn + fn) + arg)) + (define-key* puni-mode-map [remap puni-backward-delete-char] (defun puni@hungry-delete-backward (arg) (interactive "p") (+hungry-delete-or #'hungry-delete-backward - #'puni-backward-delete-char - arg)) + #'puni-backward-delete-char + arg)) [remap puni-forward-delete-char] (defun puni@hungry-delete-forward (arg) (interactive "p") (+hungry-delete-or #'hungry-delete-forward - #'puni-forward-delete-char - arg))) + #'puni-forward-delete-char + arg))) (global-hungry-delete-mode)) (yoke cape "https://github.com/minad/cape" - (defun cape-insinuate () - (add-to-list* 'completion-at-point-functions - #'cape-dabbrev - #'cape-file)) - (add-hook* '(text-mode-hook prog-mode-hook) - #'cape-insinuate)) + ;; Insinuate in a lot of modes + (defvar +capes '(cape-file cape-dabbrev)) + (defun +cape-insinuate (hook capf &optional capes) + "Insinuate CAPES into a HOOK along with CAPF function. +CAPES defaults to `+capes'. CAPF will be made un-exclusive." + (setq-local-hook hook + completion-at-point-functions + (apply #'list (cape-capf-properties capf :exclusive 'no) + (or capes +capes)))) + (+cape-insinuate 'emacs-lisp-mode-hook #'elisp-completion-at-point)) (yoke minions "https://github.com/tarsius/minions" (minions-mode)) @@ -204,10 +370,13 @@ (locate-user-emacs-file "yoke/transient/lisp")) (dash "https://github.com/magnars/dash.el") (with-editor "https://github.com/magit/with-editor" - (locate-user-emacs-file "yoke/with-editor/lisp"))) + (locate-user-emacs-file "yoke/with-editor/lisp"))) (autoload #'transient--with-suspended-override "transient") (autoload #'magit "magit" nil :interactive)) +(yoke git-modes "https://github.com/magit/git-modes" + (require 'git-modes)) + (yoke visual-fill-column "https://codeberg.org/joostkremers/visual-fill-column" (setq visual-fill-column-center-text t) (add-hook* 'visual-fill-column-mode-hook #'visual-line-mode) @@ -219,7 +388,8 @@ (locate-user-emacs-file "yoke/org-contrib/lisp"))) ;; DON'T load system org (setq load-path - (cl-remove-if (lambda (path) (string-match-p "lisp/org\\'" path)) load-path)) + (cl-remove-if (lambda (path) (string-match-p "lisp/org\\'" path)) + load-path)) (setq org-adapt-indentation nil org-auto-align-tags t org-archive-mark-done t @@ -279,29 +449,24 @@ ("=" org-verbatim) ("~" org-code) ("+" org-strikethrough))) - ;; (setq org-todo-keywords - ;; '((sequence - ;; "TODO(t)" - ;; "NEXT(n!)" ; next action - ;; "DONE(d)" ; done) - ;; (sequence - ;; "WAIT(w@)" ; waiting to be actionable again - ;; "HOLD(h@/!)" ; actinable, but will do later - ;; "IDEA(i)" ; maybe someday - ;; "KILL(k@/!)" ; cancelled, aborted or is no longer applicable - ;; )))))) (add-hook* 'org-mode-hook - #'variable-pitch-mode - #'visual-fill-column-mode - #'turn-off-auto-fill - #'org-indent-mode - #'prettify-symbols-mode - #'abbrev-mode) + #'variable-pitch-mode + #'visual-fill-column-mode + #'turn-off-auto-fill + #'org-indent-mode + #'prettify-symbols-mode + #'abbrev-mode) + (define-local-before-save-hook org-mode + (org-hide-drawer-all) + (org-align-tags 'all)) (eval-after org (require '+org) - (define-keys org-mode-map + (define-key* org-mode-map "C-M-k" #'kill-paragraph - "C-M-t" #'transpose-paragraphs) + "C-M-t" #'transpose-paragraphs + "RET" #'+org-return-dwim + "S-" #'+org-table-copy-down|+org-return + "C-c C-o" #'+org-open-at-point-dwim) (org-clock-persistence-insinuate))) (yoke org-agenda nil @@ -323,14 +488,23 @@ org-agenda-show-future-repeats 'next org-agenda-window-setup 'current-window) (setq-local-hook org-agenda-mode-hook - truncate-lines t) - (add-hook 'org-agenda-after-show-hook #'org-narrow-to-subtree)) + truncate-lines t + electric-pair-pairs (append electric-pair-pairs + (mapcar (lambda (e) + (let ((ch (string-to-char (car e)))) + (cons ch ch))) + org-emphasis-alist))) + (add-hook* 'org-agenda-mode-hook + #'hl-line-mode) + (add-hook 'org-agenda-after-show-hook #'org-narrow-to-subtree) + (define-key* (current-global-map) + "C-c c" #'org-capture + "C-c a" #'org-agenda)) (yoke ox nil ; org-export (eval-after org (require 'ox)) (eval-after ox - (require '+ox) - (require 'ox-md nil :noerror) + (require* '+ox '(ox-md nil t)) (+org-export-pre-hooks-insinuate)) (setq org-export-coding-system 'utf-8-unix org-export-headline-levels 8 @@ -340,6 +514,11 @@ org-export-with-sub-superscripts t org-export-with-toc nil)) +(yoke electric-cursor "https://codeberg.org/acdw/electric-cursor.el" + (setq electric-cursor-alist '((overwrite-mode . hbar) + (t . bar))) + (electric-cursor-mode)) + (yoke _work (sync/ "emacs/private") :depends ((+org-capture (locate-user-emacs-file "lisp")) (private (locate-user-emacs-file "lisp")) @@ -347,27 +526,167 @@ (locate-user-emacs-file "yoke/bbdb/lisp")) (bbdb-vcard "https://github.com/tohojo/bbdb-vcard/")) (require 'bbdb) - (require 'private) - (require '_work) + (require* 'private 'work) (bbdb-initialize 'gnus 'message) (setq bbdb-complete-mail-allow-cycling t)) (yoke org-taskwise "https://codeberg.org/acdw/org-taskwise.el") (yoke titlecase "https://codeberg.org/acdw/titlecase.el" - (eval-after org (require 'titlecase)) + (eval-after org (require* 'titlecase '+titlecase)) (eval-after titlecase - (require '+titlecase) (add-to-list* 'titlecase-skip-words-regexps (rx word-boundary (+ (any upper digit)) word-boundary)))) (yoke flyspell-correct "https://github.com/duckwork/flyspell-correct" (eval-after flyspell - (require 'flyspell-correct) - (require '+flyspell-correct) - (define-keys flyspell-mode-map + (require* 'flyspell-correct + `(+flyspell-correct ,(locate-user-emacs-file "lisp/+flyspell-correct"))) + (define-key* flyspell-mode-map "C-;" #'flyspell-correct-wrapper "" #'+flyspell-correct-buffer)) (add-hook 'org-mode-hook #'flyspell-mode) (setq flyspell-correct--cr-key ";")) + +(yoke helpful "https://github.com/Wilfred/helpful" + :depends ((dash "https://github.com/magnars/dash.el") + (f "https://github.com/rejeep/f.el") + (s "https://github.com/magnars/s.el") + (elisp-refs "https://github.com/Wilfred/elisp-refs")) + (define-key* (current-global-map) + " f" #'helpful-callable + " v" #'helpful-variable + " k" #'helpful-key + " ." #'helpful-at-point + " o" #'helpful-symbol) + (unless (featurep 'info-look) + (run-with-idle-timer 1 nil (lambda () + (require 'info-look) + (let ((inhibit-message t)) + (info-lookup-setup-mode 'symbol + 'emacs-lisp-mode))))) + (setf (alist-get "\\*helpful" display-buffer-alist nil nil #'string=) + '((display-buffer-in-side-window) + (side . bottom) + (window-height . 20)))) + +(yoke hippie-completing-read + "https://codeberg.org/acdw/hippie-completing-read.el" + (define-key* (current-global-map) + "M-/" #'hippie-completing-read)) + +(yoke dictionary nil ; Comes with Emacs 29! + (setq dictionary-server "localhost") ; Needs local dictd + (setf (alist-get "^\\*Dictionary\\*" display-buffer-alist nil nil #'string=) + '((display-buffer-in-side-window) + (side . bottom) + (window-height . 20)))) + +(yoke anzu "https://github.com/emacsorphanage/anzu" + (global-anzu-mode) + (define-key* (current-global-map) + [remap query-replace] #'anzu-query-replace-regexp + [remap query-replace-regexp] #'anzu-query-replace) + (define-key* isearch-mode-map + [remap isearch-query-replace] #'anzu-isearch-query-replace-regexp + [remap isearch-query-replace-regexp] #'anzu-isearch-query-replace) + (defun anzu-qr@window (fn &rest r) + "ADVICE to query-replace from the beginning of the window." + (let ((scroll-margin 0)) + (save-excursion + (goto-char (window-start)) + (apply fn r)))) + (advice-add 'anzu-query-replace-regexp :around #'anzu-qr@window) + (advice-add 'anzu-query-replace :around #'anzu-qr@window)) + +(yoke tempo nil + (require '+tempo)) + +;; (yoke tempel "https://github.com/minad/tempel" +;; ;; I would use `tempo' but it's clunkier .. :( +;; (define-key* (current-global-map) +;; "M-+" #'tempel-complete +;; "M-_" #'tempel-insert) +;; (defun tempel-capf-insinuate () +;; (setq-local completion-at-point-functions +;; (cons #'tempel-expand +;; completion-at-point-functions))) +;; (add-hook* '(prog-mode-hook +;; text-mode-hook) +;; #'tempel-capf-insinuate)) + +(yoke scule (locate-user-emacs-file "lisp") + (defvar scule-map (let ((map (make-sparse-keymap))) + (define-key map (kbd "M-u") #'scule-upcase) + (define-key map (kbd "M-l") #'scule-downcase) + (define-key map (kbd "M-c") #'scule-capitalize) + map) + "Keymap for scule twiddling.") + (define-key* (current-global-map) + "M-c" scule-map + "M-u" #'universal-argument) + (define-key universal-argument-map (kbd "M-u") #'universal-argument-more)) + +(yoke 0x0 "https://gitlab.com/willvaughn/emacs-0x0" + (setf 0x0-default-server 'ttm) + (eval-after embark + (define-key* embark-region-map + "U" #'0x0-dwim))) + +(yoke filldent "https://codeberg.org/acdw/filldent.el" + (define-key* (current-global-map) + "M-q" #'filldent-unfill-toggle)) + +(yoke avy "https://github.com/abo-abo/avy" + (require 'avy) + (setf avy-background t + (alist-get ?. avy-dispatch-alist) + (defun avy-action-embark (pt) + (unwind-protect + (save-excursion + (goto-char pt) + (embark-act)) + (select-window + (cdr (ring-ref avy-ring 0)))) + t)) + (define-key* (current-global-map) + "M-j" #'avy-goto-char-timer) + (define-key* isearch-mode-map + "M-j" #'avy-isearch)) + +(yoke frowny "https://codeberg.org/acdw/frowny.el" + (setf frowny-eyes (rx (any ":=") (opt "'") (? "-"))) + (global-frowny-mode)) + +(yoke isearch-mb "https://github.com/astoff/isearch-mb" + (eval-after (consult anzu) + (require '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)) + +(yoke keepassxc-shim "https://codeberg.org/acdw/keepassxc-shim.el" + (keepassxc-shim-activate)) + +(yoke keychain-environment "https://github.com/tarsius/keychain-environment" + :when (executable-find "keychain") + (keychain-refresh-environment)) + +(yoke macrostep "https://github.com/joddie/macrostep" + (eval-after elisp-mode (require 'macrostep)) + (define-key* '(emacs-lisp-mode-map + lisp-interaction-mode-map) + "C-c e" #'macrostep-expand)) -- cgit 1.4.1-21-gabe81