mirror of
https://github.com/fscotto/infra.git
synced 2026-09-27 19:03:47 +00:00
Refactor Emacs for authoring workflows
This commit is contained in:
@@ -1,318 +0,0 @@
|
||||
(require 'seq)
|
||||
(require 'subr-x)
|
||||
;;makes sure elfeed reads index from disk before launching
|
||||
(defvar fscotto/elfeed-initial-update-done nil
|
||||
"Non-nil once Elfeed has triggered its first automatic update this session.")
|
||||
|
||||
(defvar fscotto/elfeed-update-timer nil
|
||||
"Timer used for periodic Elfeed updates.")
|
||||
|
||||
(defun fscotto/elfeed-auto-update ()
|
||||
"Refresh Elfeed feeds in the background."
|
||||
(when (require 'elfeed nil 'noerror)
|
||||
(require 'elfeed-db)
|
||||
(elfeed-db-load)
|
||||
(elfeed-update)))
|
||||
|
||||
(defun fscotto/elfeed-start-auto-update ()
|
||||
"Start the periodic Elfeed update timer if needed."
|
||||
(unless (timerp fscotto/elfeed-update-timer)
|
||||
(setq fscotto/elfeed-update-timer
|
||||
(run-at-time "15 min" (* 15 60) #'fscotto/elfeed-auto-update))))
|
||||
|
||||
(defun fscotto/elfeed-load-db-and-open ()
|
||||
"Open Elfeed, updating once per session and then every 15 minutes.
|
||||
|
||||
Based on https://pragmaticemacs.wordpress.com/2016/08/17/read-your-rss-feeds-in-emacs-with-elfeed/
|
||||
Created: 2016-08-17
|
||||
Updated: 2025-06-13"
|
||||
(interactive)
|
||||
(require 'elfeed)
|
||||
(require 'elfeed-db)
|
||||
(elfeed-db-load)
|
||||
(elfeed)
|
||||
(fscotto/elfeed-start-auto-update)
|
||||
(unless fscotto/elfeed-initial-update-done
|
||||
(setq fscotto/elfeed-initial-update-done t)
|
||||
(message "Updating Elfeed feeds...")
|
||||
(elfeed-update)))
|
||||
|
||||
(defun fscotto/project-root ()
|
||||
"Return projectile project root or fallback to default-directory."
|
||||
(if (featurep 'projectile)
|
||||
(or (projectile-project-root) default-directory)
|
||||
default-directory))
|
||||
|
||||
(defun fscotto/project-vterm ()
|
||||
"Open vterm in project root."
|
||||
(interactive)
|
||||
(let ((default-directory (fscotto/project-root)))
|
||||
(vterm)))
|
||||
|
||||
(defun fscotto/open-multi-vterm-in (directory)
|
||||
"Open a new multi-vterm buffer in DIRECTORY."
|
||||
(let ((default-directory (file-name-as-directory directory)))
|
||||
(multi-vterm)))
|
||||
|
||||
(defun fscotto/home-multi-vterm ()
|
||||
"Open a new multi-vterm buffer in HOME."
|
||||
(interactive)
|
||||
(fscotto/open-multi-vterm-in (expand-file-name "~/")))
|
||||
|
||||
(defun fscotto/project-multi-vterm ()
|
||||
"Open a new multi-vterm buffer in project root."
|
||||
(interactive)
|
||||
(fscotto/open-multi-vterm-in (fscotto/project-root)))
|
||||
|
||||
(defconst fscotto/opencode-db-path
|
||||
(expand-file-name "~/.local/share/opencode/opencode.db")
|
||||
"Path to the OpenCode SQLite database.")
|
||||
|
||||
(defun fscotto/launch-external-terminal (&optional command directory)
|
||||
"Launch external terminal in DIRECTORY, optionally running COMMAND."
|
||||
(let* ((default-directory (file-name-as-directory (or directory (fscotto/project-root))))
|
||||
(terminal-program (or (executable-find fscotto/external-terminal-program)
|
||||
fscotto/external-terminal-program))
|
||||
(args (append
|
||||
(list fscotto/external-terminal-working-directory-option
|
||||
default-directory)
|
||||
(when command
|
||||
(append
|
||||
(list fscotto/external-terminal-execute-option)
|
||||
command)))))
|
||||
(unless (file-executable-p terminal-program)
|
||||
(user-error "External terminal not found: %s" fscotto/external-terminal-program))
|
||||
(apply #'start-process
|
||||
"fscotto-external-terminal"
|
||||
nil
|
||||
terminal-program
|
||||
args)))
|
||||
|
||||
(defun fscotto/opencode-session-candidates (directory)
|
||||
"Return OpenCode session candidates for DIRECTORY.
|
||||
|
||||
Each entry is a cons cell of display string and session id."
|
||||
(let ((sqlite3-program (executable-find "sqlite3"))
|
||||
(session-directory (directory-file-name (expand-file-name directory))))
|
||||
(unless sqlite3-program
|
||||
(user-error "sqlite3 not found"))
|
||||
(unless (file-exists-p fscotto/opencode-db-path)
|
||||
(user-error "OpenCode database not found: %s" fscotto/opencode-db-path))
|
||||
(mapcar
|
||||
(lambda (line)
|
||||
(pcase-let* ((fields (split-string line "\t"))
|
||||
(`(,session-id ,title ,updated-at) fields)
|
||||
(title (if (and title (not (string= title "")))
|
||||
title
|
||||
"Untitled session"))
|
||||
(updated-seconds (/ (string-to-number updated-at) 1000))
|
||||
(updated-label (format-time-string "%Y-%m-%d %H:%M"
|
||||
(seconds-to-time updated-seconds)))
|
||||
(short-id (if (> (length session-id) 12)
|
||||
(substring session-id 0 12)
|
||||
session-id)))
|
||||
(cons (format "%s | %s | %s" title updated-label short-id)
|
||||
session-id)))
|
||||
(process-lines
|
||||
sqlite3-program
|
||||
"-tabs"
|
||||
"-noheader"
|
||||
fscotto/opencode-db-path
|
||||
(format (concat
|
||||
"select id, title, time_updated "
|
||||
"from session "
|
||||
"where directory = '%s' and time_archived is null "
|
||||
"order by time_updated desc;")
|
||||
(replace-regexp-in-string "'" "''" session-directory))))))
|
||||
|
||||
(defun fscotto/project-opencode-latest-session-id ()
|
||||
"Return the latest saved OpenCode session id for the current project."
|
||||
(cdr (car (fscotto/opencode-session-candidates (fscotto/project-root)))))
|
||||
|
||||
(defun fscotto/project-agent-dwim ()
|
||||
"Choose an agent for the current project and launch it externally."
|
||||
(interactive)
|
||||
(let ((agent (completing-read "Agent: " '("Claude" "Codex" "Gemini" "OpenCode") nil t)))
|
||||
(pcase agent
|
||||
("Claude"
|
||||
(fscotto/launch-external-terminal '("claude" "--continue")))
|
||||
("OpenCode"
|
||||
(let ((session-id (fscotto/project-opencode-latest-session-id)))
|
||||
(if session-id
|
||||
(fscotto/launch-external-terminal (list "opencode" "--session" session-id)
|
||||
(fscotto/project-root))
|
||||
(fscotto/project-opencode))))
|
||||
("Codex"
|
||||
(fscotto/launch-external-terminal '("codex" "resume" "--last")))
|
||||
("Gemini"
|
||||
(fscotto/launch-external-terminal '("gemini" "--resume" "latest")
|
||||
(fscotto/project-root))))))
|
||||
|
||||
(defun fscotto/project-opencode-session ()
|
||||
"Resume a saved OpenCode session for the current project."
|
||||
(interactive)
|
||||
(let* ((project-directory (fscotto/project-root))
|
||||
(candidates (fscotto/opencode-session-candidates project-directory)))
|
||||
(unless candidates
|
||||
(user-error "No OpenCode sessions found for %s" project-directory))
|
||||
(let* ((selection (completing-read "OpenCode session: " candidates nil t))
|
||||
(session-id (cdr (assoc selection candidates))))
|
||||
(fscotto/launch-external-terminal (list "opencode" "--session" session-id)
|
||||
project-directory))))
|
||||
|
||||
(defun fscotto/gemini-session-candidates (directory)
|
||||
"Return Gemini session candidates for DIRECTORY.
|
||||
|
||||
Each entry is a cons cell of display string and session index.
|
||||
Tries JSON output first, falls back to text parsing if unavailable."
|
||||
(let* ((default-directory (file-name-as-directory directory))
|
||||
(json-output (shell-command-to-string
|
||||
"gemini --list-sessions --output-format json 2>/dev/null")))
|
||||
(cond
|
||||
((string-match "^{" json-output)
|
||||
(ignore-errors
|
||||
(require 'json)
|
||||
(let* ((parsed (json-parse-string json-output))
|
||||
(sessions (gethash "sessions" parsed)))
|
||||
(when (vectorp sessions)
|
||||
(seq-map-indexed
|
||||
(lambda (s idx)
|
||||
(let* ((idx-str (number-to-string (1+ idx)))
|
||||
(msg (if (hash-table-p s)
|
||||
(or (gethash "firstUserMessage" s) "Session")
|
||||
"Session"))
|
||||
(ts (and (hash-table-p s)
|
||||
(ignore-errors (gethash "lastUpdated" s))
|
||||
(when (stringp it) (string-trim it))))
|
||||
(label (if ts (format "%s [%s]" msg ts) msg)))
|
||||
(cons label idx-str)))
|
||||
sessions)))))
|
||||
(t
|
||||
(let* ((output (shell-command-to-string "gemini --list-sessions"))
|
||||
(lines (seq-filter (lambda (s) (string-match "\\S-" s))
|
||||
(split-string output "\n" t)))
|
||||
(data-lines (seq-drop lines 1))
|
||||
(candidates nil))
|
||||
(dolist (line data-lines)
|
||||
(let ((trimmed (string-trim line)))
|
||||
(when (string-match
|
||||
(rx (group (one-or-more digit))
|
||||
(one-or-more whitespace)
|
||||
(group (one-or-more nonl)))
|
||||
trimmed)
|
||||
(push (cons (match-string 2 trimmed)
|
||||
(match-string 1 trimmed))
|
||||
candidates))))
|
||||
(nreverse candidates))))))
|
||||
|
||||
(defun fscotto/project-gemini-session ()
|
||||
"Choose and resume a Gemini session for the current project."
|
||||
(interactive)
|
||||
(let* ((project-directory (fscotto/project-root))
|
||||
(candidates (fscotto/gemini-session-candidates project-directory)))
|
||||
(unless candidates
|
||||
(user-error "No Gemini sessions found for %s" project-directory))
|
||||
(let* ((selection (completing-read "Gemini session: " candidates nil t))
|
||||
(session-idx (cdr (assoc selection candidates))))
|
||||
(fscotto/launch-external-terminal
|
||||
(list "gemini" "--resume" session-idx)
|
||||
project-directory))))
|
||||
|
||||
(defun fscotto/project-agent-session ()
|
||||
"Choose an agent and resume a saved session for the current project."
|
||||
(interactive)
|
||||
(let ((agent (completing-read "Agent session: " '("Claude" "Codex" "Gemini" "OpenCode") nil t)))
|
||||
(pcase agent
|
||||
("Claude"
|
||||
(fscotto/launch-external-terminal '("claude" "--resume")))
|
||||
("OpenCode"
|
||||
(fscotto/project-opencode-session))
|
||||
("Codex"
|
||||
(fscotto/launch-external-terminal '("codex" "resume")))
|
||||
("Gemini"
|
||||
(fscotto/project-gemini-session)))))
|
||||
|
||||
(defun fscotto/project-external-terminal ()
|
||||
"Open the external terminal in project root."
|
||||
(interactive)
|
||||
(fscotto/launch-external-terminal))
|
||||
|
||||
(defun fscotto/project-opencode ()
|
||||
"Open the external terminal in project root and run opencode."
|
||||
(interactive)
|
||||
(fscotto/launch-external-terminal '("opencode")))
|
||||
|
||||
(defun fscotto/project-magit-status ()
|
||||
"Open magit-status in project root."
|
||||
(interactive)
|
||||
(let ((default-directory (fscotto/project-root)))
|
||||
(magit-status)))
|
||||
|
||||
(defun fscotto/magit-dispatch ()
|
||||
"Load Magit if necessary and open magit-dispatch."
|
||||
(interactive)
|
||||
(require 'magit)
|
||||
(call-interactively #'magit-dispatch))
|
||||
|
||||
(defun fscotto/disable-c-formatting ()
|
||||
(setq-local lsp-enable-on-type-formatting nil))
|
||||
|
||||
;; Golang development support functions
|
||||
(defun fscotto/go-format-on-save ()
|
||||
"Format Go buffers on save using gofmt."
|
||||
(add-hook 'before-save-hook #'lsp-format-buffer nil t))
|
||||
|
||||
(defun fscotto/go-mod-tidy ()
|
||||
"Esegue go mod tidy nella root del progetto."
|
||||
(interactive)
|
||||
(let ((default-directory (project-root (project-current t))))
|
||||
(compile "go mod tidy")))
|
||||
|
||||
(defun fscotto/go-mod-download ()
|
||||
"Scarica i moduli Go."
|
||||
(interactive)
|
||||
(let ((default-directory (project-root (project-current t))))
|
||||
(compile "go mod download")))
|
||||
|
||||
(defun fscotto/go-mod-after-save ()
|
||||
(when (and (eq major-mode 'go-mod-ts-mode)
|
||||
(lsp-workspaces))
|
||||
(lsp-restart-workspace)))
|
||||
|
||||
(defun fscotto/go-test-package ()
|
||||
"Run `go test` in the current package."
|
||||
(interactive)
|
||||
(let ((default-directory (project-root (project-current t))))
|
||||
(compile "go test")))
|
||||
|
||||
(defun fscotto/go-test-module ()
|
||||
"Run `go test ./...` in the current Go module."
|
||||
(interactive)
|
||||
(let ((default-directory (project-root (project-current t))))
|
||||
(compile "go test ./...")))
|
||||
|
||||
(defun fscotto/go-test-current-test ()
|
||||
"Run `go test -run` for the test at point."
|
||||
(interactive)
|
||||
(let* ((test-name (thing-at-point 'symbol t))
|
||||
(default-directory (project-root (project-current t))))
|
||||
(unless test-name
|
||||
(user-error "No test name at point"))
|
||||
(compile (format "go test -run '^%s$'" test-name))))
|
||||
|
||||
(defun fscotto/go-test-at-point ()
|
||||
"Return Go test name at point."
|
||||
(let ((sym (thing-at-point 'symbol t)))
|
||||
(unless (and sym (string-prefix-p "Test" sym))
|
||||
(user-error "No Go test at point"))
|
||||
sym))
|
||||
|
||||
(defun fscotto/sudo-edit (&optional arg)
|
||||
"Reopen current file as root via TRAMP.
|
||||
If ARG is provided (C-u), prompts for file path."
|
||||
(interactive "P")
|
||||
(if arg
|
||||
(find-file (concat "/sudo:root@localhost:" (read-file-name "File: ")))
|
||||
(if buffer-file-name
|
||||
(find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))
|
||||
(user-error "This buffer is not associated with a file"))))
|
||||
@@ -1,39 +0,0 @@
|
||||
;;; documents.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package pdf-tools
|
||||
:ensure t
|
||||
:config
|
||||
(pdf-tools-install))
|
||||
|
||||
(use-package pdf-view
|
||||
:config
|
||||
(setq-default pdf-view-display-size 'fit-width)
|
||||
(setq pdf-cache-org-imgparams t
|
||||
pdf-view-use-smooth-scrolling t)
|
||||
(setq pdf-annot-default-visible-properties t))
|
||||
|
||||
(with-eval-after-load 'pdf-view
|
||||
(define-key pdf-view-mode-map (kbd "n") 'pdf-view-next-page)
|
||||
(define-key pdf-view-mode-map (kbd "p") 'pdf-view-previous-page)
|
||||
(define-key pdf-view-mode-map (kbd "q") 'pdf-view-close))
|
||||
|
||||
(use-package nov
|
||||
:ensure t
|
||||
:mode ("\\.epub\\'" . nov-mode))
|
||||
|
||||
(use-package calibre
|
||||
:ensure t
|
||||
:commands calibre-library
|
||||
:config
|
||||
(setq calibre-calibredb-executable
|
||||
(or (executable-find "calibredb")
|
||||
(let ((flatpak-wrapper (expand-file-name "~/.local/bin/calibredb")))
|
||||
(when (file-executable-p flatpak-wrapper)
|
||||
flatpak-wrapper))
|
||||
"calibredb")
|
||||
calibre-libraries
|
||||
`(("Library" . ,(expand-file-name "~/Documents/Library")))))
|
||||
|
||||
(provide 'misc/documents)
|
||||
|
||||
;;; documents.el ends here
|
||||
@@ -1,9 +0,0 @@
|
||||
;;; doom-modeline.el -*-
|
||||
|
||||
(use-package doom-modeline
|
||||
:ensure t
|
||||
:config
|
||||
(setq doom-modeline-height 25
|
||||
doom-modeline-bar-width 3
|
||||
doom-modeline-project-detection 'projectile)
|
||||
:init (doom-modeline-mode 1))
|
||||
@@ -1,24 +0,0 @@
|
||||
;;; gptel.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package gptel
|
||||
:ensure t
|
||||
:commands (gptel gptel-send gptel-rewrite)
|
||||
:config
|
||||
(setq gptel-model 'qwen3.5:397b)
|
||||
(setq gptel-backend
|
||||
(gptel-make-ollama
|
||||
"Ollama Cloud"
|
||||
:protocol "https"
|
||||
:host "ollama.com"
|
||||
:endpoint "/api/chat"
|
||||
:models '(qwen3.5:397b)
|
||||
:stream t
|
||||
:key (lambda () (gptel-api-key-from-auth-source "ollama.com"))
|
||||
:header
|
||||
(lambda (&optional _info)
|
||||
(when-let ((key (gptel-api-key-from-auth-source "ollama.com")))
|
||||
`(("Authorization" . ,(concat "Bearer " key))))))))
|
||||
|
||||
(provide 'fscotto-gptel)
|
||||
|
||||
;;; gptel.el ends here
|
||||
@@ -1,2 +0,0 @@
|
||||
(use-package i3wm-config-mode
|
||||
:ensure t)
|
||||
@@ -1,10 +1,14 @@
|
||||
;;; rss.el -*-
|
||||
;;; rss.el --- Elfeed configuration -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'use-package)
|
||||
|
||||
(use-package elfeed
|
||||
:ensure t
|
||||
:commands elfeed
|
||||
:bind ("C-c r" . elfeed)
|
||||
:config
|
||||
(defun elfeed-play-with-mpv ()
|
||||
"Open the current elfeed entry link with mpv."
|
||||
"Open the current Elfeed entry link with mpv."
|
||||
(interactive)
|
||||
(let* ((entry (if (eq major-mode 'elfeed-show-mode)
|
||||
elfeed-show-entry
|
||||
@@ -14,44 +18,26 @@
|
||||
(progn
|
||||
(message "Opening with mpv: %s" url)
|
||||
(start-process "mpv" nil "mpv" url))
|
||||
(message "No URL found"))))
|
||||
(define-key elfeed-search-mode-map (kbd "v") #'elfeed-play-with-mpv)
|
||||
(define-key elfeed-show-mode-map (kbd "v") #'elfeed-play-with-mpv)
|
||||
:custom
|
||||
(elfeed-enclosure-default-dir "~/Downloads/")
|
||||
(elfeed-search-remain-on-entry t)
|
||||
(elfeed-search-title-max-width 100)
|
||||
(elfeed-search-title-min-width 30)
|
||||
(elfeed-search-trailing-width 25)
|
||||
(elfeed-show-truncate-long-urls t)
|
||||
(elfeed-sort-order 'descending)
|
||||
(elfeed-search-filter "+unread")
|
||||
:hook
|
||||
(elfeed-show-mode . visual-line-mode))
|
||||
(message "No URL found"))))
|
||||
|
||||
(use-package evil-collection
|
||||
:ensure t
|
||||
:after (evil elfeed)
|
||||
:config
|
||||
;; Enable Vim-style keybindings only for elfeed (search + entry views),
|
||||
;; leaving the rest of the configuration on evil's defaults.
|
||||
(evil-collection-init (list 'elfeed))
|
||||
;; Restore the custom "v" -> mpv binding, which evil's normal-state visual
|
||||
;; selection would otherwise shadow inside elfeed buffers.
|
||||
(evil-collection-define-key 'normal 'elfeed-search-mode-map
|
||||
"v" #'elfeed-play-with-mpv)
|
||||
(evil-collection-define-key 'normal 'elfeed-show-mode-map
|
||||
"v" #'elfeed-play-with-mpv))
|
||||
(setq elfeed-enclosure-default-dir "~/Downloads/"
|
||||
elfeed-search-remain-on-entry t
|
||||
elfeed-search-title-max-width 100
|
||||
elfeed-search-title-min-width 30
|
||||
elfeed-search-trailing-width 25
|
||||
elfeed-show-truncate-long-urls t
|
||||
elfeed-sort-order 'descending
|
||||
elfeed-search-filter "+unread")
|
||||
(define-key elfeed-search-mode-map (kbd "v") #'elfeed-play-with-mpv)
|
||||
(define-key elfeed-show-mode-map (kbd "v") #'elfeed-play-with-mpv)
|
||||
(add-hook 'elfeed-show-mode-hook #'visual-line-mode))
|
||||
|
||||
(use-package elfeed-org
|
||||
:ensure t
|
||||
:after elfeed
|
||||
:custom
|
||||
;; Optionally specify a number of files containing elfeed
|
||||
;; configuration. If not set then the location below is used.
|
||||
;; Note: The customize interface is also supported.
|
||||
(rmh-elfeed-org-files (list "~/.emacs.d/elfeed.org")))
|
||||
|
||||
(with-eval-after-load 'elfeed
|
||||
(rmh-elfeed-org-files (list (expand-file-name "elfeed.org" user-emacs-directory)))
|
||||
:config
|
||||
(elfeed-org))
|
||||
|
||||
(provide 'misc/rss)
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
;;; terminal.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defgroup fscotto nil
|
||||
"Personal customization group."
|
||||
:group 'applications)
|
||||
|
||||
(defcustom fscotto/external-terminal-program "alacritty"
|
||||
"Program used to launch external terminal windows."
|
||||
:type 'string
|
||||
:group 'fscotto)
|
||||
|
||||
(defcustom fscotto/external-terminal-working-directory-option "--working-directory"
|
||||
"Argument used to set the working directory for the external terminal."
|
||||
:type 'string
|
||||
:group 'fscotto)
|
||||
|
||||
(defcustom fscotto/external-terminal-execute-option "-e"
|
||||
"Argument used to execute a command in the external terminal."
|
||||
:type 'string
|
||||
:group 'fscotto)
|
||||
|
||||
(defvar-local fscotto/vterm-font-cookie nil
|
||||
"Face remap cookie used to set a custom font in vterm buffers.")
|
||||
|
||||
(defun fscotto/apply-vterm-font ()
|
||||
"Use Hack Nerd Font only inside vterm buffers."
|
||||
(when fscotto/vterm-font-cookie
|
||||
(face-remap-remove-relative fscotto/vterm-font-cookie))
|
||||
(setq fscotto/vterm-font-cookie
|
||||
(face-remap-add-relative
|
||||
'default
|
||||
'(:family "Hack Nerd Font" :height 120 :weight regular))))
|
||||
|
||||
(use-package vterm
|
||||
:ensure t
|
||||
:hook (vterm-mode . fscotto/apply-vterm-font))
|
||||
|
||||
(use-package multi-vterm
|
||||
:ensure t
|
||||
:after vterm
|
||||
:commands (multi-vterm multi-vterm-next multi-vterm-prev))
|
||||
|
||||
(provide 'terminal)
|
||||
|
||||
;;; terminal.el ends here
|
||||
@@ -1,41 +1,6 @@
|
||||
(use-package magit
|
||||
:ensure t
|
||||
:commands (magit-status magit-log)
|
||||
:init
|
||||
;; Entry point principale
|
||||
(setq magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1)
|
||||
:config
|
||||
;; Performance & UX
|
||||
(setq magit-refresh-status-buffer nil)
|
||||
(setq magit-repository-directories
|
||||
'(("~/Projects" . 2)
|
||||
("~/Work" . 2))))
|
||||
;;; vcs.el --- Optional Git interface -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package vdiff
|
||||
:ensure t
|
||||
:commands (vdiff-current-file vdiff-files vdiff-merge-conflict)
|
||||
:custom
|
||||
(vdiff-lock-scrolling t)
|
||||
(vdiff-auto-refine t))
|
||||
(autoload 'magit-status "magit" nil t)
|
||||
(global-set-key (kbd "C-x g") #'magit-status)
|
||||
|
||||
(use-package vdiff-magit
|
||||
:ensure t
|
||||
:after (magit vdiff)
|
||||
:commands (vdiff-magit vdiff-magit-dwim)
|
||||
:custom
|
||||
(vdiff-magit-use-ediff-for-merges nil)
|
||||
:config
|
||||
(define-key magit-mode-map "e" #'vdiff-magit-dwim)
|
||||
(define-key magit-mode-map "E" #'vdiff-magit)
|
||||
(transient-suffix-put 'magit-dispatch "e" :description "vdiff (dwim)")
|
||||
(transient-suffix-put 'magit-dispatch "e" :command #'vdiff-magit-dwim)
|
||||
(transient-suffix-put 'magit-dispatch "E" :description "vdiff")
|
||||
(transient-suffix-put 'magit-dispatch "E" :command #'vdiff-magit))
|
||||
|
||||
(use-package ztree
|
||||
:ensure t
|
||||
:commands (ztree-diff ztree-dir))
|
||||
|
||||
(provide 'vcs)
|
||||
|
||||
;;; vcs.el ends here
|
||||
(provide 'misc/vcs)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
;;; which-key.el -*-
|
||||
;;; which-key.el --- Discoverable native bindings -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'use-package)
|
||||
|
||||
(use-package which-key
|
||||
:ensure t
|
||||
@@ -8,157 +10,17 @@
|
||||
(setq which-key-idle-delay 0.45
|
||||
which-key-idle-secondary-delay 0.05
|
||||
which-key-max-display-columns 3
|
||||
which-key-max-description-length 45))
|
||||
|
||||
(with-eval-after-load 'which-key
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Top-level prefixes
|
||||
;; --------------------------------------------------------------------------
|
||||
which-key-max-description-length 45)
|
||||
(which-key-add-key-based-replacements
|
||||
"C-c !" "Analyze"
|
||||
"C-c o" "Open"
|
||||
"C-c v" "Version control"
|
||||
"C-c l" "LSP"
|
||||
"C-c t" "TODO / Annotations"
|
||||
"C-c b" "Buffers"
|
||||
"C-c p" "Project"
|
||||
"C-c d" "Debug"
|
||||
"C-c g" "Git"
|
||||
"C-c e" "Elfeed")
|
||||
"C-c a" "Org agenda"
|
||||
"C-c c" "Org capture"
|
||||
"C-c e" "Document export"
|
||||
"C-c e p" "Export PDF"
|
||||
"C-c e h" "Export HTML"
|
||||
"C-c e m" "Export Markdown"
|
||||
"C-c e d" "Export DOCX"
|
||||
"C-c e o" "Export ODT"
|
||||
"C-c r" "RSS (Elfeed)"
|
||||
"C-x C-b" "Ibuffer"))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Open (C-c o …)
|
||||
;; --------------------------------------------------------------------------
|
||||
(which-key-add-key-based-replacements
|
||||
"C-c o d" "Dirvish"
|
||||
"C-c o f" "RSS (Elfeed)"
|
||||
"C-c o l" "LLM chat (gptel)"
|
||||
"C-c o T" "Terminal (multi-vterm)"
|
||||
"C-c o z" "Ztree diff")
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Version control
|
||||
;; --------------------------------------------------------------------------
|
||||
(which-key-add-key-based-replacements
|
||||
"C-c v g" "Magit status (legacy)")
|
||||
|
||||
(which-key-add-key-based-replacements
|
||||
;; Core
|
||||
"C-c g g" "Status"
|
||||
"C-c g s" "Status"
|
||||
;; "C-c g b" "Branch"
|
||||
;; "C-c g c" "Commit"
|
||||
"C-c g p" "Push / Pull"
|
||||
"C-c g f" "Fetch"
|
||||
"C-c g l" "Log"
|
||||
"C-c g S" "Stash"
|
||||
|
||||
;; Files
|
||||
"C-c g d" "Diff"
|
||||
"C-c g D" "Diff (cached)"
|
||||
"C-c g B" "Blame"
|
||||
|
||||
;; Rebase / Reset
|
||||
"C-c g r" "Rebase"
|
||||
"C-c g R" "Reset"
|
||||
|
||||
;; Remote
|
||||
"C-c g y" "Show refs"
|
||||
"C-c g o" "Browse remote")
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Buffers
|
||||
;; --------------------------------------------------------------------------
|
||||
(which-key-add-key-based-replacements
|
||||
"C-x C-b" "ibuffer")
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; TODO / hl-todo
|
||||
;; --------------------------------------------------------------------------
|
||||
(which-key-add-key-based-replacements
|
||||
"C-t" "hl-todo"
|
||||
"C-t p" "Previous TODO"
|
||||
"C-t n" "Next TODO"
|
||||
"C-t o" "Occur (list)"
|
||||
"C-t i" "Insert TODO")
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; LSP (C-c l …)
|
||||
;; --------------------------------------------------------------------------
|
||||
(which-key-add-key-based-replacements
|
||||
;; Navigation
|
||||
"C-c l d" "Go to definition"
|
||||
"C-c l D" "Go to type definition"
|
||||
"C-c l i" "Go to implementation"
|
||||
|
||||
;; Symbols / diagnostics
|
||||
"C-c l s" "Workspace symbols"
|
||||
"C-c l e" "Diagnostics"
|
||||
|
||||
;; Actions
|
||||
"C-c l a" "Code actions"
|
||||
"C-c l r" "Rename symbol"
|
||||
"C-c l f" "Format buffer"
|
||||
|
||||
;; Control
|
||||
"C-c l R" "Restart workspace")
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Elfeed modes
|
||||
;; --------------------------------------------------------------------------
|
||||
(which-key-add-key-based-replacements
|
||||
"w" "Yank"
|
||||
"R" "Update feeds"
|
||||
"q" "Quit")
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Debug / DAP
|
||||
;; --------------------------------------------------------------------------
|
||||
(which-key-add-key-based-replacements
|
||||
"C-c d d" "Start debug session"
|
||||
"C-c d b" "Toggle breakpoint")
|
||||
;; "C-c d c" "Continue"
|
||||
;; "C-c d n" "Next"
|
||||
;; "C-c d i" "Step in"
|
||||
;; "C-c d o" "Step out")
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Project (future)
|
||||
;; --------------------------------------------------------------------------
|
||||
(which-key-add-key-based-replacements
|
||||
;; Core
|
||||
"C-c p p" "Switch project"
|
||||
"C-c p f" "Find file"
|
||||
"C-c p d" "Find directory"
|
||||
"C-c p b" "Switch buffer"
|
||||
"C-c p k" "Kill project buffers"
|
||||
"C-c p r" "Recent files"
|
||||
|
||||
;; Search
|
||||
"C-c p s" "Search"
|
||||
"C-c p s g" "Grep (ripgrep)"
|
||||
"C-c p s r" "Replace in project"
|
||||
|
||||
;; Actions
|
||||
"C-c p c" "Compile"
|
||||
"C-c p t" "Test"
|
||||
"C-c p v" "Open multi-vterm in project"
|
||||
"C-c p x" "Open external term"
|
||||
"C-c p a" "Choose agent"
|
||||
"C-c p A" "Choose agent session"
|
||||
"C-c p e" "Edit project config"
|
||||
"C-c p g" "Project Git status"
|
||||
"C-c p 4" "Other Window"
|
||||
"C-c p 5" "Other Frame"
|
||||
|
||||
;; Cache
|
||||
"C-c p i" "Invalidate cache")
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Cleanup annoying +prefix
|
||||
;; --------------------------------------------------------------------------
|
||||
(which-key-add-key-based-replacements
|
||||
"+prefix" "Prefix"
|
||||
"+lsp" "LSP"
|
||||
"+debug" "Debug"
|
||||
"+project" "Project"))
|
||||
(provide 'misc/which-key)
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
;;; misc-xclip.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package xclip
|
||||
:ensure t
|
||||
:config
|
||||
(xclip-mode t)
|
||||
(setq xclip-method 'xclip))
|
||||
|
||||
(provide 'xclip)
|
||||
|
||||
;;; xclip.el ends here
|
||||
Reference in New Issue
Block a user