From 69967a1b030cffff18d439f3496aeec536c7afe1 Mon Sep 17 00:00:00 2001 From: cashmere Date: Mon, 8 Jun 2026 10:08:59 +0200 Subject: chore(config): snapshot current config before larger rework config.org trimmed ~1000 lines (6411 -> 5349), noctalia theme tweaks. gitignore extended to drop per-host runtime/session state. --- .gitignore | 12 + config.el | 1005 ++++++------------------------ config.org | 1536 +++++++--------------------------------------- themes/noctalia-theme.el | 68 +- 4 files changed, 479 insertions(+), 2142 deletions(-) diff --git a/.gitignore b/.gitignore index 8090a3c..ee9c5be 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,15 @@ dirvish/thumbnails /eaf/ *.md /elpaca + +# Per-host runtime/session state (savehist, recentf, places, bookmarks, clocks, timers) +/triples.db +/tmr-timers.eld +/easysession/ +/eww-bookmarks/ +/bookmarks-*.eld +/places-*.eld +/projectile-bookmarks-*.eld +/recentf-*.eld +/savehist-*.el +/org-clock-save-*.el diff --git a/config.el b/config.el index 20d0af9..3d6b571 100644 --- a/config.el +++ b/config.el @@ -1,8 +1,6 @@ ;;; config.el --- Emacs-Kick --- A feature rich Emacs config for (neo)vi(m)mers -*- lexical-binding: t; -*- (setenv "LSP_USE_PLISTS" "true") ;; (setq debug-on-error t) -(setq gc-cons-threshold #x40000000) -;; (setq gc-cons-threshold 50000000) ;; (setenv "LSP_USE_PLISTS" "true") ;; (setq lsp-use-plists t) (setq pgtk-wait-for-event-timeout 0.001) @@ -151,7 +149,7 @@ (add-to-list 'default-frame-alist '(horizontal-scroll-bars . nil)) ;; (set-frame-parameter (selected-frame) 'alpha-background 80) ;; (add-to-list 'default-frame-alist '(alpha-background . 80)) - ;; (global-hl-line-mode -1) ;; Disable highlight of the current line + (global-hl-line-mode 1) ;; Highlight the current line (global-auto-revert-mode 1) ;; Enable global auto-revert mode to keep buffers up to date with their corresponding files. (setq-default indent-tabs-mode nil) (recentf-mode 1) ;; Enable tracking of recently opened files. @@ -296,7 +294,6 @@ :user "cashmere/ergo@emacs" :password pw))) -(when (my/load-for-hub-p) (use-package erc :ensure nil :defer t @@ -446,8 +443,6 @@ Temporarily disables notifications during the fetch." (add-hook 'erc-join-hook hook-fn)) (run-irc)))) -) ;; end (when (my/load-for-hub-p) ...) - ;; ERC keybindings and hooks — register from any daemon, since `run-irc` ;; autoloads ERC even outside the hub daemon. (with-eval-after-load 'erc @@ -518,7 +513,7 @@ Temporarily disables notifications during the fetch." (message "centered-cursor off")) (progn (setq scroll-preserve-screen-position t - scroll-conservatively 0 + scroll-conservatively 101 maximum-scroll-margin 0.5 scroll-margin 99999) (setq my/centered-cursor-enabled t) @@ -587,6 +582,10 @@ Temporarily disables notifications during the fetch." :ensure t :hook (after-init . global-clipetty-mode)) +;; (use-package kkp +;; :ensure t +;; :hook (tty-setup . global-kkp-mode)) + (use-package isearch :ensure nil ;; This is built-in, no need to fetch it. :config @@ -660,7 +659,6 @@ Temporarily disables notifications during the fetch." (mode . nix-ts-mode))) ("Scripts" (or (mode . shell-script-mode) - (mode . shell-mode) (mode . sh-mode) (mode . bash-ts-mode) (mode . lua-mode) @@ -690,7 +688,12 @@ Temporarily disables notifications during the fetch." (mode . markdown-mode) (mode . adoc-mode))) ("Org" (mode . org-mode)) - ("Terminal" (mode . vterm-mode)) + ("Terminal" (or + (mode . ghostel-mode) + (mode . eat-mode) + (mode . eshell-mode) + (mode . shell-mode) + (mode . term-mode))) ("LaTeX" (name . "\.tex$")) ("Magit" (or (mode . magit-blame-mode) @@ -828,15 +831,14 @@ Temporarily disables notifications during the fetch." ;; CLI (claude-code-ide-cli-path "claude") (claude-code-ide-cli-debug nil) - ;; Terminal backend — vterm is preferred, eat as fallback - (claude-code-ide-terminal-backend 'vterm) - (claude-code-ide-vterm-anti-flicker nil) + ;; Terminal backend + (claude-code-ide-terminal-backend 'eat) ;; Window placement — mirror eca on the right side so the two AI assistants ;; don't fight over the same slot (claude-code-ide-use-side-window t) (claude-code-ide-window-side 'right) - (claude-code-ide-window-width 100) + (claude-code-ide-window-width 75) (claude-code-ide-focus-on-open t) ;; Ediff integration for code suggestions @@ -855,7 +857,6 @@ Temporarily disables notifications during the fetch." ;; Evil: open the Claude terminal in insert state so you can type immediately. ;; Defined in :init so it applies even before claude-code-ide loads. (with-eval-after-load 'evil - (evil-set-initial-state 'vterm-mode 'insert) (evil-set-initial-state 'eat-mode 'insert)) (defun my/claude-code-ide--enter-insert (&rest _) @@ -1083,28 +1084,19 @@ Temporarily disables notifications during the fetch." ;; ;; (setq render-org-heading-gfx-scales '(1.25 1.15 1.05 1.0 1.0 1.0)) ;; ;; (setq render-org-heading-gfx-font-family "MapleMono NF") -;; TEMP: load kitty-graphics from local dev clone (/home/cashmere/projects/ -;; kitty-graphics/) instead of the elpaca-managed build, so edits to the -;; source apply on Emacs restart without an `elpaca-rebuild' cycle. -;; Swap back to the `use-package' / `:ensure' form below once changes are -;; committed + pushed and elpaca has pulled the new commit. -(when (not (display-graphic-p)) - (add-to-list 'load-path "/home/cashmere/projects/kitty-graphics") - (require 'kitty-graphics) - (setq kitty-gfx-enable-video t) - (add-hook 'dired-mode-hook #'kitty-gfx-dired-auto-preview-mode) - (setq kitty-gfx-debug nil) - (kitty-graphics-mode 1)) - -;; (use-package kitty-graphics -;; :ensure (:host github :repo "cashmeredev/kitty-graphics.el") -;; :if (not (display-graphic-p)) -;; :custom -;; (kitty-gfx-enable-video t) -;; :hook -;; (dired-mode . kitty-gfx-dired-auto-preview-mode) -;; :config -;; (kitty-graphics-mode 1)) +(use-package kitty-graphics + :ensure nil + :load-path "/home/cashmere/projects/kitty-graphics" + :demand t + :custom + (kitty-gfx-enable-video t) + (kitty-gfx-debug nil) + (kitty-gfx-shr-scale 'fit) + (kitty-gfx-shr-fit-width 0.6) + (kitty-gfx-shr-fit-height 20) + :hook (dired-mode . kitty-gfx-dired-auto-preview-mode) + :config + (kitty-graphics-setup)) (use-package org-fancy-priorities :ensure t @@ -1225,42 +1217,32 @@ BODY is the justfile content. PARAMS may include: (add-to-list 'org-src-lang-modes '("just" . just))) (defun my/snip-upload (&optional file) - "Upload FILE, region, or current buffer to snips.sh. -Passes -ext flag to hint the file type for syntax highlighting. -Copies the resulting URL to the kill ring and clipboard." + "Upload FILE, region, or current buffer to bouncer.cashmere.rs. +The xonsh `upload' command copies the URL to the clipboard; it is +also added to the kill ring." (interactive) - (let* ((input (cond - (file file) - ((use-region-p) - (buffer-substring-no-properties (region-beginning) (region-end))) - (t (buffer-substring-no-properties (point-min) (point-max))))) - (ext (cond - ((and file (file-name-extension file)) - (file-name-extension file)) - ((and (not file) (buffer-file-name) (file-name-extension (buffer-file-name))) - (file-name-extension (buffer-file-name))))) - (ext-flag (if ext (format " -- -ext %s" ext) "")) - (cmd (format "ssh pb@pb.moneyspread.st%s 2>/dev/null | sed 's/\\x1b\\[[0-9;]*m//g' | grep -oP 'https://\\S+/f/\\S+'" ext-flag)) - (url (string-trim - (if (and file (file-exists-p file)) - (shell-command-to-string (format "cat %s | %s" (shell-quote-argument file) cmd)) - (with-temp-buffer - (insert input) - (shell-command-on-region (point-min) (point-max) cmd nil t) - (buffer-string)))))) - (if (string-prefix-p "https://" url) - (let ((final-url (if (and ext (member (downcase ext) - '("png" "jpg" "jpeg" "gif" "webp" "svg" "bmp" "ico" "tiff"))) - (concat url "?r=1") - url))) - (kill-new final-url) - (message "Uploaded: %s" final-url)) - (message "Upload failed")))) + (let* ((ext (or (and file (file-name-extension file)) + (and (buffer-file-name) (file-name-extension (buffer-file-name))) + "txt")) + (cmd (format "xonsh -c 'upload %s'" ext))) + (if (and file (file-exists-p file)) + (call-process-shell-command + (format "cat %s | %s" (shell-quote-argument file) cmd)) + (shell-command-on-region + (if (use-region-p) (region-beginning) (point-min)) + (if (use-region-p) (region-end) (point-max)) + cmd nil nil)) + (let ((url (string-trim (shell-command-to-string "wl-paste")))) + (if (string-prefix-p "https://" url) + (progn + (kill-new url) + (message "Uploaded: %s" url)) + (message "Upload failed: %s" url))))) (defun my/snip-upload-file () - "Prompt for a file and upload it to snips.sh." + "Prompt for a file and upload it to bouncer.cashmere.rs." (interactive) - (my/snip-upload (read-file-name "Upload to snips.sh: "))) + (my/snip-upload (read-file-name "Upload to bouncer: "))) (defun my/setup-git-remote (dev-name srht-name) "Set up origin (dual-push) and backup remotes for the current git repo. @@ -1987,8 +1969,8 @@ Usage: emacs --eval '(my/agenda-app)' --no-splash" (setq org-publish-project-alist '(("wiki" - :base-directory "~/wiki" - :publishing-directory "~/blog/content/wiki" + :base-directory "~/garden" + :publishing-directory "~/cashmere.rs/content/wiki" :publishing-function denote-publish-to-md :recursive nil :exclude-tags ("noexport" "draft") @@ -2189,8 +2171,8 @@ Works on the base filename (without extension), e.g. matches \"-agenda\", \":age (use-package denote-publish :ensure (:repo "https://github.com/vedang/denote-publish")) -(setq denote-publish-default-base-dir "~/wiki") -(setq denote-publish-default-output-dir "~/blog/wiki") +(setq denote-publish-default-base-dir "~/garden") +(setq denote-publish-default-output-dir "~/cashmere.rs/content/wiki") (setq denote-publish-link-class "internal-link") @@ -2325,18 +2307,11 @@ Timers that expired while Emacs was closed fire immediately." (corfu-history-mode) (corfu-popupinfo-mode)) -;; (defun my/suppress-corfu-terminal-warning (orig-fun type message &rest args) -;; (unless (and (eq type 'corfu) -;; (string-match-p "corfu-terminal.*not needed" message)) -;; (apply orig-fun type message args))) - -;; (advice-add 'display-warning :around #'my/suppress-corfu-terminal-warning) - -;; (use-package corfu-terminal -;; :ensure t -;; :after corfu -;; :init -;; (corfu-terminal-mode +1)) +(use-package corfu-terminal + :ensure t + :after corfu + :config + (corfu-terminal-mode +1)) (use-package cape :ensure t @@ -2355,7 +2330,10 @@ Timers that expired while Emacs was closed fire immediately." (add-hook 'completion-at-point-functions #'cape-file) ;; (add-hook 'completion-at-point-functions #'cape-history) ;; ... -) + :config + (with-eval-after-load 'eglot + (advice-add 'eglot-completion-at-point :around #'cape-wrap-noninterruptible) + (advice-add 'eglot-completion-at-point :around #'cape-wrap-buster))) (use-package consult :ensure t @@ -2621,7 +2599,7 @@ instead of churning." (root (or (and (project-current) (project-root (project-current))) temporary-file-directory)) - (name (format ".ob-src-%s.py" + (name (format "ob-src-%s.py" (substring (md5 parent) 0 8)))) (setq-local buffer-file-name (expand-file-name name root)) (set-buffer-modified-p nil) @@ -2629,11 +2607,6 @@ instead of churning." (add-hook 'org-src-mode-hook #'my/org-src-eglot-python) -;; Kein cleanup-hook: temp file bleibt liegen. Sonst killed eglot -;; jedesmal die LSP connection wenn C-c ' das buffer schliesst → -;; neuer pyrefly process beim naechsten Edit. File ist harmlos (gitignored -;; via .gitignore pattern .ob-src-*.py). - (with-eval-after-load 'eglot (add-to-list 'eglot-server-programs '((xonsh-mode xonsh-ts-mode) @@ -2644,24 +2617,32 @@ instead of churning." ;; (add-hook 'xonsh-mode-hook #'eglot-ensure) ;; (add-hook 'xonsh-ts-mode-hook #'eglot-ensure) -(with-eval-after-load 'org - (defun org-babel-execute:xonsh (body params) - "Execute a xonsh source block. +(defvar my/ob-xonsh-installer + (lambda () + (defun org-babel-execute:xonsh (body params) + "Execute a xonsh source block. BODY is the xonsh script. PARAMS may include :dir and :cmdline." - (let* ((dir (or (cdr (assq :dir params)) default-directory)) - (cmdline (or (cdr (assq :cmdline params)) "")) - (tmp (make-temp-file "ob-xonsh-" nil ".xsh"))) - (unwind-protect - (progn - (with-temp-file tmp (insert body)) - (let ((default-directory dir)) - (shell-command-to-string - (format "xonsh %s %s" - cmdline - (shell-quote-argument tmp))))) - (when (file-exists-p tmp) (delete-file tmp))))) + (let* ((dir (or (cdr (assq :dir params)) default-directory)) + (cmdline (or (cdr (assq :cmdline params)) "")) + (tmp (make-temp-file "ob-xonsh-" nil ".xsh"))) + (unwind-protect + (progn + (with-temp-file tmp (insert body)) + (let ((default-directory dir)) + (shell-command-to-string + (format "xonsh %s %s" + cmdline + (shell-quote-argument tmp))))) + (when (file-exists-p tmp) (delete-file tmp)))))) + "Defines `org-babel-execute:xonsh'; reused in ob-async child processes.") + +(with-eval-after-load 'org + (funcall my/ob-xonsh-installer) (add-to-list 'org-src-lang-modes '("xonsh" . xonsh))) +(with-eval-after-load 'ob-async + (add-hook 'ob-async-pre-execute-src-block-hook my/ob-xonsh-installer)) + (use-package go-mode :ensure t :mode "\\.go\\'" @@ -2745,134 +2726,16 @@ BODY is the xonsh script. PARAMS may include :dir and :cmdline." ;; :ensure t ;; :after just-mode) -(use-package vterm - :ensure t - :config - (setq vterm-timer-delay 0.0001) - (setq vterm-shell "xonsh")) - -(use-package multi-vterm - :ensure t - :defer t) - (use-package eat :ensure t :custom - (eat-shell "fish") + (eat-shell "xonsh") (eat-kill-buffer-on-exit t) (eat-enable-shell-prompt-annotation t) (eat-term-name "xterm-256color") :hook - ;; Enable shell integration for directory tracking, prompt navigation, etc. (eshell-load . eat-eshell-mode) - (eshell-load . eat-eshell-visual-command-mode) - :config - ;; Tell yazi (and other programs) that this terminal supports Sixel. - ;; Eat supports Sixel rendering but yazi doesn't recognize it as a known - ;; terminal. Setting TERM_PROGRAM to "foot" (a known Sixel terminal) makes - ;; yazi select the Sixel adapter for image previews. - (advice-add 'eat :around - (lambda (orig-fn &rest args) - (let ((process-environment - (append '("TERM_PROGRAM=foot" - "TERM_PROGRAM_VERSION=1.18.0") - process-environment))) - (apply orig-fn args)))) - ;; ────────────────────────────────────────────────── - ;; Evil integration: make eat behave like vterm - ;; - ;; Strategy: - ;; - "emacs mode" in eat = normal state (vim motions on buffer text) - ;; - "semi-char mode" in eat = insert state (keys pass to terminal) - ;; - ESC switches from semi-char → emacs mode (insert → normal) - ;; - i/a/A etc switch from emacs → semi-char mode (normal → insert) - ;; ────────────────────────────────────────────────── - - ;; Don't move cursor back on ESC (inappropriate in terminal buffers) - (add-hook 'eat-mode-hook (lambda () (setq-local evil-move-cursor-back nil))) - - ;; Start eat in insert state (semi-char mode) so typing goes to shell - (evil-set-initial-state 'eat-mode 'insert) - - ;; -- Normal state: vim motions on terminal text -------------------------- - - ;; Entering insert state switches eat to semi-char mode (passthrough) - (defun my/eat-semi-char-mode-entry () - "Switch eat to semi-char mode when entering evil insert state." - (when (and (derived-mode-p 'eat-mode) - (eat-term-p (buffer-local-value 'eat-terminal (current-buffer)))) - (eat-semi-char-mode))) - - ;; Exiting insert state switches eat to emacs mode (vim motions) - (defun my/eat-emacs-mode-entry () - "Switch eat to emacs mode when entering evil normal state." - (when (and (derived-mode-p 'eat-mode) - (eat-term-p (buffer-local-value 'eat-terminal (current-buffer)))) - (eat-emacs-mode))) - - (add-hook 'evil-insert-state-entry-hook #'my/eat-semi-char-mode-entry) - (add-hook 'evil-normal-state-entry-hook #'my/eat-emacs-mode-entry) - - ;; In normal state, bind standard vim keys to re-enter insert (semi-char) - (evil-define-key 'normal eat-mode-map - "i" (lambda () (interactive) (eat-semi-char-mode) (evil-insert-state)) - "a" (lambda () (interactive) (forward-char 1) (eat-semi-char-mode) (evil-insert-state)) - "A" (lambda () (interactive) (end-of-line) (eat-semi-char-mode) (evil-insert-state)) - "I" (lambda () (interactive) (back-to-indentation) (eat-semi-char-mode) (evil-insert-state)) - "o" (lambda () (interactive) (eat-semi-char-mode) (evil-insert-state) - (eat-self-input 1 ?\n)) - ;; Paste from kill ring in normal mode - "p" (lambda () (interactive) - (eat-semi-char-mode) - (eat-yank) - (eat-emacs-mode)) - ;; Navigate prompts - (kbd "[ [") #'eat-previous-shell-prompt - (kbd "] ]") #'eat-next-shell-prompt) - - ;; In insert state: ESC escapes back to normal (emacs mode intercepts it) - ;; The default eat-semi-char-mode lets C-c, C-x, etc. pass through to Emacs - ;; which is exactly what we want. ESC is also not captured by semi-char mode, - ;; so evil's ESC → normal state transition works naturally. - - ;; -- Multi-eat: manage multiple terminal buffers ------------------------- - - (defvar my/eat-buffer-counter 0 - "Counter for naming eat terminal buffers.") - - (defun my/eat-new () - "Create a new eat terminal buffer." - (interactive) - (cl-incf my/eat-buffer-counter) - (let ((buf (generate-new-buffer - (format "*eat<%d>*" my/eat-buffer-counter))) - (process-environment - (append '("TERM_PROGRAM=foot" "TERM_PROGRAM_VERSION=1.18.0") - process-environment))) - (with-current-buffer buf - (eat-mode) - (eat-exec buf (buffer-name buf) eat-shell nil nil)) - (switch-to-buffer buf))) - - (defun my/eat-toggle () - "Toggle an eat terminal. Create one if none exists. -With prefix arg, always create a new terminal." - (interactive) - (if current-prefix-arg - (my/eat-new) - (let ((eat-bufs (cl-remove-if-not - (lambda (b) (with-current-buffer b - (derived-mode-p 'eat-mode))) - (buffer-list)))) - (cond - ;; Currently in an eat buffer → bury it - ((derived-mode-p 'eat-mode) - (bury-buffer)) - ;; Existing eat buffers → switch to most recent - (eat-bufs - (switch-to-buffer (car eat-bufs))) - ;; No eat buffers → create one - (t (eat))))))) + (eshell-load . eat-eshell-visual-command-mode)) (use-package olivetti :ensure t @@ -3170,6 +3033,21 @@ so the working-tree diff stays visible until the user explicitly stages." (require 'flash-evil) (flash-evil-setup t) + (defun my/flash-visual-extend (orig match) + (if (and match + (bound-and-true-p evil-local-mode) + (eq evil-state 'visual)) + (let* ((origin (point)) + (mpos (flash-match-pos-value match)) + (forward (and mpos (>= mpos origin))) + (flash-jump-position (if forward 'end 'start))) + (prog1 (funcall orig match) + (when (and forward (not (bolp)) (> (point) (point-min))) + (backward-char)))) + (funcall orig match))) + + (advice-add 'flash-jump-to-match :around #'my/flash-visual-extend) + ;; Restore ; and , after flash-char overwrites them ;; ; is used as prefix for prev-navigation (;b, ;d) ;; , is the local leader @@ -3238,6 +3116,12 @@ so the working-tree diff stays visible until the user explicitly stages." :hook (dired-mode . nerd-icons-dired-mode)) +(use-package diredfl + :ensure t + :hook + ((dired-mode . diredfl-mode) + (dirvish-directory-view-mode . diredfl-mode))) + (use-package nerd-icons-completion :if ek-use-nerd-fonts ;; Load the package only if the user has configured to use nerd fonts. :ensure t ;; Ensure the package is installed. @@ -3265,185 +3149,6 @@ so the working-tree diff stays visible until the user explicitly stages." (use-package hide-mode-line :ensure t) -;; (use-package awesome-tray -;; :ensure (:host github :repo "manateelazycat/awesome-tray") -;; :custom -;; ;; Position at the top -;; ;; (setq awesome-tray-position 'right) - -;; ;; Basic Visual Settings -;; ;; (awesome-tray-hide-mode-line t) -;; (awesome-tray-separator " │ ") -;; (awesome-tray-ellipsis "…") - -;; ;; Module Customizations -;; (awesome-tray-date-format "%I:%M %p") ; 12-hour format with AM/PM -;; (awesome-tray-git-format " ᚴ %s") -;; (awesome-tray-git-show-status t) -;; (awesome-tray-location-format "%l:%c") -;; (awesome-tray-evil-show-mode t) -;; (awesome-tray-evil-show-macro t) -;; (awesome-tray-evil-show-cursor-count t) -;; (awesome-tray-file-path-full-dirname-levels 2) -;; (awesome-tray-file-path-shorten-start-length 1) -;; (awesome-tray-input-method-default-style "EN") -;; (awesome-tray-input-method-local-style "中") -;; (awesome-tray-input-method-local-methods '("rime" "pinyin")) - -;; ;; Performance settings -;; (awesome-tray-refresh-idle-delay 0.5) -;; (awesome-tray-refresh-timer t) -;; (awesome-tray-update-interval 1) - -;; :config -;; ;; Start with essential modules for performance -;; (setq awesome-tray-active-modules -;; '( -;; "buffer-name" -;; "mode-name" -;; "date" -;; "location" -;; "evil" -;; "input-method" -;; )) - -;; ;; Enable awesome-tray -;; (awesome-tray-mode 1) -;; ) - -;; (setq display-time-mode 1) -;; (use-package lambda-line -;; :ensure (:host github :repo "lambda-emacs/lambda-line") -;; :custom -;; (lambda-line-lsp-indicator nil) -;; (lambda-line-icon-time t) ;; requires ClockFace font (see below) -;; (lambda-line-clockface-update-fontset "ClockFaceRect") ;; set clock icon -;; (lambda-line-position 'top) ;; Set position of status-line -;; (lambda-line-abbrev nil) ;; 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 nil) -;; (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 -;; ;; activate lambda-line -;; (lambda-line-mode) -;; ;; set divider line in footer -;; (when (eq lambda-line-position 'top) -;; (setq-default mode-line-format (list "%_")) -;; (setq mode-line-format (list "%_")))) - -;; (use-package doom-modeline -;; :ensure t -;; :hook (after-init . doom-modeline-mode) -;; :custom -;; (doom-modeline-time t) -;; (doom-modeline-time-icon t) -;; (doom-modeline-buffer-file-name-style 'buffer-name) -;; (doom-modeline-height 24) -;; (doom-modeline-buffer-encoding nil) -;; (doom-modeline-env-version t) -;; (doom-modeline-env-setup-rust nil) -;; :config -;; (setq display-time-24hr-format nil) -;; (display-time-mode 1)) -;; ;; (set-face-attribute 'mode-line nil :height 180) -;; ;; (set-face-attribute 'mode-line-inactive nil :height 180)) - -(setq mode-line-misc-info - (assq-delete-all 'eglot--managed-mode - (copy-sequence mode-line-misc-info))) - -(use-package maple-modeline - :disabled t - :ensure (:host github :repo "honmaple/emacs-maple-modeline") - ;; :hook (elpaca-after-init . maple-modeline-mode) - :config - (setq maple-modeline-separator 'nil) - (setq maple-modeline-height 25) - (setq maple-modeline-icon t) - - (maple-modeline-define-segment my-modeline-time - :format (propertize (downcase (format-time-string " %I:%M %p ")) - 'face 'bold)) - - (maple-modeline-define-segment org-clock-task - :if (and (fboundp 'org-clocking-p) (org-clocking-p)) - :format - (let ((heading (truncate-string-to-width - (substring-no-properties org-clock-heading) 35 nil nil "..."))) - (concat - (maple-modeline--concat-or - (maple-modeline--icon 'mdicon "nf-md-clock_outline" face) - "CLK") - " " (propertize heading 'face face - 'mouse-face 'mode-line-highlight - 'help-echo "Go to clocked task" - 'local-map (make-mode-line-mouse-map 'mouse-1 'org-clock-goto))))) - - (maple-modeline-define-segment tmr-timer - :if (and (fboundp 'tmr-mode-line--get-active-timers) - (tmr-mode-line--get-active-timers)) - :format - (let* ((timer (car (tmr-mode-line--get-active-timers))) - (remaining (tmr-mode-line--format-remaining timer)) - (desc (tmr-mode-line--format-description timer))) - (concat remaining desc))) - - (maple-modeline-define-segment mu4e-mail - :defines (mu4e-alert-mode-line) - :functions (mu4e-alert-view-unread-mails) - :if (and (bound-and-true-p mu4e-alert-mode-line) - (stringp mu4e-alert-mode-line) - (not (string-empty-p (string-trim mu4e-alert-mode-line)))) - :format - (let* ((raw mu4e-alert-mode-line) - ;; Extract the count number from the mode-line string (e.g. " [5] ") - (count-str (if (string-match "\\[\\([0-9]+\\)\\]" raw) - (match-string 1 raw) - (string-trim raw)))) - (concat - (maple-modeline--concat-or - (maple-modeline--icon 'mdicon "nf-md-email" face) - "Mail") - " " (propertize count-str - 'face face - 'mouse-face 'mode-line-highlight - 'help-echo "View unread emails" - 'local-map (make-mode-line-mouse-map - 'mouse-1 'mu4e-alert-view-unread-mails))))) - - (maple-modeline-define my-custom-style - :left ((evil :left (bar :left "")) - macro - buffer-info - flycheck - version-control - remote-host - region) - :right (narrow - org-clock-task - tmr-timer - mu4e-mail - python - my-modeline-time - process - count - position)) - - (setq maple-modeline-style 'my-custom-style) - - :custom-face - (header-line ((t (:inherit mode-line :box nil)))) - (mode-line ((t (:box nil)))) - (mode-line-inactive ((t (:box nil))))) - (use-package punch-line :ensure (:host github :repo "cashmeredev/punch-line") :config @@ -3459,7 +3164,8 @@ so the working-tree diff stays visible until the user explicitly stages." punch-weather-longitude "10.41" punch-weather-latitude "53.25" punch-cpu-usage t - punch-show-processes-info t) + punch-show-processes-info t + punch-line-music-info t) (punch-line-mode 1)) (use-package adaptive-wrap @@ -3480,7 +3186,7 @@ so the working-tree diff stays visible until the user explicitly stages." (set-face-attribute 'default nil :family "MapleMono NF" - :height 160 + :height 180 :font (font-spec :family "MapleMono NF" :features '(cv04 ss05 zero))) @@ -3499,393 +3205,9 @@ so the working-tree diff stays visible until the user explicitly stages." :config (setq grip-command 'auto)) ;; auto, grip, go-grip or mdopen -;; (use-package catppuccin-theme -;; :ensure t -;; :config -;; (setq catppuccin-flavor 'mocha) - -;; (load-theme 'catppuccin :no-confirm) - -;; (custom-set-faces -;; `(diff-hl-change ((t (:background unspecified :foreground ,(catppuccin-get-color 'blue)))))) - -;; (custom-set-faces -;; `(diff-hl-delete ((t (:background unspecified :foreground ,(catppuccin-get-color 'red)))))) - -;; (custom-set-faces -;; `(diff-hl-insert ((t (:background unspecified :foreground ,(catppuccin-get-color 'green))))))) - -;; (use-package modus-catppuccin -;; :ensure (:repo "https://gitlab.com/magus/modus-catppuccin" -;; :branch "main") -;; :custom -;; (catppuccin-mocha-palette-overrides -;; '((base "#232136") -;; (mantle "#2d2a45") -;; (crust "#373354") -;; (surface0 "#373354") -;; (surface1 "#47407d") -;; (surface2 "#6e6a86") -;; (overlay0 "#6e6a86") -;; (overlay1 "#6e6a86") -;; (overlay2 "#6e6a86") -;; (subtext0 "#e0def4") -;; (subtext1 "#cdcbe0") -;; (text "#e2e0f7") -;; (rosewater "#eb98c3") -;; (flamingo "#ea9a97") -;; (pink "#eb98c3") -;; (mauve "#c4a7e7") -;; (red "#eb6f92") -;; (maroon "#eb6f92") -;; (peach "#ea9a97") -;; (yellow "#f6c177") -;; (green "#a3be8c") -;; (teal "#9ccfd8") -;; (sky "#9ccfd8") -;; (sapphire "#9ccfd8") -;; (blue "#569fba") -;; (lavender "#c4a7e7"))) -;; (catppuccin-latte-palette-overrides -;; '((base "#f6f2ee") -;; (mantle "#e4dcd4") -;; (crust "#dbd1dd") -;; (surface0 "#d3c7bb") -;; (surface1 "#c4b8ac") -;; (surface2 "#b5a99d") -;; (overlay0 "#9ca0b0") -;; (overlay1 "#8c8fa1") -;; (overlay2 "#7c7f93") -;; (subtext0 "#6c6f85") -;; (subtext1 "#5c5f77") -;; (text "#3d2b5a") -;; (rosewater "#955f61") -;; (flamingo "#a5222f") -;; (pink "#a440b5") -;; (mauve "#6e33ce") -;; (red "#a5222f") -;; (maroon "#824d5b") -;; (peach "#955f61") -;; (yellow "#ac5402") -;; (green "#396847") -;; (teal "#287980") -;; (sky "#2d8a93") -;; (sapphire "#2d8a93") -;; (blue "#2848a9") -;; (lavender "#6e33ce"))) -;; :config -;; (load-theme 'catppuccin-latte :no-confirm)) - -;; (use-package modus-themes -;; :ensure t -;; :demand t -;; :custom -;; ;; Optional: Schriften schöner machen -;; (modus-themes-italic-constructs t) -;; (modus-themes-bold-constructs t) -;; (modus-themes-prompts '(bold intense)) - -;; ;; Hier injizieren wir DUSKFOX Farben in Modus Vivendi -;; (modus-themes-common-palette-overrides -;; '( -;; ;; --- Basis Farben (Duskfox) --- -;; (bg-main "#232136") -;; (fg-main "#e0def4") -;; (bg-dim "#2d2a45") ; Etwas heller als Main -;; (fg-dim "#9090c0") ; Abgedunkelter Text -;; (bg-active "#393552") ; Aktive Zeile/Elemente - -;; ;; --- Akzente (Duskfox) --- -;; (red "#eb6f92") -;; (green "#a3be8c") -;; (yellow "#f6c177") -;; (blue "#569fba") -;; (magenta "#c4a7e7") -;; (cyan "#9ccfd8") - -;; ;; --- Fein-Tuning (Mappings) --- -;; ;; Damit es nicht "arsch" aussieht, mappen wir wichtige Elemente neu: - -;; (border "#47407d") -;; (cursor magenta) - -;; ;; Modeline (Statusleiste) -;; (bg-mode-line-active "#47407d") -;; (fg-mode-line-active "#e0def4") -;; (bg-mode-line-inactive "#232136") -;; (fg-mode-line-inactive "#6e6a86") - -;; ;; Syntax Highlighting Anpassungen -;; (keyword magenta) ; Keywords in Duskfox-Pink/Lila -;; (builtin blue) ; Builtins in Blau -;; (type cyan) ; Typen in Cyan -;; (string green) ; Strings in Grün -;; (constant red) ; Konstanten in Rot -;; (fnname blue) ; Funktionsnamen -;; (variable cyan) ; Variablen - -;; ;; UI Elemente -;; (bg-region "#393552") ; Selection Background -;; (fg-region unspecified) -;; (bg-paren-match "#47407d") -;; (bg-hl-line "#2d2a45") - -;; ;; Line Numbers -;; (bg-line-number-inactive "#232136") -;; (fg-line-number-inactive "#6e6a86") -;; (bg-line-number-active "#2d2a45") -;; (fg-line-number-active "#e0def4") -;; )) -;; :config -;; ;; Lade das Basis-Theme (vivendi = dunkel) -;; (load-theme 'modus-vivendi :no-confirm)) - -;; (use-package ef-themes -;; :ensure t -;; :demand t -;; :init -;; (ef-themes-take-over-modus-themes-mode 1) - -;; :custom -;; (modus-themes-italic-constructs t) -;; (modus-themes-bold-constructs t) -;; (modus-themes-prompts '(bold intense)) - -;; (ef-light-palette-overrides -;; '( -;; (bg-main "#efefef") -;; (fg-main "#313145") -;; (bg-dim "#bebed2") -;; (fg-dim "#7c7c98") -;; (bg-alt "#9e9eaf") -;; (fg-alt "#505063") -;; (bg-active "#22223a") -;; (bg-inactive "#efefef") - -;; (red "#f43979") -;; (red-warmer "#ff669b") -;; (red-cooler "#d22a8b") -;; (red-faint "#f43979") - -;; (green "#0073a8") -;; (green-warmer "#0073a8") -;; (green-cooler "#0073a8") -;; (green-faint "#0073a8") - -;; (yellow "#ff669b") -;; (yellow-warmer "#f43979") -;; (yellow-cooler "#d22a8b") -;; (yellow-faint "#ff669b") - -;; (blue "#2155d6") -;; (blue-warmer "#0073a8") -;; (blue-cooler "#2155d6") -;; (blue-faint "#2155d6") - -;; (magenta "#6916b6") -;; (magenta-warmer "#8d17a5") -;; (magenta-cooler "#471397") -;; (magenta-faint "#6916b6") - -;; (cyan "#0073a8") -;; (cyan-warmer "#2155d6") -;; (cyan-cooler "#2155d6") -;; (cyan-faint "#0073a8") - -;; (bg-red-intense "#ff669b") -;; (bg-green-intense "#0073a8") -;; (bg-yellow-intense "#f43979") -;; (bg-blue-intense "#2155d6") -;; (bg-magenta-intense "#8d17a5") -;; (bg-cyan-intense "#0073a8") - -;; (bg-red-subtle "#bebed2") -;; (bg-green-subtle "#bebed2") -;; (bg-yellow-subtle "#bebed2") -;; (bg-blue-subtle "#bebed2") -;; (bg-magenta-subtle "#bebed2") -;; (bg-cyan-subtle "#bebed2") - -;; (bg-added "#bebed2") -;; (bg-added-faint "#efefef") -;; (bg-added-refine "#9e9eaf") -;; (fg-added "#0073a8") - -;; (bg-changed "#bebed2") -;; (bg-changed-faint "#efefef") -;; (bg-changed-refine "#9e9eaf") -;; (fg-changed "#f43979") - -;; (bg-removed "#bebed2") -;; (bg-removed-faint "#efefef") -;; (bg-removed-refine "#9e9eaf") -;; (fg-removed "#d22a8b") - -;; (bg-mode-line "#9e9eaf") -;; (fg-mode-line "#313145") -;; (bg-mode-line-active "#9e9eaf") -;; (fg-mode-line-active "#313145") -;; (bg-mode-line-inactive "#efefef") -;; (fg-mode-line-inactive "#7c7c98") - -;; (border "#7c7c98") -;; (cursor "#471397") - -;; (bg-region "#bebed2") -;; (fg-region unspecified) -;; (bg-paren-match "#9e9eaf") -;; (bg-hl-line "#bebed2") - -;; (bg-line-number-inactive "#efefef") -;; (fg-line-number-inactive "#7c7c98") -;; (bg-line-number-active "#bebed2") -;; (fg-line-number-active "#313145") - -;; (builtin blue) -;; (comment yellow-faint) -;; (constant red) -;; (fnname blue) -;; (keyword magenta) -;; (string green) -;; (type cyan) -;; (variable blue-warmer) - -;; (err red-warmer) -;; (warning yellow-warmer) -;; (info green) - -;; (link blue-warmer) -;; (link-alt magenta) -;; (name magenta-cooler) -;; (keybind blue-cooler) -;; (identifier magenta-faint) -;; (prompt green-cooler) - -;; (date-common cyan-cooler) -;; (date-deadline red) -;; (date-event fg-alt) -;; (date-holiday magenta-warmer) -;; (date-scheduled yellow) -;; (date-weekday cyan) -;; (date-weekend red-faint) - -;; (mail-cite-0 blue-warmer) -;; (mail-cite-1 magenta) -;; (mail-cite-2 cyan-cooler) -;; (mail-cite-3 yellow-cooler) -;; (mail-recipient magenta-cooler) -;; (mail-subject blue-cooler) - -;; (prose-code magenta-warmer) -;; (prose-done green) -;; (prose-macro green-cooler) -;; (prose-tag green-faint) -;; (prose-todo red-warmer) -;; (prose-verbatim blue-warmer) -;; )) - -;; :config -;; (load-theme 'ef-light :no-confirm)) - -;; (use-package kanagawa-themes -;; :ensure t -;; :config -;; (setq kanagawa-themes-org-height nil) -;; (setq kanagawa-themes-org-highlight t) -;; (load-theme 'kanagawa-lotus t)) - -;; (use-package base16-theme -;; :ensure t -;; :demand t -;; :config -;; (setq base16-distinct-fringe-background t) -;; (setq base16-highlight-mode-line t) - -;; (deftheme base24-duskfox) -;; (setq base24-duskfox-colors -;; (list :base00 "#232136" -;; :base01 "#2d2a45" -;; :base02 "#373354" -;; :base03 "#47407d" -;; :base04 "#6e6a86" -;; :base05 "#e0def4" -;; :base06 "#cdcbe0" -;; :base07 "#e2e0f7" -;; :base08 "#eb6f92" -;; :base09 "#ea9a97" -;; :base0A "#f6c177" -;; :base0B "#a3be8c" -;; :base0C "#9ccfd8" -;; :base0D "#569fba" -;; :base0E "#c4a7e7" -;; :base0F "#eb98c3" -;; :base10 "#47407d" -;; :base11 "#eb6f92" -;; :base12 "#a3be8c" -;; :base13 "#f6c177" -;; :base14 "#569fba" -;; :base15 "#c4a7e7" -;; :base16 "#9ccfd8" -;; :base17 "#e0def4")) - -;; (base16-theme-define 'base24-duskfox base24-duskfox-colors) - -;; (deftheme base24-nightfox) -;; (setq base24-nightfox-colors -;; (list :base00 "#192330" -;; :base01 "#212e3f" -;; :base02 "#29394f" -;; :base03 "#575860" -;; :base04 "#71839b" -;; :base05 "#cdcecf" -;; :base06 "#aeafb0" -;; :base07 "#e4e4e5" -;; :base08 "#c94f6d" -;; :base09 "#f4a261" -;; :base0A "#dbc074" -;; :base0B "#81b29a" -;; :base0C "#63cdcf" -;; :base0D "#719cd6" -;; :base0E "#9d79d6" -;; :base0F "#d67ad2" -;; :base10 "#575860" -;; :base11 "#c94f6d" -;; :base12 "#81b29a" -;; :base13 "#dbc074" -;; :base14 "#719cd6" -;; :base15 "#9d79d6" -;; :base16 "#63cdcf" -;; :base17 "#cdcecf")) - -;; (base16-theme-define 'base24-nightfox base24-nightfox-colors) -;; (enable-theme 'base24-nightfox)) - (add-to-list 'custom-theme-load-path "~/.emacs.d/themes/") (load-theme 'noctalia t) -;; (use-package nano-theme -;; :ensure (:host github :repo "rougier/nano-theme") -;; :init -;; (setq nano-fonts-use nil) ;; keep MapleMono NF, don't force Roboto -;; (setq nano-window-divider-show t) ;; subtle dividers between windows -;; :config -;; (load-theme 'nano-dark t) - -;; ;; Convenience: cycle between nano-light and nano-dark. -;; (defun cashmere/nano-toggle-theme () -;; "Toggle between `nano-light' and `nano-dark'." -;; (interactive) -;; (let ((dark-active (member 'nano-dark custom-enabled-themes))) -;; (mapc #'disable-theme custom-enabled-themes) -;; (load-theme (if dark-active 'nano-light 'nano-dark) t))) - -;; ;; Soften a few faces that nano leaves a bit too plain. -;; (with-eval-after-load 'org -;; (set-face-attribute 'org-document-title nil :height 1.4 :weight 'light) -;; (set-face-attribute 'org-level-1 nil :height 1.2 :weight 'medium) -;; (set-face-attribute 'org-level-2 nil :height 1.1 :weight 'medium) -;; (set-face-attribute 'org-level-3 nil :height 1.05 :weight 'medium))) - (use-package dirvish :ensure t :init @@ -4056,7 +3378,6 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." "Y" 'pass-copy-field "e" 'pass-edit "a" 'pass-insert - "g" 'pass-update-buffer "G" 'pass-insert-generated "o" 'pass-otp-options "r" 'pass-rename @@ -4154,8 +3475,8 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." "b" '(:ignore t :wk "buffer/bookmarks") "bb" '(consult-bookmark :wk "display current bookmarks") - "ba" '(ibuffer :wk "ibuffer") - "bi" '(projectile-ibuffer :wk "ibuffer project") + "bi" '(ibuffer :wk "ibuffer") + "bp" '(projectile-ibuffer :wk "ibuffer project") "bd" '(bookmark-delete :wk "delete bookmark") "bk" '(kill-current-buffer :wk "kill buffer") "bs" '(bookmark-set :wk "save bookmark") @@ -4428,8 +3749,8 @@ date) and the dired header are never skipped." "c" '(my/centered-cursor :wk "center cursor") "f" '(dirvish :wk "file manager") "r" '(async-shell-command :wk "run async") - "t" '(projectile-run-vterm :wk "terminal") - "e" '(eshell :wk "eshell") + "t" '(ghostel-project :wk "terminal (project)") + "T" '(ghostel-list-buffers :wk "terminal (switch)") "z" '(golden-ratio-mode :wk "zoom/golden ratio") "o" '(my/global-olivetti-mode :wk "center buffer") "s" '(my-org-sidecar-left :wk "org sidecar")) @@ -4469,14 +3790,14 @@ date) and the dired header are never skipped." ;; (message "No region active"))) (use-package elfeed - :ensure t + :ensure (:host github :repo "emacs-elfeed/elfeed" :branch "main") :defer t :custom (elfeed-db-directory "~/.emacs.d/elfeed") :config (setq elfeed-search-filter "@2-weeks-ago +unread" elfeed-search-title-max-width 110) - + (setq elfeed-use-libxml 't) (add-hook 'elfeed-search-mode-hook #'elfeed-update) (setq elfeed-search-sort-function @@ -4508,16 +3829,6 @@ date) and the dired header are never skipped." :config (elfeed-goodies/setup)) -(use-package shrface - :ensure t - :after elfeed - :config - (shrface-basic) - (shrface-trial) - (shrface-default-keybindings) - (setq shrface-href-versatile t - shrface-bullets-bullet-list '("◉" "○" "✸" "✿"))) - (with-eval-after-load 'elfeed (require 'shrface) (add-hook 'elfeed-show-mode-hook @@ -4617,7 +3928,8 @@ date) and the dired header are never skipped." (shrface-href-versatile t) :config (shrface-basic) - (shrface-trial)) + (shrface-trial) + (shrface-default-keybindings)) (use-package shr-tag-pre-highlight :ensure (:host github :repo "xuchunyang/shr-tag-pre-highlight.el") @@ -4867,4 +4179,79 @@ opening another file in same project does not re-notify." (use-package el-fetch :ensure t) +(use-package ghostel + :ensure t + :custom + (ghostel-shell "xonsh") + :config + (evil-define-key 'normal ghostel-mode-map + (kbd "g t") #'ghostel-next + (kbd "g T") #'ghostel-previous + (kbd "g n") #'ghostel + (kbd "g b") #'ghostel-list-buffers) + (advice-add 'enable-theme :after + (lambda (&rest _) + (when (fboundp 'ghostel-sync-theme) + (ghostel-sync-theme))))) + +(use-package evil-ghostel + :ensure (:host github :repo "dakra/ghostel" + :files ("extensions/evil-ghostel/*.el")) + :after (ghostel evil) + :hook (ghostel-mode . evil-ghostel-mode)) + +(use-package vui + :ensure (:host github :repo "d12frosted/vui.el" :files ("*.el"))) + +(add-to-list 'load-path (expand-file-name "~/garden/lisp/")) +(setq garden-directory (expand-file-name "~/garden/")) +(require 'garden-core) +(garden-auto-index-mode 1) +(autoload 'garden "garden-dashboard" nil t) +(autoload 'garden-sidecar "garden-dashboard" nil t) +(autoload 'garden-connect "garden-connect" nil t) +(autoload 'garden-connect-pick "garden-connect" nil t) +(autoload 'garden-player "garden-player" nil t) + +(autoload 'denote-capf-setup "denote-capf" nil t) +(add-hook 'org-mode-hook #'denote-capf-setup) +(autoload 'garden-publish "garden-publish" nil t) +(autoload 'garden-publish-all "garden-publish" nil t) +(autoload 'garden-publish-wiki "garden-publish" nil t) +(autoload 'garden-publish-blog "garden-publish" nil t) +(autoload 'garden-publish-deploy "garden-publish" nil t) + +(defun my/easysession-restore-services () + "Re-launch process-backed apps (mu4e, ERC) after a session is loaded." + (unless (and (fboundp 'mu4e-running-p) (mu4e-running-p)) + (mu4e t)) + (unless (and (fboundp 'erc-buffer-list) (erc-buffer-list)) + (run-irc))) + +(use-package easysession + :ensure t + :demand t + :custom + (easysession-save-interval (* 10 60)) + :config + (add-hook 'easysession-after-load-hook #'my/easysession-restore-services) + (easysession-setup)) + +(my-local-leader + "e" '(:wk "easy session" :ignore 't) + "ew" '(easysession-switch-to :wk "switch / create") + "es" '(easysession-save :wk "save") + "el" '(easysession-load :wk "load") + "eg" '(easysession-switch-to-and-restore-geometry :wk "switch + geometry") + "er" '(easysession-rename :wk "rename") + "ed" '(easysession-delete :wk "delete") + "ee" '(easysession-edit :wk "edit") + "eR" '(easysession-reset :wk "reset to default") + "em" '(easysession-save-mode :wk "toggle auto-save")) + +(use-package sops + :ensure (:type git :host github :repo "djgoku/sops") + :init + (global-sops-mode 1)) + (provide 'init) diff --git a/config.org b/config.org index 941d6c7..0726825 100644 --- a/config.org +++ b/config.org @@ -10,8 +10,6 @@ ;;; config.el --- Emacs-Kick --- A feature rich Emacs config for (neo)vi(m)mers -*- lexical-binding: t; -*- (setenv "LSP_USE_PLISTS" "true") ;; (setq debug-on-error t) -(setq gc-cons-threshold #x40000000) -;; (setq gc-cons-threshold 50000000) ;; (setenv "LSP_USE_PLISTS" "true") ;; (setq lsp-use-plists t) (setq pgtk-wait-for-event-timeout 0.001) @@ -168,7 +166,7 @@ (add-to-list 'default-frame-alist '(horizontal-scroll-bars . nil)) ;; (set-frame-parameter (selected-frame) 'alpha-background 80) ;; (add-to-list 'default-frame-alist '(alpha-background . 80)) - ;; (global-hl-line-mode -1) ;; Disable highlight of the current line + (global-hl-line-mode 1) ;; Highlight the current line (global-auto-revert-mode 1) ;; Enable global auto-revert mode to keep buffers up to date with their corresponding files. (setq-default indent-tabs-mode nil) (recentf-mode 1) ;; Enable tracking of recently opened files. @@ -331,7 +329,6 @@ :user "cashmere/ergo@emacs" :password pw))) -(when (my/load-for-hub-p) (use-package erc :ensure nil :defer t @@ -481,8 +478,6 @@ Temporarily disables notifications during the fetch." (add-hook 'erc-join-hook hook-fn)) (run-irc)))) -) ;; end (when (my/load-for-hub-p) ...) - ;; ERC keybindings and hooks — register from any daemon, since `run-irc` ;; autoloads ERC even outside the hub daemon. (with-eval-after-load 'erc @@ -544,39 +539,6 @@ Temporarily disables notifications during the fetch." ;; (load-theme 'lambda-light)) #+end_src -* COMMENT dashboard - -#+begin_src emacs-lisp -(use-package dashboard - :ensure t - :config - (setq dashboard-banner-logo-title "Jesus said 'i will rebuild this temple in 3 days.' I could make a compiler in 3 days.") - (setq dashboard-startup-banner "/home/cashmere/.emacs.d/image.jpg") - (setq dashboard-image-banner-max-width 256) - (setq dashboard-image-banner-max-height 256) - (setq dashboard-bookmarks-show-base t) - (setq dashboard-bookmarks-item-format "%s") - (setq dashboard-projects-backend 'projectile) - (setq dashboard-items '((projects . 5) - (recents . 5) - (bookmarks . 5))) - (setq dashboard-projects-switch-function #'projectile-switch-project-by-name) - (setq dashboard-center-content t) - (setq dashboard-set-file-icons t) - (setq dashboard-set-heading-icons t) - (setq dashboard-icon-type 'nerd-icons) - (setq dashboard-footer-messages '("Emacs. The world greatest operating system")) - (dashboard-setup-startup-hook) - - (setq initial-buffer-choice - (lambda () - (get-buffer-create dashboard-buffer-name))) - - (add-hook 'dashboard-mode-hook - (lambda () - (setq mode-line-format nil)))) -#+end_src - * TODO centered cursor #+begin_src emacs-lisp @@ -594,7 +556,7 @@ Temporarily disables notifications during the fetch." (message "centered-cursor off")) (progn (setq scroll-preserve-screen-position t - scroll-conservatively 0 + scroll-conservatively 101 maximum-scroll-margin 0.5 scroll-margin 99999) (setq my/centered-cursor-enabled t) @@ -672,6 +634,14 @@ Temporarily disables notifications during the fetch." :hook (after-init . global-clipetty-mode)) #+end_src +** kkp.el + +#+begin_src emacs-lisp +;; (use-package kkp +;; :ensure t +;; :hook (tty-setup . global-kkp-mode)) +#+end_src + * isearch #+begin_src emacs-lisp @@ -764,7 +734,6 @@ I adjusted the config accordingly to my modes which I use on a frequent. (mode . nix-ts-mode))) ("Scripts" (or (mode . shell-script-mode) - (mode . shell-mode) (mode . sh-mode) (mode . bash-ts-mode) (mode . lua-mode) @@ -794,7 +763,12 @@ I adjusted the config accordingly to my modes which I use on a frequent. (mode . markdown-mode) (mode . adoc-mode))) ("Org" (mode . org-mode)) - ("Terminal" (mode . vterm-mode)) + ("Terminal" (or + (mode . ghostel-mode) + (mode . eat-mode) + (mode . eshell-mode) + (mode . shell-mode) + (mode . term-mode))) ("LaTeX" (name . "\.tex$")) ("Magit" (or (mode . magit-blame-mode) @@ -883,37 +857,6 @@ Defined early so later =with-eval-after-load 'general= callbacks find =my-leader * ai -** COMMENT gptel - -#+begin_src emacs-lisp -(use-package gptel - :ensure t - :defer t - :commands (gptel gptel-send gptel-menu) - :config - (defun my/openrouter-key () - (string-trim - (shell-command-to-string "pass code/openrouter"))) - - (setq my/openrouter-backend - (gptel-make-openai - "OpenRouter" - :host "openrouter.ai" - :endpoint "/api/v1/chat/completions" - :stream t - :key #'my/openrouter-key - :models '("google/gemini-3-flash-preview:online" - "deepseek/deepseek-v3.2:online" - "minimax/minimax-m2.1:online" - ))) - - (setq gptel-backend my/openrouter-backend) - (setq gptel-log-level 'debug) - (setq gptel-include-reasoning nil) - (setq gptel-default-mode 'markdown-mode) - (setq gptel-backends (list my/openrouter-backend))) -#+end_src - ** markdown-mode #+begin_src emacs-lisp @@ -1061,8 +1004,8 @@ Defined early so later =with-eval-after-load 'general= callbacks find =my-leader ** claude-code-ide Native [[https://github.com/manzaltu/claude-code-ide.el][Claude Code IDE]] integration via MCP. Requires the =claude= CLI in -PATH (already provided through the Nix profile) and uses =vterm= as the -terminal backend (=eat= is also installed as a fallback). +PATH (already provided through the Nix profile) and uses =eat= as the +terminal backend. #+begin_src emacs-lisp (use-package claude-code-ide @@ -1087,15 +1030,14 @@ terminal backend (=eat= is also installed as a fallback). ;; CLI (claude-code-ide-cli-path "claude") (claude-code-ide-cli-debug nil) - ;; Terminal backend — vterm is preferred, eat as fallback - (claude-code-ide-terminal-backend 'vterm) - (claude-code-ide-vterm-anti-flicker nil) + ;; Terminal backend + (claude-code-ide-terminal-backend 'eat) ;; Window placement — mirror eca on the right side so the two AI assistants ;; don't fight over the same slot (claude-code-ide-use-side-window t) (claude-code-ide-window-side 'right) - (claude-code-ide-window-width 100) + (claude-code-ide-window-width 75) (claude-code-ide-focus-on-open t) ;; Ediff integration for code suggestions @@ -1114,7 +1056,6 @@ terminal backend (=eat= is also installed as a fallback). ;; Evil: open the Claude terminal in insert state so you can type immediately. ;; Defined in :init so it applies even before claude-code-ide loads. (with-eval-after-load 'evil - (evil-set-initial-state 'vterm-mode 'insert) (evil-set-initial-state 'eat-mode 'insert)) (defun my/claude-code-ide--enter-insert (&rest _) @@ -1247,14 +1188,6 @@ terminal backend (=eat= is also installed as a fallback). :hook (python-ts-mode . flycheck-python-ruff-setup)) #+end_src -** COMMENT flyover - -#+begin_src emacs-lisp -(use-package flyover - :ensure t - :hook (flycheck-mode-hook . flyover-mode)) -#+end_src - ** flycheck eglot #+begin_src emacs-lisp @@ -1401,21 +1334,6 @@ automatically encrypted before save and can be decrypted in-place with #+begin_src emacs-lisp #+end_src -** COMMENT org-modern (disabled in favor of render-org) - -#+begin_src emacs-lisp -(use-package org-modern - :ensure t - :hook (org-mode . org-modern-mode) - :config - (setq org-modern-hide-stars t) - (setq org-modern-star 'replace) - (setq org-modern-fold-stars '(("◉" . "○"))) - (setq org-modern-replace-stars "◉○◉○◉") - (global-org-modern-mode)) - -#+end_src - ** render-org TUI-first beautiful rendering for org-mode (replaces org-modern). @@ -1441,28 +1359,19 @@ Display inline images in terminal Emacs via the Kitty graphics protocol. Only activates when running in a Kitty terminal (not in GUI Emacs). #+begin_src emacs-lisp -;; TEMP: load kitty-graphics from local dev clone (/home/cashmere/projects/ -;; kitty-graphics/) instead of the elpaca-managed build, so edits to the -;; source apply on Emacs restart without an `elpaca-rebuild' cycle. -;; Swap back to the `use-package' / `:ensure' form below once changes are -;; committed + pushed and elpaca has pulled the new commit. -(when (not (display-graphic-p)) - (add-to-list 'load-path "/home/cashmere/projects/kitty-graphics") - (require 'kitty-graphics) - (setq kitty-gfx-enable-video t) - (add-hook 'dired-mode-hook #'kitty-gfx-dired-auto-preview-mode) - (setq kitty-gfx-debug nil) - (kitty-graphics-mode 1)) - -;; (use-package kitty-graphics -;; :ensure (:host github :repo "cashmeredev/kitty-graphics.el") -;; :if (not (display-graphic-p)) -;; :custom -;; (kitty-gfx-enable-video t) -;; :hook -;; (dired-mode . kitty-gfx-dired-auto-preview-mode) -;; :config -;; (kitty-graphics-mode 1)) +(use-package kitty-graphics + :ensure nil + :load-path "/home/cashmere/projects/kitty-graphics" + :demand t + :custom + (kitty-gfx-enable-video t) + (kitty-gfx-debug nil) + (kitty-gfx-shr-scale 'fit) + (kitty-gfx-shr-fit-width 0.6) + (kitty-gfx-shr-fit-height 20) + :hook (dired-mode . kitty-gfx-dired-auto-preview-mode) + :config + (kitty-graphics-setup)) #+end_src ** org-fancy-properties @@ -1622,46 +1531,36 @@ BODY is the justfile content. PARAMS may include: ** my/snip-upload -Upload buffer, region, or file to snips.sh and copy URL. +Upload buffer, region, or file to bouncer.cashmere.rs and copy URL. #+begin_src emacs-lisp (defun my/snip-upload (&optional file) - "Upload FILE, region, or current buffer to snips.sh. -Passes -ext flag to hint the file type for syntax highlighting. -Copies the resulting URL to the kill ring and clipboard." + "Upload FILE, region, or current buffer to bouncer.cashmere.rs. +The xonsh `upload' command copies the URL to the clipboard; it is +also added to the kill ring." (interactive) - (let* ((input (cond - (file file) - ((use-region-p) - (buffer-substring-no-properties (region-beginning) (region-end))) - (t (buffer-substring-no-properties (point-min) (point-max))))) - (ext (cond - ((and file (file-name-extension file)) - (file-name-extension file)) - ((and (not file) (buffer-file-name) (file-name-extension (buffer-file-name))) - (file-name-extension (buffer-file-name))))) - (ext-flag (if ext (format " -- -ext %s" ext) "")) - (cmd (format "ssh pb@pb.moneyspread.st%s 2>/dev/null | sed 's/\\x1b\\[[0-9;]*m//g' | grep -oP 'https://\\S+/f/\\S+'" ext-flag)) - (url (string-trim - (if (and file (file-exists-p file)) - (shell-command-to-string (format "cat %s | %s" (shell-quote-argument file) cmd)) - (with-temp-buffer - (insert input) - (shell-command-on-region (point-min) (point-max) cmd nil t) - (buffer-string)))))) - (if (string-prefix-p "https://" url) - (let ((final-url (if (and ext (member (downcase ext) - '("png" "jpg" "jpeg" "gif" "webp" "svg" "bmp" "ico" "tiff"))) - (concat url "?r=1") - url))) - (kill-new final-url) - (message "Uploaded: %s" final-url)) - (message "Upload failed")))) + (let* ((ext (or (and file (file-name-extension file)) + (and (buffer-file-name) (file-name-extension (buffer-file-name))) + "txt")) + (cmd (format "xonsh -c 'upload %s'" ext))) + (if (and file (file-exists-p file)) + (call-process-shell-command + (format "cat %s | %s" (shell-quote-argument file) cmd)) + (shell-command-on-region + (if (use-region-p) (region-beginning) (point-min)) + (if (use-region-p) (region-end) (point-max)) + cmd nil nil)) + (let ((url (string-trim (shell-command-to-string "wl-paste")))) + (if (string-prefix-p "https://" url) + (progn + (kill-new url) + (message "Uploaded: %s" url)) + (message "Upload failed: %s" url))))) (defun my/snip-upload-file () - "Prompt for a file and upload it to snips.sh." + "Prompt for a file and upload it to bouncer.cashmere.rs." (interactive) - (my/snip-upload (read-file-name "Upload to snips.sh: "))) + (my/snip-upload (read-file-name "Upload to bouncer: "))) #+end_src ** my/setup-git-remote @@ -2495,8 +2394,8 @@ Org Backend exporter for typst templates written and configured in org mode. (setq org-publish-project-alist '(("wiki" - :base-directory "~/wiki" - :publishing-directory "~/blog/content/wiki" + :base-directory "~/garden" + :publishing-directory "~/cashmere.rs/content/wiki" :publishing-function denote-publish-to-md :recursive nil :exclude-tags ("noexport" "draft") @@ -2761,8 +2660,8 @@ Some goodies for better integration with org files. (use-package denote-publish :ensure (:repo "https://github.com/vedang/denote-publish")) -(setq denote-publish-default-base-dir "~/wiki") -(setq denote-publish-default-output-dir "~/blog/wiki") +(setq denote-publish-default-base-dir "~/garden") +(setq denote-publish-default-output-dir "~/cashmere.rs/content/wiki") (setq denote-publish-link-class "internal-link") @@ -2902,26 +2801,6 @@ Timers that expired while Emacs was closed fire immediately." cand)))) #+end_src -** COMMENT vertico-posframe - -#+begin_src emacs-lisp -(use-package vertico-posframe - :ensure t - :init - (setq vertico-posframe-parameters '((left-fringe . 12) ;; Fringes - (right-fringe . 12) - (accept-focus . t))) - ;; (undecorated . nil) ;; Rounded frame - - :config - (vertico-posframe-mode 1) - (setq vertico-posframe-width 96 ;; Narrow frame - vertico-posframe-height vertico-count ;; Default height - ;; Don't create posframe for these commands - vertico-multiform-commands '((consult-line (:not posframe)) - (consult-ripgrep (:not posframe))))) -#+end_src - ** corfu #+begin_src emacs-lisp @@ -2936,19 +2815,16 @@ Timers that expired while Emacs was closed fire immediately." (global-corfu-mode) (corfu-history-mode) (corfu-popupinfo-mode)) +#+end_src -;; (defun my/suppress-corfu-terminal-warning (orig-fun type message &rest args) -;; (unless (and (eq type 'corfu) -;; (string-match-p "corfu-terminal.*not needed" message)) -;; (apply orig-fun type message args))) - -;; (advice-add 'display-warning :around #'my/suppress-corfu-terminal-warning) +On Emacs 32 + a multi-TTY daemon (every ~Super+Return~ spawns =kitty emacsclient -nw -c=), the native tty child-frame popup tries to open a tty device for a closed client (~Could not open file: /dev/pts/N~) and spams the backtrace. =corfu-terminal= renders the popup as an overlay instead, so no frame and no device is ever opened. -;; (use-package corfu-terminal -;; :ensure t -;; :after corfu -;; :init -;; (corfu-terminal-mode +1)) +#+begin_src emacs-lisp +(use-package corfu-terminal + :ensure t + :after corfu + :config + (corfu-terminal-mode +1)) #+end_src *** cape @@ -2971,7 +2847,10 @@ Timers that expired while Emacs was closed fire immediately." (add-hook 'completion-at-point-functions #'cape-file) ;; (add-hook 'completion-at-point-functions #'cape-history) ;; ... -) + :config + (with-eval-after-load 'eglot + (advice-add 'eglot-completion-at-point :around #'cape-wrap-noninterruptible) + (advice-add 'eglot-completion-at-point :around #'cape-wrap-buster))) #+end_src * consult @@ -3377,18 +3256,13 @@ instead of churning." (root (or (and (project-current) (project-root (project-current))) temporary-file-directory)) - (name (format ".ob-src-%s.py" + (name (format "ob-src-%s.py" (substring (md5 parent) 0 8)))) (setq-local buffer-file-name (expand-file-name name root)) (set-buffer-modified-p nil) (eglot-ensure)))) (add-hook 'org-src-mode-hook #'my/org-src-eglot-python) - -;; Kein cleanup-hook: temp file bleibt liegen. Sonst killed eglot -;; jedesmal die LSP connection wenn C-c ' das buffer schliesst → -;; neuer pyrefly process beim naechsten Edit. File ist harmlos (gitignored -;; via .gitignore pattern .ob-src-*.py). #+end_src *** xonsh LSP via eglot @@ -3417,24 +3291,38 @@ and runs via the =xonsh= interpreter. Params: - =:dir= working directory (default: =default-directory=) - =:cmdline= extra args passed to =xonsh= +The executor must also be installed inside the =ob-async= child +process — it runs in a fresh Emacs that never loads this config, so a +plain =defun= here would be void there. Stashing the installer in a +variable lets both the parent and the =ob-async-pre-execute-src-block-hook= +share one definition. + #+begin_src emacs-lisp -(with-eval-after-load 'org - (defun org-babel-execute:xonsh (body params) - "Execute a xonsh source block. +(defvar my/ob-xonsh-installer + (lambda () + (defun org-babel-execute:xonsh (body params) + "Execute a xonsh source block. BODY is the xonsh script. PARAMS may include :dir and :cmdline." - (let* ((dir (or (cdr (assq :dir params)) default-directory)) - (cmdline (or (cdr (assq :cmdline params)) "")) - (tmp (make-temp-file "ob-xonsh-" nil ".xsh"))) - (unwind-protect - (progn - (with-temp-file tmp (insert body)) - (let ((default-directory dir)) - (shell-command-to-string - (format "xonsh %s %s" - cmdline - (shell-quote-argument tmp))))) - (when (file-exists-p tmp) (delete-file tmp))))) + (let* ((dir (or (cdr (assq :dir params)) default-directory)) + (cmdline (or (cdr (assq :cmdline params)) "")) + (tmp (make-temp-file "ob-xonsh-" nil ".xsh"))) + (unwind-protect + (progn + (with-temp-file tmp (insert body)) + (let ((default-directory dir)) + (shell-command-to-string + (format "xonsh %s %s" + cmdline + (shell-quote-argument tmp))))) + (when (file-exists-p tmp) (delete-file tmp)))))) + "Defines `org-babel-execute:xonsh'; reused in ob-async child processes.") + +(with-eval-after-load 'org + (funcall my/ob-xonsh-installer) (add-to-list 'org-src-lang-modes '("xonsh" . xonsh))) + +(with-eval-after-load 'ob-async + (add-hook 'ob-async-pre-execute-src-block-hook my/ob-xonsh-installer)) #+end_src ** Go mode @@ -3554,145 +3442,19 @@ BODY is the xonsh script. PARAMS may include :dir and :cmdline." * terminals -** vterm - -#+begin_src emacs-lisp -(use-package vterm - :ensure t - :config - (setq vterm-timer-delay 0.0001) - (setq vterm-shell "xonsh")) -#+end_src - -*** multi-vterm - -#+begin_src emacs-lisp -(use-package multi-vterm - :ensure t - :defer t) -#+end_src - ** eat #+begin_src emacs-lisp (use-package eat :ensure t :custom - (eat-shell "fish") + (eat-shell "xonsh") (eat-kill-buffer-on-exit t) (eat-enable-shell-prompt-annotation t) (eat-term-name "xterm-256color") :hook - ;; Enable shell integration for directory tracking, prompt navigation, etc. (eshell-load . eat-eshell-mode) - (eshell-load . eat-eshell-visual-command-mode) - :config - ;; Tell yazi (and other programs) that this terminal supports Sixel. - ;; Eat supports Sixel rendering but yazi doesn't recognize it as a known - ;; terminal. Setting TERM_PROGRAM to "foot" (a known Sixel terminal) makes - ;; yazi select the Sixel adapter for image previews. - (advice-add 'eat :around - (lambda (orig-fn &rest args) - (let ((process-environment - (append '("TERM_PROGRAM=foot" - "TERM_PROGRAM_VERSION=1.18.0") - process-environment))) - (apply orig-fn args)))) - ;; ────────────────────────────────────────────────── - ;; Evil integration: make eat behave like vterm - ;; - ;; Strategy: - ;; - "emacs mode" in eat = normal state (vim motions on buffer text) - ;; - "semi-char mode" in eat = insert state (keys pass to terminal) - ;; - ESC switches from semi-char → emacs mode (insert → normal) - ;; - i/a/A etc switch from emacs → semi-char mode (normal → insert) - ;; ────────────────────────────────────────────────── - - ;; Don't move cursor back on ESC (inappropriate in terminal buffers) - (add-hook 'eat-mode-hook (lambda () (setq-local evil-move-cursor-back nil))) - - ;; Start eat in insert state (semi-char mode) so typing goes to shell - (evil-set-initial-state 'eat-mode 'insert) - - ;; -- Normal state: vim motions on terminal text -------------------------- - - ;; Entering insert state switches eat to semi-char mode (passthrough) - (defun my/eat-semi-char-mode-entry () - "Switch eat to semi-char mode when entering evil insert state." - (when (and (derived-mode-p 'eat-mode) - (eat-term-p (buffer-local-value 'eat-terminal (current-buffer)))) - (eat-semi-char-mode))) - - ;; Exiting insert state switches eat to emacs mode (vim motions) - (defun my/eat-emacs-mode-entry () - "Switch eat to emacs mode when entering evil normal state." - (when (and (derived-mode-p 'eat-mode) - (eat-term-p (buffer-local-value 'eat-terminal (current-buffer)))) - (eat-emacs-mode))) - - (add-hook 'evil-insert-state-entry-hook #'my/eat-semi-char-mode-entry) - (add-hook 'evil-normal-state-entry-hook #'my/eat-emacs-mode-entry) - - ;; In normal state, bind standard vim keys to re-enter insert (semi-char) - (evil-define-key 'normal eat-mode-map - "i" (lambda () (interactive) (eat-semi-char-mode) (evil-insert-state)) - "a" (lambda () (interactive) (forward-char 1) (eat-semi-char-mode) (evil-insert-state)) - "A" (lambda () (interactive) (end-of-line) (eat-semi-char-mode) (evil-insert-state)) - "I" (lambda () (interactive) (back-to-indentation) (eat-semi-char-mode) (evil-insert-state)) - "o" (lambda () (interactive) (eat-semi-char-mode) (evil-insert-state) - (eat-self-input 1 ?\n)) - ;; Paste from kill ring in normal mode - "p" (lambda () (interactive) - (eat-semi-char-mode) - (eat-yank) - (eat-emacs-mode)) - ;; Navigate prompts - (kbd "[ [") #'eat-previous-shell-prompt - (kbd "] ]") #'eat-next-shell-prompt) - - ;; In insert state: ESC escapes back to normal (emacs mode intercepts it) - ;; The default eat-semi-char-mode lets C-c, C-x, etc. pass through to Emacs - ;; which is exactly what we want. ESC is also not captured by semi-char mode, - ;; so evil's ESC → normal state transition works naturally. - - ;; -- Multi-eat: manage multiple terminal buffers ------------------------- - - (defvar my/eat-buffer-counter 0 - "Counter for naming eat terminal buffers.") - - (defun my/eat-new () - "Create a new eat terminal buffer." - (interactive) - (cl-incf my/eat-buffer-counter) - (let ((buf (generate-new-buffer - (format "*eat<%d>*" my/eat-buffer-counter))) - (process-environment - (append '("TERM_PROGRAM=foot" "TERM_PROGRAM_VERSION=1.18.0") - process-environment))) - (with-current-buffer buf - (eat-mode) - (eat-exec buf (buffer-name buf) eat-shell nil nil)) - (switch-to-buffer buf))) - - (defun my/eat-toggle () - "Toggle an eat terminal. Create one if none exists. -With prefix arg, always create a new terminal." - (interactive) - (if current-prefix-arg - (my/eat-new) - (let ((eat-bufs (cl-remove-if-not - (lambda (b) (with-current-buffer b - (derived-mode-p 'eat-mode))) - (buffer-list)))) - (cond - ;; Currently in an eat buffer → bury it - ((derived-mode-p 'eat-mode) - (bury-buffer)) - ;; Existing eat buffers → switch to most recent - (eat-bufs - (switch-to-buffer (car eat-bufs))) - ;; No eat buffers → create one - (t (eat))))))) + (eshell-load . eat-eshell-visual-command-mode)) #+end_src * olivetti @@ -3761,26 +3523,6 @@ With prefix arg, always create a new terminal." ;; (setq-default visual-fill-column-center-text t))) #+end_src -* COMMENT diff-hl - -#+begin_src emacs-lisp -(use-package diff-hl - ;; :defer t - :ensure t - :hook - (find-file . (lambda () - (global-diff-hl-mode) ;; Enable Diff-HL mode for all files. - (diff-hl-flydiff-mode) ;; Automatically refresh diffs. - (diff-hl-margin-mode))) ;; Show diff indicators in the margin. - :custom - (diff-hl-side 'left) ;; Set the side for diff indicators. - (diff-hl-margin-symbols-alist '((insert . "┃") ;; Customize symbols for each change type. - (delete . "-") - (change . "┃") - (unknown . "┆") - (ignored . "i")))) -#+end_src - * hl-todo #+begin_src emacs-lisp @@ -4072,6 +3814,21 @@ so the working-tree diff stays visible until the user explicitly stages." (require 'flash-evil) (flash-evil-setup t) + (defun my/flash-visual-extend (orig match) + (if (and match + (bound-and-true-p evil-local-mode) + (eq evil-state 'visual)) + (let* ((origin (point)) + (mpos (flash-match-pos-value match)) + (forward (and mpos (>= mpos origin))) + (flash-jump-position (if forward 'end 'start))) + (prog1 (funcall orig match) + (when (and forward (not (bolp)) (> (point) (point-min))) + (backward-char)))) + (funcall orig match))) + + (advice-add 'flash-jump-to-match :around #'my/flash-visual-extend) + ;; Restore ; and , after flash-char overwrites them ;; ; is used as prefix for prev-navigation (;b, ;d) ;; , is the local leader @@ -4169,6 +3926,16 @@ so the working-tree diff stays visible until the user explicitly stages." (dired-mode . nerd-icons-dired-mode)) #+end_src +** diredfl + +#+begin_src emacs-lisp +(use-package diredfl + :ensure t + :hook + ((dired-mode . diredfl-mode) + (dirvish-directory-view-mode . diredfl-mode))) +#+end_src + ** nerd-icons-completion #+begin_src emacs-lisp @@ -4201,290 +3968,6 @@ so the working-tree diff stays visible until the user explicitly stages." (kill-emacs)) ;; Close Emacs after installation is complete. #+end_src -* COMMENT headerline - -#+begin_src emacs-lisp -;; (require 'battery) -;; (require 'nerd-icons) -;; -;; ;; 2. Define battery faces -;; (defface my-battery-charging -;; '((t :inherit success)) -;; "Face for charging battery.") -;; -;; (defface my-battery-full -;; '((t :inherit success)) -;; "Face for full battery.") -;; -;; (defface my-battery-normal -;; '((t :inherit mode-line)) -;; "Face for normal buffer indicator.") -;; -;; (defface my-buffer-read-only -;; '((t :inherit error)) -;; "Face for read-only buffer indicator.") -;; -;; (defface my-buffer-remote -;; '((t :inherit font-lock-comment-face)) -;; "Face for remote buffer indicator.") -;; -;; ;; Evil state faces -;; (defface my-evil-normal-state -;; '((t :inherit success)) -;; "Face for evil normal state.") -;; -;; (defface my-evil-insert-state -;; '((t :inherit font-lock-keyword-face)) -;; "Face for evil insert state.") -;; -;; (defface my-evil-visual-state -;; '((t :inherit warning)) -;; "Face for evil visual state.") -;; -;; (defface my-evil-motion-state -;; '((t :inherit font-lock-doc-face :slant normal)) -;; "Face for evil motion state.") -;; -;; (defface my-evil-emacs-state -;; '((t :inherit font-lock-builtin-face)) -;; "Face for evil emacs state.") -;; -;; ;; 3. Battery functionality -;; (defvar my-battery-string nil) -;; (defun my-header-line-right () -;; "Formatiert den rechten Teil der Header-Line und richtet ihn korrekt aus." -;; (let* ((rhs (concat (my-mu4e-segment) -;; (when (my-should-show-battery) -;; my-battery-string) -;; (when (bound-and-true-p display-time-mode) -;; (concat " " display-time-string " ")))) -;; (width (if (fboundp 'string-pixel-width) -;; (string-pixel-width rhs) -;; (* (string-width rhs) (frame-char-width))))) -;; (concat (propertize " " 'display `(space :align-to (- right (,width)))) -;; rhs))) -;; -;; (defun my-update-battery () -;; "Update battery display." -;; (setq my-battery-string -;; (when (bound-and-true-p display-battery-mode) -;; (let* ((data (and battery-status-function -;; (functionp battery-status-function) -;; (funcall battery-status-function))) -;; (status (cdr (assoc ?L data))) -;; (charging? (or (string-equal "AC" status) -;; (string-equal "on-line" status))) -;; (percentage (car (read-from-string (or (cdr (assq ?p data)) "ERR")))) -;; (valid? (and (numberp percentage) -;; (>= percentage 0) -;; (<= percentage 100))) -;; (face (if valid? -;; (cond (charging? 'my-battery-charging) -;; ((< percentage 20) 'error) -;; ((< percentage 30) 'warning) -;; (t 'success)) -;; 'error)) -;; (icon (if valid? -;; (cond -;; ((>= percentage 90) -;; (nerd-icons-mdicon "nf-md-battery" :face face)) -;; ((>= percentage 60) -;; (nerd-icons-mdicon "nf-md-battery_70" :face face)) -;; ((>= percentage 30) -;; (nerd-icons-mdicon "nf-md-battery_50" :face face)) -;; (t -;; (nerd-icons-mdicon "nf-md-battery_20" :face face))) -;; (nerd-icons-mdicon "nf-md-battery_alert" :face face))) -;; (text (if valid? (format " %d%%" percentage) " N/A"))) -;; (concat (propertize icon 'help-echo "Battery status") -;; (propertize text 'face face 'help-echo "Battery status")))))) -;; -;; (defun my-override-battery () -;; "Override default battery display." -;; (when (bound-and-true-p display-battery-mode) -;; (advice-add #'battery-update :after #'my-update-battery) -;; (setq global-mode-string (delq 'battery-mode-line-string global-mode-string)) -;; (my-update-battery))) -;; -;; ;; 4. Buffer state icons (simplified from your new code) -;; (defvar my-buffer-state-icon nil) -;; (defvar my-buffer-file-icon nil) -;; -;; (defun my-update-buffer-file-icon (&rest _) -;; "Update file icon in header-line using nerd-icons." -;; (setq my-buffer-file-icon -;; (when (require 'nerd-icons nil t) -;; (let ((icon (nerd-icons-icon-for-buffer))) -;; (propertize -;; (if (or (null icon) (string-empty-p icon)) -;; (nerd-icons-faicon "nf-fa-file_o") -;; icon) -;; 'help-echo "File type"))))) -;; -;; (defun my-update-buffer-state-icon () -;; "Update buffer state indicator." -;; (setq my-buffer-state-icon -;; (concat -;; (cond (buffer-read-only -;; (propertize (nerd-icons-mdicon "nf-md-lock" :face 'my-buffer-read-only) -;; 'help-echo "Read-only buffer")) -;; ((and buffer-file-name (buffer-modified-p)) -;; (propertize (nerd-icons-mdicon "nf-md-content_save_edit" :face 'warning) -;; 'help-echo "Buffer modified")) -;; (t ""))))) -;; -;; (defun my-update-buffer-file-name () -;; "Update buffer file name with proper faces." -;; (let* ((file-name (or (and buffer-file-name -;; (file-name-nondirectory buffer-file-name)) -;; (buffer-name))) -;; (face (cond ((and buffer-file-name (buffer-modified-p)) -;; 'warning) -;; (buffer-read-only -;; 'error) -;; (t 'mode-line-buffer-id)))) -;; (propertize file-name 'face face))) -;; -;; ;; 5. Evil state indicator (keeping your formatting with letters) -;; (defvar my-evil-state-string nil) -;; -;; (defun my-update-evil-state () -;; "Update evil state indicator." -;; (setq my-evil-state-string -;; (when (bound-and-true-p evil-local-mode) -;; (let ((state (cond -;; ((evil-normal-state-p) -;; (cons (nerd-icons-mdicon "nf-md-alpha_n_circle" :face 'my-evil-normal-state) -;; "N")) -;; ((evil-insert-state-p) -;; (cons (nerd-icons-mdicon "nf-md-alpha_i_circle" :face 'my-evil-insert-state) -;; "I")) -;; ((evil-visual-state-p) -;; (cons (nerd-icons-mdicon "nf-md-alpha_v_circle" :face 'my-evil-visual-state) -;; "V")) -;; ((evil-motion-state-p) -;; (cons (nerd-icons-mdicon "nf-md-alpha_m_circle" :face 'my-evil-motion-state) -;; "M")) -;; ((evil-emacs-state-p) -;; (cons (nerd-icons-mdicon "nf-md-alpha_e_circle" :face 'my-evil-emacs-state) -;; "E")) -;; (t -;; (cons (nerd-icons-mdicon "nf-md-alpha_u_circle" :face 'mode-line) -;; "O"))))) -;; (when state -;; (concat (car state) " " (cdr state))))))) -;; -;; ;; 6. Battery toggle -;; (defvar my-show-battery t -;; "Whether to show battery in header-line.") -;; -;; (defun my-should-show-battery () -;; "Determine if battery should be shown." -;; (and my-show-battery -;; (bound-and-true-p display-battery-mode) -;; my-battery-string)) -;; -;; ;; 7. mu4e integration -;; (defvar my-mu4e-unread-count 0) -;; -;; (defun my-update-mu4e-count () -;; "Update mu4e unread count." -;; (setq my-mu4e-unread-count -;; (when (and (featurep 'mu4e-alert) -;; (bound-and-true-p mu4e-alert-mode-line)) -;; (or (when (functionp 'mu4e-alert-mode-line) -;; (mu4e-alert-mode-line)) -;; 0)))) -;; -;; (defun my-mu4e-segment () -;; "Create mu4e notification segment." -;; (when (and (featurep 'mu4e-alert) -;; (numberp my-mu4e-unread-count) -;; (> my-mu4e-unread-count 0)) -;; (let* ((icon (nerd-icons-mdicon "nf-md-email" :face 'warning)) -;; (count (if (> my-mu4e-unread-count 99) -;; "99+" -;; (number-to-string my-mu4e-unread-count))) -;; (text (propertize count 'face '(:inherit warning :weight bold)))) -;; (concat " " icon " " text " ")))) -;; -;; ;; 8. Fixed header-line-format (preserving your layout with right-aligned content) -;; (setq-default header-line-format -;; '("%e" -;; (:propertize " " display (raise +0.4)) -;; (:propertize " " display (raise -0.4)) -;; -;; ;; Left side components -;; (:eval (when my-evil-state-string -;; (list my-evil-state-string " "))) -;; (:eval (when my-buffer-file-icon -;; (list my-buffer-file-icon " "))) -;; (:eval (my-update-buffer-file-name)) -;; (:eval (when my-buffer-state-icon -;; (list " " my-buffer-state-icon))) -;; (:eval (when vc-mode -;; (list " " -;; (propertize (truncate-string-to-width -;; (substring vc-mode 5) 50) -;; 'face 'font-lock-comment-face)))) -;; (:propertize " %4l:%c" face mode-line-buffer-id) -;; -;; ;; Right side (calculated and aligned) -;; (:eval (my-header-line-right)))) -;; -;; ;; 9. Force mode-line to be hidden -;; (setq-default mode-line-format nil) -;; -;; ;; 10. Setup hooks -;; (add-hook 'find-file-hook #'my-update-buffer-file-icon) -;; (add-hook 'after-change-major-mode-hook #'my-update-buffer-file-icon) -;; (add-hook 'after-save-hook #'my-update-buffer-state-icon) -;; (add-hook 'buffer-list-update-hook #'my-update-buffer-state-icon) -;; (advice-add #'rename-buffer :after #'my-update-buffer-file-icon) -;; (advice-add #'set-visited-file-name :after #'my-update-buffer-file-icon) -;; -;; (add-hook 'evil-normal-state-entry-hook #'my-update-evil-state) -;; (add-hook 'evil-insert-state-entry-hook #'my-update-evil-state) -;; (add-hook 'evil-visual-state-entry-hook #'my-update-evil-state) -;; (add-hook 'evil-motion-state-entry-hook #'my-update-evil-state) -;; (add-hook 'evil-emacs-state-entry-hook #'my-update-evil-state) -;; (add-hook 'evil-local-mode-hook #'my-update-evil-state) -;; -;; (add-hook 'display-battery-mode-hook #'my-override-battery) -;; -;; ;; 11. Enable time and battery -;; (display-time-mode 1) -;; (display-battery-mode 1) -;; -;; ;; 12. Helper functions -;; (defun my-toggle-battery-display () -;; "Toggle battery display in header-line." -;; (interactive) -;; (setq my-show-battery (not my-show-battery)) -;; (force-mode-line-update) -;; (message "Battery display %s" (if my-show-battery "enabled" "disabled"))) -;; -;; (defun my-header-line-refresh () -;; "Force refresh header-line." -;; (interactive) -;; (force-mode-line-update)) -;; -;; ;; 13. Initialize everything -;; (my-update-buffer-file-icon) -;; (my-update-buffer-state-icon) -;; (my-update-evil-state) -;; (my-update-battery) -;; -;; ;; Install nerd-icons fonts if missing (from your new code) -;; (add-hook 'after-init-hook -;; (lambda () -;; (when (require 'nerd-icons nil t) -;; (unless (nerd-icons--find-font -;; (or nerd-icons-font-family "Symbols Nerd Font Mono")) -;; (message "Installing nerd-icons fonts...") -;; (nerd-icons-install-fonts))))) -#+end_src - * modelines ** hide modeline @@ -4493,200 +3976,6 @@ so the working-tree diff stays visible until the user explicitly stages." :ensure t) #+end_src -** awesome-tray - -#+begin_src emacs-lisp -;; (use-package awesome-tray -;; :ensure (:host github :repo "manateelazycat/awesome-tray") -;; :custom -;; ;; Position at the top -;; ;; (setq awesome-tray-position 'right) - -;; ;; Basic Visual Settings -;; ;; (awesome-tray-hide-mode-line t) -;; (awesome-tray-separator " │ ") -;; (awesome-tray-ellipsis "…") - -;; ;; Module Customizations -;; (awesome-tray-date-format "%I:%M %p") ; 12-hour format with AM/PM -;; (awesome-tray-git-format " ᚴ %s") -;; (awesome-tray-git-show-status t) -;; (awesome-tray-location-format "%l:%c") -;; (awesome-tray-evil-show-mode t) -;; (awesome-tray-evil-show-macro t) -;; (awesome-tray-evil-show-cursor-count t) -;; (awesome-tray-file-path-full-dirname-levels 2) -;; (awesome-tray-file-path-shorten-start-length 1) -;; (awesome-tray-input-method-default-style "EN") -;; (awesome-tray-input-method-local-style "中") -;; (awesome-tray-input-method-local-methods '("rime" "pinyin")) - -;; ;; Performance settings -;; (awesome-tray-refresh-idle-delay 0.5) -;; (awesome-tray-refresh-timer t) -;; (awesome-tray-update-interval 1) - -;; :config -;; ;; Start with essential modules for performance -;; (setq awesome-tray-active-modules -;; '( -;; "buffer-name" -;; "mode-name" -;; "date" -;; "location" -;; "evil" -;; "input-method" -;; )) - -;; ;; Enable awesome-tray -;; (awesome-tray-mode 1) -;; ) -#+end_src - -** lambda-line - -#+begin_src emacs-lisp -;; (setq display-time-mode 1) -;; (use-package lambda-line -;; :ensure (:host github :repo "lambda-emacs/lambda-line") -;; :custom -;; (lambda-line-lsp-indicator nil) -;; (lambda-line-icon-time t) ;; requires ClockFace font (see below) -;; (lambda-line-clockface-update-fontset "ClockFaceRect") ;; set clock icon -;; (lambda-line-position 'top) ;; Set position of status-line -;; (lambda-line-abbrev nil) ;; 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 nil) -;; (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 -;; ;; activate lambda-line -;; (lambda-line-mode) -;; ;; set divider line in footer -;; (when (eq lambda-line-position 'top) -;; (setq-default mode-line-format (list "%_")) -;; (setq mode-line-format (list "%_")))) -#+end_src - -** doom modeline -#+begin_src emacs-lisp -;; (use-package doom-modeline -;; :ensure t -;; :hook (after-init . doom-modeline-mode) -;; :custom -;; (doom-modeline-time t) -;; (doom-modeline-time-icon t) -;; (doom-modeline-buffer-file-name-style 'buffer-name) -;; (doom-modeline-height 24) -;; (doom-modeline-buffer-encoding nil) -;; (doom-modeline-env-version t) -;; (doom-modeline-env-setup-rust nil) -;; :config -;; (setq display-time-24hr-format nil) -;; (display-time-mode 1)) -;; ;; (set-face-attribute 'mode-line nil :height 180) -;; ;; (set-face-attribute 'mode-line-inactive nil :height 180)) -#+end_src - -** maple modeline - -#+begin_src emacs-lisp -(setq mode-line-misc-info - (assq-delete-all 'eglot--managed-mode - (copy-sequence mode-line-misc-info))) - -(use-package maple-modeline - :disabled t - :ensure (:host github :repo "honmaple/emacs-maple-modeline") - ;; :hook (elpaca-after-init . maple-modeline-mode) - :config - (setq maple-modeline-separator 'nil) - (setq maple-modeline-height 25) - (setq maple-modeline-icon t) - - (maple-modeline-define-segment my-modeline-time - :format (propertize (downcase (format-time-string " %I:%M %p ")) - 'face 'bold)) - - (maple-modeline-define-segment org-clock-task - :if (and (fboundp 'org-clocking-p) (org-clocking-p)) - :format - (let ((heading (truncate-string-to-width - (substring-no-properties org-clock-heading) 35 nil nil "..."))) - (concat - (maple-modeline--concat-or - (maple-modeline--icon 'mdicon "nf-md-clock_outline" face) - "CLK") - " " (propertize heading 'face face - 'mouse-face 'mode-line-highlight - 'help-echo "Go to clocked task" - 'local-map (make-mode-line-mouse-map 'mouse-1 'org-clock-goto))))) - - (maple-modeline-define-segment tmr-timer - :if (and (fboundp 'tmr-mode-line--get-active-timers) - (tmr-mode-line--get-active-timers)) - :format - (let* ((timer (car (tmr-mode-line--get-active-timers))) - (remaining (tmr-mode-line--format-remaining timer)) - (desc (tmr-mode-line--format-description timer))) - (concat remaining desc))) - - (maple-modeline-define-segment mu4e-mail - :defines (mu4e-alert-mode-line) - :functions (mu4e-alert-view-unread-mails) - :if (and (bound-and-true-p mu4e-alert-mode-line) - (stringp mu4e-alert-mode-line) - (not (string-empty-p (string-trim mu4e-alert-mode-line)))) - :format - (let* ((raw mu4e-alert-mode-line) - ;; Extract the count number from the mode-line string (e.g. " [5] ") - (count-str (if (string-match "\\[\\([0-9]+\\)\\]" raw) - (match-string 1 raw) - (string-trim raw)))) - (concat - (maple-modeline--concat-or - (maple-modeline--icon 'mdicon "nf-md-email" face) - "Mail") - " " (propertize count-str - 'face face - 'mouse-face 'mode-line-highlight - 'help-echo "View unread emails" - 'local-map (make-mode-line-mouse-map - 'mouse-1 'mu4e-alert-view-unread-mails))))) - - (maple-modeline-define my-custom-style - :left ((evil :left (bar :left "")) - macro - buffer-info - flycheck - version-control - remote-host - region) - :right (narrow - org-clock-task - tmr-timer - mu4e-mail - python - my-modeline-time - process - count - position)) - - (setq maple-modeline-style 'my-custom-style) - - :custom-face - (header-line ((t (:inherit mode-line :box nil)))) - (mode-line ((t (:box nil)))) - (mode-line-inactive ((t (:box nil))))) -#+end_src - ** punch-line #+begin_src emacs-lisp @@ -4705,7 +3994,8 @@ so the working-tree diff stays visible until the user explicitly stages." punch-weather-longitude "10.41" punch-weather-latitude "53.25" punch-cpu-usage t - punch-show-processes-info t) + punch-show-processes-info t + punch-line-music-info t) (punch-line-mode 1)) #+end_src @@ -4730,7 +4020,7 @@ so the working-tree diff stays visible until the user explicitly stages." (set-face-attribute 'default nil :family "MapleMono NF" - :height 160 + :height 180 :font (font-spec :family "MapleMono NF" :features '(cv04 ss05 zero))) @@ -4760,427 +4050,13 @@ so the working-tree diff stays visible until the user explicitly stages." * themes -** catppuccin-theme - -#+begin_src emacs-lisp -;; (use-package catppuccin-theme -;; :ensure t -;; :config -;; (setq catppuccin-flavor 'mocha) - -;; (load-theme 'catppuccin :no-confirm) - -;; (custom-set-faces -;; `(diff-hl-change ((t (:background unspecified :foreground ,(catppuccin-get-color 'blue)))))) - -;; (custom-set-faces -;; `(diff-hl-delete ((t (:background unspecified :foreground ,(catppuccin-get-color 'red)))))) - -;; (custom-set-faces -;; `(diff-hl-insert ((t (:background unspecified :foreground ,(catppuccin-get-color 'green))))))) -#+end_src - -** modus-catppuccin - -[[https://gitlab.com/magus/modus-catppuccin][modus-catppuccin]] - -#+begin_src emacs-lisp -;; (use-package modus-catppuccin -;; :ensure (:repo "https://gitlab.com/magus/modus-catppuccin" -;; :branch "main") -;; :custom -;; (catppuccin-mocha-palette-overrides -;; '((base "#232136") -;; (mantle "#2d2a45") -;; (crust "#373354") -;; (surface0 "#373354") -;; (surface1 "#47407d") -;; (surface2 "#6e6a86") -;; (overlay0 "#6e6a86") -;; (overlay1 "#6e6a86") -;; (overlay2 "#6e6a86") -;; (subtext0 "#e0def4") -;; (subtext1 "#cdcbe0") -;; (text "#e2e0f7") -;; (rosewater "#eb98c3") -;; (flamingo "#ea9a97") -;; (pink "#eb98c3") -;; (mauve "#c4a7e7") -;; (red "#eb6f92") -;; (maroon "#eb6f92") -;; (peach "#ea9a97") -;; (yellow "#f6c177") -;; (green "#a3be8c") -;; (teal "#9ccfd8") -;; (sky "#9ccfd8") -;; (sapphire "#9ccfd8") -;; (blue "#569fba") -;; (lavender "#c4a7e7"))) -;; (catppuccin-latte-palette-overrides -;; '((base "#f6f2ee") -;; (mantle "#e4dcd4") -;; (crust "#dbd1dd") -;; (surface0 "#d3c7bb") -;; (surface1 "#c4b8ac") -;; (surface2 "#b5a99d") -;; (overlay0 "#9ca0b0") -;; (overlay1 "#8c8fa1") -;; (overlay2 "#7c7f93") -;; (subtext0 "#6c6f85") -;; (subtext1 "#5c5f77") -;; (text "#3d2b5a") -;; (rosewater "#955f61") -;; (flamingo "#a5222f") -;; (pink "#a440b5") -;; (mauve "#6e33ce") -;; (red "#a5222f") -;; (maroon "#824d5b") -;; (peach "#955f61") -;; (yellow "#ac5402") -;; (green "#396847") -;; (teal "#287980") -;; (sky "#2d8a93") -;; (sapphire "#2d8a93") -;; (blue "#2848a9") -;; (lavender "#6e33ce"))) -;; :config -;; (load-theme 'catppuccin-latte :no-confirm)) -#+end_src - -** modus themes/catppuccin - -#+begin_src emacs-lisp -;; (use-package modus-themes -;; :ensure t -;; :demand t -;; :custom -;; ;; Optional: Schriften schöner machen -;; (modus-themes-italic-constructs t) -;; (modus-themes-bold-constructs t) -;; (modus-themes-prompts '(bold intense)) - -;; ;; Hier injizieren wir DUSKFOX Farben in Modus Vivendi -;; (modus-themes-common-palette-overrides -;; '( -;; ;; --- Basis Farben (Duskfox) --- -;; (bg-main "#232136") -;; (fg-main "#e0def4") -;; (bg-dim "#2d2a45") ; Etwas heller als Main -;; (fg-dim "#9090c0") ; Abgedunkelter Text -;; (bg-active "#393552") ; Aktive Zeile/Elemente - -;; ;; --- Akzente (Duskfox) --- -;; (red "#eb6f92") -;; (green "#a3be8c") -;; (yellow "#f6c177") -;; (blue "#569fba") -;; (magenta "#c4a7e7") -;; (cyan "#9ccfd8") - -;; ;; --- Fein-Tuning (Mappings) --- -;; ;; Damit es nicht "arsch" aussieht, mappen wir wichtige Elemente neu: - -;; (border "#47407d") -;; (cursor magenta) - -;; ;; Modeline (Statusleiste) -;; (bg-mode-line-active "#47407d") -;; (fg-mode-line-active "#e0def4") -;; (bg-mode-line-inactive "#232136") -;; (fg-mode-line-inactive "#6e6a86") - -;; ;; Syntax Highlighting Anpassungen -;; (keyword magenta) ; Keywords in Duskfox-Pink/Lila -;; (builtin blue) ; Builtins in Blau -;; (type cyan) ; Typen in Cyan -;; (string green) ; Strings in Grün -;; (constant red) ; Konstanten in Rot -;; (fnname blue) ; Funktionsnamen -;; (variable cyan) ; Variablen - -;; ;; UI Elemente -;; (bg-region "#393552") ; Selection Background -;; (fg-region unspecified) -;; (bg-paren-match "#47407d") -;; (bg-hl-line "#2d2a45") - -;; ;; Line Numbers -;; (bg-line-number-inactive "#232136") -;; (fg-line-number-inactive "#6e6a86") -;; (bg-line-number-active "#2d2a45") -;; (fg-line-number-active "#e0def4") -;; )) -;; :config -;; ;; Lade das Basis-Theme (vivendi = dunkel) -;; (load-theme 'modus-vivendi :no-confirm)) -#+end_src - -*** ef-themes - -#+begin_src emacs-lisp -;; (use-package ef-themes -;; :ensure t -;; :demand t -;; :init -;; (ef-themes-take-over-modus-themes-mode 1) - -;; :custom -;; (modus-themes-italic-constructs t) -;; (modus-themes-bold-constructs t) -;; (modus-themes-prompts '(bold intense)) - -;; (ef-light-palette-overrides -;; '( -;; (bg-main "#efefef") -;; (fg-main "#313145") -;; (bg-dim "#bebed2") -;; (fg-dim "#7c7c98") -;; (bg-alt "#9e9eaf") -;; (fg-alt "#505063") -;; (bg-active "#22223a") -;; (bg-inactive "#efefef") - -;; (red "#f43979") -;; (red-warmer "#ff669b") -;; (red-cooler "#d22a8b") -;; (red-faint "#f43979") - -;; (green "#0073a8") -;; (green-warmer "#0073a8") -;; (green-cooler "#0073a8") -;; (green-faint "#0073a8") - -;; (yellow "#ff669b") -;; (yellow-warmer "#f43979") -;; (yellow-cooler "#d22a8b") -;; (yellow-faint "#ff669b") - -;; (blue "#2155d6") -;; (blue-warmer "#0073a8") -;; (blue-cooler "#2155d6") -;; (blue-faint "#2155d6") - -;; (magenta "#6916b6") -;; (magenta-warmer "#8d17a5") -;; (magenta-cooler "#471397") -;; (magenta-faint "#6916b6") - -;; (cyan "#0073a8") -;; (cyan-warmer "#2155d6") -;; (cyan-cooler "#2155d6") -;; (cyan-faint "#0073a8") - -;; (bg-red-intense "#ff669b") -;; (bg-green-intense "#0073a8") -;; (bg-yellow-intense "#f43979") -;; (bg-blue-intense "#2155d6") -;; (bg-magenta-intense "#8d17a5") -;; (bg-cyan-intense "#0073a8") - -;; (bg-red-subtle "#bebed2") -;; (bg-green-subtle "#bebed2") -;; (bg-yellow-subtle "#bebed2") -;; (bg-blue-subtle "#bebed2") -;; (bg-magenta-subtle "#bebed2") -;; (bg-cyan-subtle "#bebed2") - -;; (bg-added "#bebed2") -;; (bg-added-faint "#efefef") -;; (bg-added-refine "#9e9eaf") -;; (fg-added "#0073a8") - -;; (bg-changed "#bebed2") -;; (bg-changed-faint "#efefef") -;; (bg-changed-refine "#9e9eaf") -;; (fg-changed "#f43979") - -;; (bg-removed "#bebed2") -;; (bg-removed-faint "#efefef") -;; (bg-removed-refine "#9e9eaf") -;; (fg-removed "#d22a8b") - -;; (bg-mode-line "#9e9eaf") -;; (fg-mode-line "#313145") -;; (bg-mode-line-active "#9e9eaf") -;; (fg-mode-line-active "#313145") -;; (bg-mode-line-inactive "#efefef") -;; (fg-mode-line-inactive "#7c7c98") - -;; (border "#7c7c98") -;; (cursor "#471397") - -;; (bg-region "#bebed2") -;; (fg-region unspecified) -;; (bg-paren-match "#9e9eaf") -;; (bg-hl-line "#bebed2") - -;; (bg-line-number-inactive "#efefef") -;; (fg-line-number-inactive "#7c7c98") -;; (bg-line-number-active "#bebed2") -;; (fg-line-number-active "#313145") - -;; (builtin blue) -;; (comment yellow-faint) -;; (constant red) -;; (fnname blue) -;; (keyword magenta) -;; (string green) -;; (type cyan) -;; (variable blue-warmer) - -;; (err red-warmer) -;; (warning yellow-warmer) -;; (info green) - -;; (link blue-warmer) -;; (link-alt magenta) -;; (name magenta-cooler) -;; (keybind blue-cooler) -;; (identifier magenta-faint) -;; (prompt green-cooler) - -;; (date-common cyan-cooler) -;; (date-deadline red) -;; (date-event fg-alt) -;; (date-holiday magenta-warmer) -;; (date-scheduled yellow) -;; (date-weekday cyan) -;; (date-weekend red-faint) - -;; (mail-cite-0 blue-warmer) -;; (mail-cite-1 magenta) -;; (mail-cite-2 cyan-cooler) -;; (mail-cite-3 yellow-cooler) -;; (mail-recipient magenta-cooler) -;; (mail-subject blue-cooler) - -;; (prose-code magenta-warmer) -;; (prose-done green) -;; (prose-macro green-cooler) -;; (prose-tag green-faint) -;; (prose-todo red-warmer) -;; (prose-verbatim blue-warmer) -;; )) - -;; :config -;; (load-theme 'ef-light :no-confirm)) -#+end_src - -** kanagawa-themes - -#+begin_src emacs-lisp -;; (use-package kanagawa-themes -;; :ensure t -;; :config -;; (setq kanagawa-themes-org-height nil) -;; (setq kanagawa-themes-org-highlight t) -;; (load-theme 'kanagawa-lotus t)) -#+end_src - -** base-16 theme +** theme load #+begin_src emacs-lisp -;; (use-package base16-theme -;; :ensure t -;; :demand t -;; :config -;; (setq base16-distinct-fringe-background t) -;; (setq base16-highlight-mode-line t) - -;; (deftheme base24-duskfox) -;; (setq base24-duskfox-colors -;; (list :base00 "#232136" -;; :base01 "#2d2a45" -;; :base02 "#373354" -;; :base03 "#47407d" -;; :base04 "#6e6a86" -;; :base05 "#e0def4" -;; :base06 "#cdcbe0" -;; :base07 "#e2e0f7" -;; :base08 "#eb6f92" -;; :base09 "#ea9a97" -;; :base0A "#f6c177" -;; :base0B "#a3be8c" -;; :base0C "#9ccfd8" -;; :base0D "#569fba" -;; :base0E "#c4a7e7" -;; :base0F "#eb98c3" -;; :base10 "#47407d" -;; :base11 "#eb6f92" -;; :base12 "#a3be8c" -;; :base13 "#f6c177" -;; :base14 "#569fba" -;; :base15 "#c4a7e7" -;; :base16 "#9ccfd8" -;; :base17 "#e0def4")) - -;; (base16-theme-define 'base24-duskfox base24-duskfox-colors) - -;; (deftheme base24-nightfox) -;; (setq base24-nightfox-colors -;; (list :base00 "#192330" -;; :base01 "#212e3f" -;; :base02 "#29394f" -;; :base03 "#575860" -;; :base04 "#71839b" -;; :base05 "#cdcecf" -;; :base06 "#aeafb0" -;; :base07 "#e4e4e5" -;; :base08 "#c94f6d" -;; :base09 "#f4a261" -;; :base0A "#dbc074" -;; :base0B "#81b29a" -;; :base0C "#63cdcf" -;; :base0D "#719cd6" -;; :base0E "#9d79d6" -;; :base0F "#d67ad2" -;; :base10 "#575860" -;; :base11 "#c94f6d" -;; :base12 "#81b29a" -;; :base13 "#dbc074" -;; :base14 "#719cd6" -;; :base15 "#9d79d6" -;; :base16 "#63cdcf" -;; :base17 "#cdcecf")) - -;; (base16-theme-define 'base24-nightfox base24-nightfox-colors) -;; (enable-theme 'base24-nightfox)) - (add-to-list 'custom-theme-load-path "~/.emacs.d/themes/") (load-theme 'noctalia t) #+end_src -** nano-theme - -Nicolas Rougier's N Λ N O theme — companion to =nano-modeline=. Built around six base faces (default, critical, salient, faded, popout, subtle) and a deliberately restrained palette. Light variant uses Material colors, dark variant uses Nord. - -We keep our own font (=MapleMono NF=) and skip nano's font setup (=nano-fonts-use=). =nano-window-divider-show= paints subtle dividers between windows so the minimal aesthetic still feels structured. - -#+begin_src emacs-lisp -;; (use-package nano-theme -;; :ensure (:host github :repo "rougier/nano-theme") -;; :init -;; (setq nano-fonts-use nil) ;; keep MapleMono NF, don't force Roboto -;; (setq nano-window-divider-show t) ;; subtle dividers between windows -;; :config -;; (load-theme 'nano-dark t) - -;; ;; Convenience: cycle between nano-light and nano-dark. -;; (defun cashmere/nano-toggle-theme () -;; "Toggle between `nano-light' and `nano-dark'." -;; (interactive) -;; (let ((dark-active (member 'nano-dark custom-enabled-themes))) -;; (mapc #'disable-theme custom-enabled-themes) -;; (load-theme (if dark-active 'nano-light 'nano-dark) t))) - -;; ;; Soften a few faces that nano leaves a bit too plain. -;; (with-eval-after-load 'org -;; (set-face-attribute 'org-document-title nil :height 1.4 :weight 'light) -;; (set-face-attribute 'org-level-1 nil :height 1.2 :weight 'medium) -;; (set-face-attribute 'org-level-2 nil :height 1.1 :weight 'medium) -;; (set-face-attribute 'org-level-3 nil :height 1.05 :weight 'medium))) -#+end_src - * dirvish #+begin_src emacs-lisp @@ -5301,14 +4177,6 @@ still require a restart since elpaca queues run at init time." ;; (my/global-olivetti-mode) #+end_src -* COMMENT org-modern-indent (disabled in favor of render-org) - -#+begin_src emacs-lisp -(use-package org-modern-indent - :ensure (:host github :repo "jdtsmith/org-modern-indent") - :hook (org-mode . org-modern-indent-mode)) -#+end_src - * ibuffer hide #+begin_src emacs-lisp @@ -5408,7 +4276,6 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." "Y" 'pass-copy-field "e" 'pass-edit "a" 'pass-insert - "g" 'pass-update-buffer "G" 'pass-insert-generated "o" 'pass-otp-options "r" 'pass-rename @@ -5526,8 +4393,8 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." "b" '(:ignore t :wk "buffer/bookmarks") "bb" '(consult-bookmark :wk "display current bookmarks") - "ba" '(ibuffer :wk "ibuffer") - "bi" '(projectile-ibuffer :wk "ibuffer project") + "bi" '(ibuffer :wk "ibuffer") + "bp" '(projectile-ibuffer :wk "ibuffer project") "bd" '(bookmark-delete :wk "delete bookmark") "bk" '(kill-current-buffer :wk "kill buffer") "bs" '(bookmark-set :wk "save bookmark") @@ -5836,8 +4703,8 @@ date) and the dired header are never skipped." "c" '(my/centered-cursor :wk "center cursor") "f" '(dirvish :wk "file manager") "r" '(async-shell-command :wk "run async") - "t" '(projectile-run-vterm :wk "terminal") - "e" '(eshell :wk "eshell") + "t" '(ghostel-project :wk "terminal (project)") + "T" '(ghostel-list-buffers :wk "terminal (switch)") "z" '(golden-ratio-mode :wk "zoom/golden ratio") "o" '(my/global-olivetti-mode :wk "center buffer") "s" '(my-org-sidecar-left :wk "org sidecar")) @@ -5894,14 +4761,14 @@ date) and the dired header are never skipped." #+begin_src emacs-lisp (use-package elfeed - :ensure t + :ensure (:host github :repo "emacs-elfeed/elfeed" :branch "main") :defer t :custom (elfeed-db-directory "~/.emacs.d/elfeed") :config (setq elfeed-search-filter "@2-weeks-ago +unread" elfeed-search-title-max-width 110) - + (setq elfeed-use-libxml 't) (add-hook 'elfeed-search-mode-hook #'elfeed-update) (setq elfeed-search-sort-function @@ -5933,16 +4800,6 @@ date) and the dired header are never skipped." :config (elfeed-goodies/setup)) -(use-package shrface - :ensure t - :after elfeed - :config - (shrface-basic) - (shrface-trial) - (shrface-default-keybindings) - (setq shrface-href-versatile t - shrface-bullets-bullet-list '("◉" "○" "✸" "✿"))) - (with-eval-after-load 'elfeed (require 'shrface) (add-hook 'elfeed-show-mode-hook @@ -6060,7 +4917,8 @@ date) and the dired header are never skipped." (shrface-href-versatile t) :config (shrface-basic) - (shrface-trial)) + (shrface-trial) + (shrface-default-keybindings)) #+end_src ** shr-tag-pre-highlight — syntax-highlighted code blocks @@ -6354,21 +5212,6 @@ opening another file in same project does not re-notify." (envrc-global-mode -1))) #+end_src -* COMMENT bbj - -#+begin_src emacs-lisp -(use-package bbj - :ensure (:host github :repo "bbj-dev/bbj" - :files ("clients/emacs/bbj.el")) - :defer t - :commands (bbj-browse-index bbj-login) - :custom - (bbj-host "bbs.moneyspread.st") - (bbj-port 7099) - ;; (bbj-width 80) - ) -#+end_src - * =tldr.el= #+begin_src emacs-lisp @@ -6403,6 +5246,101 @@ opening another file in same project does not re-notify." :ensure t) #+end_src +* ghost.el + +#+begin_src emacs-lisp +(use-package ghostel + :ensure t + :custom + (ghostel-shell "xonsh") + :config + (evil-define-key 'normal ghostel-mode-map + (kbd "g t") #'ghostel-next + (kbd "g T") #'ghostel-previous + (kbd "g n") #'ghostel + (kbd "g b") #'ghostel-list-buffers) + (advice-add 'enable-theme :after + (lambda (&rest _) + (when (fboundp 'ghostel-sync-theme) + (ghostel-sync-theme))))) + +(use-package evil-ghostel + :ensure (:host github :repo "dakra/ghostel" + :files ("extensions/evil-ghostel/*.el")) + :after (ghostel evil) + :hook (ghostel-mode . evil-ghostel-mode)) +#+end_src + +* garden + +#+begin_src emacs-lisp +(use-package vui + :ensure (:host github :repo "d12frosted/vui.el" :files ("*.el"))) + +(add-to-list 'load-path (expand-file-name "~/garden/lisp/")) +(setq garden-directory (expand-file-name "~/garden/")) +(require 'garden-core) +(garden-auto-index-mode 1) +(autoload 'garden "garden-dashboard" nil t) +(autoload 'garden-sidecar "garden-dashboard" nil t) +(autoload 'garden-connect "garden-connect" nil t) +(autoload 'garden-connect-pick "garden-connect" nil t) +(autoload 'garden-player "garden-player" nil t) + +(autoload 'denote-capf-setup "denote-capf" nil t) +(add-hook 'org-mode-hook #'denote-capf-setup) +(autoload 'garden-publish "garden-publish" nil t) +(autoload 'garden-publish-all "garden-publish" nil t) +(autoload 'garden-publish-wiki "garden-publish" nil t) +(autoload 'garden-publish-blog "garden-publish" nil t) +(autoload 'garden-publish-deploy "garden-publish" nil t) +#+end_src + +* easysessions + +=easysession-setup= restores the last session at startup and enables easysession-save-mode= for periodic auto-save. It is elpaca- and daemon-aware, so it picks =elpaca-after-init-hook= and per-frame restore on the daemon automatically. + +mu4e- and ERC-buffers are process-backed and cannot be reconstructed from a file path, so easysession skips them. =my/easysession-restore-services= runs on =easysession-after-load-hook= and re-launches their entry points (=mu4e= in the background, =run-irc=) idempotently — guarded by =mu4e-running-p= and =erc-buffer-list= so switching between sessions never spawns a second instance or reconnects. + +#+begin_src emacs-lisp +(defun my/easysession-restore-services () + "Re-launch process-backed apps (mu4e, ERC) after a session is loaded." + (unless (and (fboundp 'mu4e-running-p) (mu4e-running-p)) + (mu4e t)) + (unless (and (fboundp 'erc-buffer-list) (erc-buffer-list)) + (run-irc))) + +(use-package easysession + :ensure t + :demand t + :custom + (easysession-save-interval (* 10 60)) + :config + (add-hook 'easysession-after-load-hook #'my/easysession-restore-services) + (easysession-setup)) + +(my-local-leader + "e" '(:wk "easy session" :ignore 't) + "ew" '(easysession-switch-to :wk "switch / create") + "es" '(easysession-save :wk "save") + "el" '(easysession-load :wk "load") + "eg" '(easysession-switch-to-and-restore-geometry :wk "switch + geometry") + "er" '(easysession-rename :wk "rename") + "ed" '(easysession-delete :wk "delete") + "ee" '(easysession-edit :wk "edit") + "eR" '(easysession-reset :wk "reset to default") + "em" '(easysession-save-mode :wk "toggle auto-save")) +#+end_src + +* sops + +#+begin_src emacs-lisp +(use-package sops + :ensure (:type git :host github :repo "djgoku/sops") + :init + (global-sops-mode 1)) +#+end_src + * provide init #+begin_src emacs-lisp diff --git a/themes/noctalia-theme.el b/themes/noctalia-theme.el index 66500e4..35ec481 100644 --- a/themes/noctalia-theme.el +++ b/themes/noctalia-theme.el @@ -19,55 +19,55 @@ (deftheme noctalia "Noctalia theme with proper color contrast.") (let* (;; Core surface colors - (bg "#161616") - (fg "#f2f4f8") - (surface "#161616") - (on-surface "#f2f4f8") - (on-surface-variant "#b6b8bb") - (surface-variant "#353535") - (surface-container "#353535") - (surface-container-low "#252525") - (surface-container-lowest "#1c1c1c") - (surface-container-high "#3f3f3f") - (surface-container-highest "#494949") + (bg "#f4f4f4") + (fg "#161616") + (surface "#f4f4f4") + (on-surface "#161616") + (on-surface-variant "#393939") + (surface-variant "#c6c6c6") + (surface-container "#c6c6c6") + (surface-container-low "#dddddd") + (surface-container-lowest "#eaeaea") + (surface-container-high "#bcbcbc") + (surface-container-highest "#b2b2b2") ;; Accent colors (always readable on surface) - (primary "#78a9ff") - (secondary "#25be6a") - (tertiary "#be95ff") - (err "#ee5396") + (primary "#0f62fe") + (secondary "#198038") + (tertiary "#8a3ffc") + (err "#da1e28") ;; Container colors (for BACKGROUNDS only, never as foreground text) - (primary-container "#0047c5") - (secondary-container "#074623") - (tertiary-container "#5700e2") - (err-container "#8c023e") + (primary-container "#bad0f7") + (secondary-container "#7cd095") + (tertiary-container "#d3bbf6") + (err-container "#edbec0") ;; On-color text (for text ON accent backgrounds) - (on-primary "#161616") - (on-secondary "#161616") - (on-tertiary "#161616") - (on-err "#161616") + (on-primary "#f4f4f4") + (on-secondary "#f4f4f4") + (on-tertiary "#f4f4f4") + (on-err "#f4f4f4") ;; On-container text (for text on container backgrounds) - (on-primary-container "#ccdfff") - (on-secondary-container "#d4f7e4") - (on-tertiary-container "#e0ccff") - (on-err-container "#fad1e3") + (on-primary-container "#001b4c") + (on-secondary-container "#0c401c") + (on-tertiary-container "#1f014b") + (on-err-container "#43090c") ;; Outline colors - (outline-color "#636363") - (outline-variant "#3d3d3d") + (outline-color "#8d8d8d") + (outline-variant "#b3b3b3") ;; Shadow - (shadow "#000000") + (shadow "#c6c6c6") ;; Auto-lightness variants: lighten in dark mode, darken in light mode ;; Used for heading levels 5-7, rainbow delimiters 5-7, terminal variants - (primary-variant "#2c78ff") - (secondary-variant "#52dd91") - (tertiary-variant "#8f48ff") - (err-variant "#df166d")) + (primary-variant "#0143c0") + (secondary-variant "#25c054") + (tertiary-variant "#5f04eb") + (err-variant "#e95c63")) (custom-theme-set-faces 'noctalia -- cgit v1.3.1