From 47b84608255e44162b65195a2e9e93b5d16cd7d3 Mon Sep 17 00:00:00 2001 From: js0ny Date: Mon, 22 Sep 2025 01:13:21 +0100 Subject: [PATCH] feat(emacs): qwerty --- tools/doom/beancount.el | 35 +++++++++++++++++++++ tools/doom/config.el | 9 ++++-- tools/doom/evil.el | 18 ++--------- tools/doom/init.el | 4 +-- tools/emacs.d/lisp/init-ai.el | 17 +++++----- tools/emacs.d/lisp/init-beancount.el | 29 +++++++++++++++++- tools/emacs.d/lisp/init-edit.el | 2 ++ tools/emacs.d/lisp/init-evil.el | 46 ++++++++++++++-------------- 8 files changed, 108 insertions(+), 52 deletions(-) create mode 100644 tools/doom/beancount.el diff --git a/tools/doom/beancount.el b/tools/doom/beancount.el new file mode 100644 index 0000000..bfb75d7 --- /dev/null +++ b/tools/doom/beancount.el @@ -0,0 +1,35 @@ +;;; init-beancount.el --- beancount support -*- lexical-binding: t -*- +(after! beancount + + ;; 1. 自动启用 outline-minor-mode + (add-hook! 'beancount-mode-hook #'outline-minor-mode) + + ;; 2. 设置大纲导航快捷键 (使用 Doom 的 map! 宏) + (map! :map beancount-mode-map + "C-c C-n" #'outline-next-visible-heading + "C-c C-p" #'outline-previous-visible-heading) + + ;; 3. 核心功能:跨文件账户补全 (这部分逻辑完全保留) + (defvar my-beancount-accounts-files nil "List of account files.") + (setq my-beancount-accounts-files + (directory-files "~/Documents/Finance/Beancount/config/" 'full (rx ".beancount" eos))) + + (defun my-beancount--collect-accounts-from-files (oldfun &rest args) + "Collect all accounts from files specified in `my-beancount-accounts-files'." + (let ((keys (apply oldfun args)) + (hash (make-hash-table :test 'equal))) + (dolist (key keys) + (puthash key nil hash)) + ;; collect accounts from files + (save-excursion + (dolist (f my-beancount-accounts-files) + ;; `ignore-errors` is a good practice for file operations + (ignore-errors + (with-current-buffer (find-file-noselect f) + (goto-char (point-min)) + (while (re-search-forward beancount-account-regexp nil t) + (puthash (match-string-no-properties 1) nil hash)))))) + (hash-table-keys hash))) + + (advice-add #'beancount-collect + :around #'my-beancount--collect-accounts-from-files)) diff --git a/tools/doom/config.el b/tools/doom/config.el index 0ea0060..ff9d7df 100644 --- a/tools/doom/config.el +++ b/tools/doom/config.el @@ -22,10 +22,10 @@ ;; accept. For example: ;; ;; https://emacs-china.org/t/doom-emacs/23513/13 -(setq doom-font (font-spec :family "Sarasa Mono SC Nerd Font" :size 14) +(setq doom-font (font-spec :family "Maple Mono NF CN" :size 14) doom-serif-font doom-font - doom-symbol-font (font-spec :family "Sarasa Mono SC Nerd Font") - doom-variable-pitch-font (font-spec :family "Sarasa Mono SC Nerd Font" :weight 'extra-bold)) + doom-symbol-font (font-spec :family "Maple Mono NF CN") + doom-variable-pitch-font (font-spec :family "Maple Mono NF CN" :weight 'extra-bold)) ;; 如果不把这玩意设置为 nil, 会默认去用 fontset-default 来展示, 配置无效 (setq use-default-font-for-symbols nil) @@ -153,3 +153,6 @@ (if (eq system-type 'gnu/linux) (setq ee-terminal-command "kitty")) ) + + +(load! "beancount.el") diff --git a/tools/doom/evil.el b/tools/doom/evil.el index b2614da..3bf3a45 100644 --- a/tools/doom/evil.el +++ b/tools/doom/evil.el @@ -1,20 +1,8 @@ (map! - :nvm "l" 'evil-insert - :nvm "L" 'evil-insert-line - :nvm "k" 'evil-ex-search-next - :nvm "K" 'evil-ex-search-previous - :nvom "j" 'evil-forward-word-end - :nvom "J" 'evil-forward-WORD-end - :nvom "n" 'evil-next-line - :nvom "e" 'evil-previous-line - :nvom "i" 'evil-forward-char :nvm "H" 'evil-prev-buffer - :nvm "I" 'evil-next-buffer - :nvom "N" '(lambda () (interactive) (evil-next-line 5)) ; 5n - :nvom "E" '(lambda () (interactive) (evil-previous-line 5)) ; 5e - :nvom "C-w n" 'evil-window-down - :nvom "C-w e" 'evil-window-up - :nvom "C-w i" 'evil-window-right + :nvm "L" 'evil-next-buffer + :nvom "J" '(lambda () (interactive) (evil-next-line 5)) ; 5j + :nvom "K" '(lambda () (interactive) (evil-previous-line 5)) ; 5k ) ;; Swap ; and : diff --git a/tools/doom/init.el b/tools/doom/init.el index f11c6fc..83b91dd 100644 --- a/tools/doom/init.el +++ b/tools/doom/init.el @@ -114,7 +114,7 @@ :lang ;;agda ; types of types of types of types... - ;;beancount ; mind the GAAP + beancount ; mind the GAAP (cc +lsp) ; C > C++ == 1 ;;clojure ; java with a lisp ;;common-lisp ; if you've seen one lisp, you've seen them all @@ -151,7 +151,7 @@ ;lua ; one-based indices? one-based indices markdown ; writing docs for people to ignore ;;nim ; python + lisp at the speed of c - ;;nix ; I hereby declare "nix geht mehr!" + nix ; I hereby declare "nix geht mehr!" ;;ocaml ; an objective camel (org ; organize your plain life in plain text +pomodoro diff --git a/tools/emacs.d/lisp/init-ai.el b/tools/emacs.d/lisp/init-ai.el index bdaaf3d..2945fc6 100644 --- a/tools/emacs.d/lisp/init-ai.el +++ b/tools/emacs.d/lisp/init-ai.el @@ -1,11 +1,12 @@ -(use-package copilot - :vc (:url "https://github.com/copilot-emacs/copilot.el" - :rev :newest - :branch "main") - :hook (prog-mode . copilot-mode) - :config - (define-key copilot-completion-map (kbd "") 'copilot-accept-completion) - (define-key copilot-completion-map (kbd "TAB") 'copilot-accept-completion)) + +;; (use-package copilot +;; :vc (:url "https://github.com/copilot-emacs/copilot.el" +;; :rev :newest +;; :branch "main") +;; :hook (prog-mode . copilot-mode) +;; :config +;; (define-key copilot-completion-map (kbd "") 'copilot-accept-completion) +;; (define-key copilot-completion-map (kbd "TAB") 'copilot-accept-completion)) (provide 'init-ai) diff --git a/tools/emacs.d/lisp/init-beancount.el b/tools/emacs.d/lisp/init-beancount.el index 980f5f6..33cee8a 100644 --- a/tools/emacs.d/lisp/init-beancount.el +++ b/tools/emacs.d/lisp/init-beancount.el @@ -6,7 +6,34 @@ (use-package beancount :mode (("\\.beancount\\'" . beancount-mode) - ("\\.bean\\'" . beancount-mode))) + ("\\.bean\\'" . beancount-mode)) + :init + (add-hook 'beancount-mode-hook #'outline-minor-mode) + (define-key beancount-mode-map (kbd "C-c C-n") #'outline-next-visible-heading) + (define-key beancount-mode-map (kbd "C-c C-p") #'outline-previous-visible-heading) + + (defvar beancount-accounts-files nil "List of account files.") + (setq beancount-accounts-files + (directory-files "~/Dropbox/beancount/accounts/" 'full (rx ".beancount" eos))) + + (defun w/beancount--collect-accounts-from-files (oldfun regex n) + "Collect all accounts from files." + (let ((keys (funcall oldfun regex n)) + (hash (make-hash-table :test 'equal))) + (dolist (key keys) + (puthash key nil hash)) + ;; collect accounts from files + (save-excursion + (dolist (f beancount-accounts-files) + (with-current-buffer (find-file-noselect f) + (goto-char (point-min)) + (while (re-search-forward beancount-account-regexp nil t) + (puthash (match-string-no-properties n) nil hash))))) + (hash-table-keys hash))) + + (advice-add #'beancount-collect + :around #'w/beancount--collect-accounts-from-files + '((name . "collect accounts from files as well")))) (provide 'init-beancount) diff --git a/tools/emacs.d/lisp/init-edit.el b/tools/emacs.d/lisp/init-edit.el index 58e8808..c5e8191 100644 --- a/tools/emacs.d/lisp/init-edit.el +++ b/tools/emacs.d/lisp/init-edit.el @@ -97,4 +97,6 @@ (setq diff-hl-margin-mode nil) (diff-hl-flydiff-mode)) +(global-font-lock-mode t) + (provide 'init-edit) diff --git a/tools/emacs.d/lisp/init-evil.el b/tools/emacs.d/lisp/init-evil.el index ebc8d49..c4c239b 100644 --- a/tools/emacs.d/lisp/init-evil.el +++ b/tools/emacs.d/lisp/init-evil.el @@ -13,34 +13,34 @@ ; Motion - Emacs built-in read-only mode (evil-define-key '(normal visual operator motion) 'global ;; To see the keybindings, use k then type the key - "n" 'evil-next-line - "e" 'evil-previous-line - "i" 'evil-forward-char - ;"l" 'evil-insert - ;"L" 'evil-insert-0-line - "k" 'evil-search-next - "K" 'evil-search-previous - "j" 'evil-forward-word-end - "J" 'evil-forward-WORD-end - "N" '(lambda () (interactive) (evil-next-line 5)) ; 5n - "E" '(lambda () (interactive) (evil-previous-line 5)) ; 5e - (kbd "C-w n") 'evil-window-down - (kbd "C-w e") 'evil-window-up - (kbd "C-w i") 'evil-window-right - (kbd "C-w C-n") 'evil-window-down - (kbd "C-w C-e") 'evil-window-up - (kbd "C-w C-i") 'evil-window-right) - (evil-define-key '(normal visual) 'global - "l" 'evil-insert - "L" 'evil-insert-0-line) + ; "n" 'evil-next-line + ; "e" 'evil-previous-line + ; "i" 'evil-forward-char + ; ;"l" 'evil-insert + ; ;"L" 'evil-insert-0-line + ; "k" 'evil-search-next + ; "K" 'evil-search-previous + ; "j" 'evil-forward-word-end + ; "J" 'evil-forward-WORD-end + "J" '(lambda () (interactive) (evil-next-line 5)) ; 5n + "K" '(lambda () (interactive) (evil-previous-line 5)) ; 5e + ; (kbd "C-w n") 'evil-window-down + ; (kbd "C-w e") 'evil-window-up + ; (kbd "C-w i") 'evil-window-right + ; (kbd "C-w C-n") 'evil-window-down + ; (kbd "C-w C-e") 'evil-window-up + ; (kbd "C-w C-i") 'evil-window-right) + ; (evil-define-key '(normal visual) 'global + ; "l" 'evil-insert + ; "L" 'evil-insert-0-line) (evil-define-key '(normal motion) 'global "H" #'tab-line-switch-to-prev-tab - "I" #'tab-line-switch-to-next-tab) + "L" #'tab-line-switch-to-next-tab) (evil-define-key '(visual operator) 'global "H" #'evil-beginning-of-line - "I" #'evil-end-of-line) + "L" #'evil-end-of-line) (evil-ex-define-cmd "bn" #'tab-line-switch-to-next-tab) - (evil-ex-define-cmd "bp" #'tab-line-switch-to-prev-tab)) + (evil-ex-define-cmd "bp" #'tab-line-switch-to-prev-tab))) ;; Text Objects Keymap - Use `l` for inner (swap i and l) ;; https://github.com/emacs-evil/evil/blob/master/evil-maps.el#L398-L421