diff options
| -rw-r--r-- | config.org | 805 | ||||
| -rw-r--r-- | init.el | 2 |
2 files changed, 191 insertions, 616 deletions
@@ -146,6 +146,7 @@ use-package loads it from `load-path'; otherwise return REMOTE." ;; (add-to-list 'default-frame-alist '(alpha-background . 80)) (global-hl-line-mode 1) ;; Highlight the current line (add-hook 'org-mode-hook (lambda () (setq-local global-hl-line-mode nil))) ;; hl-line repaints wipe kitty-graphics scaled headings + (add-hook 'markdown-mode-hook (lambda () (setq-local global-hl-line-mode nil))) ;; same conflict for kitty-graphics markdown headings (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) (when (daemonp) @@ -192,11 +193,15 @@ use-package loads it from `load-path'; otherwise return REMOTE." (derived-mode-p 'compilation-mode))) (defun my/compile-or-recompile () - "Recompile with the last command if a compilation ran before, else prompt." + "Recompile with the last command if a ghostel compilation ran before, else prompt. +Selects the compilation window so the cursor lands in it." (interactive) - (if (get-buffer "*compilation*") - (recompile) - (call-interactively #'compile))) + (if (get-buffer ghostel-compile-buffer-name) + (ghostel-recompile) + (call-interactively #'ghostel-compile)) + (let ((buffer (get-buffer ghostel-compile-buffer-name))) + (when buffer + (pop-to-buffer buffer)))) (defun my/focus-async-shell-window (window) "Focus the async-shell window and make q bury it without killing the process." @@ -291,11 +296,9 @@ use-package loads it from `load-path'; otherwise return REMOTE." (use-package async :ensure t) #+end_src -* erc +* clatter #+begin_src emacs-lisp -;; Always-available IRC entry points so `M-x run-irc` works from any daemon -;; (hub, work, standalone). Calling `erc-tls` autoloads ERC on demand. (defun my/soju-password () "Read the Soju bouncer password from the sops-nix secret." (string-trim @@ -304,215 +307,83 @@ use-package loads it from `load-path'; otherwise return REMOTE." "/home/cashmere/.config/sops-nix/secrets/senpai_password") (buffer-string)))) -(defun run-irc () - "Connect to all IRC networks via Soju bouncer." - (interactive) - (let ((pw (my/soju-password))) - (erc-tls :server "bouncer.cashmere.rs" - :port 6699 - :nick "cashmere1337" - :user "cashmere/irc.libera.chat@emacs" - :password pw) - (erc-tls :server "bouncer.cashmere.rs" - :port 6699 - :nick "cashmere" - :user "cashmere/ergo@emacs" - :password pw) - (erc-tls :server "bouncer.cashmere.rs" - :port 6699 - :nick "cashmere" - :user "cashmere/mansion@emacs" - :password pw))) - -(use-package erc - :ensure nil - :defer t +(use-package clatter + :ensure (:host github :repo "parenworks/clatter.el" :files ("*.el")) + :commands (clatter clatter-connect) :custom - ;; connection - (erc-nick "cashmere1337") - (erc-user-full-name "cashmere") - - ;; behaviour - (erc-join-buffer 'buffer) - (erc-kill-buffer-on-part nil) - (erc-kill-queries-on-quit t) - (erc-kill-server-buffer-on-quit t) - - ;; visuals - (erc-fill-function 'erc-fill-wrap) - (erc-timestamp-format "[%H:%M]") - (erc-timestamp-format-left "[%H:%M]") - (erc-timestamp-format-right "[%H:%M]") - (erc-hide-list '("JOIN" "PART" "QUIT" "NICK" "MODE")) - (erc-track-exclude-types '("JOIN" "PART" "QUIT" "NICK" "MODE" "324" "329" "332" "333" "353" "477")) - (erc-track-shorten-start 4) - (erc-track-visibility 'visible) - - ;; prompt - (erc-prompt (lambda () (concat (buffer-name) ">"))) - - ;; modules - (erc-modules '(autojoin - button - completion - fill - irccontrols - list - match - move-to-prompt - netsplit - networks - nicks - noncommands - notifications - readonly - ring - scrolltobottom - stamp - track)) + (clatter-networks + '(("libera" + :server "bouncer.cashmere.rs" :port 6699 :tls t + :nick "cashmere1337" + :username "cashmere/irc.libera.chat@emacs") + ("ergo" + :server "bouncer.cashmere.rs" :port 6699 :tls t + :nick "cashmere" + :username "cashmere/ergo@emacs") + ("mansion" + :server "bouncer.cashmere.rs" :port 6699 :tls t + :nick "cashmere" + :username "cashmere/mansion@emacs"))) + (clatter-flyspell-enable nil) + (clatter-format-strip-only t) + (clatter-message-order 'oldest-first) + (clatter-read-marker-enabled nil) + (clatter-chathistory-limit 1000) :config - ;; highlight own nick - (setq erc-current-nick-highlight-type 'all) - (setq erc-keywords '("cashmere")) - (setq erc-pals '("cashmere")) - - ;; nicks module (built-in nick coloring in Emacs 30) - (setq erc-nicks-contrast-range '(40 . 90)) + (require 'gnutls) + (clatter-setup) + (setq clatter-hl-keywords '("cashmere")) + (advice-add 'clatter-buffer-name :override #'my/clatter-buffer-name) + (add-hook 'clatter-mode-hook (lambda () (setq-local corfu-auto nil))) + (general-def 'normal clatter-mode-map + "gb" #'my/clatter-switch-buffer + "gH" #'clatter-chathistory-request + "gh" #'clatter-chathistory-more)) - ;; scrolltobottom -- keep input always at bottom - (setq erc-scrolltobottom-all t) - (erc-scrolltobottom-mode 1) +(defun my/clatter-buffer-name (network target) + "Name clatter buffers by bare channel/query TARGET, server by NETWORK." + (if (string= target "*server*") + (format "*%s*" network) + target)) - ;; fill-wrap -- modern chat-like wrapping - (setq erc-fill-wrap-align-prompt nil) - (setq erc-fill-static-center 14) - - ;; track -- activity in modeline - (setq erc-track-position-in-mode-line t) - - ;; keep large buffer for soju history replay - (setq erc-max-buffer-size 100000) - - (erc-update-modules)) - -(defvar my/consult-source-erc - (list :name "IRC" - :narrow ?i - :category 'buffer - :face 'erc-default-face - :state #'consult--buffer-state - :items (lambda () - (mapcar #'buffer-name - (cl-remove-if-not - (lambda (buf) - (with-current-buffer buf - (derived-mode-p 'erc-mode))) - (buffer-list)))))) - -(defun my/erc-switch-channel () - "Switch to an ERC channel buffer via consult." +(defun my/clatter-switch-buffer () + "Switch to a clatter IRC buffer." (interactive) - (consult-buffer (list my/consult-source-erc))) + (let ((bufs (cl-remove-if-not + (lambda (b) + (with-current-buffer b (derived-mode-p 'clatter-mode))) + (buffer-list)))) + (if bufs + (switch-to-buffer + (completing-read "IRC buffer: " (mapcar #'buffer-name bufs) nil t)) + (message "No clatter buffers.")))) -(defun my/erc-fetch-history (&optional count) - "Fetch COUNT previous messages from Soju via CHATHISTORY. -Defaults to 1000 (soju max). With prefix arg, prompts for count. -Temporarily disables notifications during the fetch." - (interactive "P") - (let ((target (erc-default-target))) - (if (not target) - (message "Not in a channel buffer.") - (let ((n (min (if count - (read-number "Messages to fetch: " 1000) - 1000) - 1000))) - (erc-notifications-disable) - (erc-server-send (format "CHATHISTORY LATEST %s * %d" target n)) - (run-at-time 5 nil #'erc-notifications-enable))))) +(defvar my/clatter-inhibit-popup nil + "When non-nil, clatter buffers are not auto-displayed by `display-buffer'.") -(defun my/erc-quit-all () - "Disconnect from IRC and kill all ERC buffers." - (interactive) - (erc-cmd-QUIT "bye") - (run-at-time 1 nil - (lambda () - (dolist (buf (buffer-list)) - (when (with-current-buffer buf (derived-mode-p 'erc-mode)) - (kill-buffer buf)))))) +(defun my/clatter-popup-suppressed-p (buf &rest _) + "Non-nil when BUF is a clatter buffer and popups are inhibited." + (and my/clatter-inhibit-popup + (get-buffer buf) + (with-current-buffer (get-buffer buf) + (derived-mode-p 'clatter-mode)))) -(defun my/erc-reconnect () - "Reconnect to the current ERC server." - (interactive) - (erc-cmd-RECONNECT)) +(add-to-list 'display-buffer-alist + '(my/clatter-popup-suppressed-p + display-buffer-no-window + (allow-no-window . t))) -(defun my/erc-list-channels () - "Request channel list from the current ERC server." - (interactive) - (erc-cmd-LIST)) - -(defun persp-irc () - "Switch to (or create) the IRC frame and show ERC buffers." +(defun run-irc () + "Connect to all IRC networks via the Soju bouncer, in the background." (interactive) - (let* ((erc-bufs (cl-remove-if-not - (lambda (buf) - (with-current-buffer buf - (derived-mode-p 'erc-mode))) - (buffer-list))) - (irc-frame (cl-find-if - (lambda (f) - (string= (frame-parameter f 'name) "irc")) - (frame-list)))) - (if irc-frame - (select-frame-set-input-focus irc-frame) - (select-frame-set-input-focus (make-frame '((name . "irc"))))) - (if erc-bufs - (switch-to-buffer (car erc-bufs)) - (letrec ((hook-fn (lambda () - (switch-to-buffer (current-buffer)) - (remove-hook 'erc-join-hook hook-fn)))) - (add-hook 'erc-join-hook hook-fn)) - (run-irc)))) - -;; ERC keybindings and hooks — register from any daemon, since `run-irc` -;; autoloads ERC even outside the hub daemon. -(with-eval-after-load 'erc - (add-hook 'erc-mode-hook - (lambda () - (setq-local scroll-margin 0) - (setq-local maximum-scroll-margin 0.0) - (setq-local corfu-auto nil))) - - ;; Prevent accidental ERC buffer kills from parting channels - (add-hook 'kill-buffer-query-functions - (lambda () - (if (and (derived-mode-p 'erc-mode) - (erc-server-process-alive) - (not (eq this-command 'my/erc-quit-all))) - (yes-or-no-p - (format "ERC buffer %s is connected. Really kill (will part channel)? " - (buffer-name))) - t))) - - (with-eval-after-load 'general - (general-def 'normal erc-mode-map - "q" 'quit-window - "Q" 'my/erc-quit-all - "gb" 'my/erc-switch-channel - "gn" 'erc-track-switch-buffer - "gH" 'my/erc-fetch-history - "go" 'erc-channel-names - "gj" 'erc-join-channel - "gl" 'my/erc-list-channels - "gr" 'my/erc-reconnect - "RET" 'erc-send-current-line) - - (general-def '(normal insert) erc-mode-map - "M-n" 'erc-track-switch-buffer - "C-k" 'erc-previous-command - "C-j" 'erc-next-command))) + (let ((pw (my/soju-password))) + (setq my/clatter-inhibit-popup t) + (dolist (net '("libera" "ergo" "mansion")) + (clatter-connect net :password pw)) + (run-at-time 8 nil (lambda () (setq my/clatter-inhibit-popup nil))))) #+end_src -* TODO centered cursors +* centered cursors #+begin_src emacs-lisp (defvar my/centered-cursor-enabled nil) @@ -536,69 +407,6 @@ Temporarily disables notifications during the fetch." (message "centered-cursor on")))) #+end_src -* cursory - -#+begin_src emacs-lisp -(use-package cursory - :ensure t - :demand t - :if (display-graphic-p) - :config - (setq cursory-presets - '((box - :cursor-color success ; will typically be green - :blink-cursor-interval 1.2) - (box-no-blink - :inherit box - :blink-cursor-mode -1) - (bar - :cursor-type (bar . 2) - :cursor-color error ; will typically be red - :blink-cursor-interval 0.8) - (bar-no-other-window - :inherit bar - :cursor-in-non-selected-windows nil) - (bar-no-blink - :inherit bar - :blink-cursor-mode -1) - (underscore - :cursor-color warning ; will typically be yellow - :cursor-type (hbar . 3) - :blink-cursor-interval 0.3 - :blink-cursor-blinks 50) - (underscore-no-other-window - :inherit underscore - :cursor-in-non-selected-windows nil) - (underscore-thick - :inherit underscore - :cursor-type (hbar . 8) - :cursor-in-non-selected-windows (hbar . 3)) - (t ; the default values - :cursor-color unspecified ; use the theme's original - :cursor-type box - :cursor-in-non-selected-windows hollow - :blink-cursor-mode 1 - :blink-cursor-blinks 10 - :blink-cursor-interval 0.2 - :blink-cursor-delay 0.2))) - - ;; I am using the default value of `cursory-latest-state-file'. - - ;; Set last preset or fall back to desired style from - ;; `cursory-presets'. Alternatively, use the function - ;; `cursory-set-last-or-fallback' (can be added to the - ;; `after-init-hook'. - (cursory-set-preset (or (cursory-restore-latest-preset) 'box)) - - ;; Persist configurations between Emacs sessions. Also apply the - ;; :cursor-color again when swithcing to another theme. - (cursory-mode 1) - :bind - ;; We have to use the "point" mnemonic, because C-c c is often the - ;; suggested binding for `org-capture' and is the one I use as well. - ("C-c p" . cursory-set-preset)) -#+end_src - * clipetty Only =y= (evil-yank) reaches the system clipboard; deletes (=d=, =x=, =c=) and word kills (M-DEL, C-w in insert) stay in the kill-ring only. Clipetty's global mode would sync every kill via OSC 52, so instead the OSC 52 escape is emitted explicitly after each yank. @@ -766,7 +574,7 @@ I adjusted the config accordingly to my modes which I use on a frequent. (or (mode . eca-chat-mode))) - ("ERC" (or (mode . erc-mode))) + ("IRC" (or (mode . clatter-mode))) ("Emacs" (or (mode . emacs-lisp-mode) @@ -890,10 +698,6 @@ 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 =eat= as the -terminal backend. - #+begin_src emacs-lisp (use-package claude-code-ide :ensure (:host github :repo "manzaltu/claude-code-ide.el" @@ -918,7 +722,7 @@ terminal backend. (claude-code-ide-cli-path "claude") (claude-code-ide-cli-debug nil) ;; Terminal backend - (claude-code-ide-terminal-backend 'eat) + (claude-code-ide-terminal-backend 'ghostel) ;; Window placement — mirror eca on the right side so the two AI assistants ;; don't fight over the same slot @@ -971,27 +775,12 @@ terminal backend. ;; Leader-key bindings (SPC a …) — defined pre-load so :commands autoloads fire. (with-eval-after-load 'general + ;; 2026-06-23: replaced claude-code-ide bindings with pi-coding-agent under `a'. + ;; pi-coding-agent only exposes 3 user-facing commands, so the prefix is intentionally sparse. (my-leader - "a" '(:ignore t :wk "claude-code") - "aa" '(claude-code-ide :wk "start / toggle") - "am" '(claude-code-ide-menu :wk "transient menu") - "at" '(claude-code-ide-toggle :wk "toggle window") - "aT" '(claude-code-ide-toggle-recent :wk "toggle recent") - "ap" '(claude-code-ide-send-prompt :wk "send prompt") - "a@" '(claude-code-ide-insert-at-mentioned :wk "@mention region") - "ac" '(claude-code-ide-continue :wk "continue last") - "ar" '(claude-code-ide-resume :wk "resume session") - "as" '(claude-code-ide-switch-to-buffer :wk "switch buffer") - "al" '(claude-code-ide-list-sessions :wk "list sessions") - "aq" '(claude-code-ide-stop :wk "stop") - "a?" '(claude-code-ide-check-status :wk "check status") - "ad" '(claude-code-ide-show-debug :wk "show debug") - "aD" '(claude-code-ide-clear-debug :wk "clear debug")) - - (my-leader 'visual - "a@" '(claude-code-ide-insert-at-mentioned :wk "@mention region"))) - - (global-set-key (kbd "C-c C-'") #'claude-code-ide-menu) + "aa" '(pi-coding-agent :wk "start") + "at" '(pi-coding-agent-toggle :wk "toggle") + "ao" '(pi-coding-agent-open-session-file :wk "open session"))) :config ;; Runs only on first invocation — not at Emacs startup. @@ -1007,6 +796,16 @@ terminal backend. (setopt evil-collection-eca-maps 't)) #+end_src +** pi-coding-agent + +#+begin_src emacs-lisp +(use-package pi-coding-agent + :ensure t + :commands (pi-coding-agent + pi-coding-agent-toggle + pi-coding-agent-open-session-file)) +#+end_src + * eldoc #+begin_src emacs-lisp @@ -1018,14 +817,6 @@ terminal backend. (setq eldoc-echo-area-display-truncation-message nil) :init (global-eldoc-mode)) - -(use-package eldoc-box - :ensure t - :defer t - :config - (setq eldoc-box-max-pixel-width 800) - (setq eldoc-box-max-pixel-height 600)) - #+end_src * flymake @@ -1150,6 +941,7 @@ terminal backend. (setq org-src-fontify-natively t org-src-tab-acts-natively t org-edit-src-content-indentation 0) + (add-to-list 'org-src-lang-modes '("nix" . nix-ts)) (setq org-log-done t org-auto-align-tags t org-tags-column -80 @@ -1241,48 +1033,6 @@ Only activates when running in a Kitty terminal (not in GUI Emacs). (kitty-graphics-setup)) #+end_src -** org-fancy-properties - -#+begin_src emacs-lisp -(use-package org-fancy-priorities - :ensure t - :hook - (org-mode . org-fancy-priorities-mode) - :config - (setq org-fancy-priorities-list '("⚡" "⬆" "⬇" "☕"))) - -(setq org-priority-faces - '((?A . (:background "#e91e63" :foreground "#ffffff" :weight bold)) - (?B . (:background "#ff9800" :foreground "#1a1a1a" :weight bold)) - (?C . (:background "#2196f3" :foreground "#ffffff" :weight bold)) - (?D . (:background "#795548" :foreground "#ffffff" :weight bold)))) -#+end_src - -** TODO org-agenda settings :deprecated: - -Old config - -#+begin_src emacs-lisp -;; (setq org-agenda-start-on-weekday nil -;; org-agenda-block-separator nil -;; org-agenda-remove-tags t) - -;; (setq org-agenda-skip-scheduled-if-done t -;; org-agenda-skip-deadline-if-done t -;; org-agenda-include-deadlines t -;; org-agenda-block-separator nil -;; org-agenda-compact-blocks t -;; org-agenda-start-day nil -;; org-agenda-span 1 -;; org-agenda-start-on-weekday nil -;; org-agenda-hide-tags-regexp "task" -;; org-agenda-prefix-format -;; '((agenda . " %i %?-12t% s") -;; (todo . " %i ") -;; (tags . " %i ") -;; (search . " %i "))) -#+end_src - ** org-babel #+begin_src emacs-lisp @@ -2087,35 +1837,6 @@ Skips capture tasks and projects." #'my/org-agenda-fix-block-spacing) #+end_src -** agenda-app - -Standalone agenda kiosk. Launch with: - -=emacs --eval '(my/agenda-app)' --no-splash= - -#+begin_src emacs-lisp -(defun my/agenda-app () - "Launch Emacs as a dedicated agenda kiosk. -Opens the 'd' (Today) agenda view in a clean, distraction-free frame. -Usage: emacs --eval '(my/agenda-app)' --no-splash" - (interactive) - (set-frame-name "Agenda") - (delete-other-windows) - (org-agenda nil "d") - (delete-other-windows) - (setq mode-line-format nil) - (menu-bar-mode -1) - (tool-bar-mode -1) - (scroll-bar-mode -1) - (when (bound-and-true-p tab-bar-mode) - (tab-bar-mode -1)) - (when (find-font (font-spec :family "Lato")) - (buffer-face-set '(:family "Lato"))) - (text-scale-increase 2) - (hide-mode-line-mode 1) - (winner-mode 1)) -#+end_src - ** ox-contrib #+begin_src emacs-lisp @@ -2448,19 +2169,6 @@ Some goodies for better integration with org files. ) #+end_src -** denote-project-notes - -#+begin_src emacs-lisp - -#+end_src - -** denote-explore - -#+begin_src emacs-lisp -(use-package denote-explore - :ensure t) -#+end_src - ** denote-publish #+begin_src emacs-lisp @@ -2619,7 +2327,7 @@ Timers that expired while Emacs was closed fire immediately." :custom (corfu-cycle t) (corfu-auto t) - (corfu-auto-delay 0.001) + (corfu-auto-delay 0.2) (corfu-auto-prefix 2) :init (global-corfu-mode) @@ -2754,16 +2462,16 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi (setq eglot-connect-timeout 30) (setq eglot-events-buffer-size 0) (setq eglot-report-progress nil) - (setq jsonrpc-default-request-timeout 10) + (setq jsonrpc-default-request-timeout 10)) - (add-hook 'eglot-managed-mode-hook - (lambda () - (eglot-inlay-hints-mode -1))) + ;; (add-hook 'eglot-managed-mode-hook + ;; (lambda () + ;; (eglot-inlay-hints-mode -1))) - (setq eglot-code-action-indications '(eldoc-hint)) + ;; (setq eglot-code-action-indications '(eldoc-hint)) - (setq eglot-ignored-server-capabilities - '(:inlayHintProvider :documentHighlightProvider))) + ;; (setq eglot-ignored-server-capabilities + ;; '(:inlayHintProvider :documentHighlightProvider))) #+end_src ** typst-mode @@ -2811,6 +2519,29 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi (put 'eglot-workspace-configuration 'safe-local-variable #'listp) #+end_src +** c-ts-mode + +Built-in tree-sitter mode (Emacs 29+) driven by =clangd=. The =c= grammar ships via =treesit-grammars.with-all-grammars= in =emacs.nix=, so no on-the-fly compilation is needed. =clangd= picks up include paths and flags from a =compile_commands.json= in the project root (generate it with =bear -- make=, =cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON=, or =meson=); without one it falls back to sane defaults but cross-file navigation is limited. + +#+begin_src emacs-lisp +(use-package c-ts-mode + :ensure nil + :mode (("\\.c\\'" . c-ts-mode) + ("\\.h\\'" . c-ts-mode)) + :hook (c-ts-mode . eglot-ensure) + :custom + (c-ts-mode-indent-offset 2) + (c-ts-mode-indent-style 'k&r) + :config + (with-eval-after-load 'eglot + (add-to-list 'eglot-server-programs + '((c-ts-mode c-mode) . + ("clangd" + "--background-index" + "--clang-tidy" + "--header-insertion=never"))))) +#+end_src + ** c3-ts-mode Not on MELPA, so installed straight from GitHub. The tree-sitter grammar is built on first load via =treesit-install-language-grammar= (needs =cc= / =gcc= on PATH), and eglot drives the =c3-lsp= server. On NixOS install =c3c=, =c3-lsp= and =gcc=. @@ -2822,6 +2553,8 @@ Not on MELPA, so installed straight from GitHub. The tree-sitter grammar is buil ("\\.c3i\\'" . c3-ts-mode) ("\\.c3t\\'" . c3-ts-mode)) :hook (c3-ts-mode . eglot-ensure) + :custom + (c3-ts-mode-indent-offset 2) :init (add-to-list 'treesit-language-source-alist '(c3 "https://github.com/c3lang/tree-sitter-c3")) @@ -3309,6 +3042,12 @@ so the working-tree diff stays visible until the user explicitly stages." (message "auto-staged (intent-to-add): %s" (file-name-nondirectory file))))))) (add-hook 'after-save-hook #'my/auto-git-add-new-file) + +(defun my/magit-uncommit () + "Undo the last commit, leaving its changes in the working tree, unstaged." + (interactive) + (magit-reset-mixed "HEAD^") + (message "Uncommitted HEAD^ — changes preserved, unstaged")) #+end_src * indent-guide @@ -3349,16 +3088,18 @@ so the working-tree diff stays visible until the user explicitly stages." (evil-set-initial-state 'messages-buffer-mode 'normal) (evil-set-initial-state 'dired-mode 'normal) (evil-set-initial-state 'ibuffer-mode 'normal) - (evil-set-initial-state 'erc-mode 'normal)) + (evil-set-initial-state 'clatter-mode 'normal) + (define-key evil-insert-state-map (kbd "C-w") 'evil-window-map)) (modify-syntax-entry ?_ "w") (defun my/eldoc-and-jump () "Show documentation at point. Works in both GUI and terminal." (interactive) - (if (display-graphic-p) - (eldoc-box-help-at-point) - (eldoc-doc-buffer t))) + ;; (if (display-graphic-p) + ;; (eldoc-box-help-at-point) + ;; (eldoc-doc-buffer t)) + (eldoc-doc-buffer t)) (define-key evil-normal-state-map (kbd "K") #'my/eldoc-and-jump) #+end_src @@ -3640,67 +3381,22 @@ Native =undo-redo= (via =evil-undo-system='undo-redo=); just raise the undo limi #+end_src * modelines -** hide modeline -#+begin_src emacs-lisp -(use-package hide-mode-line - :ensure t) -#+end_src - -** COMMENT punch-line - -#+begin_src emacs-lisp -(use-package punch-line - :ensure (:host github :repo "cashmeredev/punch-line") - :config - (setq punch-line-left-separator " " - punch-line-right-separator " " - punch-show-git-info nil - punch-show-buffer-position t - punch-show-column-info t - punch-show-erc-info nil - punch-line-music-max-length 80 - punch-line-modal-divider-style 'block - punch-line-section-backgrounds 'auto - punch-line-glyph-style 'nerd - punch-show-weather-info t - punch-weather-longitude "10.41" - punch-weather-latitude "53.25" - punch-cpu-usage nil - punch-show-processes-info nil - punch-line-music-info nil) - (punch-line-mode 1)) -#+end_src - -** svg-line +** doom-modeline #+begin_src emacs-lisp -(use-package svg-line - :ensure (:host nil :repo "ssh://git.cashmere.rs/svg-line.git" - :branch "feat/tty-kitty-modeline") +(use-package doom-modeline + :ensure t + :init (doom-modeline-mode 1) :config - (require 'svg-line-segments) - (setq svg-line-weather-latitude "53.25" - svg-line-weather-longitude "10.41") - (svg-line-weather-mode 1) - - (svg-line-define 'cashmere-mode-line - :target 'mode-line - :layout 'lines - :active #'mode-line-window-selected-p - :background (lambda () (face-background 'mode-line nil t)) - :foreground (lambda () (face-foreground 'mode-line nil t)) - :inactive-background (lambda () (face-background 'mode-line-inactive nil t)) - :inactive-foreground (lambda () (face-foreground 'mode-line-inactive nil t)) - :content - (lambda () - (list (cons (list #'svg-line-segment-evil " " - #'svg-line-segment-buffer #'svg-line-segment-vc) - (list #'svg-line-segment-weather #'svg-line-segment-battery - #'svg-line-segment-position " " - #'svg-line-segment-major-mode))))) - - (svg-line-activate 'cashmere-mode-line)) + (setq doom-modeline-hud t + doom-modeline-irc t + doom-modeline-irc-buffers nil + doom-modeline-mu4e t + doom-modeline-buffer-file-name-style 'relative-to-project + doom-modeline-buffer-encoding nil + doom-modeline-time t + doom-modeline-time-live-icon t)) #+end_src * soph @@ -3765,16 +3461,15 @@ created later still get them." #+begin_src emacs-lisp (use-package dirvish - :ensure t + :ensure (:host github :repo "latiagertrutis/dirvish" :branch "main") :init (dirvish-override-dired-mode) :custom (dirvish-quick-access-entries - '(("h" "~/" "Home") - ("d" "~/Downloads/" "Downloads") - ;; ("p" "~/projects/" "Projects") - )) + '(("h" "~/" "home") + ("d" "~/Downloads/" "downloads") + ("c" "~/.config/" "config"))) (dirvish-reuse-session 'open) (dirvish-attributes '(file-size)) @@ -3947,6 +3642,18 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." (advice-add 'embark-export :after #'my/embark-export-auto-wgrep)) #+end_src +** search in arbitrary directories + +#+begin_src emacs-lisp +(defun my/consult-fd-in (dir) + (interactive "DFind files in: ") + (consult-fd dir)) + +(defun my/consult-ripgrep-in (dir) + (interactive "DGrep in: ") + (consult-ripgrep dir)) +#+end_src + * workspaces #+begin_src emacs-lisp @@ -3971,8 +3678,8 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." persp-add-buffer-on-after-change-major-mode t persp-kill-foreign-buffer-behaviour 'kill persp-remove-buffers-from-nil-persp-behaviour nil - persp-auto-resume-time 1.0 - persp-auto-save-opt 1 + persp-auto-resume-time -1 + persp-auto-save-opt 0 uniquify-buffer-name-style nil) (add-to-list 'persp-filter-save-buffers-functions @@ -4146,7 +3853,6 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." (defun my/workspace-switch-to-project (&optional dir) (let* ((dir (or dir default-directory)) - (default-directory dir) (name (projectile-project-name dir))) (when persp-mode (if (or (eq my/workspaces-on-switch-project t) @@ -4156,7 +3862,8 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." (my/workspace-switch name t) (switch-to-buffer (my/workspace-fallback-buffer))) (ignore-errors (persp-rename name (get-current-persp)))) - (funcall my/workspace-switch-project-function)))) + (let ((default-directory dir)) + (funcall my/workspace-switch-project-function))))) (with-eval-after-load 'projectile (setq projectile-switch-project-action #'my/workspace-switch-to-project)) @@ -4166,30 +3873,17 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." (define-key persp-mode-map [remap evil-window-delete] #'my/workspace-close-window-or-workspace)) - (defun my/workspace-restore-services (&rest _) - (run-with-idle-timer - 1 nil - (lambda () - (unless (and (fboundp 'mu4e-running-p) (mu4e-running-p)) - (mu4e t))))) - (add-hook 'persp-after-load-state-functions #'my/workspace-restore-services) - (add-hook 'persp-filter-save-buffers-functions (lambda (buf) - (with-current-buffer buf (derived-mode-p 'erc-mode)))) - - (run-with-timer (* 10 60) (* 10 60) - (lambda () (when persp-mode (persp-save-state-to-file)))) + (with-current-buffer buf (derived-mode-p 'clatter-mode)))) - (defun my/workspace--inhibit-erc-part (orig &rest args) - (let ((erc-kill-channel-hook nil) - (erc-kill-server-hook nil) - (erc-kill-buffer-hook nil)) + (defun my/workspace--inhibit-irc-part (orig &rest args) + (cl-letf (((symbol-function 'clatter--on-kill-buffer) #'ignore)) (apply orig args))) - (advice-add 'my/workspace-kill :around #'my/workspace--inhibit-erc-part) - (advice-add 'my/workspace-kill-session :around #'my/workspace--inhibit-erc-part) + (advice-add 'my/workspace-kill :around #'my/workspace--inhibit-irc-part) + (advice-add 'my/workspace-kill-session :around #'my/workspace--inhibit-irc-part) - (when (daemonp) (persp-mode 1))) + (persp-mode 1)) #+end_src #+begin_src emacs-lisp @@ -4221,8 +3915,11 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." (defun my/ibuffer-workspace () (interactive) - (ibuffer nil (format "*ibuffer: %s*" (my/workspace-current-name)) - (list (cons 'persp t)))) + (let ((name (my/workspace-current-name))) + (if (equal name my/workspaces-master) + (ibuffer nil "*ibuffer: master*") + (ibuffer nil (format "*ibuffer: %s*" name) + (list (cons 'persp t)))))) #+end_src #+begin_src emacs-lisp @@ -4386,10 +4083,13 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." :wk "find file/switch project") "sp" '(consult-projectile :wk "search project") "ss" '(consult-line :wk "search project") + "sd" '(my/consult-ripgrep-in :wk "grep in dir") + "sf" '(my/consult-fd-in :wk "find file in dir") "/" '(consult-ripgrep :wk "search project") "." '(find-file :wk "find file") "," '(consult-buffer :wk "switch buffer") ":" (lambda () (interactive) (execute-extended-command nil)) + "u" '(universal-argument :wk "universal argument") "d" '(:ignore t :wk "denote") "dj" '(denote-journal-new-or-existing-entry :wk "journal") @@ -4447,6 +4147,7 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." "gt" '(eglot-find-typeDefinition :wk "go to type definition") "gr" '(xref-find-references :wk "find references") "gs" '(magit-file-stage :wk "stage file") + "gu" '(my/magit-uncommit :wk "uncommit (keep & unstage)") "gb" '(vc-annotate :wk "blame") "gT" '(my/code-todos-harvest :wk "harvest code TODOs") @@ -4479,8 +4180,8 @@ activates automatically. Edit, then `C-c C-c' commits, `C-c C-k' aborts." "w L" '(buf-move-right :wk "Buffer move right") "c" '(:ignore t :wk "code") - "cc" '(my/compile-or-recompile :wk "compile / recompile") - "cC" '(compile :wk "compile (new command)") + "cc" '(my/compile-or-recompile :wk "compile") + "cC" '(ghostel-compile :wk "recompile") "ca" '(eglot-code-actions :wk "code actions") "cr" '(eglot-rename :wk "lsp rename") "cf" '(eglot-format :wk "format buffer") @@ -5066,18 +4767,6 @@ date) and the dired header are never skipped." (delete '(:eval mu4e-alert-mode-line) global-mode-string))) #+end_src -* color-tools - -this package provides the ability to display rgb and hex colors. - -#+begin_src emacs-lisp -(use-package denote-project-notes - :ensure t - :after org - :config - (setq denote-project-notes-identifier '(project stayem))) -#+end_src - * arrow.el #+begin_src emacs-lisp @@ -5193,16 +4882,6 @@ opening another file in same project does not re-notify." '(("nh-switch" "nh os switch --quiet $*")))) #+end_src -* atuin-eshell - -#+begin_src emacs-lisp -(use-package eshell-atuin - :ensure t - :after eshell - :config - (eshell-atuin-mode)) -#+end_src - * elfetch #+begin_src emacs-lisp @@ -5219,6 +4898,7 @@ opening another file in same project does not re-notify." (ghostel-shell "xonsh") (ghostel-ssh-install-terminfo t) :config + (require 'ghostel-compile) (setq-default window-adjust-process-window-size-function #'window-adjust-process-window-size-largest) (add-to-list 'ghostel-tramp-shells '("rpc" login-shell)) @@ -5245,6 +4925,8 @@ opening another file in same project does not re-notify." :ensure (:host github :repo "dakra/ghostel" :files ("extensions/evil-ghostel/*.el")) :after (ghostel evil) + :custom + (evil-ghostel-escape 'evil) :hook (ghostel-mode . evil-ghostel-mode)) #+end_src @@ -5326,16 +5008,6 @@ Interactive commands: =garden-player= opens the player; =garden-player-play-next tramp-verbose 1)) #+end_src -* difftastic - -#+begin_src emacs-lisp -(use-package difftastic - :ensure t - :defer t - :init - (difftastic-bindings-mode)) -#+end_src - * magit-delta #+begin_src emacs-lisp @@ -5354,103 +5026,6 @@ Interactive commands: =garden-player= opens the player; =garden-player-play-next :ensure t) #+end_src -* dashboard - -#+begin_src emacs-lisp -(use-package grid - :ensure (:host github :repo "ichernyshovvv/grid.el") - :demand t) - -(use-package enlight - :ensure (:host github :repo "ichernyshovvv/enlight") - :demand t - :after grid - :config - (require 'enlight-menu) - (defface my/enlight-header - '((t (:inherit font-lock-keyword-face :weight bold))) - "Enlight banner face.") - - (defvar my/enlight-banner - (propertize - "███████ ███ ███ █████ ██████ ███████ -██ ████ ████ ██ ██ ██ ██ -█████ ██ ████ ██ ███████ ██ ███████ -██ ██ ██ ██ ██ ██ ██ ██ -███████ ██ ██ ██ ██ ██████ ███████" - 'face 'my/enlight-header)) - - (defun my/enlight-stats () - (concat - (format "%d packages" (length (elpaca--queued))) - (when (bound-and-true-p after-init-time) - (format " · %s" (emacs-init-time "%.2fs"))) - (format " · %s" (format-time-string "%a %d %b %H:%M")))) - - (defun my/enlight-recent () - (if (bound-and-true-p recentf-list) - (mapconcat - (lambda (f) - (let ((s (abbreviate-file-name f))) - (if (> (length s) 32) - (concat "…" (substring s (- (length s) 31))) - s))) - (seq-take recentf-list 8) - "\n") - (propertize "no recent files" 'face 'shadow))) - - (defun my/enlight-content () - (concat - (grid-make-box `(:align center :width 80 :content ,my/enlight-banner)) - "\n" - (grid-make-box `(:align center :width 80 - :content ,(propertize (my/enlight-stats) 'face 'shadow))) - "\n\n" - (grid-make-row - (list - (grid-make-box - `(:width 40 :border t :padding 1 - :content ,(enlight-menu - '(("Quick actions" - ("Agenda" (org-agenda nil "d") "a") - ("Recent file" consult-recent-file "r") - ("Switch project" projectile-switch-project "p") - ("Find note" denote-open-or-create "n") - ("Journal entry" denote-journal-new-or-existing-entry "j") - ("Magit" magit-status "g") - ("Files" dirvish "f") - ("Mail" mu4e "m") - ("IRC" run-irc "i") - ("Switch workspace" my/workspace-switch-to "w") - ("Restore session" my/workspace-load-session "S")))))) - " " - (grid-make-box - `(:width 38 :border t :padding 1 - :content ,(concat (propertize "Recent files\n\n" 'face 'enlight-menu-section) - (my/enlight-recent))))))))) - -(defun my/enlight-refresh (&rest _) - (enlight--update 'enlight-content (my/enlight-content))) -(advice-add 'enlight :before #'my/enlight-refresh) - -(defun my/session-exists-p () - (file-exists-p (file-name-concat persp-save-dir persp-auto-save-fname))) - -(setq initial-buffer-choice - (lambda () - (if (and (fboundp 'enlight) (not (my/session-exists-p))) - (enlight) - (get-buffer-create "*scratch*")))) - -(add-hook 'elpaca-after-init-hook - (lambda () - (when (and (fboundp 'enlight-open) (not (my/session-exists-p))) - (enlight-open)))) - -(with-eval-after-load 'evil - (evil-set-initial-state 'enlight-mode 'emacs)) -#+end_src - * provide init #+begin_src emacs-lisp @@ -52,7 +52,7 @@ use-package-compute-statistics t)) ;; Install org before tangling config.org -(elpaca (org :wait t)) +(elpaca (org :ref "release_9.8.5" :depth nil :wait t)) ;; Shadow built-in transient with newer version before magit loads (elpaca (transient :wait t)) |
