aboutsummaryrefslogtreecommitdiff
path: root/tw/home/files/emacs-init.el
diff options
context:
space:
mode:
Diffstat (limited to 'tw/home/files/emacs-init.el')
-rw-r--r--tw/home/files/emacs-init.el1027
1 files changed, 0 insertions, 1027 deletions
diff --git a/tw/home/files/emacs-init.el b/tw/home/files/emacs-init.el
deleted file mode 100644
index 0f20782d..00000000
--- a/tw/home/files/emacs-init.el
+++ /dev/null
@@ -1,1027 +0,0 @@
-;;; init.el --- Emacs configuration. -*- lexical-binding: t -*-
-;;; Commentary:
-;;; Code:
-
-(startup-redirect-eln-cache
- (expand-file-name "emacs/eln" (or (getenv "XDG_CACHE_HOME") "~/.cache/")))
-(add-hook 'after-init-hook #'native-compile-prune-cache)
-
-;; Load settings set through Custom.
-;; (setq custom-file (locate-user-emacs-file "custom.el"))
-;; (when (file-readable-p custom-file)
-;; (load custom-file))
-
-(defun tw/xdg-emacs-subdir (type name &optional create)
- "Get the name of a file or directory called NAME under $XDG_<TYPE>_HOME/emacs.
-If CREATE is true and the resulting directory does not exist, create it."
- (let ((dir (expand-file-name
- (concat "emacs/" (string-trim-right name "/"))
- (pcase type
- ('cache (or (getenv "XDG_CACHE_HOME") "~/.cache/"))
- ('config (or (getenv "XDG_CONFIG_HOME") "~/.config/"))
- ('data (or (getenv "XDG_DATA_HOME") "~/.local/share/"))
- ;; The following two are Guix/GuixSD extensions.
- ('log (or (getenv "XDG_LOG_HOME") "~/.local/var/log/"))
- ('state (or (getenv "XDG_STATE_HOME") "~/.local/var/lib/"))
- (_ (error "Unknown XDG directory type: %S" type))))))
- (when (and create (not (file-accessible-directory-p dir)))
- (make-directory dir t))
- dir))
-
-;; Global/built-in Custom settings
-;; Apply these as early as possible so that e.g. the native-comp files go to the right place.
-(mapc (apply-partially #'apply #'customize-set-variable)
- `((native-comp-async-report-warnings-errors silent "Don't pop up Warnings buffer for native compilation.")
- ;; Emacs GUI customization.
- (inhibit-startup-screen t "Don't show the startup screen with help links.")
- (menu-bar-mode nil "Hide the menu bar globally.")
- (tool-bar-mode nil "Hide the tool bar globally.")
- (tooltip-mode nil "Show tooltips in the echo area instead.")
- (max-mini-window-height 3 "Let the echo area grow to a maximum of 3 lines, e.g. when using `eldoc-mode'.")
- (scroll-up-aggressively 0.0 "Don't recenter the window if the point moves off the page.")
- (scroll-down-aggressively 0.0 "Don't recenter the window if the point moves off the page.")
- (pixel-scroll-precision-mode t "Enable pixel-by-pixel scrolling, e.g. to handle inline images.")
- ;; Niceties.
- (tramp-default-method "scpx" "ssh and scp hang forever. scpx is faster than sshx for large files.")
- (global-hl-line-mode t "Highlight the current line in all buffers.")
- (indicate-empty-lines t "Show a little marker in the margin for lines past EOF.")
- (column-number-mode t "Show the column number in the statusline.")
- (electric-pair-mode t "Auto-pair suitable characters like parentheses.")
- (tab-always-indent complete "Enable completion-on-tab.")
- (completion-cycle-threshold 6 "Allow cycling through completions if there are 6 or fewer of them.")
- (completion-styles (basic partial-completion) "Enable fast completion styles.")
- (shell-kill-buffer-on-exit t "Kill *shell* buffers as soon as their shell session exits.")
- ;; Indentation, formatting.
- (indent-tabs-mode nil "Always use spaces to indent.")
- (sentence-end-double-space nil "Use a single space after a sentence.")
- (fill-column 78 "Make hard-wrapped text a bit wider.")
- (require-final-newline t "Always add a final newline on save, if there is none.")
- ;; Make Emacs a good Guix citizen.
- (package-archives nil "Don't fetch packages from the internet; only get them from Guix.")
- ;; Default mode.
- (major-mode text-mode "Use `text-mode' by default in new buffers, not `fundamental-mode'.")
- ;; Recent files and history. Keep them out of ~/.config.
- (package-user-dir ,(tw/xdg-emacs-subdir 'data "elpa") "Save ELPA-related files here.")
- (auto-save-list-file-prefix ,(tw/xdg-emacs-subdir 'data "auto-save-list/saves-") "Put auto-save lists here.")
- (make-backup-files nil "Don't create backup files. They're annoying.")
- (backup-directory-alist (("." . ,(tw/xdg-emacs-subdir 'data "backup"))) "Put backup files in a sensible place.")
- (backup-by-copying t "Avoid breaking hardlinks when making backup files.")
- (auto-save-file-name-transforms
- ;; `file-name-as-directory' is important, since Emacs takes the directory part when UNIQUIFY is t.
- ((".*" ,(file-name-as-directory (tw/xdg-emacs-subdir 'data "auto-save" t)) t))
- "Put auto-save #files# in a sensible directory.")
- (recentf-max-saved-items 1000 "Save lots of recently-opened files.")
- (recentf-save-file ,(tw/xdg-emacs-subdir 'data "recentf.el") "Save recently-opened files here.")
- (recentf-mode t "Save recently-opened files.")
- (savehist-file ,(tw/xdg-emacs-subdir 'data "savehist.el") "Save minibuffer history here.")
- (savehist-mode t "Save minibuffer history on quit.")))
-
-(defalias 'yes-or-no-p #'y-or-n-p
- "Always use `y-or-n-p' when asking for confirmation.")
-
-;; Custom modes depending on file names.
-(mapc (apply-partially #'add-to-list 'auto-mode-alist)
- `((,(rx (or bos "/") "PKGBUILD" eos) . bash-ts-mode)
- (,(rx ".install" eos) . bash-ts-mode)
- (,(rx (or bos "/") "COMMIT_EDITMSG" eos) . diff-mode) ; useful for `git commit -v'
- (,(rx bos "/tmp/neomutt-") . mail-mode)
- (,(rx ".eml" eos) . mail-mode)
- (,(rx "." (1+ anything) "rc" eos) . conf-unix-mode)))
-
-(add-to-list 'magic-mode-alist
- `(,(rx "#!" (* (not space))
- (? "env" (+ space) (? "-S" (+ space)))
- (or "guile" "racket"))
- . scheme-mode))
-
-(add-hook 'mail-mode-hook #'auto-fill-mode)
-
-(defun tw/show-trailing-whitespace ()
- "Highlight trailing spaces in the current buffer."
- (setq-local show-trailing-whitespace t))
-
-(mapc (lambda (hook)
- (add-hook hook #'tw/show-trailing-whitespace))
- '(prog-mode-hook conf-mode-hook yaml-mode-hook alidist-mode-hook))
-
-(defun tw/enable-word-wrap ()
- "Enable word wrapping."
- (toggle-word-wrap +1))
-(add-hook 'markdown-mode-hook #'tw/enable-word-wrap)
-(add-hook 'org-mode-hook #'tw/enable-word-wrap)
-
-;; `use-package' requirements.
-(require 'package)
-(package-initialize t)
-(eval-when-compile
- (require 'use-package))
-(use-package diminish) ; for using :diminish later
-(use-package bind-key) ; for using :bind later
-
-;; Some packages below have `:commands (...) :demand t'.
-;; We need :commands for the byte-compiler, but we want to load the package immediately.
-
-(use-package gcmh ; "garbage collector magic hack": run GC when not in focus
- :config (gcmh-mode +1)
- :diminish gcmh-mode)
-
-;; Look and feel
-(set-face-attribute 'default nil :family "Hermit" :height 100)
-;; For some reason, Emacs doesn't detect italic support, and falls back to
-;; underlining. Stop it from doing this and use italics instead.
-(set-face-attribute 'italic nil :slant 'italic :underline nil)
-
-(use-package catppuccin-theme
- :load-path "./"
- :custom
- (catppuccin-flavor 'mocha "Use the darkest Catppuccin theme.")
- (catppuccin-italic-comments t "Make comments italic. It looks nicer.")
- (catppuccin-italic-variables t "Make variable names italic. It looks nicer.")
- :config (catppuccin-reload))
-
-(use-package smart-mode-line
- :hook (after-init . sml/setup)
- :custom
- (sml/no-confirm-load-theme t "Stop Emacs from constantly asking for user confirmation.")
- (sml/mode-width 'right "Move the minor-mode list to the right of the modeline.")
- (sml/theme 'respectful "Make `smart-mode-line' blend in with the active theme."))
-
-;; General editor behaviour.
-;; TODO: Move from ivy + counsel to vertico + orderless + consult + marginalia
-;; (+ embark?), to integrate better with vanilla Emacs and `completing-read'.
-;; https://github.com/minad/vertico -- light completion engine
-;; https://github.com/minad/vertico#child-frames-and-popups
-;; https://github.com/minad/vertico#complementary-packages
-;; https://github.com/minad/marginalia -- docstrings in M-x menu
-;; https://github.com/oantolin/orderless -- regex search for vertico
-;; https://github.com/minad/consult -- collection of commands using vertico
-;; https://github.com/oantolin/embark -- make vertico better depending on thing at point
-
-(use-package ivy
- :commands (ivy-mode) :demand t
- :custom
- (ivy-use-selectable-prompt t "Allow selecting the ivy input as-is.")
- (ivy-use-virtual-buffers t "Show recentf and bookmarks in buffers list.")
- :config (ivy-mode +1)
- :diminish ivy-mode)
-
-(use-package counsel ; extra niceties for `ivy-mode'
- :after (ivy evil) ; evil for :bind-ing to <leader>
- :bind (("<leader>SPC" . counsel-M-x) ; <leader><leader> doesn't work
- ("<leader>fr" . counsel-buffer-or-recentf)
- :map evil-visual-state-map
- ("<leader>SPC" . counsel-M-x))
- :commands (counsel-mode) :demand t
- :config (counsel-mode +1)
- :diminish counsel-mode)
-
-(use-package dash-docs
- :custom
- (dash-docs-docsets-path
- (file-name-as-directory (tw/xdg-emacs-subdir 'data "dash-docsets" t))
- "Store docsets in the XDG data directory.")
- (dash-docs-browser-func 'eww "Open documentation pages using `eww' instead of an external browser.")
- (dash-docs-enable-debugging nil "Disable popping up useless warnings."))
-
-(defun tw/counsel-dash-is-help ()
- "Install `counsel-dash-at-point' as `evil-lookup-func'."
- ;; Note: `evil-lookup-func' is already set to something else by
- ;; `tw/help-is-eldoc' for `eglot-mode'.
- (setq-local evil-lookup-func #'counsel-dash-at-point
- counsel-dash-docsets
- (cl-case major-mode
- (lisp-mode '("Common Lisp"))
- ((python-mode python-ts-mode) '("Python 3"))
- (c++-mode '("C++"))
- (cmake-mode '("CMake"))
- (puppet-mode '("Puppet"))
- (yaml-mode '("Ansible"))
- (tcl-mode '("Tcl"))
- (html-mode '("HTML" "CSS"))
- ((css-mode css-ts-mode) '("CSS"))
- (web-mode '("HTML" "CSS")))))
-
-(use-package counsel-dash
- :after (dash-docs which-key)
- :commands (counsel-dash-at-point) :demand t
- :init (which-key-add-key-based-replacements
- "<leader>d" '("docs" . "Documentation"))
- :bind (("<leader>K" . counsel-dash-at-point)
- ("<leader>dK" . counsel-dash)
- ("<leader>di" . counsel-dash-install-docset)
- ("<leader>da" . counsel-dash-activate-docset)
- ("<leader>dd" . counsel-dash-deactivate-docset))
- :hook (( lisp-mode python-mode python-ts-mode cmake-mode c++-mode puppet-mode yaml-mode
- tcl-mode html-mode css-mode css-ts-mode web-mode)
- . tw/counsel-dash-is-help)
- :config
- ;; Activate all installed docsets by default.
- (setq counsel-dash-common-docsets (dash-docs-installed-docsets)))
-
-(use-package rainbow-mode
- :after (evil)
- :bind (("<leader>tR" . rainbow-mode)))
-
-(use-package form-feed
- :commands (global-form-feed-mode) :demand t
- :config (global-form-feed-mode +1)
- :diminish form-feed-mode)
-
-(use-package display-line-numbers
- ;; Included in Emacs >= 26. Better than `linum-mode'.
- ;; There is also `global-display-line-numbers-mode', but that also
- ;; enables line numbers in help windows, which I don't want.
- :hook (prog-mode conf-mode yaml-mode alidist-mode))
-
-(use-package which-key
- :commands (which-key-mode) :demand t
- :config (which-key-mode +1)
- :diminish which-key-mode)
-
-(use-package undo-tree
- :after (evil) ; for our :bind-ing
- :bind (("<leader>U" . undo-tree-visualize))
- :custom
- (undo-tree-history-directory-alist
- `(("." . ,(file-name-as-directory (tw/xdg-emacs-subdir 'data "undo-tree-history"))))
- "Store all `undo-tree' history in a single directory, instead of next to the associated file.")
- :commands (global-undo-tree-mode)
- :demand t ; this is required so that the :config stanza is actually run asap despite :bind
- :config (global-undo-tree-mode +1)
- :diminish undo-tree-mode)
-
-;; IDE-like features.
-(use-package project
- :after (which-key evil)
- :init
- (which-key-add-key-based-replacements
- "<leader>p" '("project" . "Project"))
- (evil-define-key '(normal visual) 'global
- (kbd "<leader>fp") #'project-find-file) ; also <leader>pf
- :bind-keymap ("<leader>p" . project-prefix-map))
-
-(use-package vc
- :after (which-key evil)
- :init (which-key-add-key-based-replacements
- "<leader>v" '("vc" . "Version control")
- "<leader>vM" '("merge" . "Version control merging"))
- :bind-keymap ("<leader>v" . vc-prefix-map))
-
-(use-package log-edit
- :after (evil vc)
- :config
- (evil-define-key '(normal visual) log-edit-mode-map
- (kbd "<localleader>\\") #'log-edit-done
- (kbd "<localleader>a") #'log-edit-insert-changelog
- (kbd "<localleader>d") #'log-edit-show-diff
- (kbd "<localleader>f") #'log-edit-show-files
- (kbd "<localleader>k") #'log-edit-kill-buffer
- (kbd "<localleader>w") #'log-edit-generate-changelog-from-diff))
-
-(use-package company
- :config (global-company-mode +1)
- :diminish company-mode)
-
-(use-package company-quickhelp
- :after (company)
- :config (company-quickhelp-mode +1)
- :diminish company-quickhelp-mode)
-
-(use-package company-posframe
- :after (company)
- :config (company-posframe-mode +1)
- :diminish company-posframe-mode)
-
-(use-package flyspell
- :hook mail-mode)
-
-(use-package flymake
- :after (evil which-key)
- :demand t ; needed for `flymake-collection'
- :hook (prog-mode yaml-mode alidist-mode)
- :init (which-key-add-key-based-replacements
- "<leader>e" '("errors" . "Flymake"))
- :bind (("<leader>eb" . flymake-start)
- ("<leader>ec" . display-local-help) ; Show the error message at point in the minibuffer.
- ; `flymake' also shows it using `eldoc', but documentation
- ; seems to override error messages.
- ; `flymake-show-diagnostic' only says "Nothing at point".
- ("<leader>el" . flymake-show-buffer-diagnostics)
- ("<leader>ep" . flymake-show-project-diagnostics)
- ("<leader>en" . flymake-goto-next-error)
- ("<leader>eN" . flymake-goto-prev-error)
- ("<leader>ev" . flymake-running-backends)
- ("<leader>eV" . flymake-disabled-backends))
- :custom
- (flymake-suppress-zero-counters nil "Show severity counters even when they are zero."))
-
-(use-package flymake-collection
- :after (flymake)
- :demand t ; we need it loaded now
- ;; This needs to be called in `after-init-hook' so that all other
- ;; packages' `:flymake-hook's are processed before f-c-hook-setup is
- ;; called. See https://github.com/mohkale/flymake-collection.
- :hook (after-init . flymake-collection-hook-setup))
-
-;; Language Server Protocol.
-(defun tw/help-is-eldoc (&rest _)
- "Set up `evil-lookup-func' to display the `eldoc' buffer."
- (when (eglot-managed-p)
- (setq-local evil-lookup-func #'eldoc-doc-buffer)))
-
-(use-package eglot
- ;; I have clang (for clangd) and python-lsp-server installed.
- ;; `:hook' adds `-mode' to the package name, but `eglot-mode' doesn't exist.
- :hook (((python-mode python-ts-mode c-mode c++-mode c-or-c++-ts-mode) . eglot-ensure)
- (eglot-managed-mode . tw/help-is-eldoc))
- :commands (eglot)
- :functions (eglot-managed-p)
- :custom
- (eglot-autoshutdown t "Shut down language servers after deleting their last associated buffer.")
- (eglot-sync-connect 0.1 "Wait for the language server in the background if it takes longer than 100ms."))
-
-;; Tree-sitter
-;; TODO: Try any/all of the following new tree-sitter-based major modes.
-;; Enable them using the following, replacing the relevant "old" major mode:
-;; (add-to-list 'major-mode-remap-alist '(ruby-mode . ruby-ts-mode))
-;; New major mode 'css-ts-mode'.
-;; New major mode 'dockerfile-ts-mode'.
-;; New major mode 'ruby-ts-mode'.
-
-(mapc (lambda (dir)
- (add-to-list 'treesit-extra-load-path (file-name-as-directory (expand-file-name dir))))
- '("/run/current-system/profile/lib/tree-sitter"
- "~/.guix-home/profile/lib/tree-sitter"
- "~/.guix-profile/lib/tree-sitter"))
-
-(use-package treesit
- :custom
- (treesit-font-lock-level 4 "Enable Angry Fruit Salad mode."))
-
-;; Non-LSP language modes.
-(use-package c-ts-mode
- :init
- (add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
- (add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
- (add-to-list 'major-mode-remap-alist '(c-or-c++-mode . c-or-c++-ts-mode)))
-
-(use-package cmake-ts-mode
- :mode (rx (or (: (or bos "/") "CMakeLists.txt") ".cmake") eos))
-
-(use-package json-ts-mode
- :mode (rx ".json" eos)
- :config
- (evil-define-key '(normal visual) json-ts-mode-map
- (kbd "<localleader>==") #'json-pretty-print
- (kbd "<localleader>=b") #'json-pretty-print-buffer
- (kbd "<localleader>=o") #'json-pretty-print-ordered
- (kbd "<localleader>=B") #'json-pretty-print-buffer-ordered))
-
-(use-package gnuplot
- :commands (gnuplot-mode gnuplot-make-buffer)
- :mode ((rx ".gnuplot" eos) . gnuplot-mode))
-
-(use-package graphviz-dot-mode
- :mode (rx ".dot" eos)
- :custom (graphviz-dot-view-command "xdot %s" "Use xdot for previewing graphviz files."))
-
-(use-package haskell-mode
- :mode (rx (or ".hs" ".lhs" ".hsc" ".cpphs" ".c2hs") eos))
-
-(use-package hcl-mode
- :mode (rx "." (or "hcl" "nomad") eos))
-
-(use-package mmm-mode
- :commands (mmm-mode)
- ;; Don't highlight submodes specially at all. The default background is annoying.
- :custom-face (mmm-default-submode-face ((t (:background unspecified)))))
-
-(use-package puppet-mode
- :mode (rx ".pp" eos))
-
-(use-package python
- :after (flymake-collection)
- :commands (python-mode python-ts-mode)
- :mode (((rx ".py" (? (or ?\i ?\w)) eos) . python-ts-mode)
- ((rx ".aurora" eos) . python-ts-mode))
- :config
- ;; Disable all flymake-collection linters in Python modes, since eglot/pylsp
- ;; should take care of it. It doesn't do type checking, so enable mypy.
- (cl-dolist (mode '(python-ts-mode python-mode))
- (add-to-list 'flymake-collection-config `(,mode flymake-mypy))))
-
-(use-package rec-mode
- :mode (rx ".rec" eos))
-
-(use-package sh-script ; built-in
- ;; Use `bash-ts-mode' instead of `sh-mode' if possible.
- ;; `bash-ts-mode' falls back to `sh-mode' if necessary.
- ;; Manually configuring :mode etc would be annoying, since there are a lot of entries.
- :config (add-to-list 'major-mode-remap-alist '(sh-mode . bash-ts-mode))
- :custom (sh-basic-offset 2 "Use 2 spaces for `sh-mode' indents."))
-
-(use-package tcl
- :mode ((rx ".tcl" eos) . tcl-mode)
- :magic ((rx "#%Module1.0") . tcl-mode))
-
-(use-package web-mode
- :mode (rx "." (or "htm" "html" "js" "css" "scss") eos)
- :custom
- (web-mode-css-indent-offset 2 "Indent CSS by two spaces."))
-
-(use-package yaml-mode
- :mode (rx (or (seq ".y" (? "a") "ml")
- (seq "aliPublish" (* (not ?/)) ".conf"))
- eos))
-
-(defun tw/ledger-format-on-save ()
- "Re-indent the entire file."
- ;; Subset of `ledger-mode-clean-buffer'. That also sorts the buffer, which I don't want.
- (save-excursion
- (let ((start (point-min-marker))
- (end (point-max-marker)))
- (untabify start end)
- (ledger-post-align-postings start end)
- (ledger-mode-remove-extra-lines))))
-
-(defun tw/enable-ledger-format-on-save ()
- "Enable reformating the open file on save."
- (add-hook 'before-save-hook #'tw/ledger-format-on-save 0 t))
-
-(use-package ledger-mode
- :after (evil)
- :commands (ledger-mode)
- :mode (rx ".journal" eos)
- :hook (ledger-mode . tw/enable-ledger-format-on-save)
- :custom
- (ledger-default-date-format ledger-iso-date-format "Use hledger-style dates.")
- (ledger-reconcile-default-date-format ledger-iso-date-format "Use hledger-style dates.")
- (ledger-reconcile-default-commodity "€" "Make euros the default currency.")
- (ledger-post-account-alignment-column 2 "Use 2-space indents.")
- (ledger-post-amount-alignment-at :decimal "Align amounts at decimal points/commas.")
- (ledger-post-amount-alignment-column 52 "Align amounts' decimal points to the 52nd column.")
- (ledger-highlight-xact-under-point nil "Don't highlight the transaction at point.")
- :config
- (evil-define-key 'normal ledger-mode-map
- (kbd "TAB") #'ledger-indent-line))
-
-(use-package lisp
- :init (which-key-add-key-based-replacements
- "<leader>k" '("sexp-nav" . "S-expression navigation"))
- :bind (("<leader>kl" . forward-sexp)
- ("<leader>kh" . backward-sexp)
- ("<leader>kL" . forward-list)
- ("<leader>kH" . backward-list)
- ("<leader>kj" . down-list)
- ("<leader>kk" . up-list)
- ("<leader>kK" . backward-up-list)
- ("<leader>kd" . kill-sexp)
- ("<leader>kD" . backward-kill-sexp)
- ("<leader>kb" . beginning-of-defun)
- ("<leader>kB" . beginning-of-defun-comments)
- ("<leader>ke" . end-of-defun)
- ("<leader>kv" . mark-sexp)
- ("<leader>kV" . mark-defun)
- ("<leader>kN" . narrow-to-defun)
- ("<leader>ks" . insert-pair)
- ("<leader>kr" . raise-sexp)
- ("<leader>kc" . check-parens)))
-
-(defun tw/resize-repl-window ()
- "Make the REPL window small, so it stays out of the way."
- (shrink-window (- (window-height) 5)))
-
-(use-package geiser
- :after (evil)
- :commands (geiser
- geiser-eval-buffer geiser-eval-definition geiser-eval-region
- geiser-eval-last-sexp geiser-mode-switch-to-repl
- geiser-mode-switch-to-repl-and-enter)
- :hook ((scheme-mode . geiser-autodoc-mode)
- (geiser-repl-mode . tw/resize-repl-window))
- :config
- (evil-define-key '(normal visual) scheme-mode-map
- (kbd "<localleader>z") #'geiser-mode-switch-to-repl
- (kbd "<localleader>Z") #'geiser-mode-switch-to-repl-and-enter
- (kbd "<localleader>eb") #'geiser-eval-buffer
- (kbd "<localleader>ef") #'geiser-eval-definition
- (kbd "<localleader>er") #'geiser-eval-region
- (kbd "<localleader>el") #'geiser-eval-last-sexp)
- :defines scheme-mode-map)
-
-(use-package geiser-guile
- :after (geiser))
-
-(use-package sly
- :after (evil)
- :hook ((lisp-mode . sly-mode) ; `common-lisp-mode' is `lisp-mode'.
- (sly-mrepl-mode . tw/resize-repl-window))
- :config
- (evil-define-key '(normal visual) lisp-mode-map
- (kbd "<localleader>C-c") #'sly-interrupt
- (kbd "<localleader>z") #'sly
- (kbd "<localleader>Z") #'sly-mrepl-sync
- (kbd "<localleader>i") #'sly-inspect
- (kbd "<localleader>D") #'sly-disassemble-symbol
- (kbd "<localleader>E") #'sly-edit-value
- (kbd "<localleader>eT") #'sly-list-threads ; eval requests get a new thread each
- (kbd "<localleader>e:") #'sly-interactive-eval
- (kbd "<localleader>el") #'sly-eval-last-expression
- (kbd "<localleader>ep") #'sly-pprint-eval-last-expression
- (kbd "<localleader>eb") #'sly-eval-buffer
- (kbd "<localleader>ef") #'sly-eval-defun
- (kbd "<localleader>er") #'sly-eval-region
- (kbd "<localleader>eF") #'sly-compile-defun
- (kbd "<localleader>eB") #'sly-compile-file
- (kbd "<localleader>eL") #'sly-compile-and-load-file
- (kbd "<localleader>eR") #'sly-compile-region
- (kbd "<localleader>eU") #'sly-undefine-function
- (kbd "<localleader>eM") #'sly-remove-method
- (kbd "<localleader>dd") #'sly-describe-symbol
- (kbd "<localleader>df") #'sly-describe-function
- (kbd "<localleader>da") #'sly-apropos
- (kbd "<localleader>dA") #'sly-apropos-all
- (kbd "<localleader>dg") #'sly-edit-definition
- (kbd "<localleader>dC-o") #'sly-pop-find-definition-stack
- (kbd "<localleader>dG") #'sly-edit-uses
- (kbd "<localleader>dwc") #'sly-who-calls
- (kbd "<localleader>dwC") #'sly-calls-who
- (kbd "<localleader>dwr") #'sly-who-references
- (kbd "<localleader>dwb") #'sly-who-binds
- (kbd "<localleader>dws") #'sly-who-sets
- (kbd "<localleader>dwm") #'sly-who-macroexpands
- (kbd "<localleader>dwS") #'sly-who-specializes
- (kbd "<localleader>dhs") #'hyperspec-lookup ; hyperspec.el is bundled with sly; opens in browser
- (kbd "<localleader>dhf") #'hyperspec-lookup-format
- (kbd "<localleader>dhm") #'hyperspec-lookup-reader-macro
- (kbd "<localleader>cl") #'sly-list-connections
- (kbd "<localleader>cn") #'sly-next-connection
- (kbd "<localleader>cp") #'sly-prev-connection
- (kbd "<localleader>m1") #'sly-expand-1
- (kbd "<localleader>mm") #'sly-macroexpand-all
- (kbd "<localleader>mf") #'sly-format-string-expand
- (kbd "<localleader>tt") #'sly-trace-dialog-toggle-trace
- (kbd "<localleader>ts") #'sly-trace-dialog
- (kbd "<localleader>tf") #'sly-toggle-trace-fdefinition
- (kbd "<localleader>tF") #'sly-untrace-all
- (kbd "<localleader>ss") #'sly-stickers-dwim ; an ephemeral `print' around the thing at point
- (kbd "<localleader>sr") #'sly-stickers-replay
- (kbd "<localleader>sb") #'sly-stickers-toggle-break-on-stickers
- (kbd "<localleader>sf") #'sly-stickers-fetch
- (kbd "<localleader>sn") #'sly-stickers-next-sticker
- (kbd "<localleader>sp") #'sly-stickers-prev-sticker
- (kbd "<localleader>ta") #'sly-autodoc-mode)
- :custom
- (sly-mrepl-history-file-name (tw/xdg-emacs-subdir 'data "sly-mrepl-history")))
-
-;; Org-mode
-(use-package org
- :commands (org-mode)
- :mode ((rx ".org" eos) . org-mode)
- :custom
- (org-latex-src-block-backend 'minted "Colourise source code.")
- (org-latex-packages-alist
- '(("" "svg")
- ("" "minted"))
- "Use svg and syntax highlighting packages.")
- (org-latex-pdf-process
- '("latexmk -shell-escape -f -pdf -%latex -interaction=nonstopmode -output-directory=%o %f")
- "Allow -shell-escape needed by svg and minted packages."))
-
-(use-package ob ; org-babel
- :after (org)
- :custom
- (org-confirm-babel-evaluate nil "Allow running code blocks without confirmation.")
- ;; List of supported languages:
- ;; https://orgmode.org/worg/org-contrib/babel/languages/index.html
- (org-babel-load-languages
- '((emacs-lisp . t)
- (lisp . t)
- (dot . t)
- (python . t)
- (gnuplot . t)
- (rec . t)) ; see `ob-rec' below
- "Load bindings for more languages for use in #+begin_src blocks."))
-
-(defun tw/latex-section-commands (name)
- "Create a pair of section commands like (\"\\NAME{%s}\" . \"\\NAME*{%s}\").
-For use in `org-latex-classes'."
- (cons (format "\\%s{%%s}" name) (format "\\%s*{%%s}" name)))
-(defconst tw/latex-part (tw/latex-section-commands "part")
- "Part LaTeX commands for `org-latex-classes'.")
-(defconst tw/latex-chapter (tw/latex-section-commands "chapter")
- "Chapter LaTeX commands for `org-latex-classes'.")
-(defconst tw/latex-section-and-below
- (mapcar #'tw/latex-section-commands
- '("section" "subsection" "subsubsection" "paragraph" "subparagraph"))
- "Section to subparagraph LaTeX commands for `org-latex-classes'.")
-
-(use-package ox-latex ; org-export-latex
- :after (org)
- :custom
- (org-latex-classes
- `(("paperlike" "\\documentclass{paperlike}" . ,tw/latex-section-and-below)
- ("examtext" "\\documentclass{examtext}" . ,tw/latex-section-and-below)
- ("minutes" "\\documentclass{minutes}" . ,tw/latex-section-and-below)
- ("mapreport" "\\documentclass{mapreport}" ,tw/latex-chapter . ,tw/latex-section-and-below)
- ("pt3report" "\\documentclass{pt3report}" ,tw/latex-chapter . ,tw/latex-section-and-below)
- ("article" "\\documentclass{article}" . ,tw/latex-section-and-below)
- ("scrartcl" "\\documentclass{scrartcl}" . ,tw/latex-section-and-below)
- ("report" "\\documentclass{report}" ,tw/latex-part ,tw/latex-chapter . ,tw/latex-section-and-below)
- ("report-noparts" "\\documentclass{report}" ,tw/latex-chapter . ,tw/latex-section-and-below)
- ("book" "\\documentclass{book}" ,tw/latex-part ,tw/latex-chapter . ,tw/latex-section-and-below)
- ("book-noparts" "\\documentclass{book}" ,tw/latex-chapter . ,tw/latex-section-and-below)
- ("checklist" "\\documentclass{checklist}" . ,tw/latex-section-and-below))
- "Define more documentclasses for org-latex."))
-
-(use-package outline
- :commands (outline-mode outline-minor-mode)
- :custom
- ;; Mirror the default "C-c @" binding for `outline-minor-mode'.
- (outline-minor-mode-prefix (kbd "<localleader>@") "Use localleader for `outline-minor-mode' keybindings."))
-
-;; My own custom packages, and stuff that isn't on MELPA.
-(use-package actionlint
- :after (flymake)
- :load-path "include/"
- :hook ((yaml-mode yaml-ts-mode) . actionlint-setup))
-
-(use-package alidist-mode
- :after (flymake)
- :load-path "include/"
- :commands (alidist-mode)
- :mode (rx (or bot "/") "alidist/" (1+ (not ?\/)) ".sh" eot))
-
-(use-package flymake-guile
- :after (flymake)
- :load-path "include/"
- :hook (scheme-mode . flymake-guile-enable))
-
-(use-package bemscript-mode
- :load-path "include/"
- :mode (rx ".bem" eos))
-
-(use-package ifm-mode
- :load-path "include/"
- :mode (rx ".ifm" eos))
-
-(use-package pam-env-mode
- :load-path "include/"
- :mode (rx (or bos "/") (or "pam_env.conf" ".pam_environment") eos))
-
-(use-package environmentd-mode
- :load-path "include/"
- :mode (rx (or bos "/")
- (or (: (? "etc/") "environment")
- (: ".environment.d/" (1+ (not ?\/)) ".conf"))
- eos))
-
-(use-package ob-rec
- ;; `org-babel' hooks for `rec-mode'
- :after (org ob rec-mode)
- :load-path "include/")
-
-(use-package vcard-mode
- :load-path "include/"
- :mode (rx "." (or "vcf" "vcard") eos))
-
-;; Vim keybindings.
-(defun tw/switch-to-other-buffer ()
- "Switch to the last-used buffer."
- (interactive)
- (switch-to-buffer (other-buffer)))
-
-(defun tw/new-buffer ()
- "Open a new, empty buffer."
- (interactive)
- (switch-to-buffer (generate-new-buffer "untitled")))
-
-(defun tw/delete-current-buffer-file ()
- "Ask for confirmation, then delete the file associated with the current buffer."
- (interactive)
- (let ((buffer (current-buffer)))
- (when (yes-or-no-p (concat "Delete `" (buffer-file-name buffer) "'?"))
- (delete-file (buffer-file-name buffer))
- (kill-buffer buffer))))
-
-(use-package evil
- :after (which-key)
- :commands (evil-mode evil-ex-nohighlight)
- :init (setq evil-want-keybinding nil) ; evil-collection needs this
- :custom
- (evil-echo-state nil "Don't show the '--- INSERT ---' string in the echo area on evil state changes.")
- (evil-undo-system 'undo-tree "Use `undo-tree' for evil's undo-redo function.")
- (evil-search-module 'evil-search "Use evil's built-in search function, for search history support.")
- (evil-want-minibuffer t "Use evil bindings in the minibuffer too.")
- (evil-want-C-u-scroll t "Scroll on C-u in normal mode, not `universal-argument'.")
- (evil-want-C-u-delete t "Delete line on C-u in insert mode, not `universal-argument'.")
- (evil-want-Y-yank-to-eol t "Yank from point to end-of-line on Y.")
- (evil-symbol-word-search t "Always search by full variable names when using * and #.")
- :config
- (evil-mode +1)
- (evil-set-leader '(normal visual) (kbd "SPC")) ; <leader>
- (evil-set-leader '(normal visual) (kbd "\\") t) ; <localleader>
- (evil-define-key '(normal motion) diff-mode-shared-map ; not `diff-mode-map', else toggling `read-only-mode' destroys the binding
- (kbd "<localleader>\\") #'read-only-mode) ; mirror default binding from evil-collection
- (evil-define-key '(normal insert visual replace) 'global
- (kbd "C-s") #'save-buffer)
- ;; Global major-mode-independent keys should be defined here. Major
- ;; mode-dependent keys (e.g. for launching a REPL) should go under
- ;; <localleader> instead. Use `use-package' `:bind' for those.
- (evil-define-key '(normal visual) 'global
- ;; These keybindings mirror the default Spacemacs ones because I have
- ;; muscle memory of those.
- (kbd "<leader>:") #'eval-expression
- (kbd "<leader>TAB") #'tw/switch-to-other-buffer
- (kbd "<leader>bb") #'switch-to-buffer
- (kbd "<leader>bd") #'kill-current-buffer
- (kbd "<leader>bn") #'tw/new-buffer
- (kbd "<leader>br") #'revert-buffer-quick
- (kbd "<leader>bs") #'scratch-buffer
- (kbd "<leader>bw") #'read-only-mode
- (kbd "<leader>bx") #'kill-buffer-and-window
- (kbd "<leader>fd") #'tw/delete-current-buffer-file
- (kbd "<leader>ff") #'find-file
- (kbd "<leader>fR") #'rename-visited-file
- (kbd "<leader>fs") #'save-buffer
- (kbd "<leader>h") help-map
- (kbd "<leader>hw") #'which-key-show-top-level
- (kbd "<leader>sc") #'evil-ex-nohighlight
- (kbd "<leader>td") #'toggle-debug-on-error
- (kbd "<leader>tf") #'auto-fill-mode
- (kbd "<leader>tl") #'toggle-truncate-lines
- (kbd "<leader>tn") #'display-line-numbers-mode
- (kbd "<leader>u") #'universal-argument
- (kbd "<leader>w") evil-window-map
- (kbd "<leader>wd") #'evil-window-delete ; analogous to "<leader>bd"
- (kbd "<leader>wx") #'kill-buffer-and-window) ; analogous to "<leader>bx"
- (which-key-add-key-based-replacements
- ;; Names are a `cons' of a short name and a long name.
- ;; E.g. for <leader>b, "buffer" is shown under "b" in the "<leader>" menu,
- ;; while "Buffers" is shown as the title in the "<leader>b" menu.
- "<leader>b" '("buffer" . "Buffers")
- "<leader>f" '("file" . "Files")
- "<leader>h" '("help" . "General help and documentation")
- "<leader>q" '("quit" . "Finish editing the current buffer in emacsclient")
- "<leader>s" '("search" . "Search operations and options")
- "<leader>t" '("toggle" . "Toggles and quick settings")
- "<leader>w" '("window" . "Windows"))
- :functions (evil-define-key evil-set-leader
- evil-define-key* evil-window-delete evil-delay)
- :defines (evil-visual-state-map))
-
-(use-package evil-collection
- :after (evil)
- :commands (evil-collection-init) :demand t
- :config (evil-collection-init)
- :diminish evil-collection-unimpaired-mode
- :custom
- ;; Without `evil-collection-key-blacklist', in `diff-mode', space isn't
- ;; assigned to the leader key automatically, unlike in other modes.
- (evil-collection-key-blacklist '("SPC" "\\") "Don't bind to our leader keys at all.")
- (evil-collection-setup-minibuffer t "Use evil-collection in minibuffer to match `evil-want-minibuffer'."))
-
-(use-package evil-org
- :after (evil org)
- :hook org-mode
- :config
- (evil-define-key '(normal visual) org-mode-map
- (kbd "<localleader>\\") #'org-ctrl-c-ctrl-c
- (kbd "<localleader>ib") #'org-insert-structure-template
- (kbd "<localleader>id") #'org-insert-drawer
- (kbd "<localleader>iD") #'org-insert-time-stamp
- (kbd "<localleader>ih") #'org-insert-heading
- (kbd "<localleader>iH") #'org-insert-subheading
- (kbd "<localleader>it") #'org-insert-todo-heading
- (kbd "<localleader>iT") #'org-insert-todo-subheading
- (kbd "<localleader>ii") #'org-insert-item
- (kbd "<localleader>il") #'org-insert-link
- (kbd "<localleader>p") #'org-set-property
- (kbd "<localleader>t") #'org-set-tags
- ;; Source code block editing
- (kbd "<localleader>'") #'org-edit-src-code
- (kbd "<localleader>e") #'org-export-dispatch)
- (evil-define-key '(normal visual) org-src-mode-map
- (kbd "<localleader>'") #'org-edit-src-exit
- (kbd "<localleader>\\") #'org-edit-src-save
- (kbd "<localleader>a") #'org-edit-src-abort))
-
-(use-package evil-replace-with-register
- :after (evil)
- :commands (evil-replace-with-register-install) :demand t
- ;; :custom (evil-replace-with-register-key "gR" "Use the default key.")
- :config (evil-replace-with-register-install))
-
-(use-package evil-commentary ; e.g. "gcc" / "gcap" to comment out blocks of text
- :after (evil)
- :commands (evil-commentary-mode) :demand t
- :config (evil-commentary-mode +1)
- :diminish evil-commentary-mode)
-
-(use-package evil-expat ; for :reverse, :remove, :rename, :colo, :g*, ... ex commands
- :after (evil))
-
-(use-package evil-surround
- :after (evil)
- :commands (global-evil-surround-mode) :demand t
- :config (global-evil-surround-mode +1))
-
-(use-package smartparens ; required by evil-cleverparens
- ;; :custom
- ;; (sp-sexp-prefix '() "Set up Guix gexp-related sexp prefixes.")
- )
-
-(use-package evil-cleverparens
- :after (evil smartparens)
- :hook ((lisp-mode lisp-data-mode scheme-mode) . evil-cleverparens-mode)
- :custom
- (evil-cleverparens-use-additional-movement-keys nil "Disable overriding of standard vim bracket navigation keys."))
-
-(use-package evil-multiedit
- ;; See: https://github.com/hlissner/evil-multiedit#usage
- :commands (evil-multiedit-default-keybinds) :demand t
- :config (evil-multiedit-default-keybinds))
-
-(use-package evil-args
- :after (evil)
- :config
- ;; Bind evil-args text objects only.
- ;; See https://github.com/wcsmith/evil-args for more bindings.
- (define-key evil-inner-text-objects-map "a" 'evil-inner-arg)
- (define-key evil-outer-text-objects-map "a" 'evil-outer-arg))
-
-(use-package evil-numbers
- :after (evil)
- :bind (("<leader>+" . evil-numbers/inc-at-pt)
- ("<leader>-" . evil-numbers/dec-at-pt)))
-
-(use-package evil-goggles ; visual previews for edit operations
- :after (evil)
- :commands (evil-goggles-mode evil-goggles-use-diff-faces) :demand t
- :config
- (evil-goggles-mode +1)
- (evil-goggles-use-diff-faces)
- :diminish evil-goggles-mode)
-
-(use-package evil-traces ; visual previews for :ex commands
- :after (evil)
- :commands (evil-traces-mode evil-traces-use-diff-faces) :demand t
- :config
- (evil-traces-mode +1)
- (evil-traces-use-diff-faces)
- :diminish evil-traces-mode)
-
-(use-package evil-markdown
- :after (evil markdown-mode)
- :hook markdown-mode)
-
-;; Lots of useful text objects and keybinds:
-;; https://github.com/iyefrat/evil-tex#incomplete-showcase
-(use-package evil-tex
- :after (evil tex-mode)
- :hook TeX-mode)
-
-(use-package evil-text-object-python
- :after (evil python)
- :hook (python-mode . evil-text-object-python-add-bindings))
-
-;; Lisp features
-(use-package aggressive-indent
- :hook (scheme-mode emacs-lisp-mode lisp-mode sh-mode bash-ts-mode))
-
-(defun tw/find-asd-systems (directory)
- "Return a list of Common Lisp .asd systems found in DIRECTORY."
- (let ((asd-rx (rx ".asd" eos)))
- ;; `locate-dominating-file' will call this function once with the original
- ;; file name as DIRECTORY, but `directory-files' fails if its argument is
- ;; a regular file, so protect against this.
- (and (directory-name-p directory)
- (mapcar (lambda (file)
- (string-trim-right file asd-rx))
- (directory-files directory nil asd-rx)))))
-
-(defun tw/lisp-project-setup ()
- "Set up a Lisp REPL for the current project."
- (when-let ((fname (buffer-file-name))
- (project-directory
- (or (locate-dominating-file fname "guix.scm")
- (locate-dominating-file fname #'tw/find-asd-systems)
- (project-current nil (file-name-directory fname)))))
- (cd project-directory)
- (setq-local
- inferior-lisp-program
- `(;; If a guix.scm file exists, run Lisp in a Guix shell to get dependencies.
- ,@(and (file-exists-p (file-name-concat project-directory "guix.scm"))
- '("guix" "shell" "-Df" "guix.scm" "--"))
- "sbcl" "--noinform"
- ;; Load all defined asdf systems.
- ,@(mapcan (lambda (system)
- (list "--load" (format "%s.asd" system)
- "--eval" (format "(require '%s)" system)))
- ;; Heuristic: shorter names are earlier in the dependency tree.
- ;; For example, X-test.asd depends on X.asd.
- (sort (tw/find-asd-systems project-directory)
- (lambda (s1 s2)
- (< (length s1) (length s2)))))
- ;; Assume the project directory name is the name of the main package.
- "--eval" ,(format "(in-package #:%s)"
- (file-name-base
- (directory-file-name project-directory)))))))
-
-(use-package inf-lisp
- :after (lisp-mode)
- :hook (lisp-mode . tw/lisp-project-setup)
- :custom
- (inferior-lisp-program "sbcl"))
-
-(defun tw/lisp-evil-setup ()
- "Set up evil in general `lisp-mode' buffers."
- ;; https://github.com/wcsmith/evil-args#customization
- (setq-local evil-args-delimiters '(" ")))
-
-;; Sadly, not all Lisp modes derive from `lisp-mode'.
-(add-hook 'lisp-mode-hook #'tw/lisp-evil-setup)
-(add-hook 'lisp-data-mode-hook #'tw/lisp-evil-setup) ; for elisp
-(add-hook 'scheme-mode-hook #'tw/lisp-evil-setup)
-
-;; buffer-locally set `evil-lookup-func' (used on K keys) for
-;; languages where something better than man pages is available
-;; (e.g. `describe-symbol' for elisp).
-(defun tw/elisp-lookup-func ()
- "Show help in `emacs-lisp-mode' buffers."
- (let ((sym (symbol-at-point)))
- (if sym (describe-symbol sym)
- (call-interactively #'describe-symbol))))
-
-(defun tw/emacs-lisp-evil-setup ()
- "Set up evil in `emacs-lisp-mode' buffers."
- (setq-local evil-lookup-func #'tw/elisp-lookup-func))
-
-(add-hook 'emacs-lisp-mode-hook #'tw/emacs-lisp-evil-setup)
-
-(evil-define-key '(normal visual) emacs-lisp-mode-map
- (kbd "<localleader>eb") #'eval-buffer
- (kbd "<localleader>ef") #'eval-defun
- (kbd "<localleader>er") #'eval-region
- (kbd "<localleader>el") #'eval-last-sexp
- (kbd "<localleader>ep") #'eval-print-last-sexp)
-
-;; Guix-related .dir-locals.el entries. These are fine; don't prompt every time.
-(add-to-list 'safe-local-variable-values '(geiser-repl-per-project-p . t))
-(add-to-list 'safe-local-variable-values '(geiser-guile-binary . ("guix" "repl")))
-(mapc (apply-partially #'add-to-list 'safe-local-eval-forms)
- '((modify-syntax-entry 126 "'")
- (modify-syntax-entry 36 "'")
- (modify-syntax-entry 43 "'")
- (let ((root-dir-unexpanded (locate-dominating-file default-directory ".dir-locals.el")))
- (when root-dir-unexpanded
- (let* ((root-dir (file-local-name (expand-file-name root-dir-unexpanded)))
- (root-dir* (directory-file-name root-dir)))
- (unless (boundp 'geiser-guile-load-path)
- (defvar geiser-guile-load-path 'nil))
- (make-local-variable 'geiser-guile-load-path)
- (require 'cl-lib)
- (cl-pushnew root-dir* geiser-guile-load-path :test #'string-equal))))
- (progn
- (require 'lisp-mode)
- (defun emacs27-lisp-fill-paragraph (&optional justify)
- (interactive "P")
- (or (fill-comment-paragraph justify)
- (let ((paragraph-start
- (concat paragraph-start "\\|\\s-*\\([(;\"]\\|\\s-:\\|`(\\|#'(\\)"))
- (paragraph-separate
- (concat paragraph-separate "\\|\\s-*\".*[,\\.]$"))
- (fill-column
- (if (and (integerp emacs-lisp-docstring-fill-column)
- (derived-mode-p 'emacs-lisp-mode))
- emacs-lisp-docstring-fill-column
- fill-column)))
- (fill-paragraph justify))
- t))
- (setq-local fill-paragraph-function #'emacs27-lisp-fill-paragraph))
-
- ;; Forms used by Guix upstream.
- (add-to-list 'completion-ignored-extensions ".go")
- (setq-local guix-directory (locate-dominating-file
- default-directory ".dir-locals.el"))
- (with-eval-after-load 'yasnippet
- (let ((guix-yasnippets (expand-file-name
- "etc/snippets/yas"
- (locate-dominating-file
- default-directory ".dir-locals.el"))))
- (unless (member guix-yasnippets yas-snippet-dirs)
- (add-to-list 'yas-snippet-dirs guix-yasnippets)
- (yas-reload-all))))
- (let ((root-dir-unexpanded (locate-dominating-file
- default-directory ".dir-locals.el")))
- (when root-dir-unexpanded
- (let* ((root-dir (expand-file-name root-dir-unexpanded))
- (root-dir* (directory-file-name root-dir)))
- (unless (boundp 'geiser-guile-load-path)
- (defvar geiser-guile-load-path 'nil))
- (make-local-variable 'geiser-guile-load-path)
- (require 'cl-lib)
- (cl-pushnew root-dir* geiser-guile-load-path
- :test #'string-equal))))))
-
-;;; init.el ends here