nixconfig/emacs/init.el
2024-09-07 09:52:01 +02:00

891 lines
26 KiB
EmacsLisp
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; 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://gitea.lyrion.ch/zilti/guixconfig
;; Package-Requires: ((emacs "29.1"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;; Description
;;
;;; Code:
;;; Requirements
;; Since I am using `cl-defun` in this init file, I need to require
;; `cl-macs`.
(require 'cl-macs)
;;; 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))))
;;; 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)
;;; Package Management Configuration
;; See: https://github.com/radian-software/el-patch
(use-package el-patch)
;;;; Guix Management
(use-package guix
:after magit-popup)
;;; Helper Functions
(cl-defun conditional-keybind
(filter-fn target-fn
&optional (fail-fn #'self-insert-command))
"Creates a keybinding that checks `filter-fn`. If it succeeds,
`target-fn` is run, otherwise `fail-fn`. If no fail-fn is given,
`self-insert-command` is run instead.
`target-fn` and `fail-fn` must both be interactive."
(lambda (_prefix)
(interactive "P")
(if (funcall filter-fn)
(call-interactively target-fn)
(call-interactively fail-fn))))
;;; Emacs
(use-package emacs
:after org
: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))
(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 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))
(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
: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
:custom
(org-babel-load-languages '((emacs-lisp . 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)
)
(use-package org-roam
:custom
(org-roam-directory "~/org/roam")
:config
(org-roam-db-autosync-mode))
(use-package consult-notes
:config
(consult-notes-org-roam-mode t))
(use-package websocket
:after org-roam)
(use-package org-roam-ui
: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
: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)
)
(use-package unicode-fonts
:config
(unicode-fonts-setup))
(set-frame-parameter nil 'alpha-background 90)
(add-to-list 'default-frame-alist '(alpha-background . 90))
(use-package 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
(lambda-line-position 'bottom) ;; Set position of status-line
(lambda-line-abbrev t) ;; abbreviate major modes
(lambda-line-hspace " ") ;; add some cushion
(lambda-line-prefix t) ;; use a prefix symbol
(lambda-line-prefix-padding nil) ;; no extra space for prefix
(lambda-line-status-invert nil) ;; no invert colors
(lambda-line-gui-ro-symbol "") ;; symbols
(lambda-line-gui-mod-symbol "")
(lambda-line-gui-rw-symbol "")
(lambda-line-vc-symbol "")
(lambda-line-space-top +.50) ;; padding on top and bottom of line
(lambda-line-space-bottom -.50)
(lambda-line-symbol-position 0.1) ;; adjust the vertical placement of symbol
:config
;; add evil indicator
(advice-add 'lambda-line-compose :around
(lambda (orig-fun status name primary tertiary secondary)
(funcall orig-fun
status
(concat name evil-mode-line-tag)
primary tertiary secondary)))
;; activate lambda-line
(lambda-line-mode)
(lambda-line-clockface-update-fontset "ClockFaceRect")
(customize-set-variable 'flymake-mode-line-counter-format '("" flymake-mode-line-error-counter flymake-mode-line-warning-counter flymake-mode-line-note-counter ""))
(customize-set-variable 'flymake-mode-line-format '(" " flymake-mode-line-exception flymake-mode-line-counters))
;; set divider line in footer
(when (eq lambda-line-position 'top)
(setq-default mode-line-format (list "%_"))
(setq mode-line-format (list "%_"))))
(use-package lambda-themes
:vc (:fetcher github :repo "lambda-emacs/lambda-themes")
:custom
(lambda-themes-set-italic-comments t)
(lambda-themes-set-italic-keywords t)
(lambda-themes-set-variable-pitch t)
:config
;; load preferred theme
(load-theme 'lambda-dark))
;;;; 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
;; :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))
(use-package password-store)
(use-package password-store-otp)
(use-package pass)
;;; Evil Mode
(use-package evil
:init
(setq evil-want-keybinding nil
evil-emacs-state-tag " 󰯸 "
evil-normal-state-tag " 󰰓 "
evil-visual-state-tag " 󰰬 "
evil-insert-state-tag " 󰰅 "
evil-motion-state-tag " 󰬔 "
evil-operator-state-tag " 󰰕 ")
:config
(evil-set-leader 'normal (kbd "<SPC>"))
(evil-set-leader 'normal (kbd "z") t)
(evil-ex-define-cmd "q" 'delete-frame)
(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
:delight evil-collection-unimpaired-mode
:custom
(evil-collection-outline-bind-tab-p 1)
:commands evil-collection-init
:init
(evil-collection-init))
;;; Search, Completion, Execution
;;;; Preliminary Packages
(use-package savehist
:ensure nil
:init
(savehist-mode))
(use-package orderless
:after consult
:config
(with-eval-after-load 'eglot
(setq completion-category-defaults nil))
(setq completion-styles '(orderless basic)
completion-category-defaults nil
completion-category-overrides '((file (styles basic partial-completion)))))
(use-package embark-consult
:hook
(embark-collect-mode . consult-preview-at-point-mode)
:config
(require 'consult-flymake)
(require 'consult-xref)
:custom
(xref-show-xrefs-function #'consult-xref)
:bind
(:map evil-normal-state-map
("<leader><SPC>" . 'consult-find)
("<leader>gs" . 'consult-eglot-symbols)
("<leader>b" . 'consult-buffer)
("<leader>gb" . 'consult-project-buffer)
("<leader>g/" . 'consult-git-grep)
("<leader>/" . 'consult-grep)
("/" . 'consult-line))
("C-<SPC>" . 'embark-act)
("C-M-<return>" . 'embark-bindings))
(use-package wgrep
:config
(setq wgrep-auto-save-buffer t))
(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)
:config
(which-key-mode t))
;;;; Code Completion
(use-package cape
:config
(require 'cape-char)
(require 'cape-keyword)
(defun my/capf ()
(setq completion-at-point-functions
(list (cape-capf-super
#'tempel-complete
#'cape-dabbrev
#'cape-file
#'cape-dict
#'cape-line
#'cape-emoji
#'cape-keyword))))
(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)
(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."
(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))
(corfu-popupinfo-delay '(0.1 . 0.5))
:config
(setq corfu-sort-override-function #'my/corfu-combined-sort)
(add-to-list 'savehist-additional-variables 'corfu-history)
:commands
global-corfu-mode
:init
(require 'corfu-popupinfo)
(require 'corfu-history)
(global-corfu-mode)
(corfu-popupinfo-mode 1)
(corfu-history-mode 1))
(use-package nerd-icons-corfu
:after corfu
:init
(add-to-list 'corfu-margin-formatters 'nerd-icons-corfu-formatter))
(use-package corfu-terminal
:if (not (display-graphic-p))
:after corfu
:hook
global-corfu-mode)
(use-package tempel)
(use-package xref-union
:custom
(xref-union-excluded-backends (lambda (b) (eq b #'etags--xref-backend)))
:hook
cider-mode)
;;; Basic Navigation
(use-package goto-chg
:bind
(:map evil-normal-state-map
("g," . 'goto-last-change)
("g;" . 'goto-last-change-reverse)))
(use-package evil-snipe
: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
(magit-mode . turn-off-evil-snipe-override-mode)
;; See https://github.com/hlissner/evil-snipe/issues/95
;; :config
;; (evilem-define "gs" 'evil-snipe-repeat
;; :bind ((evil-snipe-scope 'buffer)
;; (evil-snipe-enable-highlight)
;; (evil-snipe-enable-incremental-highlight)))
)
(use-package evil-easymotion
:after evil
:config
(evilem-default-keybindings "<leader>"))
;;; 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)."
(interactive)
(transpose-sexps 1)
(forward-sexp -2))
(defun cc/move-sexp-forward ()
"Move balanced expression (sexp) to the right of point forward one sexp.
Point must be at the beginning of balanced expression (sexp)."
(interactive)
(forward-sexp 1)
(transpose-sexps 1)
(forward-sexp -1))
(defvar last-sexp nil)
(defun cc/clone-sexp ()
"Clone the sexp right after the cursor."
(interactive)
(call-interactively #'mark-sexp)
(call-interactively #'kill-ring-save)
(call-interactively #'evil-paste-before)
(call-interactively #'forward-char)
(call-interactively #'paredit-newline))
(defun cc/slurp-forward ()
"Slurps forward when the key is after the closing paren."
(interactive)
(call-interactively #'backward-char)
(call-interactively #'paredit-forward-slurp-sexp))
(defun cc/barf-forward ()
"Barfs forward even when the key is after the closing paren."
(interactive)
(call-interactively #'backward-char)
(call-interactively #'paredit-forward-barf-sexp))
(defun looking-at-opening-paren ()
(looking-at (rx (or "(" "{" "["))))
(defun being-past-closing-paren ()
(looking-back (rx (or ")" "}" "]"))))
;;;; Basic
(use-package paredit
: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)
(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
#'cc/clone-sexp)
(kbd ">") (conditional-keybind #'being-past-closing-paren
#'cc/slurp-forward)
(kbd "<") (conditional-keybind #'being-past-closing-paren
#'cc/barf-forward))
:hook
clojure-ts-mode
clojure-mode
emacs-lisp-mode
scheme-mode)
;;;; Visual Aid
;; (use-package rainbow-delimiters
;; :hook
;; emacs-lisp-mode
;; scheme-mode)
;;; Programming
(use-package editorconfig
:delight editorconfig-mode
:commands
editorconfig-mode
:init
(editorconfig-mode 1))
(use-package flymake
:ensure nil
:delight '(:eval (cons "" (flymake--mode-line-counters))))
(use-package eglot
:ensure nil
:custom
(eglot-connect-timeout 90)
(eglot-autoshutdown t)
(eglot-report-progress t)
:config
(add-to-list 'eglot-server-programs '(scheme-mode . ("chicken-lsp-server")))
(setq-default eglot-workspace-configuration
'((clojure-lsp (maxCompletions . 300))))
: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))
(use-package consult-eglot
:after (consult eglot))
;;;; 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 (embark cider)
:config
(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-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")
:delight (cider-mode '(:eval (concat "  [" (cider--modeline-info) "]")))
:config
(evil-define-key 'normal 'cider-mode-map
(kbd "<localleader>ce") #'cider-eval-sexp-at-point))
;;;; Scheme
(use-package geiser
:custom
(geiser-chicken-match-limit 200)
:config
(defalias 'run-geiser 'geiser))
(use-package paren-face
:hook
scheme-mode
emacs-lisp-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
: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
(use-package scheme
:ensure nil
:hook
(scheme-mode . eglot-ensure)
(scheme-mode . (lambda ()
(setq-local prettify-symbols-alist
'(("lambda" . "λ")
("compose" . "")
("and" . "")
("or" . "")
("not" . "¬"))))))
(defun flymake-chicken-init ()
(add-hook flymake-diagnostic-functions
flymake-chicken-backend nil t)
(flymake-mode))
(use-package geiser-chicken)
;;;;; Guile
(use-package geiser-guile
:config
(when (executable-find "guix")
(add-to-list 'geiser-guile-load-path
(expand-file-name "~/.config/guix/current/share/guile/site/3.0"))))
;; (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 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
;; 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
;; The following snippet is a convenience function for git-commit to add the ticket number, if found
;; in the branch name, to the commit message.
(defun add-git-commit-ticket-id-from-branch ()
"A git-commit-mode-hook which inserts the first consecutive
sequence of at least 3 digits in the current branch name at
the beginning of the commit message buffer (in square
brackets)."
(when-let ((branch (magit-get-current-branch)))
(when (string-match "\\([[:digit:]]\\{3,\\}\\)" branch)
(let ((prefix (format "[T-%s] \n" (match-string 1 branch))))
(goto-char (point-min))
(insert prefix)
(forward-char -1)))))
(add-hook 'git-commit-mode-hook 'add-git-commit-ticket-id-from-branch)
;; 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
:after magit-popup
:init
(progn (unload-feature 'transient t)
(require 'transient)))
(use-package hl-todo)
(use-package magit-todos
:after (magit hl-todo)
:hook
(magit-mode . magit-todos-mode))
(use-package magit-popup)
(use-package forge
:after magit
:custom
(forge-alist '(("github.com" "api.github.com" "github.com" forge-github-repository)
("gitlab.com" "gitlab.com/api/v4" "gitlab.com" forge-gitlab-repository)
("dev.bevuta.com" "dev.bevuta.com/api/v4" "dev.bevuta.com" forge-gitlab-repository)
("codeberg.org" "codeberg.org/api/v1" "codeberg.org" forge-gitea-repository)
("gitea.lyrion.ch:7920" "gitea.oyrion.ch/api/v1" "gitea.lyrion.ch" forge-gitea-repository)
("git.sr.ht" nil "git.sr.ht" forge-srht-repository)))
:config
(advice-add 'magit :after (lambda (&rest _args)
(call-interactively #'forge-pull))))
(use-package git-gutter
: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
;; https://github.com/politza/pdf-tools/#known-problems
(add-hook 'TeX-after-compilation-finished-functions
#'TeX-revert-document-buffer)
;;; 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
:ensure nil
:after password-store
:custom
(rcirc-server-alist
`(("liberachat.irc.lyrion.ch"
:server-alias "irc.libera.chat"
:port 6697
:nick "zilti"
:full-name "Daniel Ziltener"
:user-name "zilti/irc.libera.chat"
:password ,(password-store-get "Privat/Soju")
:encryption tls
:channels ("#chicken")))
`(("oftc.irc.lyrion.ch"
:server-alias "irc.oftc.net"
:port 6697
:nick "zilti"
:full-name "Daniel Ziltener"
:user-name "zilti/irc.oftc.net"
:password ,(password-store-get "Privat/Soju")
:encryption tls
:channels ()))))
;;; Wrapping Up
(use-package envrc
:config
(envrc-global-mode))
(provide 'init)
;;; init.el ends here