From 0f308b1c90444f5f0293bf40aa1ef177bc51036c Mon Sep 17 00:00:00 2001 From: Timo Wilken Date: Fri, 30 Dec 2022 10:54:17 +0100 Subject: Reorganise Guix home declaration into module tree --- emacs-init.el | 538 ---------------------------------------------------------- 1 file changed, 538 deletions(-) delete mode 100644 emacs-init.el (limited to 'emacs-init.el') diff --git a/emacs-init.el b/emacs-init.el deleted file mode 100644 index 8badabce..00000000 --- a/emacs-init.el +++ /dev/null @@ -1,538 +0,0 @@ -;;; init.el --- Emacs configuration. -*- lexical-binding: t -*- -;;; Commentary: -;;; Code: - -;; 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) - "Get the name of a subdirectory called NAME under $XDG__HOME/emacs." - (expand-file-name - (concat (string-trim-right name "/") "/") - (expand-file-name - "emacs/" (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)))))) - -;; 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.") - (native-compile-target-directory ,(tw/xdg-emacs-subdir 'cache "eln") "Put native-compiled binaries in the cache.") - (inhibit-startup-screen t "Don't show the startup screen with help links.") - (indent-tabs-mode nil "Always use spaces to indent.") - (sh-basic-offset 2 "Use 2 spaces for `sh-mode' indents.") - (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.") - (global-hl-line-mode t "Highlight the current line in all buffers.") - (column-number-mode t "Show the column number in the statusline.") - (electric-pair-mode t "Auto-pair suitable characters like parentheses.") - (backup-directory-alist (("." . ,(tw/xdg-emacs-subdir 'data "backup"))) "Save all backup files in one place to avoid clutter.") - (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.") - (max-mini-window-height 3 "Let the echo area grow to a maximum of 4 lines, e.g. when using `eldoc-mode'.") - (package-archives nil "Don't fetch packages from the internet; only get them from Guix.") - (recentf-max-saved-items 10000 "Save lots of recently-opened files."))) - -(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) . sh-mode) - (,(rx ".install" eos) . sh-mode) - (,(rx bos "/tmp/neomutt-") . mail-mode) - (,(rx "." (1+ anything) "rc" eos) . conf-unix-mode) - (,(rx ".gnuplot" eos) . gnuplot-mode) - (,(rx ".aurora" eos) . python-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) - -;; `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. - -;; Look and feel -(set-face-attribute 'default nil :family "Hermit" :height 100) - -(use-package autothemer - ;; The "catppuccin" theme is linked to the appropriate variant by guix home. - :config (load-theme 'catppuccin-mocha t)) - -(defun tw/get-catppuccin-color (name) - "Get the hex code of the Catppuccin color named NAME." - (cl-loop for color in (autothemer--theme-colors autothemer-current-theme) - when (string= (autothemer--color-name color) name) - return (autothemer--color-value color))) - -(custom-set-faces - `(cursor ((default :background ,(tw/get-catppuccin-color "rosewater"))) t - "Make the cursor \"rosewater\", as recommended by Catppuccin upstream, overriding catppuccin/emacs.")) - -(use-package smart-mode-line - :commands (sml/setup) :demand t - :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.") - :config (sml/setup)) - -;; General editor behaviour. -(use-package ivy - :commands (ivy-mode) :demand t - :config (ivy-mode +1) - :diminish ivy-mode) - -(use-package counsel ; extra niceties for `ivy-mode' - :after (ivy evil) ; evil for :bind-ing to - :bind (("SPC" . counsel-M-x) ; doesn't work - ("fr" . counsel-buffer-or-recentf) - :map evil-visual-state-map - ("SPC" . counsel-M-x)) - :commands (counsel-mode) :demand t - :config (counsel-mode +1) - :diminish counsel-mode) - -(defun tw/counsel-dash-is-help () - "Install `counsel-dash-at-point' as `evil-lookup-func'." - (setq-local evil-lookup-func #'counsel-dash-at-point)) - -(use-package counsel-dash - :bind (("K" . counsel-dash-at-point) ; TODO: just install as `evil-lookup-func'? - ("dK" . counsel-dash) - ("di" . counsel-dash-install-docset) - ("da" . counsel-dash-activate-docset) - ("dd" . counsel-dash-deactivate-docset)) - :hook (python-mode . tw/counsel-dash-is-help) - :custom - (counsel-dash-docsets-path (tw/xdg-emacs-subdir 'data "dash-docsets") "Store docsets in the XDG data directory.") - (counsel-dash-browser-func 'eww "Open documentation pages using `eww' instead of an external browser.") - (counsel-dash-enable-debugging nil "Disable popping up useless warnings.")) - -(use-package rainbow-mode - :after (evil) - :bind (("tR" . rainbow-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)) - -(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 (("U" . undo-tree-visualize)) - :custom - (undo-tree-history-directory-alist - `(("." . ,(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)) - -;; IDE-like features. -(use-package vc - :after (which-key evil) - :init (which-key-add-key-based-replacements - "g" '("vc" . "Version control") - "gM" '("merge" . "Version control merging")) - :bind-keymap ("g" . vc-prefix-map)) - -(use-package company - :hook (prog-mode ledger-mode) - ;; Use TAB for selecting completions. Config from: - ;; https://github.com/company-mode/company-mode/blob/master/company-tng.el - :bind (:map company-active-map - ([tab] . company-select-next) - ([backtab] . company-select-previous)) - :custom - (company-minimum-prefix-length 2 "Start showing completion candidates slightly earlier.") - (company-idle-delay (lambda () (if (company-in-string-or-comment) nil 0.3)) - "Automatically show completions when editing non-comment parts of code.") - :diminish company-mode) - -(use-package company-quickhelp - :after (company autothemer) ; autothemer needed for `tw/get-catppuccin-color' - :hook company-mode - :custom - (company-quickhelp-delay 0.2 "Automatically show quickhelp for completions.") - (company-quickhelp-color-background (tw/get-catppuccin-color "surface0") "Give the quickhelp tooltip a nicer background colour.") - (company-quickhelp-color-foreground (tw/get-catppuccin-color "text") "Give the quickhelp tooltip the default text colour.")) - -(use-package company-posframe - :after (company company-quickhelp) - :hook company-mode - :diminish company-posframe-mode) - -(use-package flyspell - :hook mail-mode) - -(use-package flymake - :after (evil which-key) - :hook prog-mode - :init (which-key-add-key-based-replacements - "e" '("errors" . "Flymake")) - :bind (("eb" . flymake-start) - ("el" . flymake-show-buffer-diagnostics) - ("ep" . flymake-show-project-diagnostics) - ("e." . 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. - ("en" . flymake-goto-next-error) - ("eN" . flymake-goto-prev-error)) - :custom - (flymake-suppress-zero-counters nil "Show severity counters even when they are zero.")) - -(use-package flymake-collection - :after (flymake) - ;; 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." - (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 c-mode c++-mode) . eglot) - :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.") - :config - ;; TODO: only run `tw/help-is-eldoc' if `eglot-managed-p' is true. - (add-hook 'eglot-managed-mode-hook #'tw/help-is-eldoc)) - -;; Non-LSP language modes. -(use-package mmm-mode - :commands (mmm-mode)) -(use-package cmake-mode - :mode (rx (or (: (or bos "/") "CMakeLists.txt") ".cmake") eos)) -(use-package puppet-mode - :mode (rx ".pp" eos)) -(use-package web-mode - :mode (rx "." (or "htm" "html" "js" "css" "scss") eos)) -(use-package yaml-mode - :mode (rx ".y" (? "a") "ml" eos)) -(use-package rec-mode - :mode (rx ".rec" eos)) -(use-package hcl-mode - :mode (rx "." (or "hcl" "nomad") eos)) -(use-package graphviz-dot-mode - :mode (rx ".dot" eos) - :custom (graphviz-dot-view-command "xdot %s" "Use xdot for previewing graphviz files.")) -(use-package tcl - :mode ((rx ".tcl" eos) . tcl-mode) - :magic ((rx "#%Module1.0") . tcl-mode)) - -(use-package ledger-mode - :mode (rx ".journal" eos) - :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.")) - -(use-package geiser - :after (evil) - :commands (geiser geiser-eval-buffer geiser-eval-definition geiser-eval-region geiser-eval-last-sexp) - :hook (scheme-mode . geiser-autodoc-mode) - :config - (evil-define-key '(normal visual) scheme-mode-map - (kbd "i") #'geiser - (kbd "eb") #'geiser-eval-buffer - (kbd "ef") #'geiser-eval-definition - (kbd "er") #'geiser-eval-region - (kbd "el") #'geiser-eval-last-sexp) - :defines scheme-mode-map) - -(use-package geiser-racket - :after (geiser)) -(use-package geiser-guile - :after (geiser)) - -;; Org-mode -(use-package org) -(use-package ob ; org-babel - :after (org)) - -(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 "@") "Use localleader for `outline-minor-mode' keybindings.")) - -;; My own custom packages, and stuff that isn't on MELPA. -;; (use-package actionlint ; TODO: port to flymake -;; :after (flycheck) -;; :load-path "include/") - -(use-package alidist-mode - :after (flymake mmm-mode yaml-mode) - :mode (rx (or bos "/") "alidist/" (1+ anything) ".sh" eos) - :load-path "include/") - -(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 org-latex-classes - :after (ox-latex) - :load-path "include/") - -(use-package ob-rec - ;; `org-babel' hooks for `rec-mode' - :after (org ob) - :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"))) - -(use-package evil - :after (which-key) - :commands (evil-mode evil-ex-nohighlight) - :init (setq evil-want-keybinding nil) ; evil-collection needs this - :custom - (evil-undo-system 'undo-tree "Use `undo-tree' for evil's undo-redo function.") - (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.") - :config - (evil-mode +1) - (evil-set-leader '(normal visual) (kbd "SPC")) ; - (evil-set-leader '(normal visual) (kbd "\\") t) ; - (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 - ;; 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 ":") #'eval-expression - (kbd "TAB") #'tw/switch-to-other-buffer - (kbd "bb") #'switch-to-buffer - (kbd "bd") #'kill-current-buffer - (kbd "bn") #'tw/new-buffer - (kbd "br") #'revert-buffer-quick - (kbd "bx") #'kill-buffer-and-window - (kbd "ff") #'find-file - (kbd "fs") #'save-buffer - (kbd "h") help-map - (kbd "sc") #'evil-ex-nohighlight - (kbd "tf") #'auto-fill-mode - (kbd "tl") #'toggle-truncate-lines - (kbd "tn") #'display-line-numbers-mode - (kbd "u") #'universal-argument - (kbd "w") evil-window-map - (kbd "wd") #'evil-window-delete ; analogous to "bd" - (kbd "wx") #'kill-buffer-and-window) ; analogous to "bx" - (which-key-add-key-based-replacements - ;; Names are a `cons' of a short name and a long name. - ;; E.g. for b, "buffer" is shown under "b" in the "" menu, - ;; while "Buffers" is shown as the title in the "b" menu. - "b" '("buffer" . "Buffers") - "f" '("file" . "Files") - "h" '("help" . "General help and documentation") - "q" '("quit" . "Finish editing the current buffer in emacsclient") - "s" '("search" . "Search operations and options") - "t" '("toggle" . "Toggles and quick settings") - "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)) - -(use-package evil-org - :after (evil org) - :hook org-mode - :config - (evil-define-key '(normal visual) org-mode-map - (kbd "\\") #'org-ctrl-c-ctrl-c - (kbd "'") #'org-edit-src-code - (kbd "e") #'org-export-dispatch) - (evil-define-key '(normal visual) org-src-mode-map - (kbd "'") #'org-edit-src-exit - (kbd "\\") #'org-edit-src-save - (kbd "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 - :after (evil) - :commands (evil-commentary-mode) :demand t - :config (evil-commentary-mode +1)) - -(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 evil-smartparens - :after (evil smartparens) - :hook smartparens-enabled-hook) - -(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 (("+" . evil-numbers/inc-at-pt) - ("-" . 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) - -(use-package evil-tex - :after (evil tex) - :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 common-lisp-mode)) - -(defun tw/lisp-evil-setup () - "Set up evil in general `lisp-mode' buffers." - (setq-local evil-symbol-word-search t - ;; https://github.com/wcsmith/evil-args#customization - 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) - -(defun tw/hack-guile-indents () - "Set the proper `scheme-indent-function' for Guix macros." - (put 'modify-phases 'scheme-indent-function 1) - (put 'add-before 'scheme-indent-function 2) - (put 'substitute* 'scheme-indent-function 1)) - -(add-hook 'scheme-mode-hook #'tw/hack-guile-indents) - -(evil-define-key '(normal visual) emacs-lisp-mode-map - (kbd "eb") #'eval-buffer - (kbd "ef") #'eval-defun - (kbd "er") #'eval-region - (kbd "el") #'eval-last-sexp - (kbd "ep") #'eval-print-last-sexp) - -;;; init.el ends here -- cgit v1.2.3