Compare commits

..

10 Commits

Author SHA1 Message Date
User
58e01139b5 feat: Integrate consult with xref and enhance denote backlink commands
- Configure consult-xref for xref-show-definitions and xref-show-xrefs
- Add custom denote backlink commands with consult preview support
- Replace denote-backlinks keybindings with new consult-enabled versions
- Fix hardcoded org path to use org-directory variable
2026-07-02 22:17:25 +08:00
User
ddd2ba4905 style: Convert tabs to spaces across Emacs config 2026-07-02 17:36:06 +08:00
User
abe00aa936 fix(base): Correct async package loading condition on Android 2026-07-02 17:33:25 +08:00
User
3aa98696cf refactor(kbd): Replace my-color-picker with consult-colors-emacs 2026-07-02 17:09:30 +08:00
User
74691ac72b refactor(org): Centralize org-directory and simplify paths
- Replace scattered platform conditionals with unified `org-directory`
- Update todo keywords to include WAITING state
- Streamline capture templates
- Remove unused priority-based agenda custom commands
2026-07-02 17:09:30 +08:00
User
ffa5717770 feat: Add denote-lint, replace consult-note with consult-denote 2026-07-02 17:09:17 +08:00
User
a1a1797035 feat(org): Hide spaces between CJK and markup characters 2026-06-30 22:11:14 +08:00
User
97d0a4a3e4 refactor: Reorganize package configurations and fix bindings 2026-06-30 22:10:17 +08:00
User
8328d2a8ff fix: Replace projectile-ibuffer with project-ibuffer 2026-06-30 22:08:52 +08:00
959db450d7 fix(ui): Load correct theme on Android 2026-06-28 15:49:31 +08:00
24 changed files with 500 additions and 482 deletions

View File

