diff --git a/emacs/init.el b/emacs/init.el index 3d46a7d..9ade6e0 100644 --- a/emacs/init.el +++ b/emacs/init.el @@ -22,97 +22,50 @@ ;; Description ;; ;;; Code: -;;;; Requirements +;;; Requirements ;; Since I am using `cl-defun` in this init file, I need to require ;; `cl-macs`. (require 'cl-macs) -;;;; Early Variables +;;; Early Variables (setq custom-file "~/.config/emacs/custom.el") (when (file-exists-p custom-file) (load custom-file)) (defvar init-dir (file-name-directory (or load-file-name (buffer-file-name)))) -;;;; Personal Information Setup +;;; Package Management + +;;;; Repositories +(require 'package) +(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) +(package-initialize) + +;;;; VC + +;; This will be unnecessary starting at Emacs 30 + +(unless (package-installed-p 'vc-use-package) + (package-vc-install "https://github.com/slotThe/vc-use-package")) +(setopt use-package-always-ensure t) +(require 'vc-use-package) + +;;; Personal Information Setup (setq user-full-name "Daniel Ziltener" user-mail-address "dziltener@lyrion.ch") ;; I use `pass` as password storage. (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) - -;;;; Elpaca - -;;;;; Installation - -(defvar elpaca-installer-version 0.6) -(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) -(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) -(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) -(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" - :ref nil - :files (:defaults "elpaca-test.el" (:exclude "extensions")) - :build (:not elpaca--activate-package))) -(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) - (build (expand-file-name "elpaca/" elpaca-builds-directory)) - (order (cdr elpaca-order)) - (default-directory repo)) - (add-to-list 'load-path (if (file-exists-p build) build repo)) - (unless (file-exists-p repo) - (make-directory repo t) - (when (< emacs-major-version 28) (require 'subr-x)) - (condition-case-unless-debug err - (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) - ((zerop (call-process "git" nil buffer t "clone" - (plist-get order :repo) repo))) - ((zerop (call-process "git" nil buffer t "checkout" - (or (plist-get order :ref) "--")))) - (emacs (concat invocation-directory invocation-name)) - ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" - "--eval" "(byte-recompile-directory \".\" 0 'force)"))) - ((require 'elpaca)) - ((elpaca-generate-autoloads "elpaca" repo))) - (progn (message "%s" (buffer-string)) (kill-buffer buffer)) - (error "%s" (with-current-buffer buffer (buffer-string)))) - ((error) (warn "%s" err) (delete-directory repo 'recursive)))) - (unless (require 'elpaca-autoloads nil t) - (require 'elpaca) - (elpaca-generate-autoloads "elpaca" repo) - (load "./elpaca-autoloads"))) -(add-hook 'after-init-hook #'elpaca-process-queues) -(elpaca `(,@elpaca-order)) - -;;;;; use-package integration - -(elpaca elpaca-use-package - (elpaca-use-package-mode) - (setq elpaca-use-package-by-default t)) -(elpaca-wait) - -;;;; Package Management Configuration +;;; Package Management Configuration ;; See: https://github.com/radian-software/el-patch (use-package el-patch) -;;;;; Guix Management -(use-package guix) +;;;; Guix Management +(use-package guix + :after magit-popup) -;;;; Helper Functions +;;; Helper Functions (cl-defun conditional-keybind (filter-fn target-fn &optional (fail-fn #'self-insert-command)) @@ -126,10 +79,9 @@ (call-interactively target-fn) (call-interactively fail-fn)))) -;;;; Emacs +;;; Emacs (use-package emacs - :elpaca nil - :delight (eldoc-mode " 󰙎") + :after org :custom (completion-cycle-threshold 10) (display-time-mode t) @@ -137,43 +89,87 @@ (enable-remote-dir-locals t) (fill-column 100) (global-hl-line-mode t) + (global-prettify-symbols-mode t) (indent-tabs-mode nil) (menu-bar-mode nil) (minibuffer-prompt-properties (read-only t cursor-intangible t face minibuffer-prompt)) + (native-comp-async-report-warnings-errors nil) (read-extended-command-predicate #'command-completion-default-include-p) (recentf-mode t) + (pixel-scroll-precision-large-scroll-height 30) (scroll-bar-mode nil) (tab-always-indent 'complete) (tool-bar-mode nil) + (newsticker-url-list-defaults nil) + (newsticker-url-list + '(("Tagesschau" "https://www.tagesschau.de/index~atom.xml" nil nil nil) + ("NZZ Neuste" "https://www.nzz.ch/recent.rss" nil nil nil) + ("SRF News" "https://www.srf.ch/news/bnf/rss/1646" nil nil nil) + ("SRF Wissen" "https://www.srf.ch/bnf/rss/630" nil nil nil) + ("Deutschlandfunk Nachrichten" "https://www.deutschlandfunk.de/nachrichten-100.rss" nil nil nil) + ("Deutschlandfunk Wissen" "https://www.deutschlandfunk.de/wissen-106.rss" nil nil nil) + ("RBB" "https://www.rbb24.de/aktuell/index.xml/feed=rss.xml" nil nil nil) + ("Guix" "https://guix.gnu.org/feeds/blog.atom" nil nil nil) + ("Mastering Emacs" "https://www.masteringemacs.org/feed" nil nil nil) + ("Schiene.de" "https://www.schiene.de/feed/" nil nil nil) + ("Anil Dash Blog" "https://www.anildash.com/feed.xml" nil nil nil) + ("Karl Voit's Blog" "https://karl-voit.at/feeds/lazyblorg-all.atom_1.0.links-and-content.xml" nil nil nil) + ("Vaxry's Blog" "https://blog.vaxry.net/feed" nil nil nil))) :custom-face - ;;(default ((t (:weight bold :height 113 :width normal :family "VictorMono Nerd Font")))) - (default ((t (:weight regular :height 105 :width narrow :family "MonaspiceXe Nerd Font Mono")))) + (default ((t (:weight normal :height 110 :family "MonaspiceXe Nerd Font Mono")))) + (fixed-pitch ((t (:weight normal :height 110 :family "MonaspiceXe Nerd Font Mono")))) + (variable-pitch ((t (:weight normal :height 135 :family "MonaspiceXe Nerd Font Propo")))) :hook (minibuffer-setup . cursor-intangible-mode) :config + (setq xref-backend-functions (list)) (advice-add 'risky-local-variable-p :override #'ignore) (global-display-fill-column-indicator-mode t) (pixel-scroll-precision-mode 1)) -;;;; Org Mode +(defun set-buffer-variable-pitch () + (interactive) + (variable-pitch-mode t) + (setq line-spacing 3) + (set-face-attribute 'org-table nil :inherit 'fixed-pitch) + (set-face-attribute 'org-code nil :inherit 'fixed-pitch) + (set-face-attribute 'org-block nil :inherit 'fixed-pitch) + ;; investigate: this face does not exist + ;;(set-face-attribute 'org-block-background nil :inherit 'fixed-pitch) + ) + +(use-package outline-minor + :ensure nil + :bind + (:map evil-normal-state-map + ("zoc" . #'outline-cycle-buffer)) + :hook + clojure-mode + scheme-mode + emacs-lisp-mode) + +;;; Org Mode (use-package org - :elpaca (:repo "https://git.savannah.gnu.org/git/emacs/org-mode.git" :branch "emacs-sync") + :vc (:fetcher "https://git.savannah.gnu.org/git/emacs/org-mode.git" :rev "emacs-sync") + :preface + (defun cc/org-local-stuff () + (setq-local visual-fill-column-center-text t)) :after visual-fill-column - :ensure t :custom (org-babel-load-languages '((emacs-lisp . t) - (scheme . t))) - (visual-fill-column-center-text t) + (scheme . t) + (shell . t))) :hook (org-mode . org-indent-mode) (org-src-mode . hack-local-variables) (org-mode . visual-line-mode) + (org-mode . set-buffer-variable-pitch) :config (setq org-directory "~/org") - (add-to-list 'org-modules 'collector)) + ;;(add-to-list 'org-modules 'collector) + ) (use-package org-roam - :ensure t :custom (org-roam-directory "~/org/roam") :config @@ -184,11 +180,9 @@ (consult-notes-org-roam-mode t)) (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) @@ -197,16 +191,15 @@ (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))) + (org-mode . org-modern-mode) + (org-agenda-finalize . org-modern-agenda)) (use-package org-rainbow-tags :hook (org-mode . org-rainbow-tags-mode)) -;;;; Design +;;; Design (use-package color-theme-modern) (use-package moe-theme) (use-package catppuccin-theme @@ -222,42 +215,14 @@ ) (use-package unicode-fonts - :ensure t :config (unicode-fonts-setup)) -(use-package ligature - :config - (ligature-set-ligatures - 't - '( ;; SS01 - "==" "===" "=/=" "!=" "!==" "/=" "/==" "~~" "=~" "!~" - ;; SS02 - ">=" "<=" - ;; SS03 - "->" "<-" "=>" "" "<~" "<~~" "~>" "~~>" "<~>" - ;; SS04 - "" "" "/\\" "\\/" - ;; SS05 - "|>" "<|" - ;; SS06 - "##" "###" - ;; SS07 - "***" "/*" "*/" "/*/" "(*" "*)" "(*)" - ;; SS08 - ".=" ".-" "..<" - ;; CALT - "//" "///" "&&" "!!" "??" "?." "?:" "||" "::" ":::" ";;" ".." "..." "=!=" "#=" ":=" "=:" "=:=" - ":>" ">:" "<:" ":<" "..=" "..-" - )) - (global-ligature-mode t)) - (set-frame-parameter nil 'alpha-background 90) (add-to-list 'default-frame-alist '(alpha-background . 90)) (use-package lambda-line - ;;:straight (:type git :host github :repo "lambda-emacs/lambda-line") - :elpaca (:host github :repo "lambda-emacs/lambda-line") + :vc (:fetcher github :repo "lambda-emacs/lambda-line") :custom (lambda-line-icon-time t) ;; requires ClockFace font (see below) (lambda-line-clockface-update-fontset "ClockFaceRect") ;; set clock icon @@ -293,8 +258,7 @@ (setq mode-line-format (list "%_")))) (use-package lambda-themes - ;;:straight (:type git :host github :repo "lambda-emacs/lambda-themes") - :elpaca (:host github :repo "lambda-emacs/lambda-themes") + :vc (:fetcher github :repo "lambda-emacs/lambda-themes") :custom (lambda-themes-set-italic-comments t) (lambda-themes-set-italic-keywords t) @@ -303,34 +267,33 @@ ;; load preferred theme (load-theme 'lambda-dark)) -;;;;; Long line handling +;;;; Long line handling (use-package visual-fill-column :custom (visual-fill-column-enable-sensible-window-split t) :hook (prog-mode . visual-line-mode) - visual-line-mode) + visual-line-mode + ;; :config + ;; (add-hook 'prog-mode-hook #'visual-line-mode) + ;; (add-hook 'visual-line-mode-hook #'visual-fill-column-mode) + ) (use-package adaptive-wrap :config (setq-default adaptive-wrap-extra-indent 4) + ;;(add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode) :hook (visual-line-mode . adaptive-wrap-prefix-mode)) -;;;; 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 pass) + +;;; Evil Mode (use-package evil - ;; :after evil-leader - :ensure t :init (setq evil-want-keybinding nil evil-emacs-state-tag " 󰯸 " @@ -342,6 +305,7 @@ :config (evil-set-leader 'normal (kbd "")) (evil-set-leader 'normal (kbd "z") t) + (evil-ex-define-cmd "q" 'delete-frame) (evil-mode 1) :bind (:map evil-normal-state-map @@ -358,10 +322,10 @@ :init (evil-collection-init)) -;;;; Search, Completion, Execution -;;;;; Preliminary Packages +;;; Search, Completion, Execution +;;;; Preliminary Packages (use-package savehist - :elpaca nil + :ensure nil :init (savehist-mode)) @@ -380,6 +344,8 @@ :config (require 'consult-flymake) (require 'consult-xref) + :custom + (xref-show-xrefs-function #'consult-xref) :bind (:map evil-normal-state-map ("" . 'consult-find) @@ -421,11 +387,15 @@ :commands which-key-setup-minibuffer :init - (which-key-setup-minibuffer)) + (which-key-setup-minibuffer) + :config + (which-key-mode t)) -;;;;; Code Completion +;;;; Code Completion (use-package cape - :preface + :config + (require 'cape-char) + (require 'cape-keyword) (defun my/capf () (setq completion-at-point-functions (list (cape-capf-super @@ -436,11 +406,35 @@ #'cape-line #'cape-emoji #'cape-keyword)))) - :config + (defun my/eglot-capf () + (setq completion-at-point-functions + (list (cape-capf-super + #'eglot-completion-at-point + #'tempel-complete + #'cape-dabbrev + #'cape-file + #'cape-dict + #'cape-line + #'cape-emoji + #'cape-keyword)))) + (defun my/geiser-capf () + (setq completion-at-point-functions + (list (apply #'cape-capf-super + (append geiser-capf--capfs + (list + #'tempel-complete + #'cape-dabbrev + #'cape-file + #'cape-dict + #'cape-line + #'cape-emoji + #'cape-keyword)))))) (advice-add 'eglot-completion-at-point :around #'cape-wrap-buster) :hook (org-mode . my/capf) - (prog-mode . my/capf)) + (prog-mode . my/capf) + (eglot-managed-mode . my/eglot-capf) + (geiser-mode . my/geiser-capf)) (defun my/corfu-combined-sort (candidates) "Sort CANDIDATES using both display-sort-function and corfu-sort-function." @@ -468,6 +462,8 @@ :commands global-corfu-mode :init + (require 'corfu-popupinfo) + (require 'corfu-history) (global-corfu-mode) (corfu-popupinfo-mode 1) (corfu-history-mode 1)) @@ -486,10 +482,12 @@ (use-package tempel) (use-package xref-union + :custom + (xref-union-excluded-backends (lambda (b) (eq b #'etags--xref-backend))) :hook - cider-connected) + cider-mode) -;;;; Basic Navigation +;;; Basic Navigation (use-package goto-chg :bind (:map evil-normal-state-map @@ -497,15 +495,17 @@ ("g;" . 'goto-last-change-reverse))) (use-package evil-snipe - :delight (evil-snipe-local-mode " 󰓾 ") + :after evil-easymotion :custom (evil-snipe-scope 'whole-visible) (evil-snipe-repeat-scope 'whole-buffer) (evil-snipe-spillover-scope 'whole-buffer) (evil-snipe-tab-increment t) + :commands + evil-snipe-override-mode + :init + (evil-snipe-override-mode 1) :hook - evil-mode - (evil-mode . evil-snipe-override-mode) (magit-mode . turn-off-evil-snipe-override-mode) ;; See https://github.com/hlissner/evil-snipe/issues/95 ;; :config @@ -516,11 +516,12 @@ ) (use-package evil-easymotion + :after evil :config (evilem-default-keybindings "")) -;;;; Lisp Navigation and Editing -;;;;; Helper Functions +;;; Lisp Navigation and Editing +;;;; Helper Functions (defun cc/move-sexp-backward () "Move balanced expression (sexp) to the right of point backward one sexp. Point must be at the beginning of balanced expression (sexp)." @@ -565,22 +566,13 @@ Point must be at the beginning of balanced expression (sexp)." (defun being-past-closing-paren () (looking-back (rx (or ")" "}" "]")))) -;;;;; Basic -(use-package symex - :custom - (symex-modal-backend 'evil) - :config - (symex-initialize) - :bind - (:map evil-insert-state-map - ("C-ß" . #'symex-mode-interface))) +;;;; Basic (use-package paredit - :hook - clojure-ts-mode - emacs-lisp-mode - scheme-mode :config + ;; (add-hook 'clojure-ts-mode-hook #'paredit-mode) + ;; (add-hook 'emacs-lisp-mode-hook #'paredit-mode) + ;; (add-hook 'scheme-mode-hook #'paredit-mode) (evil-define-key 'insert paredit-mode-map (kbd "r") (conditional-keybind #'looking-at-opening-paren #'paredit-raise-sexp) @@ -593,71 +585,20 @@ Point must be at the beginning of balanced expression (sexp)." (kbd ">") (conditional-keybind #'being-past-closing-paren #'cc/slurp-forward) (kbd "<") (conditional-keybind #'being-past-closing-paren - #'cc/barf-forward))) + #'cc/barf-forward)) + :hook + clojure-ts-mode + clojure-mode + emacs-lisp-mode + scheme-mode) -;; (use-package smartparens -;; :delight (smartparens-mode " 󰅲 ") -;; :hook -;; (smartparens-mode . show-smartparens-mode) -;; (smartparens-mode . smartparens-strict-mode) -;; clojure-ts-mode -;; emacs-lisp-mode -;; scheme-mode -;; :custom -;; (sp-undo-pairs-separately t) -;; :config -;; (add-to-list 'sp-clojure-modes 'clojure-ts-mode) -;; (add-to-list 'sp-clojure-modes 'clojurec-ts-mode) -;; (add-to-list 'sp-clojure-modes 'clojurescript-ts-mode) -;; (add-to-list 'sp-lisp-modes 'clojure-ts-mode) -;; (add-to-list 'sp-lisp-modes 'clojurec-ts-mode) -;; (add-to-list 'sp-lisp-modes 'clojurescript-ts-mode) -;; ;; TODO: Remove the following three lines once merge request got accepted -;; (load-file (concat init-dir "lib/smartparens-clojure.el")) -;; (load-file (concat init-dir "lib/smartparens-emacs-lisp.el")) -;; (load-file (concat init-dir "lib/smartparens-scheme.el")) -;; (require 'smartparens-clojure) -;; (require 'smartparens-emacs-lisp) -;; (require 'smartparens-scheme) -;; (evil-define-key 'insert smartparens-mode-map -;; (kbd "r") (conditional-keybind #'looking-at-opening-paren -;; #'sp-raise-sexp) -;; (kbd "w") (conditional-keybind #'looking-at-opening-paren -;; #'cc/move-sexp-backward) -;; (kbd "s") (conditional-keybind #'looking-at-opening-paren -;; #'cc/move-sexp-forward) -;; (kbd "c") (conditional-keybind #'looking-at-opening-paren -;; #'sp-clone-sexp) -;; (kbd "m") (conditional-keybind #'looking-at-opening-paren -;; #'sp-mark-sexp) -;; (kbd "DEL") (conditional-keybind #'being-past-closing-paren -;; #'sp-backward-delete-sexp -;; #'evil-delete-backward-char-and-join) -;; (kbd ">") (conditional-keybind #'being-past-closing-paren -;; (lambda (prefix) -;; (interactive "P") -;; (call-interactively #'backward-char) -;; (call-interactively #'sp-forward-slurp-sexp) -;; (call-interactively #'sp-forward-sexp) -;; (call-interactively #'forward-char))) -;; (kbd "<") (conditional-keybind #'being-past-closing-paren -;; (lambda (prefix) -;; (interactive "P") -;; (call-interactively #'backward-char) -;; (call-interactively #'sp-forward-barf-sexp) -;; (call-interactively #'forward-char))))) - -;; (use-package evil-cleverparens -;; :after smartparens -;; :hook smartparens) - -;;;;; Visual Aid +;;;; Visual Aid ;; (use-package rainbow-delimiters ;; :hook ;; emacs-lisp-mode ;; scheme-mode) -;;;; Programming +;;; Programming (use-package editorconfig :delight editorconfig-mode :commands @@ -666,166 +607,111 @@ Point must be at the beginning of balanced expression (sexp)." (editorconfig-mode 1)) (use-package flymake + :ensure nil :delight '(:eval (cons "  " (flymake--mode-line-counters)))) (use-package eglot - :preface - (defun my/eglot-capf () - (setq completion-at-point-functions - (list (cape-capf-super - #'eglot-completion-at-point - #'tempel-complete - #'cape-dabbrev - #'cape-file - #'cape-dict - #'cape-line - #'cape-emoji - #'cape-keyword)))) + :ensure nil :custom (eglot-connect-timeout 90) (eglot-autoshutdown t) (eglot-report-progress t) :config - (defun eglot-mode () - (eglot-inlay-hints-mode +1) - (my/eglot-capf)) + (add-to-list 'eglot-server-programs '(scheme-mode . ("chicken-lsp-server"))) (setq-default eglot-workspace-configuration '((clojure-lsp (maxCompletions . 300)))) - (add-to-list 'eglot-server-programs - '((clojure-mode clojurec-mode clojurescript-mode) - "clojure-lsp" - :initializationOptions - (:preferences - (:includeInlayParameterNameHints - "all" - :includeInlayParameterNameHintsWhenArgumentMatchesName - t - :includeInlayFunctionParameterTypeHints - t - :includeInlayVariableTypeHints - t - :includeInlayVariableTypeHintsWhenTypeMatchesName - t - :includeInlayPRopertyDeclarationTypeHints - t - :includeInlayFunctionLikeReturnTypeHints - t - :includeInlayEnumMemberValueHints - t)))) :hook + (clojure-mode . eglot-ensure) (eglot-managed-mode . (lambda () (add-hook 'before-save-hook (lambda () (call-interactively #'eglot-format-buffer)) nil 'local))) - (eglot-managed-mode . eglot-inlay-hints-mode) - (eglot-managed-mode . my/eglot-capf)) + (eglot-managed-mode . eglot-inlay-hints-mode)) (use-package consult-eglot :after (consult eglot)) -(use-package tree-sitter - :ensure t) - -;;;;; Clojure -(use-package clojure-ts-mode +;;;; Clojure +(use-package clojure-mode :preface (defun embark-eglot-rename (from to) "Renames the symbol at point." (interactive "sRename: \nsRename %s to: ") (funcall-interactively #'eglot-rename to)) - :delight "" - :after (tree-sitter embark) + :after (embark cider) :config - (require 'sesman) - (sesman-install-menu clojure-mode-map) (defvar-keymap embark-clj-identifier-map :parent embark-identifier-map "c" #'embark-eglot-rename) (add-to-list 'embark-keymap-alist '(identifier . embark-clj-identifier-map)) :hook - ((clojure-ts-mode . eglot-ensure) - (clojure-ts-mode . prettify-symbols-mode) - (clojure-ts-mode . (lambda () - (setq-local sesman-system 'CIDER) - (setq-local prettify-symbols-alist '(("fn" . "λ"))))) - (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 '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))) + (clojure-mode . (lambda () + (setq-local prettify-symbols-alist + '(("fn" . "λ") + ("comp" . "∘") + ("and" . "∧") + ("or" . "∨") + ("not" . "¬")))))) (use-package cider - :elpaca (:host github :repo "clojure-emacs/cider" :tag "v1.12.0") + ;;:elpaca (:host github :repo "clojure-emacs/cider" :tag "v1.12.0") :delight (cider-mode '(:eval (concat "  [" (cider--modeline-info) "]"))) :config - (evil-define-key 'insert 'cider-mode-map - "C-x C-e" #'cider-eval-last-sexp) (evil-define-key 'normal 'cider-mode-map (kbd "ce") #'cider-eval-sexp-at-point)) -;;;;; Scheme +;;;; Scheme (use-package geiser - :preface - (defun my/geiser-capf () - (setq completion-at-point-functions - (append geiser-capf--capfs - (list (cape-capf-super - #'tempel-complete - #'cape-dabbrev - #'cape-file - #'cape-dict - #'cape-line - #'cape-emoji - #'cape-keyword))))) :custom (geiser-chicken-match-limit 200) :config - (defalias 'run-geiser 'geiser) - :hook - (geiser-mode . my/geiser-capf)) + (defalias 'run-geiser 'geiser)) (use-package paren-face :hook scheme-mode emacs-lisp-mode - clojure-ts-mode) + clojure-ts-mode + ;; :config + ;; (add-hook 'scheme-mode-hook #'paren-face-mode) + ;; (add-hook 'emacs-lisp-mode-hook #'paren-face-mode) + ;; (add-hook 'clojure-ts-mode-hook #'paren-face-mode) + ) (use-package highlight-parentheses - :hook prog-mode) + :custom + (highlight-parentheses-highlight-adjacent t) + (highlight-parentheses-colors '("yellow" "light gray" "dark gray" "dim gray")) + :hook + prog-mode + ;; :config + ;; (add-hook 'prog-mode-hook #'highlight-parentheses-mode) + ) -;;;;;; Chicken Scheme +;;;;; Chicken Scheme (use-package scheme - :elpaca nil + :ensure nil :hook (scheme-mode . eglot-ensure) - (scheme-mode . prettify-symbols-mode) (scheme-mode . (lambda () (setq-local prettify-symbols-alist - '(("lambda" . "λ")))))) + '(("lambda" . "λ") + ("compose" . "∘") + ("and" . "∧") + ("or" . "∨") + ("not" . "¬")))))) (defun flymake-chicken-init () - (add-hook 'flymake-diagnostic-functions - #'flymake-chicken-backend nil t) + (add-hook flymake-diagnostic-functions + flymake-chicken-backend nil t) (flymake-mode)) (use-package geiser-chicken) -;;;;;; Guile +;;;;; Guile (use-package geiser-guile :config @@ -842,13 +728,16 @@ Point must be at the beginning of balanced expression (sexp)." ;; :config ;; (add-hook 'flymake-diagnostic-functions #'flymake-chicken-backend nil t)) -;;;; Other Languages +;;; Other Languages (use-package zig-mode :hook (zig-mode . eglot-ensure) :mode ("\\.zig\\'" . zig-mode)) +(use-package nix-mode + :mode ("\\.nix\\'" . nix-mode)) + ;; (use-package lsp-tailwindcss ;; :init ;; (setq lsp-tailwindcss-add-on-mode t @@ -862,43 +751,90 @@ Point must be at the beginning of balanced expression (sexp)." :hook ((dhall-mode . lsp))) -;;;; Version Control +;;; Version Control -;;;;; Git +;;;; Git + +;; Magit requires 'transient' >= 0.5.0, but due to bad defaults, Emacs' package manager refuses to +;; upgrade this and other built-in packages to higher releases from GNU Elpa. +(use-package transient + :init + (progn (unload-feature 'transient t) + (require 'transient))) +;; To fix this, you have to add this to your init file: +;; (setq package-install-upgrade-built-in t) +;; You must also make sure the updated version is loaded, by evaluating the `progn` form below. (use-package magit - :autoload - magit) + :after magit-popup + :init + (progn (unload-feature 'transient t) + (require 'transient))) + +(use-package hl-todo) (use-package magit-todos - :after magit + :after (magit hl-todo) :hook (magit-mode . magit-todos-mode)) +(use-package magit-popup) + (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 - :delight git-gutter-mode - :hook prog-mode) + :hook + prog-mode + ;; :config + ;; (add-hook 'prog-mode-hook #'git-gutter-mode) + ) +;;; File Formats +;;;; Beancount +(use-package beancount + :vc (:fetcher github :repo "beancount/beancount-mode")) +;;;; Asciidoc +(use-package adoc-mode + :hook + (adoc-mode . visual-line-mode) + (adoc-mode . (lambda () (setq-local visual-fill-column-center-text t)))) -;;;; LaTeX +;;; LaTeX ;; https://github.com/politza/pdf-tools/#known-problems (add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer) -;;;; Communication -;;;;; IRC +;;; Communication + +;;;; E-Mail + +(use-package gnus + :custom + (message-send-mail-function 'message-send-mail-with-sendmail) + (sendmail-program "msmtp") + (message-sendmail-f-is-evil t) + (message-sendmail-extra-arguments '("--read-envelope-from"))) + +(use-package piem + :vc (piem :url "https://git.kyleam.com/piem")) + +(use-package git-email + :vc (:fetcher codeberg :repo "martianh/git-email") + :after (magit piem) + :init + (require 'git-email-magit) + (require 'git-email-gnus) + (require 'git-email-piem)) + +(use-package notmuch) + +(use-package consult-notmuch) + +;;;; IRC (use-package rcirc - :elpaca nil - :ensure t + :ensure nil :after password-store :custom (rcirc-server-alist @@ -921,7 +857,7 @@ Point must be at the beginning of balanced expression (sexp)." :encryption tls :channels ())))) -;;;; Wrapping Up +;;; Wrapping Up (use-package envrc :config (envrc-global-mode)) diff --git a/emacs/init.org b/emacs/init.org index 40746e5..d078932 100644 --- a/emacs/init.org +++ b/emacs/init.org @@ -40,30 +40,54 @@ for authorized =.dir-local= variables and similar stuff. ** Package Manager -I use =straight.el= as package manager. +Most packages are being installed using =Guix=, for the few remaining ones that have to be fetched from Git, I use +[[https://github.com/progfolio/elpaca][Elpaca]]. -#+NAME: straight-settings -| Setting | Value | -|-------------------------+-------| -| Use Straight as default | f | +#+begin_src emacs-lisp +(defvar elpaca-installer-version 0.6) +(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) +(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) +(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) +(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" + :ref nil + :files (:defaults "elpaca-test.el" (:exclude "extensions")) + :build (:not elpaca--activate-package))) +(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) + (build (expand-file-name "elpaca/" elpaca-builds-directory)) + (order (cdr elpaca-order)) + (default-directory repo)) + (add-to-list 'load-path (if (file-exists-p build) build repo)) + (unless (file-exists-p repo) + (make-directory repo t) + (when (< emacs-major-version 28) (require 'subr-x)) + (condition-case-unless-debug err + (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) + ((zerop (call-process "git" nil buffer t "clone" + (plist-get order :repo) repo))) + ((zerop (call-process "git" nil buffer t "checkout" + (or (plist-get order :ref) "--")))) + (emacs (concat invocation-directory invocation-name)) + ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" + "--eval" "(byte-recompile-directory \".\" 0 'force)"))) + ((require 'elpaca)) + ((elpaca-generate-autoloads "elpaca" repo))) + (progn (message "%s" (buffer-string)) (kill-buffer buffer)) + (error "%s" (with-current-buffer buffer (buffer-string)))) + ((error) (warn "%s" err) (delete-directory repo 'recursive)))) + (unless (require 'elpaca-autoloads nil t) + (require 'elpaca) + (elpaca-generate-autoloads "elpaca" repo) + (load "./elpaca-autoloads"))) +(add-hook 'after-init-hook #'elpaca-process-queues) +(elpaca `(,@elpaca-order)) +#+end_src -#+begin_src emacs-lisp :var tbl=straight-settings - (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)) - - (let ((settings (car tbl))) - (setq straight-use-package-by-default - (string= "t" (cl-first settings)))) +A few additional lines are necessary to integrate it with =use-package=: +#+begin_src emacs-lisp +(elpaca elpaca-use-package + (elpaca-use-package-mode) + (setq elpaca-use-package-by-default nil)) +(elpaca-wait) #+end_src * Helper Functions @@ -86,28 +110,47 @@ The first one is a function to create conditional keybindings. * Core Emacs Customization :important: -#+begin_src emacs-lisp -(use-package emacs - :delight (eldoc-mode " 󰙎") - :custom - (completion-cycle-threshold 10) - (display-time-mode t) - (enable-recursive-minibuffers t) - (enable-remote-dir-locals t) - (global-hl-line-mode t) - (indent-tabs-mode nil) - (menu-bar-mode nil) - (minibuffer-prompt-properties (read-only t cursor-intangible t face minibuffer-prompt)) - (read-extended-command-predicate #'command-completion-default-include-p) - (recentf-mode t) - (scroll-bar-mode nil) - (tab-always-indent 'complete) - (tool-bar-mode nil) - :custom-face - (default ((t (:weight bold :height 113 :width normal :family "VictorMono Nerd Font")))) - :hook - (minibuffer-setup . cursor-intangible-mode) - :config - (advice-add 'risky-local-variable-p :override #'ignore)) +Enabled core modes: + +#+NAME: enabled-core-modes +- display-time-mode +- global-hl-line-mode +- global-prettify-symbols-mode +- recentf-mode + +Disabled core modes: + +#+NAME: disabled-core-modes +- indent-tabs-mode +- menu-bar-mode +- scroll-bar-mode +- tool-bar-mode + +#+begin_src emacs-lisp :var enabled=enabled-core-modes :var disabled=disabled-core-modes + (use-package emacs + :custom + (completion-cycle-threshold 10) + (display-time-mode t) + (enable-recursive-minibuffers t) + (enable-remote-dir-locals t) + (fill-column 100) + (global-hl-line-mode t) + (global-prettify-symbols-mode t) + (indent-tabs-mode nil) + (menu-bar-mode nil) + (minibuffer-prompt-properties (read-only t cursor-intangible t face minibuffer-prompt)) + (read-extended-command-predicate #'command-completion-default-include-p) + (recentf-mode t) + (scroll-bar-mode nil) + (tab-always-indent 'complete) + (tool-bar-mode nil) + :custom-face + (default ((t (:weight bold :height 113 :width normal :family "VictorMono Nerd Font")))) + :hook + (minibuffer-setup . cursor-intangible-mode) + :config + (advice-add 'risky-local-variable-p :override #'ignore)) #+end_src +** Sending Mail + diff --git a/home.nix b/home.nix index 19da9f9..057638e 100644 --- a/home.nix +++ b/home.nix @@ -30,8 +30,6 @@ args@{ config, pkgs, split-monitor-workspaces, flatpaks, ... }: iconv kteatime lagrange - libffi - libgccjit liquidprompt kdePackages.dolphin kdePackages.ksshaskpass @@ -39,6 +37,7 @@ args@{ config, pkgs, split-monitor-workspaces, flatpaks, ... }: libuuid lm_sensors gnumake + mattermost # (nerdfonts.override { fonts = [ "VictorMono" "MPlus" ]; }) nerdfonts nixd @@ -57,6 +56,8 @@ args@{ config, pkgs, split-monitor-workspaces, flatpaks, ... }: signal-desktop slurp space-cadet-pinball + lutris + steam sqlite stow swappy @@ -174,14 +175,13 @@ args@{ config, pkgs, split-monitor-workspaces, flatpaks, ... }: packages = [ "flathub:app/com.github.tchx84.Flatseal//stable" "flathub:app/com.usebottles.bottles//stable" - "flathub:app/com.valvesoftware.Steam//stable" "flathub:app/info.beyondallreason.bar//stable" ]; }; services.syncthing = { enable = true; - tray.enable = true; + # tray.enable = true; }; fonts.fontconfig.enable = true;