feat: add dashboard and enhance completion

- Add startup dashboard with recent files and bookmarks
- Enhance corfu with icons and minibuffer transfer
- Add avy-zap, markdown-mode, consult-dir
- Optimize GC settings and editor config
This commit is contained in:
trogloxene
2026-04-02 14:56:29 +08:00
parent 9ecad315b5
commit c7352d0460
10 changed files with 311 additions and 76 deletions

View File

@@ -8,12 +8,53 @@
;; 安装gcmh用于管理内存回收
(use-package gcmh
:demand t
:init
(setq gcmh-idle-delay 5 ; 空闲 5 秒后 GC
gcmh-high-cons-threshold (* 16 1024 1024)) ; 高阈值 16MB
(setq gcmh-idle-delay 'auto
gcmh-auto-idle-delay-factor 10
gcmh-high-cons-threshold #x4000000)
:config
(gcmh-mode 1))
(use-package emacs
:hook (((prog-mode markdown-mode conf-mode) . enable-trailing-whitespace))
:init
(setq kill-whole-line t ; Kill line including '\n'
line-move-visual nil
track-eol t ; Keep cursor at end of lines. Require line-move-visual is nil.
set-mark-command-repeat-pop t) ; Repeating C-SPC after popping mark pops it again
;; Visualize TAB, (HARD) SPACE, NEWLINE
(setq-default show-trailing-whitespace nil) ; Don't show trailing whitespace by default
(defun enable-trailing-whitespace ()
"Show trailing spaces and delete on saving."
(setq show-trailing-whitespace t)
(add-hook 'before-save-hook #'delete-trailing-whitespace nil t))
;; Prettify the process list
(with-no-warnings
(defun my/list-processes--prettify ()
"Prettify process list."
(when-let* ((entries tabulated-list-entries))
(setq tabulated-list-entries nil)
(dolist (p (process-list))
(when-let* ((val (cadr (assoc p entries)))
(name (aref val 0))
(pid (aref val 1))
(status (aref val 2))
(status (list status
'face
(if (memq status '(stop exit closed failed))
'error
'success)))
(buf-label (aref val 3))
(tty (list (aref val 4) 'face 'font-lock-doc-face))
(thread (list (aref val 5) 'face 'font-lock-doc-face))
(cmd (list (aref val 6) 'face 'completions-annotations)))
(push (list p (vector name pid status buf-label tty thread cmd))
tabulated-list-entries)))))
(advice-add #'list-processes--refresh :after #'my/list-processes--prettify)))
(use-package restart-emacs)
;; 安装multiple-cursors
@@ -49,7 +90,7 @@
;; 安装consult增强搜索和其他菜单
(use-package consult
:config
(defun consult-fd-global ()
"Search for all files use fd"
(interactive)
@@ -65,9 +106,69 @@
(when *is-mac*
(setopt consult-locate-args "mdfind -name")))
;; 安装embark一个菜单用用就明白了
(use-package consult-dir
:bind (("C-x C-d" . consult-dir)
:map minibuffer-local-completion-map
("C-x C-d" . consult-dir)
("C-x C-j" . consult-dir-jump-file)))
;; embark
(use-package embark
:config (setq prefix-help-command 'embark-prefix-help-command))
:config (setq prefix-help-command 'embark-prefix-help-command)
:init
(defun my/embark-preview ()
"Previews candidate in vertico buffer, unless it's a consult command."
(interactive)
(unless (bound-and-true-p consult--preview-function)
(save-selected-window
(let ((embark-quit-after-action nil))
(embark-dwim)))))
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none))))
(with-no-warnings
(with-eval-after-load 'which-key
(defun embark-which-key-indicator ()
"An embark indicator that displays keymaps using which-key.
The which-key help message will show the type and value of the
current target followed by an ellipsis if there are further
targets."
(lambda (&optional keymap targets prefix)
(if (null keymap)
(which-key--hide-popup-ignore-command)
(which-key--show-keymap
(if (eq (plist-get (car targets) :type) 'embark-become)
"Become"
(format "Act on %s '%s'%s"
(plist-get (car targets) :type)
(embark--truncate-target (plist-get (car targets) :target))
(if (cdr targets) "" "")))
(if prefix
(pcase (lookup-key keymap prefix 'accept-default)
((and (pred keymapp) km) km)
(_ (key-binding prefix 'accept-default)))
keymap)
nil nil t (lambda (binding)
(not (string-suffix-p "-argument" (cdr binding))))))))
(setq embark-indicators
'(embark-which-key-indicator
embark-highlight-indicator
embark-isearch-highlight-indicator))
(defun embark-hide-which-key-indicator (fn &rest args)
"Hide the which-key indicator immediately when using the completing-read prompter."
(which-key--hide-popup-ignore-command)
(let ((embark-indicators
(remq #'embark-which-key-indicator embark-indicators)))
(apply fn args)))
(advice-add #'embark-completing-read-prompter
:around #'embark-hide-which-key-indicator))))
;; 安装embark-consult和wgrep
(use-package embark-consult)
@@ -83,6 +184,9 @@
'embark-collect-mode-hook
#'consult-preview-at-point-mode))))
;; nerd-icon
(use-package nerd-icons)
;; 启用savehist保存命令顺序
(use-package savehist
:hook (after-init . savehist-mode)
@@ -116,16 +220,36 @@
;; ibuffer-projectile
(use-package ibuffer-projectile
:init (add-hook 'ibuffer-hook
(lambda ()
(ibuffer-projectile-set-filter-groups)
(unless (eq ibuffer-sorting-mode 'alphabetic)
(ibuffer-do-sort-by-alphabetic)))))
:config (add-hook 'ibuffer-hook
(lambda ()
(ibuffer-projectile-set-filter-groups)
(unless (eq ibuffer-sorting-mode 'alphabetic)
(ibuffer-do-sort-by-alphabetic))))
(when (centaur-treesit-available-p)
(defun treesit-mark-bigger-node ()
"Use tree-sitter to mark regions."
(let* ((root (treesit-buffer-root-node))
(node (treesit-node-descendant-for-range root (region-beginning) (region-end)))
(node-start (treesit-node-start node))
(node-end (treesit-node-end node)))
;; Node fits the region exactly. Try its parent node instead.
(when (and (= (region-beginning) node-start) (= (region-end) node-end))
(when-let* ((node (treesit-node-parent node)))
(setq node-start (treesit-node-start node)
node-end (treesit-node-end node))))
(set-mark node-end)
(goto-char node-start)))
(add-to-list 'er/try-expand-list 'treesit-mark-bigger-node)))
;; avy中文支持
(use-package ace-pinyin
:init (ace-pinyin-global-mode +1))
;; avy-zap
(use-package avy-zap
:bind (("M-z" . avy-zap-to-char-dwim)
("M-Z" . avy-zap-up-to-char-dwim)))
;; jinx拼写检查
(unless *is-windows*
(use-package jinx
@@ -153,22 +277,29 @@
;; consult-flycheck
(use-package consult-flycheck)
;; markdown
(use-package markdown-mode
:mode ("README\\.md\\'" . gfm-mode)
:init (setq markdown-command "multimarkdown")
:bind (:map markdown-mode-map
("C-c C-e" . markdown-do)))
;; 安装emms
(use-package emms
:init
;; 设置音乐文件默认目录
(when *is-windows*
(setq emms-source-file-default-directory "F:/luping26-1-11/"))
:config
;; --- 基础设置 ---
(require 'emms-setup)
(emms-all) ; 加载所有稳定功能
;; 使用简单模式的 mpv 播放器
;; 移除默认的 emms-player-mpv
(require 'emms-player-simple)
;; 定义简单的 mpv 播放器
(define-emms-simple-player mpv-simple '(file url streamlist playlist)
(concat "\\.\\("
@@ -186,41 +317,41 @@
"--keep-open=yes"
"--fs=no"
"--quiet")
;; 设置播放器列表
(setq emms-player-list '(emms-player-mpv-simple
emms-player-vlc
emms-player-mplayer))
(setq emms-playlist-default-playlist-name "*EMMS Playlist*")
(setq emms-playlist-buffer-name "*EMMS Playlist*")
;; 使用更快的文件查找方法(windows上需要使用internal)
;; (setq emms-source-file-directory-tree-function 'emms-source-file-directory-tree-find)
(setq emms-source-file-directory-tree-function 'emms-source-file-directory-tree-internal)
;; 使用原生 Elisp 元数据读取器
(setq emms-info-functions '(emms-info-native))
;; 异步读取元数据
(setq emms-info-asynchronously t)
;; 使用更详细的曲目描述
(setq emms-track-description-function #'emms-info-track-description)
;; 模式行设置
(require 'emms-mode-line)
(emms-mode-line-mode 1)
(emms-mode-line-blank) ; 初始为空
;; 自定义模式行格式
(setq emms-mode-line-format " [%s] ")
(setq emms-mode-line-length-limit 60)
;; 播放时间显示
(require 'emms-playing-time)
(emms-playing-time-mode 1)
;; 歌词设置
(require 'emms-lyrics)
(setq emms-lyrics-display-on-modeline t) ; 在模式行显示歌词
@@ -231,60 +362,60 @@
(setq emms-lyrics-dir "~/Music/lyrics") ; 歌词文件目录
(setq emms-lyrics-display-format " %s ") ; 歌词显示格式
(emms-lyrics 1) ; 启用歌词显示
;; 浏览器设置
(require 'emms-browser)
(setq emms-browser-default-browse-type 'artist)
(setq emms-browser-covers nil) ; 禁用封面
;; 浏览器显示格式
(setq emms-browser-info-title-format "%i%n")
(setq emms-browser-playlist-info-title-format "%i%n")
;; 添加浏览器快捷键
(define-key emms-browser-mode-map (kbd "SPC") 'emms-browser-add-tracks-and-play)
;; 缓存设置
(require 'emms-cache)
(emms-cache 1) ; 启用缓存
;; 历史记录
(require 'emms-history)
(add-hook 'emms-player-started-hook #'emms-last-played-update-current)
;; 音量控制
(require 'emms-volume)
;; 在播放列表中使用 +/- 控制音量
(define-key emms-playlist-mode-map (kbd "+") #'emms-volume-raise)
(define-key emms-playlist-mode-map (kbd "-") #'emms-volume-lower)
;; 添加(playlist中的)快捷键
(define-key emms-playlist-mode-map (kbd "SPC") 'emms-pause)
(define-key emms-playlist-mode-map (kbd "N") 'emms-next)
(define-key emms-playlist-mode-map (kbd "P") 'emms-previous)
(define-key emms-playlist-mode-map (kbd "R") 'emms-random)
(define-key emms-playlist-mode-map (kbd "/") 'emms-playlist-limit)
;; 启用标记功能
(require 'emms-mark)
;; 启用播放列表排序
(require 'emms-playlist-sort)
(define-key emms-playlist-mode-map (kbd "S s") 'emms-playlist-sort-map)
;; 启用播放列表限制/过滤
(require 'emms-playlist-limit)
;; 启用标签编辑器
(require 'emms-tag-editor)
;; 启用评分系统
(require 'emms-score)
(emms-score 1)
;; 启动后自动恢复播放列表
;; (add-hook 'after-init-hook 'emms-history-load)
;; 显示加载完成消息
(message "EMMS loaded")