nixconfig/emacs/init.el

526 lines
14 KiB
EmacsLisp

;;; init.el --- Description -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2023 Daniel Ziltener
;;
;; Author: Daniel Ziltener <dziltener@lyrion.ch>
;; Maintainer: Daniel Ziltener <dziltener@lyrion.ch>
;; Created: November 13, 2023
;; Modified: November 13, 2023
;; Version: 0.0.1
;; Keywords: abbrev bib c calendar comm convenience data docs emulations extensions faces files frames games hardware help hypermedia i18n internal languages lisp local maint mail matching mouse multimedia news outlines processes terminals tex tools unix vc wp
;; Homepage: https://github.com/dziltener@lyrion.ch/init
;; Package-Requires: ((emacs "24.3"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;; Description
;;
;;; Code:
;;;; Early Variables
(setq custom-file "~/.emacs.d/custom.el")
(when (file-exists-p custom-file)
(load custom-file))
;;;; Personal Information Setup
(setq user-full-name "Daniel Ziltener"
user-mail-address "dziltener@lyrion.ch")
(auth-source-pass-enable)
;;;; Straight.el
;; (defvar bootstrap-version)
;; (let ((bootstrap-file
;; (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
;; (bootstrap-version 6))
;; (unless (file-exists-p bootstrap-file)
;; (with-current-buffer
;; (url-retrieve-synchronously
;; "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
;; 'silent 'inhibit-cookies)
;; (goto-char (point-max))
;; (eval-print-last-sexp)))
;; (load bootstrap-file nil 'nomessage))
;; (setq straight-use-package-by-default t)
;;;; Package Management Configuration
;; See: https://github.com/radian-software/el-patch
(use-package el-patch)
;;;; Emacs
(use-package emacs
:custom
(completion-cycle-threshold 10)
(read-extended-command-predicate #'command-completion-default-include-p)
(tab-always-indent 'complete)
(global-hl-line-mode t)
(menu-bar-mode nil)
(scroll-bar-mode nil)
(tool-bar-mode nil))
;;;; Org Mode
(use-package org
:ensure t
:hook
(org-src-mode . hack-local-variables)
:config
(setq org-directory "~/org")
(add-to-list 'org-modules 'collector))
(use-package org-roam
:ensure t
:custom
(org-roam-directory "~/org/roam")
:config
(progn (org-roam-db-autosync-mode)))
(use-package websocket
:ensure t
:after org-roam)
(use-package org-roam-ui
:ensure t
:after org-roam
:custom
(org-roam-ui-sync-theme t)
(org-roam-ui-follow t)
(org-roam-ui-update-on-save t)
(org-roam-ui-open-on-start t))
(use-package org-modern
:ensure t
:hook
((org-mode . org-modern-mode)
(org-agenda-finalize . org-modern-agenda)))
(use-package org-rainbow-tags
:hook
(org-mode . org-rainbow-tags-mode))
;;;; Design
(use-package color-theme-modern)
(use-package moe-theme)
(use-package catppuccin-theme
:custom
(catppuccin-flavor 'mocha)
(catppuccin-highlight-matches t)
(catppuccin-italic-comments t)
:custom-face
(font-lock-doc-face ((t (:inherit font-lock-comment-face
:foreground "#fab387"))))
:config
(load-theme 'catppuccin))
(set-frame-parameter nil 'alpha-background 80)
(add-to-list 'default-frame-alist '(alpha-background . 80))
(set-frame-font "Victor Mono Nerd Font-10:bold" nil t)
;;;; Security
(use-package keychain-environment
:init
(keychain-refresh-environment))
(use-package pass)
(use-package password-store)
(use-package password-store-otp)
;;;; Evil Mode
(use-package evil
;; :after evil-leader
:ensure t
:init
(setq evil-want-keybinding nil)
:config
(evil-set-leader 'normal (kbd "<SPC>"))
(evil-set-leader 'normal (kbd "z") t)
(evil-mode 1)
:bind
(:map evil-normal-state-map
("<leader>f" . 'find-file)
("<leader>k" . 'kill-buffer)))
(use-package evil-collection
:after evil
:ensure t
:custom
(evil-collection-outline-bind-tab-p 1)
:commands evil-collection-init
:init
(evil-collection-init))
;;;; Search, Completion, Execution
;;;;; Preliminary Packages
(use-package savehist
:init
(savehist-mode))
(use-package orderless
:after eglot
:config
(setq completion-styles '(orderless basic)
completion-category-defaults nil
completion-category-overrides '((file (styles partial-completion)))))
(use-package consult
:bind
(:map evil-normal-state-map
("<leader><SPC>" . 'consult-find)
("<leader>es" . 'consult-eglot-symbols)
("<leader>b" . 'consult-buffer)
("<leader>g/" . 'consult-git-grep)
("<leader>/" . 'consult-grep)
("/" . 'consult-line)))
(use-package embark
:bind
("C-<SPC>" . 'embark-act)
("C-M-<return>" . 'embark-bindings))
(use-package embark-consult
:after (embark consult)
:hook
(embark-collect-mode . consult-preview-at-point-mode))
(use-package vertico
:commands
vertico-mode
:init
(vertico-mode))
(use-package marginalia
:commands
marginalia-mode
:init
(marginalia-mode))
(use-package nerd-icons-completion
:after marginalia
:commands
nerd-icons-completion-mode
:hook
(marginalia-mode-hook . nerd-icons-completion-marginalia-setup)
:init
(nerd-icons-completion-mode))
(use-package which-key
:commands
which-key-setup-minibuffer
:init
(which-key-setup-minibuffer))
;;;;; Code Completion
(use-package cape
:config
(advice-add 'eglot-completion-at-point :around #'cape-wrap-buster))
(defun my/corfu-combined-sort (candidates)
"Sort CANDIDATES using both display-sort-function and corfu-sort-function."
(let ((candidates
(let ((display-sort-func (corfu--metadata-get 'display-sort-function)))
(if display-sort-func
(funcall display-sort-func candidates)
candidates))))
(if corfu-sort-function
(funcall corfu-sort-function candidates)
candidates)))
(use-package corfu
:custom
(corfu-cycle t)
(corfu-preselect 'prompt)
(corfu-auto t)
(corfu-scroll-margin 5)
(corfu-quit-no-match 'separator)
(evil-collection-corfu-key-themes '(tab-n-go))
:config
(setq corfu-sort-override-function #'my/corfu-combined-sort)
:commands
global-corfu-mode
:init
(global-corfu-mode)
;:bind
;; (:map corfu-map
;; ("TAB" . corfu-next)
;; ([tab] . corfu-next)
;; ("S-TAB" . corfu-previous)
;; ([backtab] . corfu-previous))
)
(use-package corfu-history
:config
(add-to-list 'savehist-additional-variables 'corfu-history)
:hook
(global-corfu-mode . corfu-history-mode))
(use-package corfu-popupinfo
:after (corfu corfu-terminal)
:custom
(corfu-popupinfo-delay '(0.1 . 0.5))
:commands
corfu-popupinfo-mode
:init
(corfu-popupinfo-mode))
(use-package nerd-icons-corfu
:after corfu
:init
(add-to-list 'corfu-margin-formatters 'nerd-icons-corfu-formatter))
(use-package corfu-terminal
:if (display-graphic-p)
:after corfu
:commands
corfu-terminal-mode
:init
(corfu-terminal-mode +1))
(use-package tempel)
;;;; Basic Navigation
(use-package goto-chg
:bind
(:map evil-normal-state-map
("g," . 'goto-last-change)
("g;" . 'goto-last-change-reverse)))
;;;; Lisp Navigation and Editing
;;;;; Basic
(use-package lispy
;;:custom
;;(lispy-compat ("cider" "edebug" "magit-blame-mode"))
:hook
emacs-lisp-mode
:config
(setq lispy-close-quotes-at-end-p t)
(evil-define-key 'insert 'prog-mode-map
"(" #'lispy-parens
"{" #'lispy-braces
"}" #'special-lispy-brackets
")" #'lispy-right-nostring
"\"" #'lispy-quotes
(kbd "<DEL>") #'lispy-delete-backward
">" #'special-lispy-slurp
"<" #'special-lispy-barf
"r" #'special-lispy-raise
"e" #'special-lispy-eval))
(use-package lispyville
:bind
(:map evil-normal-state-map
("<leader>," . 'lispyville-comment-or-uncomment)
("<leader>." . 'lispyville-comment-and-clone-dwim)
("<leader>ci" . 'lispyville-comment-or-uncomment-line))
:hook
(lispy-mode . lispyville-mode))
;;;;; Visual Aid
(use-package rainbow-delimiters
:hook
emacs-lisp-mode)
;;;; Programming
(use-package editorconfig
:commands
editorconfig-mode
:init
(editorconfig-mode 1))
(defun my/eglot-capf ()
(setq-local completion-at-point-functions
(list (cape-super-capf
#'eglot-completion-at-point
#'tempel-complete
#'cape-file
#'cape-dict))))
(use-package eglot
:custom
(eglot-connect-timeout 90)
(eglot-autoshutdown t)
(eglot-report-progress t)
:config
(defun eglot-mode ()
(eglot-inlay-hints-mode +1)
(my/eglot-capf))
(setq-default eglot-workspace-configuration
'((clojure-lsp (maxCompletions . 300))))
(add-to-list 'eglot-server-programs
'((clojure-ts-mode clojurec-ts-mode clojurescript-ts-mode)
"clojure-lsp"
:initializationOptions
(:preferences
(:includeInlayParameterNameHints
"all"
:includeInlayParameterNameHintsWhenArgumentMatchesName
t
:includeInlayFunctionParameterTypeHints
t
:includeInlayVariableTypeHints
t
:includeInlayVariableTypeHintsWhenTypeMatchesName
t
:includeInlayPRopertyDeclarationTypeHints
t
:includeInlayFunctionLikeReturnTypeHints
t
:includeInlayEnumMemberValueHints
t))))
:hook
(eglot-managed-mode . eglot-inlay-hints-mode)
(eglot-managed-mode . #'my/eglot-capf))
(use-package consult-eglot
:after (consult eglot))
(use-package tree-sitter
:ensure t)
;;;;; Clojure
(use-package clojure-ts-mode
:after (tree-sitter cider lispy)
:config
(require 'sesman)
(sesman-install-menu clojure-mode-map)
:hook
((clojure-ts-mode . eglot-ensure)
(clojure-ts-mode . rainbow-delimiters-mode)
(clojure-ts-mode . (lambda () (setq-local sesman-system 'CIDER)))
(clojure-ts-mode . (lambda () (sesman-install-menu clojure-mode-map)))
(clojurec-ts-mode . (lambda () (sesman-install-menu clojurec-mode-map)))
(clojurescript-ts-mode . (lambda () (sesman-install-menu clojurescript-mode-map))))
:mode (("\\.clj\\'" . clojure-ts-mode)
("\\.cljc\\'" . clojurec-ts-mode)
("\\.cljs\\'" . clojurescript-ts-mode))
:init
(add-to-list 'lispy-clojure-modes 'clojure-ts-mode)
(add-to-list 'lispy-clojure-modes 'clojurec-ts-mode)
(add-to-list 'lispy-clojure-modes 'clojurescript-ts-mode)
(add-to-list 'tree-sitter-major-mode-language-alist '(clojure-ts-mode . clojure))
(add-to-list 'tree-sitter-major-mode-language-alist '(clojurec-ts-mode . clojure))
(add-to-list 'tree-sitter-major-mode-language-alist '(clojurescript-ts-mode . clojure)))
(use-package cider
:hook
(clojure-ts-mode . cider-mode)
:config
(evil-define-key 'insert 'cider-mode-map
"C-x C-e" #'cider-eval-last-sexp)
(evil-define-key 'normal 'cider-mode-map
(kbd "<localleader>ce") #'cider-eval-sexp-at-point))
;;;;; Chicken Scheme
(defun flymake-chicken-init ()
(add-hook 'flymake-diagnostic-functions #'flymake-chicken-backend nil t)
(flymake-mode))
(use-package geiser
:config
(defalias 'run-geiser 'geiser))
(use-package lsp-scheme
:autoload lsp-scheme-chicken
:hook
(scheme-mode . lsp-scheme)
:custom
(lsp-scheme-implementation "chicken")
:config
(progn (add-to-list 'eglot-server-programs '(scheme-mode . ("chicken-lsp-server"))))
(require 'lsp-scheme))
;; (use-package flymake-chicken
;; :hook
;; ((scheme-mode . flymake-chicken-init)
;; (scheme-mode . flymake-mode))
;; :custom
;; (flycheck-global-modes '(not scheme-mode))
;; :config
;; (add-hook 'flymake-diagnostic-functions #'flymake-chicken-backend nil t))
;;;; Other Languages
(use-package nix-ts-mode
:hook
eglot-ensure
:mode ("\\.nix\\'" . nix-ts-mode))
;; (use-package lsp-tailwindcss
;; :init
;; (setq lsp-tailwindcss-add-on-mode t
;; lsp-tailwindcss-experimental-class-regex ["\"([^\"]*)\""])
;; :config
;; (add-to-list 'lsp-tailwindcss-major-modes 'clojurescript-ts-mode)
;; (add-to-list 'lsp-tailwindcss-major-modes 'clojurec-ts-mode))
(use-package dhall-mode
:mode "\\.dhall\'"
:hook
((dhall-mode . lsp)))
;;;; Version Control
;;;;; Git
(use-package magit
:autoload
magit)
(use-package magit-todos
:after magit
:hook
(magit-mode . magit-todos-mode))
(use-package forge
:after magit
:config
(advice-add 'magit :after (lambda (&rest _args) (call-interactively #'forge-pull))))
(use-package code-review
:after forge
:custom
(code-review-auth-login-marker 'forge))
(use-package git-gutter
:hook prog-mode)
;;;; LaTeX
;; https://github.com/politza/pdf-tools/#known-problems
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)
;;;; Communication
;;;;; IRC
(use-package circe
:ensure t
:hook
(circe-chat-mode . enable-circe-color-nicks)
:custom
(circe-network-options
'(("Lyrion Libera Chat"
:host "lyrion.ch"
:port 6697
:tls t
:nick "zilti"
:sasl-username "zilti/irc.libera.chat"
:sasl-password (lambda (_) (password-store-get "Privat/Soju"))))))
(provide 'init)
;;; init.el ends here
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(custom-safe-themes
'("75fb82e748f32de807b3f9e8c72de801fdaeeb73c791f405d8f73711d0710856" "0527c20293f587f79fc1544a2472c8171abcc0fa767074a0d3ebac74793ab117" default))
'(magit-todos-insert-after '(bottom) nil nil "Changed by setter of obsolete option `magit-todos-insert-at'")
'(safe-local-variable-values
'((eval progn
(global-display-fill-column-indicator-mode t)
(make-variable-buffer-local 'cider-jack-in-nrepl-middlewares)
(add-to-list 'cider-jack-in-nrepl-middlewares "shadow.cljs.devtools.server.nrepl/middleware")))))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)