- 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
447 lines
14 KiB
EmacsLisp
447 lines
14 KiB
EmacsLisp
;;; init-package.el --- major packages -*- lexical-binding: t -*-
|
||
|
||
;;; Commentary:
|
||
|
||
;;; Code:
|
||
|
||
(setopt use-package-enable-imenu-support t)
|
||
|
||
;; 安装gcmh用于管理内存回收
|
||
(use-package gcmh
|
||
:demand t
|
||
:init
|
||
(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
|
||
(use-package multiple-cursors)
|
||
|
||
;; 安装crux,增强快捷键,快捷键配置在init-kbd.el中
|
||
(use-package crux)
|
||
|
||
;; 安装hungry-delete
|
||
(use-package hungry-delete)
|
||
|
||
;; 安装drag-stuff,拖动字符
|
||
(use-package drag-stuff)
|
||
|
||
;; 安装which-key,快捷键提示
|
||
(use-package which-key
|
||
:defer 0
|
||
:config
|
||
(which-key-mode))
|
||
|
||
;; 安装vertico
|
||
(use-package vertico
|
||
:init (vertico-mode t))
|
||
|
||
;; 安装orderless,用于模糊搜索
|
||
(use-package orderless
|
||
:custom (completion-styles '(orderless basic)))
|
||
|
||
;; 安装marginalia,用于命令注释
|
||
(use-package marginalia
|
||
:init (marginalia-mode))
|
||
|
||
;; 安装consult,增强搜索和其他菜单
|
||
(use-package consult
|
||
:config
|
||
|
||
(defun consult-fd-global ()
|
||
"Search for all files use fd"
|
||
(interactive)
|
||
(let ((consult-fd-args "fd -H -I -i -c never --full-path")
|
||
(default-directory "~/"))
|
||
(consult-fd)))
|
||
|
||
(if *is-windows*
|
||
(progn
|
||
(setq consult-locate-args (encode-coding-string "es.exe -i -p -r" 'gbk))
|
||
(add-to-list 'process-coding-system-alist '("es" gbk . gbk))))
|
||
|
||
(when *is-mac*
|
||
(setopt consult-locate-args "mdfind -name")))
|
||
|
||
(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)
|
||
: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)
|
||
(use-package wgrep)
|
||
|
||
(with-eval-after-load
|
||
'consult
|
||
'(with-eval-after-load
|
||
'embark
|
||
'(progn
|
||
(require 'embark-consult)
|
||
(add-hook
|
||
'embark-collect-mode-hook
|
||
#'consult-preview-at-point-mode))))
|
||
|
||
;; nerd-icon
|
||
(use-package nerd-icons)
|
||
|
||
;; 启用savehist,保存命令顺序
|
||
(use-package savehist
|
||
:hook (after-init . savehist-mode)
|
||
:init (setq enable-recursive-minibuffers t
|
||
history-length 50
|
||
savehist-additional-variables '(mark-ring
|
||
global-mark-ring
|
||
search-ring
|
||
regexp-search-ring
|
||
extended-command-history)
|
||
savehist-autosave-interval 300))
|
||
|
||
;; saveplace,保存光标位置
|
||
(use-package saveplace
|
||
:hook (after-init . save-place-mode))
|
||
|
||
;; undo增强
|
||
(use-package undo-fu)
|
||
|
||
(use-package undo-fu-session
|
||
:init (undo-fu-session-global-mode))
|
||
|
||
;; vundop,撤回树
|
||
(use-package vundo
|
||
:init (setq undo-limit 800000
|
||
undo-strong-limit 1200000
|
||
undo-outer-limit 12000000))
|
||
|
||
;; expand-region,快速展开选中
|
||
(use-package expand-region)
|
||
|
||
;; ibuffer-projectile
|
||
(use-package ibuffer-projectile
|
||
: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
|
||
:hook (org-mode-hook . jinx-mode)
|
||
:bind ([remap ispell-word] . jinx-correct)
|
||
:config (setq jinx-languages "en_US")
|
||
(add-to-list 'jinx-exclude-regexps '(t "\\cc"))
|
||
(with-eval-after-load 'jinx
|
||
(dolist (range '((#x4E00 . #x9FFF)
|
||
(#x3400 . #x4DBF)
|
||
(#x3000 . #x303F)
|
||
(#xFF00 . #xFFEF)
|
||
(#x20000 . #x2A6DF)))
|
||
(let ((start (car range))
|
||
(end (cdr range)))
|
||
(dotimes (i (- end start))
|
||
(modify-syntax-entry (+ start i) "_" jinx--syntax-table)))))
|
||
(require 'init-jinx)))
|
||
|
||
;; flycheck
|
||
(use-package flycheck
|
||
:init
|
||
(add-hook 'after-init-hook #'global-flycheck-mode))
|
||
|
||
;; 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 "\\.\\("
|
||
(mapconcat 'identity
|
||
'("mp3" "mp4" "avi" "mkv" "flv" "mov" "wmv" "webm"
|
||
"ogg" "ogv" "oga" "ogx"
|
||
"flac" "wav" "aac" "m4a" "wma"
|
||
"mpg" "mpeg" "mpe" "mpv"
|
||
"3gp" "3g2"
|
||
"m3u" "pls")
|
||
"\\|")
|
||
"\\)\\'\\|http[s]?://")
|
||
"mpv"
|
||
"--force-window=immediate"
|
||
"--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) ; 在模式行显示歌词
|
||
(setq emms-lyrics-display-on-minibuffer nil) ; 不在 minibuffer 显示
|
||
(setq emms-lyrics-display-buffer nil) ; 不使用专用缓冲区
|
||
(setq emms-lyrics-scroll-p t) ; 启用歌词滚动
|
||
(setq emms-lyrics-scroll-timer-interval 0.4) ; 滚动间隔
|
||
(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")
|
||
|
||
;; 关闭自动连播
|
||
(add-hook 'emms-playlist-mode-hook
|
||
(lambda ()
|
||
(setq emms-single-track t))))
|
||
|
||
;; 提供 EMMS 快捷启动函数
|
||
(defun my-emms-start-browser ()
|
||
"Open emms browser."
|
||
(interactive)
|
||
(emms-browser)
|
||
(message "EMMS browser loaded"))
|
||
|
||
(defun my-emms-play-directory (dir)
|
||
"Play all files in directory.."
|
||
(interactive "Dchoose a directory: ")
|
||
(emms-play-directory-tree dir)
|
||
(message "playing: %s" dir))
|
||
|
||
;; vterm
|
||
(unless *is-windows*
|
||
(use-package vterm))
|
||
|
||
(provide 'init-package)
|
||
|
||
;;; init-package.el ends here
|