From 7cff749776b99c728b35d0ac22502d91f00c6e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Schwarz=C3=A4ugl?= Date: Fri, 6 Mar 2026 12:59:12 +0100 Subject: [PATCH] chore: update emacs structure --- SwarselSystems.org | 602 +++++++++++++++++--------------------- files/emacs/early-init.el | 22 +- files/emacs/init.el | 516 ++++++++++++++++---------------- 3 files changed, 519 insertions(+), 621 deletions(-) diff --git a/SwarselSystems.org b/SwarselSystems.org index 0b8b72c..ac08109 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -31689,22 +31689,22 @@ Also packed into the hook function is the line =(fset 'epg-wait-for-status 'igno (defvar swarsel-file-name-handler-alist file-name-handler-alist) (defvar swarsel-vc-handled-backends vc-handled-backends) + (defun swarsel/restore-startup-settings () + "Restore startup-tuned variables to their regular runtime values." + (setq gc-cons-threshold (* 32 1024 1024) + gc-cons-percentage 0.1 + jit-lock-defer-time 0.05 + read-process-output-max (* 1024 1024) + file-name-handler-alist swarsel-file-name-handler-alist + vc-handled-backends swarsel-vc-handled-backends) + (fset 'epg-wait-for-status #'ignore)) + (setq gc-cons-threshold most-positive-fixnum gc-cons-percentage 0.6 file-name-handler-alist nil vc-handled-backends nil) - (add-hook 'emacs-startup-hook - (lambda () - (progn - (setq gc-cons-threshold (* 32 1024 1024) - gc-cons-percentage 0.1 - jit-lock-defer-time 0.05 - read-process-output-max (* 1024 1024) - file-name-handler-alist swarsel-file-name-handler-alist - vc-handled-backends swarsel-vc-handled-backends) - (fset 'epg-wait-for-status 'ignore) - ))) + (add-hook 'emacs-startup-hook #'swarsel/restore-startup-settings) #+end_src *** Setup frames @@ -32183,7 +32183,27 @@ We set a hook that runs everytime we save the file. It would be a bit more effic (swarsel/run-formatting) ))) - (setq org-html-htmlize-output-type nil) + (defun swarsel/org-babel-tangle-single-block-advice (orig-fun &rest args) + "Run ORIG-FUN with redisplay and messages temporarily inhibited." + (let ((inhibit-redisplay t) + (inhibit-message t)) + (apply orig-fun args))) + + (defun swarsel/org-babel-tangle-timing-advice (orig-fun &rest args) + "Run ORIG-FUN and report elapsed tangle time." + (let ((tim (current-time))) + (prog1 (apply orig-fun args) + (message "org-tangle took %f sec" (float-time (time-subtract (current-time) tim)))))) + + (defun swarsel/markdown-mode-keys () + "Local markdown key customizations." + (local-set-key (kbd "C-c C-x C-l") #'org-latex-preview) + (local-set-key (kbd "C-c C-x C-u") #'markdown-toggle-url-hiding)) + + (defun swarsel/eglot-ensure-and-format () + "Ensure eglot is running and enable format-on-save for current buffer." + (eglot-ensure) + (add-hook 'before-save-hook #'eglot-format nil 'local)) ;; (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'swarsel/org-babel-tangle-config))) @@ -32421,27 +32441,27 @@ I also define some keybinds to some combinations directly. Those are used mostly "wm" '(delete-other-windows :wk "maximize") "" 'up-list "" 'down-list - )) + ) - ;; General often used hotkeys - (general-define-key - "C-M-a" (lambda () (interactive) (org-capture nil "a")) ; make new anki card - "C-c d" 'crux-duplicate-current-line-or-region - "C-c D" 'crux-duplicate-and-comment-current-line-or-region - "" 'swarsel/last-buffer - "M-\\" 'indent-region - "M-r" 'swarsel/consult-magit-repos - "M-i" 'swarsel/org-insert-link-to-heading - "" 'yank - "" 'kill-region - "" 'kill-ring-save - "" 'evil-undo - "" 'evil-redo - "C-S-c C-S-c" 'mc/edit-lines - "C->" 'mc/mark-next-like-this - "C-<" 'mc/mark-previous-like-this - "C-c C-<" 'mc/mark-all-like-this - ) + ;; General often used hotkeys + (general-define-key + "C-M-a" (lambda () (interactive) (org-capture nil "a")) ; make new anki card + "C-c d" 'crux-duplicate-current-line-or-region + "C-c D" 'crux-duplicate-and-comment-current-line-or-region + "" 'swarsel/last-buffer + "M-\\" 'indent-region + "M-r" 'swarsel/consult-magit-repos + "M-i" 'swarsel/org-insert-link-to-heading + "" 'yank + "" 'kill-region + "" 'kill-ring-save + "" 'evil-undo + "" 'evil-redo + "C-S-c C-S-c" 'mc/edit-lines + "C->" 'mc/mark-next-like-this + "C-<" 'mc/mark-previous-like-this + "C-c C-<" 'mc/mark-all-like-this + )) #+end_src *** Directory setup / File structure @@ -32481,9 +32501,10 @@ This section also sets the emacs directory to the =~/.cache/= directory which is url-history-file (expand-file-name "url/history" user-emacs-directory)) ;; Use no-littering to automatically set common paths to the new user-emacs-directory - (use-package no-littering) - (setq custom-file (make-temp-file "emacs-custom-")) - (load custom-file t) + (use-package no-littering + :config + (setq custom-file (make-temp-file "emacs-custom-")) + (load custom-file t)) #+end_src @@ -32511,7 +32532,8 @@ Many people dislike the Emacs backup files; I do enjoy them, but have to admit t delete-old-versions t ; Clean up the backups version-control t ; Use version numbers on backups, kept-new-versions 5 ; keep some new versions - kept-old-versions 2) ; and some old ones, too + kept-old-versions 2 ; and some old ones, too + backup-by-copying-when-linked t) #+end_src ** General init.el setup + UI @@ -32548,7 +32570,7 @@ Here I set up some things that are too minor to put under other categories. (add-hook 'before-save-hook 'delete-trailing-whitespace) (global-hl-line-mode 1) ;; (setq redisplay-dont-pause t) ;; obsolete - (setq blink-cursor-mode nil) ;; blink-cursor is an unexpected source of slowdown + (blink-cursor-mode -1) ;; blink-cursor is an unexpected source of slowdown (global-subword-mode 1) ; Iterate through CamelCase words (setq blink-matching-paren nil) ;; this makes the cursor jump around annoyingly (delete-selection-mode 1) @@ -32560,7 +32582,6 @@ Here I set up some things that are too minor to put under other categories. bidi-display-reordering 'left-to-right bidi-inhibit-bpa t) (global-so-long-mode) - (setq process-adaptive-read-buffering nil) ;; not sure if this is a good idea (setq fast-but-imprecise-scrolling t redisplay-skip-fontification-on-input t inhibit-compacting-font-caches t) @@ -32568,9 +32589,7 @@ Here I set up some things that are too minor to put under other categories. which-func-update-delay 1.0) (setq undo-limit 80000000 evil-want-fine-undo t - auto-save-default t - password-cache-expiry nil - ) + auto-save-default t) (setq browse-url-browser-function 'browse-url-firefox) ;; (setenv "DISPLAY" ":0") ;; needed for firefox ;; disable a keybind that does more harm than good @@ -32661,16 +32680,18 @@ Lastly, I load the =highlight-indent-guides= package. This adds a neat visual in tab-width 2) (setq tab-always-indent 'complete) - (setq python-indent-guess-indent-offset-verbose nil) + + (use-package python + :ensure nil + :custom + (python-indent-guess-indent-offset-verbose nil)) (use-package highlight-indent-guides :hook (prog-mode . highlight-indent-guides-mode) - :init - (setq highlight-indent-guides-method 'column) - (setq highlight-indent-guides-responsive 'top) - ) - - (with-eval-after-load 'highlight-indent-guides + :custom + (highlight-indent-guides-method 'column) + (highlight-indent-guides-responsive nil) + :config (set-face-attribute 'highlight-indent-guides-even-face nil :background "gray10") (set-face-attribute 'highlight-indent-guides-odd-face nil :background "gray20") (set-face-attribute 'highlight-indent-guides-stack-even-face nil :background "gray40") @@ -32779,8 +32800,7 @@ This gives support for many different modes, and works beautifully out of the bo (use-package evil-collection :after evil :config - (evil-collection-init) - (setq forge-add-default-bindings nil)) + (evil-collection-init)) #+end_src **** evil-snipe :PROPERTIES: @@ -32839,7 +32859,7 @@ This makes it so that when setting a mark in evil mode (using =m =), it cre #+begin_src emacs-lisp (use-package evil-visual-mark-mode - :config (evil-visual-mark-mode)) + :commands evil-visual-mark-mode) #+end_src **** evil-textobj-tree-sitter @@ -32853,14 +32873,14 @@ This adds support for tree-sitter objects. This allows for the following chords: #+begin_src emacs-lisp - (use-package evil-textobj-tree-sitter) - ;; bind `function.outer`(entire function block) to `f` for use in things like `vaf`, `yaf` - (define-key evil-outer-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.outer")) - ;; bind `function.inner`(function block without name and args) to `f` for use in things like `vif`, `yif` - (define-key evil-inner-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.inner")) - - ;; You can also bind multiple items and we will match the first one we can find - (define-key evil-outer-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj ("if_statement.outer" "conditional.outer" "loop.outer") '((python-mode . ((if_statement.outer) @if_statement.outer)) (python-ts-mode . ((if_statement.outer) @if_statement.outer))))) + (use-package evil-textobj-tree-sitter + :config + ;; bind `function.outer`(entire function block) to `f` for use in things like `vaf`, `yaf` + (define-key evil-outer-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.outer")) + ;; bind `function.inner`(function block without name and args) to `f` for use in things like `vif`, `yif` + (define-key evil-inner-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.inner")) + ;; You can also bind multiple items and we will match the first one we can find + (define-key evil-outer-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj ("if_statement.outer" "conditional.outer" "loop.outer") '((python-mode . ((if_statement.outer) @if_statement.outer)) (python-ts-mode . ((if_statement.outer) @if_statement.outer)))))) #+end_src **** evil-numbers @@ -33015,21 +33035,21 @@ This is really the perfect solution for me, but it might not be for everyone. (use-package mini-modeline :after smart-mode-line + :custom + (mini-modeline-display-gui-line nil) + (mini-modeline-enhance-visual nil) + (mini-modeline-truncate-p nil) + (mini-modeline-l-format nil) + (mini-modeline-right-padding 5) + (mini-modeline-r-format '("%e" mode-line-front-space mode-line-mule-info mode-line-client + mode-line-modified mode-line-remote mode-line-frame-identification + mode-line-buffer-identification " " mode-line-position " " mode-name evil-mode-line-tag)) :config (mini-modeline-mode t) - (setq mini-modeline-display-gui-line nil) - (setq mini-modeline-enhance-visual nil) - (setq mini-modeline-truncate-p nil) - (setq mini-modeline-l-format nil) - (setq mini-modeline-right-padding 5) - (setq window-divider-mode t) - (setq window-divider-default-places t) - (setq window-divider-default-bottom-width 1) - (setq window-divider-default-right-width 1) - (setq mini-modeline-r-format '("%e" mode-line-front-space mode-line-mule-info mode-line-client - mode-line-modified mode-line-remote mode-line-frame-identification - mode-line-buffer-identification " " mode-line-position " " mode-name evil-mode-line-tag )) - ) + (setq window-divider-default-places t + window-divider-default-bottom-width 1 + window-divider-default-right-width 1) + (window-divider-mode 1)) (use-package smart-mode-line :config @@ -33139,8 +33159,8 @@ The big winner here are the convenient keybinds being setup here for general use #+begin_src emacs-lisp (use-package consult - :config - (setq consult-fontify-max-size 1024) + :custom + (consult-fontify-max-size 1024) :bind (("C-x b" . consult-buffer) ("C-c " . consult-global-mark) @@ -33248,8 +33268,8 @@ This pair of packages provides information on keybinds in addition to function n (use-package which-key :init (which-key-mode) :diminish which-key-mode - :config - (setq which-key-idle-delay 0.3)) + :custom + (which-key-idle-delay 0.3)) (use-package helpful :bind @@ -33257,8 +33277,8 @@ This pair of packages provides information on keybinds in addition to function n ("C-h v" . helpful-variable) ("C-h k" . helpful-key) ("C-h C-." . helpful-at-point)) - :config - (setq help-window-select nil)) + :custom + (help-window-select nil)) #+end_src *** Ligatures @@ -33420,6 +33440,12 @@ This part of the configuration mostly makes some aesthetic changes, enables neat :bind (("C-" . org-fold-outer) ("C-c s" . org-store-link)) + :custom + (org-html-htmlize-output-type nil) + (org-fold-core-style 'overlays) + (org-src-preserve-indentation nil) + (org-export-with-broken-links 'mark) + (org-confirm-babel-evaluate nil) :config (setq org-ellipsis " ⤵" org-link-descriptive t @@ -33442,13 +33468,32 @@ This part of the configuration mostly makes some aesthetic changes, enables neat (setq org-capture-templates '(("t" "Todo" entry (file+headline "~/Org/Tasks.org" "Inbox") "* TODO %?\n %i\n %a") - ("j" "Journal" entry (file+datetree "~/Org/Journal.org") + ("j" "Journal" entry (file+olp+datetree "~/Org/Journal.org") "* %?\nEntered on %U\n %i\n %a"))) (setq org-refile-targets '((swarsel-archive-org-file :maxlevel . 1) (swarsel-tasks-org-file :maxlevel . 1))) + (org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . t) + (python . t) + (js . t) + (shell . t))) + + (add-to-list 'org-src-lang-modes '("conf-unix" . conf-unix)) + + (advice-add 'org-babel-tangle-single-block :around #'swarsel/org-babel-tangle-single-block-advice) + (advice-add 'org-babel-tangle :around #'swarsel/org-babel-tangle-timing-advice) + + (require 'org-tempo) + (add-to-list 'org-structure-template-alist '("sh" . "src shell")) + (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) + (add-to-list 'org-structure-template-alist '("py" . "src python :results output")) + (add-to-list 'org-structure-template-alist '("nix" . "src nix-ts :tangle")) + (add-to-list 'org-structure-template-alist '("ne" . "bash :exports both")) + ) #+end_src @@ -33487,87 +33532,6 @@ Function definition in: [[#h:fa710375-2efe-49b4-af6a-a875aca6e4a2][Visual-fill c #+end_src -**** Fix headings not folding sometimes -:PROPERTIES: -:CUSTOM_ID: h:c1a0adea-ca97-43d7-b5a0-b856d2ebc9a8 -:END: - -There is a weird bug in org-mode that makes it so that headings were not folding correctly sometimes. This setting seems to fix it. - -#+begin_src emacs-lisp - - (setq org-fold-core-style 'overlays) - -#+end_src - -**** Babel -:PROPERTIES: -:CUSTOM_ID: h:3e0b6da3-0497-4080-bb49-bab949c03bc4 -:END: - -org-babel allows to run blocks in other programming languages within an org-mode buffer, similar to what e.g. jupyterhub offers for python. - -It also offers a very useful utility of exporting org-mode buffers to different formats; the feature I enjoy most is what makes this file useful: the tangling functionality. - -***** Language Configuration -:PROPERTIES: -:CUSTOM_ID: h:5d5ed7be-ec5f-4e17-bbb8-820ab6a9961c -:END: - -- This configures the languages that babel recognizes. - -#+begin_src emacs-lisp - (setq org-src-preserve-indentation nil) - - (org-babel-do-load-languages - 'org-babel-load-languages - '((emacs-lisp . t) - (python . t) - (js . t) - (shell . t) - )) - - (push '("conf-unix" . conf-unix) org-src-lang-modes) - - (setq org-export-with-broken-links 'mark) - (setq org-confirm-babel-evaluate nil) - - ;; tangle is too slow, try to speed it up - (defadvice org-babel-tangle-single-block (around inhibit-redisplay activate protect compile) - "inhibit-redisplay and inhibit-message to avoid flicker." - (let ((inhibit-redisplay t) - (inhibit-message t)) - ad-do-it)) - - (defadvice org-babel-tangle (around time-it activate compile) - "Display the execution time" - (let ((tim (current-time))) - ad-do-it - (message "org-tangle took %f sec" (float-time (time-subtract (current-time) tim))))) - - -#+end_src - -***** old easy structure templates (org-tempo) -:PROPERTIES: -:CUSTOM_ID: h:d112ed66-b2dd-45cc-8d70-9cf6631f28a9 -:END: - -- org 9.2 changed the way structure templates work. This brings back the old way it worked. - - Usage: Type =<=, followed by one of the below keywords and press =TAB=. The corresponding source block should appear. - - #+begin_src emacs-lisp - - (require 'org-tempo) - (add-to-list 'org-structure-template-alist '("sh" . "src shell")) - (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) - (add-to-list 'org-structure-template-alist '("py" . "src python :results output")) - (add-to-list 'org-structure-template-alist '("nix" . "src nix-ts :tangle")) - (add-to-list 'org-structure-template-alist '("ne" . "bash :exports both")) - - #+end_src - **** aucTex :PROPERTIES: :CUSTOM_ID: h:4696e2fc-3296-47dc-8fc3-66912c329d4c @@ -33577,33 +33541,20 @@ This provides several utilities for LaTeX in Emacs, including many completions a #+begin_src emacs-lisp - (use-package auctex) - (setq TeX-auto-save t) - (setq TeX-save-query nil) - (setq TeX-parse-self t) - (setq-default TeX-engine 'luatex) - (setq-default TeX-master nil) - - (add-hook 'LaTeX-mode-hook 'visual-line-mode) - (add-hook 'LaTeX-mode-hook 'flyspell-mode) - (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode) - (add-hook 'LaTeX-mode-hook 'reftex-mode) - (setq LaTeX-electric-left-right-brace t) - (setq font-latex-fontify-script nil) - (setq TeX-electric-sub-and-superscript t) - ;; (setq reftex-plug-into-AUCTeX t) - -#+end_src - -**** org-download -:PROPERTIES: -:CUSTOM_ID: h:406e5ecb-66f0-49bf-85ca-8b499f73ec5b -:END: - -This package allows to download and copy images into org-mode buffers. Sadly it does not work in a very stable manner - if you copy images that are also links to another page (like is often the case in a Google image search), Emacs might crash from this. - -#+begin_src emacs-lisp - + (use-package auctex + :hook ((LaTeX-mode . visual-line-mode) + (LaTeX-mode . flyspell-mode) + (LaTeX-mode . LaTeX-math-mode) + (LaTeX-mode . reftex-mode)) + :custom + (TeX-auto-save t) + (TeX-save-query nil) + (TeX-parse-self t) + (TeX-engine 'luatex) + (TeX-master nil) + (LaTeX-electric-left-right-brace t) + (font-latex-fontify-script nil) + (TeX-electric-sub-and-superscript t)) #+end_src @@ -33616,9 +33567,9 @@ This package automatically toggles LaTeX-fragments in org-files. It seems to als #+begin_src emacs-lisp - (use-package org-fragtog) - (add-hook 'org-mode-hook 'org-fragtog-mode) - (add-hook 'markdown-mode-hook 'org-fragtog-mode) + (use-package org-fragtog + :hook ((org-mode . org-fragtog-mode) + (markdown-mode . org-fragtog-mode))) #+end_src @@ -33659,6 +33610,8 @@ When holding presentations, I think it is important to not have too many distrac ("" . swarsel/org-present-next)) :hook ((org-present-mode . swarsel/org-present-start) (org-present-mode-quit . swarsel/org-present-end)) + :config + (add-hook 'org-present-after-navigate-functions #'swarsel/org-present-slide) ) @@ -33744,14 +33697,6 @@ When holding presentations, I think it is important to not have too many distrac (swarsel/org-present-slide) )) - (defun clojure-leave-clojure-mode-function () - ) - - (add-hook 'buffer-list-update-hook #'clojure-leave-clojure-mode-function) - (add-hook 'org-present-mode-hook 'swarsel/org-present-start) - (add-hook 'org-present-mode-quit-hook 'swarsel/org-present-end) - (add-hook 'org-present-after-navigate-functions 'swarsel/org-present-slide) - #+end_src **** Render markdown blocks as body to expand noweb blocks @@ -33808,16 +33753,6 @@ It supports all functions that I normally need. Note that getting completions fo lsp-nix-nixd-home-manager-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.pyramid.options.home-manager.users.type.getSubOptions []" )) - (add-to-list 'auto-mode-alist '("\\.nix\\.enc\\'" . nix-mode)) - (add-to-list 'auto-mode-alist '("\\.nix\\.enc\\'" . nix-ts-mode)) - - - (with-eval-after-load 'lsp-mode - (lsp-register-client - (make-lsp-client :new-connection (lsp-stdio-connection "nixd") - :major-modes '(nix-mode nix-ts-mode) - :priority 0 - :server-id 'nixd))) #+end_src *** HCL Mode :PROPERTIES: @@ -33830,8 +33765,8 @@ This adds support for Hashicorp Configuration Language. Used at work, it is most (use-package hcl-mode :mode "\\.hcl\\'" - :config - (setq hcl-indent-level 2)) + :custom + (hcl-indent-level 2)) #+end_src *** Jenkinsfile/Groovy @@ -33886,11 +33821,10 @@ This adds support for Terraform configuration files. This is basically the same (use-package terraform-mode :mode "\\.tf\\'" - :config - (setq terraform-indent-level 2) - (setq terraform-format-on-save t)) - - (add-hook 'terraform-mode-hook #'outline-minor-mode) + :hook (terraform-mode . outline-minor-mode) + :custom + (terraform-indent-level 2) + (terraform-format-on-save t)) #+end_src *** nix formatting @@ -33918,9 +33852,9 @@ Adds functions for formatting shellscripts. Similarly to [[id:460a47fd-cddc-4080 #+begin_src emacs-lisp (use-package shfmt - :config - (setq shfmt-command "shfmt") - (setq shfmt-arguments '("-i" "4" "-s" "-sr"))) + :custom + (shfmt-command "shfmt") + (shfmt-arguments '("-i" "4" "-s" "-sr"))) #+end_src @@ -33937,14 +33871,16 @@ Adds a mode for markdown, specifically MultiMarkdown, which allows me to render #+begin_src emacs-lisp - (setq markdown-command "pandoc") - (use-package markdown-mode :ensure t :mode ("README\\.md\\'" . gfm-mode) - :init (setq markdown-command "multimarkdown") + :init + (setq markdown-command "multimarkdown") + :hook (markdown-mode . swarsel/markdown-mode-keys) :bind (:map markdown-mode-map - ("C-c C-e" . markdown-do))) + ("C-c C-e" . markdown-do) + ("C-c C-x C-l" . org-latex-preview) + ("C-c C-x C-u" . markdown-toggle-url-hiding))) #+end_src @@ -33955,13 +33891,9 @@ Adds a mode for markdown, specifically MultiMarkdown, which allows me to render Allows me to render LaTeX just where I write it. I do not need this as much anymore, but during my studies this was very valuable to me. -#+begin_src emacs-lisp +#+begin_src emacs-lisp :tangle no - (add-hook 'markdown-mode-hook - (lambda () - (local-set-key (kbd "C-c C-x C-l") 'org-latex-preview) - (local-set-key (kbd "C-c C-x C-u") 'markdown-toggle-url-hiding) - )) + ;; Keybindings are configured in use-package markdown-mode above. #+end_src @@ -33974,37 +33906,37 @@ This adds elfeed, a neat RSS reader for Emacs. I use this as a client for [[#h:9 #+begin_src emacs-lisp - (use-package elfeed) - - (use-package elfeed-goodies) - (elfeed-goodies/setup) - - (setq elfeed-db-directory "~/.elfeed/db/") + (use-package elfeed + :custom + (elfeed-db-directory "~/.elfeed/db/") + (elfeed-use-curl t) + (elfeed-set-timeout 36000) + :config + (define-key elfeed-show-mode-map (kbd ";") #'visual-fill-column-mode) + (define-key elfeed-show-mode-map (kbd "j") #'elfeed-goodies/split-show-next) + (define-key elfeed-show-mode-map (kbd "k") #'elfeed-goodies/split-show-prev) + (define-key elfeed-search-mode-map (kbd "j") #'next-line) + (define-key elfeed-search-mode-map (kbd "k") #'previous-line) + (define-key elfeed-show-mode-map (kbd "S-SPC") #'scroll-down-command)) + (use-package elfeed-goodies + :after elfeed + :config + (elfeed-goodies/setup)) (use-package elfeed-protocol - :after elfeed) - - (elfeed-protocol-enable) - (setq elfeed-use-curl t) - (setq elfeed-set-timeout 36000) - (setq elfeed-protocol-enabled-protocols '(fever)) - (setq elfeed-protocol-fever-update-unread-only t) - (setq elfeed-protocol-fever-fetch-category-as-tag t) - - (let ((domain (getenv "SWARSEL_RSS_DOMAIN"))) - (setq elfeed-protocol-feeds - `((,(concat "fever+https://Swarsel@" domain) - :api-url ,(concat "https://" domain "/api/fever.php") - :password-file "~/.emacs.d/.fever")))) - - - (define-key elfeed-show-mode-map (kbd ";") 'visual-fill-column-mode) - (define-key elfeed-show-mode-map (kbd "j") 'elfeed-goodies/split-show-next) - (define-key elfeed-show-mode-map (kbd "k") 'elfeed-goodies/split-show-prev) - (define-key elfeed-search-mode-map (kbd "j") 'next-line) - (define-key elfeed-search-mode-map (kbd "k") 'previous-line) - (define-key elfeed-show-mode-map (kbd "S-SPC") 'scroll-down-command) + :after elfeed + :custom + (elfeed-protocol-enabled-protocols '(fever)) + (elfeed-protocol-fever-update-unread-only t) + (elfeed-protocol-fever-fetch-category-as-tag t) + :config + (elfeed-protocol-enable) + (let ((domain (getenv "SWARSEL_RSS_DOMAIN"))) + (setq elfeed-protocol-feeds + `((,(concat "fever+https://Swarsel@" domain) + :api-url ,(concat "https://" domain "/api/fever.php") + :password-file "~/.emacs.d/.fever"))))) #+end_src @@ -34071,7 +34003,7 @@ In order to update the language grammars, run the next command below. NOTE: sinc (use-package treesit-auto :custom - (setq treesit-auto-install t) + (treesit-auto-install t) :config (treesit-auto-add-to-auto-mode-alist 'all) (global-treesit-auto-mode)) @@ -34112,8 +34044,8 @@ In emacs, there are two packages for managing dev environments - emacs-direnv (d (use-package avy :bind (("M-o" . avy-goto-char-timer)) - :config - (setq avy-all-windows 'all-frames)) + :custom + (avy-all-windows 'all-frames)) #+end_src @@ -34128,22 +34060,14 @@ To install a documentation, use the =devdocs=install= command and select the app #+begin_src emacs-lisp - (use-package devdocs) - - (add-hook 'python-mode-hook - (lambda () (setq-local devdocs-current-docs '("python~3.12" "numpy~1.23" "matplotlib~3.7" "pandas~1")))) - (add-hook 'python-ts-mode-hook - (lambda () (setq-local devdocs-current-docs '("python~3.12" "numpy~1.23" "matplotlib~3.7" "pandas~1")))) - - (add-hook 'c-mode-hook - (lambda () (setq-local devdocs-current-docs '("c")))) - (add-hook 'c-ts-mode-hook - (lambda () (setq-local devdocs-current-docs '("c")))) - - (add-hook 'c++-mode-hook - (lambda () (setq-local devdocs-current-docs '("cpp")))) - (add-hook 'c++-ts-mode-hook - (lambda () (setq-local devdocs-current-docs '("cpp")))) + (use-package devdocs + :hook ((python-mode . (lambda () (setq-local devdocs-current-docs '("python~3.12" "numpy~1.23" "matplotlib~3.7" "pandas~1")))) + (python-ts-mode . (lambda () (setq-local devdocs-current-docs '("python~3.12" "numpy~1.23" "matplotlib~3.7" "pandas~1")))) + (c-mode . (lambda () (setq-local devdocs-current-docs '("c")))) + (c-ts-mode . (lambda () (setq-local devdocs-current-docs '("c")))) + (c++-mode . (lambda () (setq-local devdocs-current-docs '("cpp")))) + (c++-ts-mode . (lambda () (setq-local devdocs-current-docs '("cpp"))))) + ) ; (devdocs-update-all) @@ -34205,10 +34129,11 @@ The following settings are needed to make sure emacs works for magit commits and ;; yubikey support for pushing commits ;; commiting is enabled through nixos gpg-agent config - (use-package pinentry) - (pinentry-start) - (setq epg-pinentry-mode 'loopback) - (setenv "SSH_AUTH_SOCK" (string-chop-newline (shell-command-to-string "gpgconf --list-dirs agent-ssh-socket"))) + (use-package pinentry + :config + (pinentry-start) + (setq epg-pinentry-mode 'loopback) + (setenv "SSH_AUTH_SOCK" (string-chop-newline (shell-command-to-string "gpgconf --list-dirs agent-ssh-socket")))) #+end_src *** Forge @@ -34231,7 +34156,9 @@ NOTE: Make sure to configure a GitHub token before using this package! #+begin_src emacs-lisp (use-package forge - :after magit) + :after magit + :init + (setq forge-add-default-bindings nil)) #+end_src @@ -34299,7 +34226,7 @@ Complimentary to the delimiters-packages above, this package sets the background #+begin_src emacs-lisp (use-package rainbow-mode - :config (rainbow-mode)) + :hook ((css-mode css-ts-mode web-mode html-mode html-ts-mode) . rainbow-mode)) #+end_src *** Corfu @@ -34347,15 +34274,15 @@ Navigation functions defined here: [[#h:a1802f9b-bb71-4fd5-86fa-945da18e8b81][co (" " . swarsel/corfu-quit-and-down)) ) - (use-package nerd-icons-corfu) - - (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter) - - (setq nerd-icons-corfu-mapping - '((array :style "cod" :icon "symbol_array" :face font-lock-type-face) - (boolean :style "cod" :icon "symbol_boolean" :face font-lock-builtin-face) - ;; ... - (t :style "cod" :icon "code" :face font-lock-warning-face))) + (use-package nerd-icons-corfu + :after corfu + :config + (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter) + (setq nerd-icons-corfu-mapping + '((array :style "cod" :icon "symbol_array" :face font-lock-type-face) + (boolean :style "cod" :icon "symbol_boolean" :face font-lock-builtin-face) + ;; ... + (t :style "cod" :icon "code" :face font-lock-warning-face)))) #+end_src @@ -34451,9 +34378,6 @@ Tramp allows for SSH access of files over Emacs. I have no ideas what the option "-o ControlMaster=auto -o ControlPersist=yes")) ) - (setq vterm-tramp-shells '(("ssh" "'sh'"))) - - #+end_src @@ -34471,7 +34395,6 @@ This is a simple highlighting utility that uses the margin to visually show the ((prog-mode org-mode) . diff-hl-mode) :init - (diff-hl-flydiff-mode) (diff-hl-margin-mode) (diff-hl-show-hunk-mouse-mode)) @@ -34530,19 +34453,17 @@ A blocking issue can still occur while entering a direnv that has a longer evalu ;;rustic-mode tex-mode LaTeX-mode - ) . (lambda () (progn - (eglot-ensure) - (add-hook 'before-save-hook 'eglot-format nil 'local)))) + ) . swarsel/eglot-ensure-and-format) :custom (eldoc-echo-area-use-multiline-p nil) - (completion-category-defaults nil) - (fset #'jsonrpc--log-event #'ignore) (eglot-events-buffer-size 0) (eglot-sync-connect nil) (eglot-connect-timeout nil) (eglot-autoshutdown t) (eglot-send-changes-idle-time 3) (flymake-no-changes-timeout 5) + :config + (fset #'jsonrpc--log-event #'ignore) :bind (:map eglot-mode-map ("M-(" . flymake-goto-next-error) ("C-c ," . eglot-code-actions))) @@ -34570,7 +34491,13 @@ company is now disabled since it seems that corfu runs just fine with lsp-mode a ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l") (setq lsp-keymap-prefix "C-c l") (setq lsp-auto-guess-root "t") - :commands lsp) + :commands lsp + :config + (lsp-register-client + (make-lsp-client :new-connection (lsp-stdio-connection "nixd") + :major-modes '(nix-mode nix-ts-mode) + :priority 0 + :server-id 'nixd))) ;; (use-package company) @@ -34654,7 +34581,7 @@ This brings back warnings and errors on the sideline for eglot; a feature that I This setting ensures that hard links are preserved during the backup process, which is useful for maintaining the integrity of files that are linked in multiple locations. -#+begin_src emacs-lisp +#+begin_src emacs-lisp :tangle no (setq backup-by-copying-when-linked t) @@ -34797,6 +34724,8 @@ The hook functions are defined here: [[#h:34506761-06b9-43b5-a818-506d9b3faf28][ :ensure nil ;; :load-path "/usr/share/emacs/site-lisp/mu4e/" ;;:defer 20 ; Wait until 20 seconds after startup + :hook ((mu4e-compose-mode . swarsel/mu4e-send-from-correct-address) + (mu4e-compose-post . swarsel/mu4e-restore-default)) :config ;; This is set to 't' to avoid mail syncing issues when using mbsync @@ -34840,11 +34769,30 @@ The hook functions are defined here: [[#h:34506761-06b9-43b5-a818-506d9b3faf28][ ;; this does the equivalent of (setq mu4e-user-mail-address-list '(address1@about.com address2@about.com [...]))) (setq mu4e-user-mail-address-list (mapcar #'intern (split-string (or (getenv "SWARSEL_MAIL_ALL") "") "[ ,]+" t))) + + (setq mu4e--log-max-size 1000) + + (mu4e t) + + (let ((work (getenv "SWARSEL_MAIL_WORK"))) + (when (and work (not (string-empty-p work))) + (setq swarsel-smime-cert-path "~/.Certificates/$SWARSEL_MAIL_WORK.pem") + (setq swarsel-smime-cert-path (substitute-env-vars swarsel-smime-cert-path)) + (setq mml-secure-prefer-scheme 'smime) + (setq mml-secure-smime-sign-with-sender t) + (add-hook 'mu4e-compose-mode-hook + (lambda () + (when (and (boundp 'user-mail-address) + (stringp user-mail-address) + (string-equal user-mail-address (getenv "SWARSEL_MAIL_WORK"))) + (mml-secure-message-sign-smime)))) + (setq smime-keys + `((,(getenv "SWARSEL_MAIL_WORK") + ,swarsel-smime-cert-path + ("~/Certificates/harica-root.pem" + "~/Certificates/harica-intermediate.pem")))) + )) ) - - - (add-hook 'mu4e-compose-mode-hook #'swarsel/mu4e-send-from-correct-address) - (add-hook 'mu4e-compose-post-hook #'swarsel/mu4e-restore-default) #+end_src **** mu4e-alert @@ -34873,40 +34821,8 @@ This adds the simple utility of sending desktop notifications whenever a new mai (add-hook 'after-init-hook #'mu4e-alert-enable-notifications) ) - (mu4e t) #+end_src -**** Work: Signing Mails (S/MIME, smime) -:PROPERTIES: -:CUSTOM_ID: h:3584632a-9d6d-4ba6-8aa5-e1383581993c -:END: - -Used to automatically sign messages sent from my work email address using S/MIME certificate. - -#+begin_src emacs-lisp - (let ((work (getenv "SWARSEL_MAIL_WORK"))) - (when (and work (not (string-empty-p work))) - - (setq swarsel-smime-cert-path "~/.Certificates/$SWARSEL_MAIL_WORK.pem") - (setq swarsel-smime-cert-path (substitute-env-vars swarsel-smime-cert-path)) - (setq mml-secure-prefer-scheme 'smime) - (setq mml-secure-smime-sign-with-sender t) - (add-hook 'mu4e-compose-mode-hook - (lambda () - (when (and (boundp 'user-mail-address) - (stringp user-mail-address) - (string-equal user-mail-address (getenv "SWARSEL_MAIL_WORK"))) - (mml-secure-message-sign-smime)))) - - (setq smime-keys - `((,(getenv "SWARSEL_MAIL_WORK") - ,swarsel-smime-cert-path - ("~/Certificates/harica-root.pem" - "~/Certificates/harica-intermediate.pem" - )))) - )) - -#+end_src *** Calendar :PROPERTIES: @@ -35057,8 +34973,11 @@ This sets up the =dashboard=, which is really quite useless. But, it looks cool ) )))) -(add-to-list 'recentf-exclude "\\Archive\\.org\\'") -(add-to-list 'recentf-exclude "\\Tasks\\.org\\'") +(use-package recentf + :ensure nil + :config + (add-to-list 'recentf-exclude "\\Archive\\.org\\'") + (add-to-list 'recentf-exclude "\\Tasks\\.org\\'")) #+end_src @@ -35070,7 +34989,9 @@ This sets up the =dashboard=, which is really quite useless. But, it looks cool #+begin_src emacs-lisp (use-package vterm - :ensure t) + :ensure t + :custom + (vterm-tramp-shells '(("ssh" "'sh'")))) #+end_src @@ -35091,7 +35012,6 @@ This sets up the =dashboard=, which is really quite useless. But, it looks cool #+begin_src emacs-lisp - (setq mu4e--log-max-size 1000) (setq message-log-max 30) (setq comint-buffer-maximum-size 50) (add-hook 'comint-output-filter-functions 'comint-truncate-buffer) diff --git a/files/emacs/early-init.el b/files/emacs/early-init.el index b86d1c1..de4015e 100644 --- a/files/emacs/early-init.el +++ b/files/emacs/early-init.el @@ -2,22 +2,22 @@ (defvar swarsel-file-name-handler-alist file-name-handler-alist) (defvar swarsel-vc-handled-backends vc-handled-backends) + (defun swarsel/restore-startup-settings () + "Restore startup-tuned variables to their regular runtime values." + (setq gc-cons-threshold (* 32 1024 1024) + gc-cons-percentage 0.1 + jit-lock-defer-time 0.05 + read-process-output-max (* 1024 1024) + file-name-handler-alist swarsel-file-name-handler-alist + vc-handled-backends swarsel-vc-handled-backends) + (fset 'epg-wait-for-status #'ignore)) + (setq gc-cons-threshold most-positive-fixnum gc-cons-percentage 0.6 file-name-handler-alist nil vc-handled-backends nil) - (add-hook 'emacs-startup-hook - (lambda () - (progn - (setq gc-cons-threshold (* 32 1024 1024) - gc-cons-percentage 0.1 - jit-lock-defer-time 0.05 - read-process-output-max (* 1024 1024) - file-name-handler-alist swarsel-file-name-handler-alist - vc-handled-backends swarsel-vc-handled-backends) - (fset 'epg-wait-for-status 'ignore) - ))) + (add-hook 'emacs-startup-hook #'swarsel/restore-startup-settings) (tool-bar-mode 0) (menu-bar-mode 0) diff --git a/files/emacs/init.el b/files/emacs/init.el index 580ccbb..b42ef75 100644 --- a/files/emacs/init.el +++ b/files/emacs/init.el @@ -213,7 +213,27 @@ create a new one." (swarsel/run-formatting) ))) -(setq org-html-htmlize-output-type nil) +(defun swarsel/org-babel-tangle-single-block-advice (orig-fun &rest args) + "Run ORIG-FUN with redisplay and messages temporarily inhibited." + (let ((inhibit-redisplay t) + (inhibit-message t)) + (apply orig-fun args))) + +(defun swarsel/org-babel-tangle-timing-advice (orig-fun &rest args) + "Run ORIG-FUN and report elapsed tangle time." + (let ((tim (current-time))) + (prog1 (apply orig-fun args) + (message "org-tangle took %f sec" (float-time (time-subtract (current-time) tim)))))) + +(defun swarsel/markdown-mode-keys () + "Local markdown key customizations." + (local-set-key (kbd "C-c C-x C-l") #'org-latex-preview) + (local-set-key (kbd "C-c C-x C-u") #'markdown-toggle-url-hiding)) + +(defun swarsel/eglot-ensure-and-format () + "Ensure eglot is running and enable format-on-save for current buffer." + (eglot-ensure) + (add-hook 'before-save-hook #'eglot-format nil 'local)) ;; (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'swarsel/org-babel-tangle-config))) @@ -380,27 +400,27 @@ create a new one." "wm" '(delete-other-windows :wk "maximize") "" 'up-list "" 'down-list - )) + ) -;; General often used hotkeys -(general-define-key - "C-M-a" (lambda () (interactive) (org-capture nil "a")) ; make new anki card - "C-c d" 'crux-duplicate-current-line-or-region - "C-c D" 'crux-duplicate-and-comment-current-line-or-region - "" 'swarsel/last-buffer - "M-\\" 'indent-region - "M-r" 'swarsel/consult-magit-repos - "M-i" 'swarsel/org-insert-link-to-heading - "" 'yank - "" 'kill-region - "" 'kill-ring-save - "" 'evil-undo - "" 'evil-redo - "C-S-c C-S-c" 'mc/edit-lines - "C->" 'mc/mark-next-like-this - "C-<" 'mc/mark-previous-like-this - "C-c C-<" 'mc/mark-all-like-this - ) + ;; General often used hotkeys + (general-define-key + "C-M-a" (lambda () (interactive) (org-capture nil "a")) ; make new anki card + "C-c d" 'crux-duplicate-current-line-or-region + "C-c D" 'crux-duplicate-and-comment-current-line-or-region + "" 'swarsel/last-buffer + "M-\\" 'indent-region + "M-r" 'swarsel/consult-magit-repos + "M-i" 'swarsel/org-insert-link-to-heading + "" 'yank + "" 'kill-region + "" 'kill-ring-save + "" 'evil-undo + "" 'evil-redo + "C-S-c C-S-c" 'mc/edit-lines + "C->" 'mc/mark-next-like-this + "C-<" 'mc/mark-previous-like-this + "C-c C-<" 'mc/mark-all-like-this + )) ;; set Nextcloud directory for journals etc. (setq @@ -418,9 +438,10 @@ create a new one." url-history-file (expand-file-name "url/history" user-emacs-directory)) ;; Use no-littering to automatically set common paths to the new user-emacs-directory -(use-package no-littering) -(setq custom-file (make-temp-file "emacs-custom-")) -(load custom-file t) +(use-package no-littering + :config + (setq custom-file (make-temp-file "emacs-custom-")) + (load custom-file t)) (let ((backup-dir "~/tmp/emacs/backups") (auto-saves-dir "~/tmp/emacs/auto-saves/")) @@ -437,7 +458,8 @@ create a new one." delete-old-versions t ; Clean up the backups version-control t ; Use version numbers on backups, kept-new-versions 5 ; keep some new versions - kept-old-versions 2) ; and some old ones, too + kept-old-versions 2 ; and some old ones, too + backup-by-copying-when-linked t) ;; use UTF-8 everywhere (set-language-environment "UTF-8") @@ -452,7 +474,7 @@ create a new one." (add-hook 'before-save-hook 'delete-trailing-whitespace) (global-hl-line-mode 1) ;; (setq redisplay-dont-pause t) ;; obsolete -(setq blink-cursor-mode nil) ;; blink-cursor is an unexpected source of slowdown +(blink-cursor-mode -1) ;; blink-cursor is an unexpected source of slowdown (global-subword-mode 1) ; Iterate through CamelCase words (setq blink-matching-paren nil) ;; this makes the cursor jump around annoyingly (delete-selection-mode 1) @@ -464,7 +486,6 @@ create a new one." bidi-display-reordering 'left-to-right bidi-inhibit-bpa t) (global-so-long-mode) -(setq process-adaptive-read-buffering nil) ;; not sure if this is a good idea (setq fast-but-imprecise-scrolling t redisplay-skip-fontification-on-input t inhibit-compacting-font-caches t) @@ -472,9 +493,7 @@ create a new one." which-func-update-delay 1.0) (setq undo-limit 80000000 evil-want-fine-undo t - auto-save-default t - password-cache-expiry nil - ) + auto-save-default t) (setq browse-url-browser-function 'browse-url-firefox) ;; (setenv "DISPLAY" ":0") ;; needed for firefox ;; disable a keybind that does more harm than good @@ -519,16 +538,18 @@ create a new one." tab-width 2) (setq tab-always-indent 'complete) -(setq python-indent-guess-indent-offset-verbose nil) + +(use-package python + :ensure nil + :custom + (python-indent-guess-indent-offset-verbose nil)) (use-package highlight-indent-guides :hook (prog-mode . highlight-indent-guides-mode) - :init - (setq highlight-indent-guides-method 'column) - (setq highlight-indent-guides-responsive 'top) - ) - -(with-eval-after-load 'highlight-indent-guides + :custom + (highlight-indent-guides-method 'column) + (highlight-indent-guides-responsive nil) + :config (set-face-attribute 'highlight-indent-guides-even-face nil :background "gray10") (set-face-attribute 'highlight-indent-guides-odd-face nil :background "gray20") (set-face-attribute 'highlight-indent-guides-stack-even-face nil :background "gray40") @@ -598,8 +619,7 @@ create a new one." (use-package evil-collection :after evil :config - (evil-collection-init) - (setq forge-add-default-bindings nil)) + (evil-collection-init)) ;; enables 2-char inline search (use-package evil-snipe @@ -619,16 +639,16 @@ create a new one." (global-evil-surround-mode 1)) (use-package evil-visual-mark-mode - :config (evil-visual-mark-mode)) + :commands evil-visual-mark-mode) -(use-package evil-textobj-tree-sitter) -;; bind `function.outer`(entire function block) to `f` for use in things like `vaf`, `yaf` -(define-key evil-outer-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.outer")) -;; bind `function.inner`(function block without name and args) to `f` for use in things like `vif`, `yif` -(define-key evil-inner-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.inner")) - -;; You can also bind multiple items and we will match the first one we can find -(define-key evil-outer-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj ("if_statement.outer" "conditional.outer" "loop.outer") '((python-mode . ((if_statement.outer) @if_statement.outer)) (python-ts-mode . ((if_statement.outer) @if_statement.outer))))) +(use-package evil-textobj-tree-sitter + :config + ;; bind `function.outer`(entire function block) to `f` for use in things like `vaf`, `yaf` + (define-key evil-outer-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.outer")) + ;; bind `function.inner`(function block without name and args) to `f` for use in things like `vif`, `yif` + (define-key evil-inner-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.inner")) + ;; You can also bind multiple items and we will match the first one we can find + (define-key evil-outer-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj ("if_statement.outer" "conditional.outer" "loop.outer") '((python-mode . ((if_statement.outer) @if_statement.outer)) (python-ts-mode . ((if_statement.outer) @if_statement.outer)))))) (use-package evil-numbers) @@ -681,21 +701,21 @@ create a new one." (use-package mini-modeline :after smart-mode-line + :custom + (mini-modeline-display-gui-line nil) + (mini-modeline-enhance-visual nil) + (mini-modeline-truncate-p nil) + (mini-modeline-l-format nil) + (mini-modeline-right-padding 5) + (mini-modeline-r-format '("%e" mode-line-front-space mode-line-mule-info mode-line-client + mode-line-modified mode-line-remote mode-line-frame-identification + mode-line-buffer-identification " " mode-line-position " " mode-name evil-mode-line-tag)) :config (mini-modeline-mode t) - (setq mini-modeline-display-gui-line nil) - (setq mini-modeline-enhance-visual nil) - (setq mini-modeline-truncate-p nil) - (setq mini-modeline-l-format nil) - (setq mini-modeline-right-padding 5) - (setq window-divider-mode t) - (setq window-divider-default-places t) - (setq window-divider-default-bottom-width 1) - (setq window-divider-default-right-width 1) - (setq mini-modeline-r-format '("%e" mode-line-front-space mode-line-mule-info mode-line-client - mode-line-modified mode-line-remote mode-line-frame-identification - mode-line-buffer-identification " " mode-line-position " " mode-name evil-mode-line-tag )) - ) + (setq window-divider-default-places t + window-divider-default-bottom-width 1 + window-divider-default-right-width 1) + (window-divider-mode 1)) (use-package smart-mode-line :config @@ -746,8 +766,8 @@ create a new one." orderless-matching-styles '(orderless-literal orderless-regexp))) (use-package consult - :config - (setq consult-fontify-max-size 1024) + :custom + (consult-fontify-max-size 1024) :bind (("C-x b" . consult-buffer) ("C-c " . consult-global-mark) @@ -803,8 +823,8 @@ create a new one." (use-package which-key :init (which-key-mode) :diminish which-key-mode - :config - (setq which-key-idle-delay 0.3)) + :custom + (which-key-idle-delay 0.3)) (use-package helpful :bind @@ -812,8 +832,8 @@ create a new one." ("C-h v" . helpful-variable) ("C-h k" . helpful-key) ("C-h C-." . helpful-at-point)) - :config - (setq help-window-select nil)) + :custom + (help-window-select nil)) (use-package ligature :init @@ -901,6 +921,12 @@ create a new one." :bind (("C-" . org-fold-outer) ("C-c s" . org-store-link)) + :custom + (org-html-htmlize-output-type nil) + (org-fold-core-style 'overlays) + (org-src-preserve-indentation nil) + (org-export-with-broken-links 'mark) + (org-confirm-babel-evaluate nil) :config (setq org-ellipsis " ⤵" org-link-descriptive t @@ -923,13 +949,32 @@ create a new one." (setq org-capture-templates '(("t" "Todo" entry (file+headline "~/Org/Tasks.org" "Inbox") "* TODO %?\n %i\n %a") - ("j" "Journal" entry (file+datetree "~/Org/Journal.org") + ("j" "Journal" entry (file+olp+datetree "~/Org/Journal.org") "* %?\nEntered on %U\n %i\n %a"))) (setq org-refile-targets '((swarsel-archive-org-file :maxlevel . 1) (swarsel-tasks-org-file :maxlevel . 1))) + (org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . t) + (python . t) + (js . t) + (shell . t))) + + (add-to-list 'org-src-lang-modes '("conf-unix" . conf-unix)) + + (advice-add 'org-babel-tangle-single-block :around #'swarsel/org-babel-tangle-single-block-advice) + (advice-add 'org-babel-tangle :around #'swarsel/org-babel-tangle-timing-advice) + + (require 'org-tempo) + (add-to-list 'org-structure-template-alist '("sh" . "src shell")) + (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) + (add-to-list 'org-structure-template-alist '("py" . "src python :results output")) + (add-to-list 'org-structure-template-alist '("nix" . "src nix-ts :tangle")) + (add-to-list 'org-structure-template-alist '("ne" . "bash :exports both")) + ) (use-package org-appear @@ -943,64 +988,24 @@ create a new one." (use-package visual-fill-column :hook (org-mode . swarsel/org-mode-visual-fill)) -(setq org-fold-core-style 'overlays) +(use-package auctex + :hook ((LaTeX-mode . visual-line-mode) + (LaTeX-mode . flyspell-mode) + (LaTeX-mode . LaTeX-math-mode) + (LaTeX-mode . reftex-mode)) + :custom + (TeX-auto-save t) + (TeX-save-query nil) + (TeX-parse-self t) + (TeX-engine 'luatex) + (TeX-master nil) + (LaTeX-electric-left-right-brace t) + (font-latex-fontify-script nil) + (TeX-electric-sub-and-superscript t)) -(setq org-src-preserve-indentation nil) - -(org-babel-do-load-languages - 'org-babel-load-languages - '((emacs-lisp . t) - (python . t) - (js . t) - (shell . t) - )) - -(push '("conf-unix" . conf-unix) org-src-lang-modes) - -(setq org-export-with-broken-links 'mark) -(setq org-confirm-babel-evaluate nil) - -;; tangle is too slow, try to speed it up -(defadvice org-babel-tangle-single-block (around inhibit-redisplay activate protect compile) - "inhibit-redisplay and inhibit-message to avoid flicker." - (let ((inhibit-redisplay t) - (inhibit-message t)) - ad-do-it)) - -(defadvice org-babel-tangle (around time-it activate compile) - "Display the execution time" - (let ((tim (current-time))) - ad-do-it - (message "org-tangle took %f sec" (float-time (time-subtract (current-time) tim))))) - -(require 'org-tempo) -(add-to-list 'org-structure-template-alist '("sh" . "src shell")) -(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) -(add-to-list 'org-structure-template-alist '("py" . "src python :results output")) -(add-to-list 'org-structure-template-alist '("nix" . "src nix-ts :tangle")) -(add-to-list 'org-structure-template-alist '("ne" . "bash :exports both")) - -(use-package auctex) -(setq TeX-auto-save t) -(setq TeX-save-query nil) -(setq TeX-parse-self t) -(setq-default TeX-engine 'luatex) -(setq-default TeX-master nil) - -(add-hook 'LaTeX-mode-hook 'visual-line-mode) -(add-hook 'LaTeX-mode-hook 'flyspell-mode) -(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode) -(add-hook 'LaTeX-mode-hook 'reftex-mode) -(setq LaTeX-electric-left-right-brace t) -(setq font-latex-fontify-script nil) -(setq TeX-electric-sub-and-superscript t) -;; (setq reftex-plug-into-AUCTeX t) - - - -(use-package org-fragtog) -(add-hook 'org-mode-hook 'org-fragtog-mode) -(add-hook 'markdown-mode-hook 'org-fragtog-mode) +(use-package org-fragtog + :hook ((org-mode . org-fragtog-mode) + (markdown-mode . org-fragtog-mode))) (use-package org-modern :config (setq org-modern-block-name @@ -1017,6 +1022,8 @@ create a new one." ("" . swarsel/org-present-next)) :hook ((org-present-mode . swarsel/org-present-start) (org-present-mode-quit . swarsel/org-present-end)) + :config + (add-hook 'org-present-after-navigate-functions #'swarsel/org-present-slide) ) @@ -1102,14 +1109,6 @@ create a new one." (swarsel/org-present-slide) )) -(defun clojure-leave-clojure-mode-function () - ) - -(add-hook 'buffer-list-update-hook #'clojure-leave-clojure-mode-function) -(add-hook 'org-present-mode-hook 'swarsel/org-present-start) -(add-hook 'org-present-mode-quit-hook 'swarsel/org-present-end) -(add-hook 'org-present-after-navigate-functions 'swarsel/org-present-slide) - (defun org-babel-execute:markdown (body params) "Just return BODY unchanged, allowing noweb expansion." body) @@ -1145,21 +1144,10 @@ create a new one." lsp-nix-nixd-home-manager-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.pyramid.options.home-manager.users.type.getSubOptions []" )) -(add-to-list 'auto-mode-alist '("\\.nix\\.enc\\'" . nix-mode)) -(add-to-list 'auto-mode-alist '("\\.nix\\.enc\\'" . nix-ts-mode)) - - -(with-eval-after-load 'lsp-mode - (lsp-register-client - (make-lsp-client :new-connection (lsp-stdio-connection "nixd") - :major-modes '(nix-mode nix-ts-mode) - :priority 0 - :server-id 'nixd))) - (use-package hcl-mode :mode "\\.hcl\\'" - :config - (setq hcl-indent-level 2)) + :custom + (hcl-indent-level 2)) (use-package groovy-mode) @@ -1173,65 +1161,60 @@ create a new one." (use-package terraform-mode :mode "\\.tf\\'" - :config - (setq terraform-indent-level 2) - (setq terraform-format-on-save t)) - -(add-hook 'terraform-mode-hook #'outline-minor-mode) + :hook (terraform-mode . outline-minor-mode) + :custom + (terraform-indent-level 2) + (terraform-format-on-save t)) (use-package nixpkgs-fmt) (use-package shfmt - :config - (setq shfmt-command "shfmt") - (setq shfmt-arguments '("-i" "4" "-s" "-sr"))) - -(setq markdown-command "pandoc") + :custom + (shfmt-command "shfmt") + (shfmt-arguments '("-i" "4" "-s" "-sr"))) (use-package markdown-mode :ensure t :mode ("README\\.md\\'" . gfm-mode) - :init (setq markdown-command "multimarkdown") + :init + (setq markdown-command "multimarkdown") + :hook (markdown-mode . swarsel/markdown-mode-keys) :bind (:map markdown-mode-map - ("C-c C-e" . markdown-do))) + ("C-c C-e" . markdown-do) + ("C-c C-x C-l" . org-latex-preview) + ("C-c C-x C-u" . markdown-toggle-url-hiding))) -(add-hook 'markdown-mode-hook - (lambda () - (local-set-key (kbd "C-c C-x C-l") 'org-latex-preview) - (local-set-key (kbd "C-c C-x C-u") 'markdown-toggle-url-hiding) - )) - -(use-package elfeed) - -(use-package elfeed-goodies) -(elfeed-goodies/setup) - -(setq elfeed-db-directory "~/.elfeed/db/") +(use-package elfeed + :custom + (elfeed-db-directory "~/.elfeed/db/") + (elfeed-use-curl t) + (elfeed-set-timeout 36000) + :config + (define-key elfeed-show-mode-map (kbd ";") #'visual-fill-column-mode) + (define-key elfeed-show-mode-map (kbd "j") #'elfeed-goodies/split-show-next) + (define-key elfeed-show-mode-map (kbd "k") #'elfeed-goodies/split-show-prev) + (define-key elfeed-search-mode-map (kbd "j") #'next-line) + (define-key elfeed-search-mode-map (kbd "k") #'previous-line) + (define-key elfeed-show-mode-map (kbd "S-SPC") #'scroll-down-command)) +(use-package elfeed-goodies + :after elfeed + :config + (elfeed-goodies/setup)) (use-package elfeed-protocol - :after elfeed) - -(elfeed-protocol-enable) -(setq elfeed-use-curl t) -(setq elfeed-set-timeout 36000) -(setq elfeed-protocol-enabled-protocols '(fever)) -(setq elfeed-protocol-fever-update-unread-only t) -(setq elfeed-protocol-fever-fetch-category-as-tag t) - -(let ((domain (getenv "SWARSEL_RSS_DOMAIN"))) - (setq elfeed-protocol-feeds - `((,(concat "fever+https://Swarsel@" domain) - :api-url ,(concat "https://" domain "/api/fever.php") - :password-file "~/.emacs.d/.fever")))) - - -(define-key elfeed-show-mode-map (kbd ";") 'visual-fill-column-mode) -(define-key elfeed-show-mode-map (kbd "j") 'elfeed-goodies/split-show-next) -(define-key elfeed-show-mode-map (kbd "k") 'elfeed-goodies/split-show-prev) -(define-key elfeed-search-mode-map (kbd "j") 'next-line) -(define-key elfeed-search-mode-map (kbd "k") 'previous-line) -(define-key elfeed-show-mode-map (kbd "S-SPC") 'scroll-down-command) + :after elfeed + :custom + (elfeed-protocol-enabled-protocols '(fever)) + (elfeed-protocol-fever-update-unread-only t) + (elfeed-protocol-fever-fetch-category-as-tag t) + :config + (elfeed-protocol-enable) + (let ((domain (getenv "SWARSEL_RSS_DOMAIN"))) + (setq elfeed-protocol-feeds + `((,(concat "fever+https://Swarsel@" domain) + :api-url ,(concat "https://" domain "/api/fever.php") + :password-file "~/.emacs.d/.fever"))))) (use-package rg) @@ -1266,7 +1249,7 @@ create a new one." (use-package treesit-auto :custom - (setq treesit-auto-install t) + (treesit-auto-install t) :config (treesit-auto-add-to-auto-mode-alist 'all) (global-treesit-auto-mode)) @@ -1281,25 +1264,17 @@ create a new one." (use-package avy :bind (("M-o" . avy-goto-char-timer)) - :config - (setq avy-all-windows 'all-frames)) + :custom + (avy-all-windows 'all-frames)) -(use-package devdocs) - -(add-hook 'python-mode-hook - (lambda () (setq-local devdocs-current-docs '("python~3.12" "numpy~1.23" "matplotlib~3.7" "pandas~1")))) -(add-hook 'python-ts-mode-hook - (lambda () (setq-local devdocs-current-docs '("python~3.12" "numpy~1.23" "matplotlib~3.7" "pandas~1")))) - -(add-hook 'c-mode-hook - (lambda () (setq-local devdocs-current-docs '("c")))) -(add-hook 'c-ts-mode-hook - (lambda () (setq-local devdocs-current-docs '("c")))) - -(add-hook 'c++-mode-hook - (lambda () (setq-local devdocs-current-docs '("cpp")))) -(add-hook 'c++-ts-mode-hook - (lambda () (setq-local devdocs-current-docs '("cpp")))) +(use-package devdocs + :hook ((python-mode . (lambda () (setq-local devdocs-current-docs '("python~3.12" "numpy~1.23" "matplotlib~3.7" "pandas~1")))) + (python-ts-mode . (lambda () (setq-local devdocs-current-docs '("python~3.12" "numpy~1.23" "matplotlib~3.7" "pandas~1")))) + (c-mode . (lambda () (setq-local devdocs-current-docs '("c")))) + (c-ts-mode . (lambda () (setq-local devdocs-current-docs '("c")))) + (c++-mode . (lambda () (setq-local devdocs-current-docs '("cpp")))) + (c++-ts-mode . (lambda () (setq-local devdocs-current-docs '("cpp"))))) + ) ; (devdocs-update-all) @@ -1326,13 +1301,16 @@ create a new one." ;; yubikey support for pushing commits ;; commiting is enabled through nixos gpg-agent config -(use-package pinentry) -(pinentry-start) -(setq epg-pinentry-mode 'loopback) -(setenv "SSH_AUTH_SOCK" (string-chop-newline (shell-command-to-string "gpgconf --list-dirs agent-ssh-socket"))) +(use-package pinentry + :config + (pinentry-start) + (setq epg-pinentry-mode 'loopback) + (setenv "SSH_AUTH_SOCK" (string-chop-newline (shell-command-to-string "gpgconf --list-dirs agent-ssh-socket")))) (use-package forge - :after magit) + :after magit + :init + (setq forge-add-default-bindings nil)) (use-package git-timemachine :hook (git-time-machine-mode . evil-normalize-keymaps) @@ -1361,7 +1339,7 @@ create a new one." ;; (if (char-equal c ?<) t (,electric-pair-inhibit-predicate c)))))) (use-package rainbow-mode - :config (rainbow-mode)) + :hook ((css-mode css-ts-mode web-mode html-mode html-ts-mode) . rainbow-mode)) (use-package corfu :init @@ -1394,15 +1372,15 @@ create a new one." (" " . swarsel/corfu-quit-and-down)) ) -(use-package nerd-icons-corfu) - -(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter) - -(setq nerd-icons-corfu-mapping - '((array :style "cod" :icon "symbol_array" :face font-lock-type-face) - (boolean :style "cod" :icon "symbol_boolean" :face font-lock-builtin-face) - ;; ... - (t :style "cod" :icon "code" :face font-lock-warning-face))) +(use-package nerd-icons-corfu + :after corfu + :config + (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter) + (setq nerd-icons-corfu-mapping + '((array :style "cod" :icon "symbol_array" :face font-lock-type-face) + (boolean :style "cod" :icon "symbol_boolean" :face font-lock-builtin-face) + ;; ... + (t :style "cod" :icon "code" :face font-lock-warning-face)))) (use-package cape :bind @@ -1460,14 +1438,11 @@ create a new one." "-o ControlMaster=auto -o ControlPersist=yes")) ) -(setq vterm-tramp-shells '(("ssh" "'sh'"))) - (use-package diff-hl :hook ((prog-mode org-mode) . diff-hl-mode) :init - (diff-hl-flydiff-mode) (diff-hl-margin-mode) (diff-hl-show-hunk-mouse-mode)) @@ -1488,19 +1463,17 @@ create a new one." ;;rustic-mode tex-mode LaTeX-mode - ) . (lambda () (progn - (eglot-ensure) - (add-hook 'before-save-hook 'eglot-format nil 'local)))) + ) . swarsel/eglot-ensure-and-format) :custom (eldoc-echo-area-use-multiline-p nil) - (completion-category-defaults nil) - (fset #'jsonrpc--log-event #'ignore) (eglot-events-buffer-size 0) (eglot-sync-connect nil) (eglot-connect-timeout nil) (eglot-autoshutdown t) (eglot-send-changes-idle-time 3) (flymake-no-changes-timeout 5) + :config + (fset #'jsonrpc--log-event #'ignore) :bind (:map eglot-mode-map ("M-(" . flymake-goto-next-error) ("C-c ," . eglot-code-actions))) @@ -1518,7 +1491,13 @@ create a new one." ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l") (setq lsp-keymap-prefix "C-c l") (setq lsp-auto-guess-root "t") - :commands lsp) + :commands lsp + :config + (lsp-register-client + (make-lsp-client :new-connection (lsp-stdio-connection "nixd") + :major-modes '(nix-mode nix-ts-mode) + :priority 0 + :server-id 'nixd))) ;; (use-package company) @@ -1562,8 +1541,6 @@ create a new one." ; 'line to show errors on the current line (setq sideline-backends-right '(sideline-flymake))) -(setq backup-by-copying-when-linked t) - (use-package dirvish :init (dirvish-override-dired-mode) @@ -1638,6 +1615,8 @@ create a new one." :ensure nil ;; :load-path "/usr/share/emacs/site-lisp/mu4e/" ;;:defer 20 ; Wait until 20 seconds after startup + :hook ((mu4e-compose-mode . swarsel/mu4e-send-from-correct-address) + (mu4e-compose-post . swarsel/mu4e-restore-default)) :config ;; This is set to 't' to avoid mail syncing issues when using mbsync @@ -1681,12 +1660,31 @@ create a new one." ;; this does the equivalent of (setq mu4e-user-mail-address-list '(address1@about.com address2@about.com [...]))) (setq mu4e-user-mail-address-list (mapcar #'intern (split-string (or (getenv "SWARSEL_MAIL_ALL") "") "[ ,]+" t))) + + (setq mu4e--log-max-size 1000) + + (mu4e t) + + (let ((work (getenv "SWARSEL_MAIL_WORK"))) + (when (and work (not (string-empty-p work))) + (setq swarsel-smime-cert-path "~/.Certificates/$SWARSEL_MAIL_WORK.pem") + (setq swarsel-smime-cert-path (substitute-env-vars swarsel-smime-cert-path)) + (setq mml-secure-prefer-scheme 'smime) + (setq mml-secure-smime-sign-with-sender t) + (add-hook 'mu4e-compose-mode-hook + (lambda () + (when (and (boundp 'user-mail-address) + (stringp user-mail-address) + (string-equal user-mail-address (getenv "SWARSEL_MAIL_WORK"))) + (mml-secure-message-sign-smime)))) + (setq smime-keys + `((,(getenv "SWARSEL_MAIL_WORK") + ,swarsel-smime-cert-path + ("~/Certificates/harica-root.pem" + "~/Certificates/harica-intermediate.pem")))) + )) ) - -(add-hook 'mu4e-compose-mode-hook #'swarsel/mu4e-send-from-correct-address) -(add-hook 'mu4e-compose-post-hook #'swarsel/mu4e-restore-default) - (use-package mu4e-alert :config (mu4e-alert-enable-notifications) @@ -1704,30 +1702,6 @@ create a new one." (add-hook 'after-init-hook #'mu4e-alert-enable-notifications) ) -(mu4e t) - -(let ((work (getenv "SWARSEL_MAIL_WORK"))) - (when (and work (not (string-empty-p work))) - - (setq swarsel-smime-cert-path "~/.Certificates/$SWARSEL_MAIL_WORK.pem") - (setq swarsel-smime-cert-path (substitute-env-vars swarsel-smime-cert-path)) - (setq mml-secure-prefer-scheme 'smime) - (setq mml-secure-smime-sign-with-sender t) - (add-hook 'mu4e-compose-mode-hook - (lambda () - (when (and (boundp 'user-mail-address) - (stringp user-mail-address) - (string-equal user-mail-address (getenv "SWARSEL_MAIL_WORK"))) - (mml-secure-message-sign-smime)))) - - (setq smime-keys - `((,(getenv "SWARSEL_MAIL_WORK") - ,swarsel-smime-cert-path - ("~/Certificates/harica-root.pem" - "~/Certificates/harica-intermediate.pem" - )))) - )) - (use-package org-caldav :init ;; set org-caldav-sync-initalization @@ -1856,15 +1830,19 @@ create a new one." ) )))) -(add-to-list 'recentf-exclude "\\Archive\\.org\\'") -(add-to-list 'recentf-exclude "\\Tasks\\.org\\'") +(use-package recentf + :ensure nil + :config + (add-to-list 'recentf-exclude "\\Archive\\.org\\'") + (add-to-list 'recentf-exclude "\\Tasks\\.org\\'")) (use-package vterm - :ensure t) + :ensure t + :custom + (vterm-tramp-shells '(("ssh" "'sh'")))) (use-package multiple-cursors) -(setq mu4e--log-max-size 1000) (setq message-log-max 30) (setq comint-buffer-maximum-size 50) (add-hook 'comint-output-filter-functions 'comint-truncate-buffer)