@@ -68,7 +68,6 @@
search-ring
regexp-search-ring
extended-command-history)
savehist-ignored-variables '(consult-notes-history)
savehist-autosave-interval 300))
;; saveplace保存光标位置
@@ -80,7 +79,7 @@
(use-package restart-emacs)
;; async
(if *is-android*
(unless *is-android*
(use-package async
:hook
(after-init . dired-async-mode)
@@ -238,11 +237,6 @@
:config
(setq eww-auto-rename-buffer t))
;; shr
(use-package shr
:config
(setq shr-inhibit-images nil))
(provide 'init-base)
;;; init-base.el ends here

View File

@@ -35,6 +35,14 @@
(*is-linux*
(setq consult-locate-args "plocate --basename --ignore-case")))
;; help
(define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
(setq consult-narrow-key "<")
;; xref
(setq xref-show-definitions-function #'consult-xref)
(setq xref-show-xrefs-function #'consult-xref)
;; set some buffer filter
(setq consult-buffer-filter
(cl-union consult-buffer-filter

View File

@@ -35,7 +35,7 @@
:stream t
:models '(kimi-for-coding)
:header (lambda (_)
(when-let ((key (gptel--get-api-key)))
(when-let* ((key (gptel--get-api-key)))
`(("User-Agent" . "RooCode/3.30.3")
("HTTP-Referer" . "https://github.com/RooVetGit/Roo-Cline")
("X-Title" . "Roo Code")
@@ -53,7 +53,8 @@
(string-trim clean)))
(defun my-gptel-save-session ()
"Save current gptel session to ~/gptel/sessions/ with AI-generated filename.
"Save current gptel session to ~/gptel/sessions/ with AI-generated
filename.
The filename is prefixed with a YYYYMMDD-HHmmss timestamp and generated
from the last 1500 characters of the buffer."
(interactive)
@@ -63,11 +64,15 @@ from the last 1500 characters of the buffer."
(content (with-current-buffer buf
(buffer-substring-no-properties (point-min) (point-max))))
(tail (substring content (max 0 (- (length content) 1500))))
(prompt-text (format "Based on the following conversation, generate a short kebab-case filename (3 to 5 lowercase English words, hyphen-separated, no file extension). Output ONLY the filename, nothing else.\n\n%s"
(prompt-text (format "Based on the following conversation, generate a short kebab-case
filename (3 to 5 lowercase English words, hyphen-separated, no file
extension). Output ONLY the filename, nothing else.\n\n%s"
tail)))
(message "Generating filename with AI...")
(let ((fsm (gptel-request prompt-text
:system "You are a filename generator. Output ONLY a short kebab-case filename (3-5 lowercase English words separated by hyphens). No explanations, no quotes, no punctuation, no file extension."
:system "You are a filename generator. Output ONLY a short kebab-case
filename (3-5 lowercase English words separated by hyphens). No
explanations, no quotes, no punctuation, no file extension."
:stream nil
:callback
(lambda (response info)
@@ -132,7 +137,7 @@ from the last 1500 characters of the buffer."
:models '((kimi-for-coding))
:request-params '(:temperature 0.6 :thinking (:type "disabled"))
:header (lambda (_)
(when-let ((key (gptel--get-api-key)))
(when-let* ((key (gptel--get-api-key)))
`(("User-Agent" . "RooCode/3.30.3")
("HTTP-Referer" . "https://github.com/RooVetGit/Roo-Cline")
("X-Title" . "Roo Code")

View File

@@ -110,9 +110,36 @@ otherwise toggle global-jinx-mode."
`~/org/my-org-note/20260508T220745==metanote--all-my-metanotes__org.org'"
(interactive)
(find-file
"~/org/my-org-note/20260508T220745==metanote--all-my-metanotes__org.org"))
(concat org-directory "/20260508T220745==metanote--all-my-metanotes__org.org")))
(defun org-table-align-all ()
(defun my-denote-find-file ()
"Find file use denote-file-prompt."
(interactive)
(let ((denote-excluded-files-regexp "=journal"))
(find-file (denote-file-prompt))))
(defun my-denote-find-backlink-with-location ()
"Like `denote-find-backlink-with-location' but with consult preview."
(interactive)
(when-let* ((current-file buffer-file-name)
(id (or (denote-retrieve-filename-identifier current-file)
(user-error "The current file does not have a Denote identifier")))
(files (denote-directory-files nil :omit-current :text-only))
(fetcher (lambda () (xref-matches-in-files id files))))
(consult-xref fetcher nil)))
(defun my-denote-org-find-backlink-for-heading-with-location ()
"Like `denote-org-backlinks-for-heading' but with consult preview."
(interactive)
(unless (featurep 'denote-org)
(require 'denote-org))
(when-let* ((heading-id (or (denote-org--get-file-id-and-heading-id-or-context)
(user-error "The current file does not have a denote identifier")))
(files (denote-directory-files nil :omit-current :text-only))
(fetcher (lambda () (xref-matches-in-files heading-id files))))
(consult-xref fetcher nil)))
(defun my-org-table-align-all ()
"Ajust all table in current buffer."
(interactive)
(save-excursion
@@ -251,18 +278,18 @@ argument)."
(when-let* ((proj (project-current t)))
(consult-ripgrep (project-root proj))))
(defun my-color-picker ()
"Pick a color with preview."
(interactive)
(let* ((colors (defined-colors))
(choice (completing-read
"Color: "
(mapcar (lambda (c)
(propertize
(format "%-20s %s" c "████")
'face `(:foreground ,c)))
colors))))
(string-trim (car (split-string choice)))))
(defun consult-colors-emacs (color)
"Show a list of all supported colors for a particular frame.
You can insert the name (default), or insert or kill the hexadecimal or RGB
value of the selected COLOR."
(interactive
(list (consult--read (list-colors-duplicates (defined-colors))
:prompt "Emacs color: "
:require-match t
:category 'color
:history '(:input consult-colors-history))))
(insert color))
(defun fix-theme-colors ()
"Fix invalid color name in theme files."

View File

@@ -37,7 +37,7 @@
"R" 'rainbow-mode
"b" 'indent-bars-mode
"t" 'consult-theme
"c" 'my-color-picker
"c" 'consult-colors-emacs
"f" 'describe-face
"r" 'rainbow-delimiters-mode
"k" 'keycast-header-line-mode
@@ -69,7 +69,7 @@
"v" 'magit-project-status
"V" 'project-vc-dir
"a" 'my-gptel-agent-project
"i" 'projectile-ibuffer)
"i" 'project-ibuffer)
;; v for version control
(general-def
@@ -91,9 +91,9 @@
;; o for org-mode
(general-def
:prefix "C-c o"
"f" 'consult-notes
"f" 'my-denote-find-file
"g" 'consult-denote-grep
"s" 'consult-org-agenda
"g" 'consult-notes-search-in-all-notes
"C" 'calendar
"c" 'org-capture
"d" 'denote
@@ -232,8 +232,8 @@
"C-," 'crux-duplicate-current-line-or-region
"C-c o l" 'denote-link
"C-c o L" 'denote-org-link-to-heading
"C-c o b" 'denote-backlinks
"C-c o B" 'denote-org-backlinks-for-heading
"C-c o b" 'my-denote-find-backlink-with-location
"C-c o B" 'my-denote-org-find-backlink-for-heading-with-location
"C-c o t" 'my-org-tree-slide-start)
;; org-tree-slide-mode

View File

@@ -11,7 +11,22 @@
(org-mode . my-org-electric-pair-fix)
(org-mode . electric-pair-local-mode)
:init
(setq org-directory
(cond
(*is-windows* "h:/emacs/my-org-note")
(*is-mac* "~/org/my-org-note")
(*is-linux* "~/org/my-org-note")
(*is-android* "~/storage/shared/my-org-note")))
:config
(defvar org-hide-space-keywords
'(("\\cc\\( \\)[*/_=~+]\\cc.*?[*/_=~+]"
(0 (prog1 () (add-text-properties (match-beginning 1) (match-end 1) '(invisible t)))))
("[*/_=~+].*?\\cc[*/_=~+]\\( \\)\\cc"
(0 (prog1 () (add-text-properties (match-beginning 1) (match-end 1) '(invisible t)))))))
(font-lock-add-keywords 'org-mode org-hide-space-keywords 'append)
(if *is-windows*
(add-hook 'org-mode-hook 'font-lock-update))
@@ -33,20 +48,11 @@
;; 设置todo关键字
(setq org-todo-keywords
(quote ((sequence "TODO(t)" "STARTED(S)" "|" "DONE(d!/!)")
(sequence "IDKY(i)" "SOMEDAY(s)" "|" "CANCELLED(c@/!)"))))
(quote ((sequence "TODO(t)" "SOMEDAY(S)" "STARTED(s)" "WAITING(w)" "|" "DONE(d!/!)" "CANCELLED(c@/!)")
(sequence "IDKY(i)" "|" "KNOWN(k)" "CANCELLED(c@/!)"))))
;; agenda相关
(cond
(*is-windows*
(setq org-agenda-files '("h:/emacs/hugo/this-is-my-blog/all-blog.org"
"h:/emacs/my-org-note/20260509T232442==agenda--all-my-todos__org.org")))
(*is-mac*
(setq org-agenda-files '("~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org")))
(*is-linux*
(setq org-agenda-files '("~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org")))
(*is-android*
(setq org-agenda-files '("~/storage/shared/my-org-note/20260509T232442==agenda--all-my-todos__org.org"))))
(setq org-agenda-files `(,(concat org-directory "/20260509T232442==agenda--all-my-todos__org.org")))
(setq org-agenda-span 'day)
(setq org-agenda-skip-function-global
@@ -75,26 +81,28 @@
:hook
(after-init . denote-rename-buffer-mode)
(dired-mode . denote-dired-mode)
:config
(cond
(*is-android*
(setq denote-directory "~/storage/shared/my-org-note/"))
(*is-windows*
(setq denote-directory "H:/emacs/my-org-note/"))
(t
(setq denote-directory "~/org/my-org-note/")))
:init
(setq denote-prompts '(title signature keywords))
(setq denote-title-history nil)
(setq denote-signature-history
'("note" "project" "fun" "wisdom" "article" "data" "metanote" "agenda" "journal" "archive"))
(setq denote-known-keywords
'("emacs"))
(setq denote-title-history nil))
(setq denote-directory org-directory)
(setq denote-org-store-link-to-heading 'context
denote-prompts '(title signature keywords))
(setq denote-title-history nil
denote-signature-history
'("note" "project" "fun" "wisdom" "article" "data" "metanote" "agenda" "journal" "archive")
denote-known-keywords
'("emacs")
denote-title-history nil))
;; denote-org
(use-package denote-org)
;; denote-lint
(use-package denote-lint
:straight '(denote-lint :type git
:host github
:repo "Andsy10/denote-lint")
:config
(setq org-link-elisp-confirm-function nil))
;; denote-journal
(use-package denote-journal
:hook
@@ -108,16 +116,12 @@
;; denote-explore
(use-package denote-explore)
;; consult-notes
(use-package consult-notes
:straight
'(consult-notes :fork (:host github :repo "Andsy10/consult-notes"))
;; consult-denote
(use-package consult-denote
:hook
(after-init . consult-notes-denote-mode)
:config
(setq consult-notes-denote-display-keywords-indicator "_")
(setq consult-notes-denote-display-id-format 'date)
(setq consult-notes-denote-display-signature t))
(after-init . consult-denote-mode)
:init
(setq consult-denote-grep-command 'consult-ripgrep))
;; org-download
(use-package org-download
@@ -149,23 +153,7 @@
(org-agenda-finalize . disable-truncate-lines)
:config
(setq org-agenda-custom-commands
'(("pa" "priority >= A"
((org-ql-block '(and (priority "A") (todo))
((org-ql-block-header "priority = A")))))
("pb" "priority >= B"
((org-ql-block '(and (priority >= "B") (todo))
((org-ql-block-header "priority >= B")
(org-super-agenda-groups
'((:name "priority = A" :priority "A")
(:name "priority = B" :priority "B")))))))
("pc" "priority >= C"
((org-ql-block '(and (priority >= "C") (todo))
((org-ql-block-header "priority >= C")
(org-super-agenda-groups
'((:name "priority = A" :priority "A")
(:name "priority = B" :priority "B")
(:name "priority = C" :priority "C")))))))
("qd" "TODO entries sort by closed time"
'(("qd" "TODO entries sort by closed time"
((org-ql-block '(closed)
((org-ql-block-header "Closed TODOs")
(org-super-agenda-groups
@@ -190,6 +178,7 @@
((org-ql-block-header "all TODOs")
(org-super-agenda-groups
'((:name "started" :todo "STARTED")
(:name "waiting" :todo "WAITING")
(:name "priority = A" :priority "A")
(:name "priority = B" :priority "B")
(:name "priority = C" :priority "C")
@@ -201,39 +190,24 @@
(use-package org-capture
:straight nil
:config
(setq my-org-capture-file (concat org-directory "/20260509T232442==agenda--all-my-todos__org.org"))
(setq org-capture-templates
(cond
((or *is-linux* *is-mac*)
'(("t" "TODO" entry
(file+headline "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* TODO %<%m-%d> %?\n%T"
:empty-lines 1)
("s" "SOMEDAY" entry
(file+headline "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* SOMEDAY %<%m-%d> %?\n%T"
:empty-lines 1)
`(("t" "TODO" entry
(file+headline ,my-org-capture-file "Something to do")
"* TODO %<%m-%d> %?\n%T" :empty-lines 1)
("s" "STARTED" entry
(file+headline ,my-org-capture-file "Something to do")
"* STARTED %<%m-%d> %?\n%T" :empty-lines 1)
("S" "SOMEDAY" entry
(file+headline ,my-org-capture-file "Something to do")
"* SOMEDAY %<%m-%d> %?\n%T" :empty-lines 1)
("i" "IDKY" entry
(file+headline "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* IDKY %<%m-%d> %?\n%T"
:empty-lines 1)))
(*is-android*
'(("t" "TODO" entry
(file+headline "~/storage/shared/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* TODO %<%m-%d> %?\n%T"
:empty-lines 1)
("s" "SOMEDAY" entry
(file+headline "~/storage/shared/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* SOMEDAY %<%m-%d> %?\n%T"
:empty-lines 1)
("i" "IDKY" entry
(file+headline "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* IDKY %<%m-%d> %?\n%T"
:empty-lines 1)))
(t nil))))
(file+headline ,my-org-capture-file "Something to know")
"* IDKY %<%m-%d> %?\n%T" :empty-lines 1))))
;; hugo
(use-package ox-hugo
:config
:init
(with-eval-after-load 'org-capture
(defun org-hugo-new-subtree-post-capture-template ()
"Returns `org-capture' template string for new Hugo post.
@@ -248,25 +222,18 @@ See `org-capture-templates' for more information."
":END:"
"\n\n") ;Place the cursor here finally
"\n")))
(if *is-windows*
(add-to-list 'org-capture-templates
'("h" ;`org-capture' binding + h
`("h" ;`org-capture' binding + h
"Hugo post"
entry
;; It is assumed that below file is present in `org-directory'
;; and that it has a "Blog Ideas" heading. It can even be a
;; symlink pointing to the actual location of all-posts.org!
(file+headline "h:/emacs/hugo/this-is-my-blog/all-blog.org" "Blog Ideas")
(function org-hugo-new-subtree-post-capture-template)))
(add-to-list 'org-capture-templates
'("h" ;`org-capture' binding + h
"Hugo post"
entry
;; It is assumed that below file is present in `org-directory'
;; and that it has a "Blog Ideas" heading. It can even be a
;; symlink pointing to the actual location of all-posts.org!
(file+headline "~/org/hugo/this-is-my-blog/all-blog.org" "Blog Ideas")
(function org-hugo-new-subtree-post-capture-template))))))
(file+headline ,(if *is-windows*
"h:/emacs/hugo/this-is-my-blog/all-blog.org"
"~/org/hugo/this-is-my-blog/all-blog.org")
"Blog Ideas")
(function org-hugo-new-subtree-post-capture-template)))))
;; presentation
(use-package org-tree-slide)

View File

@@ -75,7 +75,10 @@ _a_ : all dwim
(use-package consult-jinx
:straight
(:host github :repo "Andsy10/consult-jinx")))
(consult-jinx
:type git
:host github
:repo "Andsy10/consult-jinx")))
;; eat终端
(unless *is-windows*
@@ -151,9 +154,15 @@ _a_ : all dwim
'((magit-project-status "Magit" ?v)
(eat-project "Eat" ?E)
(project-query-replace-regexp "Query Replace" ?R)
(consult-ripgrep "Ripgrep" ?r))))))
(consult-ripgrep "Ripgrep" ?r)
(consult-project-buffer "Buffers" ?b)
(project-ibuffer "Ibuffer" ?i))))))
(use-package ibuffer-projectile)
(use-package project-ibuffer
:straight
(project-ibuffer :type git
:host github
:repo "Andsy10/project-ibuffer"))
;; emms
(use-package emms

View File

@@ -59,7 +59,7 @@
(:map markdown-mode-map
("C-c C-e" . markdown-do))
:hook
(markdown-mode . toggle-truncate-lines)
(markdown-mode . visual-line-mode)
:init
(setq markdown-command "multimarkdown"
markdown-fontify-code-blocks-natively t))
@@ -67,6 +67,10 @@
(use-package edit-indirect)
;; html
(use-package shr
:config
(setq shr-inhibit-images nil))
(use-package htmlize)
(provide 'init-prog)

View File

@@ -89,6 +89,9 @@
;; 优化换行规则
(setq word-wrap-by-category t)
;; 禁用制表符
(setq-default indent-tabs-mode nil)
;; 修改mac键位
(when *is-mac*
(setq mac-command-modifier 'meta)

View File

@@ -41,7 +41,6 @@
search-ring
regexp-search-ring
extended-command-history)
savehist-ignored-variables '(consult-notes-history)
savehist-autosave-interval 300))
(use-package saveplace

View File

@@ -81,6 +81,8 @@
(setq word-wrap-by-category t)
(setq-default indent-tabs-mode nil)
(setq kill-whole-line t)
(provide 'init-terminal-startup)

View File

@@ -16,12 +16,14 @@
'(solarized-emacs :fork (:host github :repo "Andsy10/solarized-emacs"))
:init
;; 把主题加载延迟到frame创建之后防止daemon模式下宏不能正常展开
(if (daemonp)
(if (and (daemonp) (not *is-android*))
(add-hook 'after-make-frame-functions
(lambda (frame)
(with-selected-frame frame
(load-theme 'my-dark t))))
(load-theme 'my-dark t)))
(if *is-android*
(load-theme 'my-light t)
(load-theme 'my-dark t))))
;; 行号
(use-package display-line-numbers
@@ -48,8 +50,6 @@
(use-package rainbow-delimiters)
;; 很多主题
;; (use-package doom-themes)
;; (use-package color-theme-modern)
(use-package naysayer-theme)
(use-package ef-themes)