Files
.emacs.d/lisp/init-package.el
andsy10 ccd5c085f8 refactor(config): Clean up and reorganize Emacs configuration
Remove unused packages (EMMS, jinx, god-mode), simplify terminal
setup with ido instead of vertico/orderless, and reorganize
keybindings. Add new packages (debase, discomfort, git-timemachine,
edit-indirect) and improve EXWM, dired, and theme
configurations. Move restart-fcitx5 to kbd-func and update Linux
PATH for Guix.
2026-05-30 23:02:29 +08:00

442 lines
13 KiB
EmacsLisp
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;;; init-package.el --- major packages -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:
(setopt use-package-enable-imenu-support t)
;; restart-emacs
(use-package restart-emacs)
;; async
(unless *is-android*
(use-package async
:init
(dired-async-mode)
(async-bytecomp-package-mode 1)
(setq async-bytecomp-allowed-packages '(all))))
;; multiple-cursors
(use-package multiple-cursors
:config
(setq mc/insert-numbers-default 1))
;; crux实用函数
(use-package crux)
;; hungry-delete快速删除
(use-package hungry-delete)
;; drag-stuff拖动字符
(use-package drag-stuff)
;; mwim更聪明的beginning/end of line
(use-package mwim
:bind (([remap move-beginning-of-line] . mwim-beginning)
([remap move-end-of-line] . mwim-end)
([remap org-beginning-of-line] . mwim-beginning)
([remap org-end-of-line] . mwim-end)))
;; which-key快捷键提示
(use-package which-key
:delight
:defer 0
:config
(which-key-mode))
;; ripgrep
(use-package rg)
;; verticominibuffer补全
(use-package vertico
:init
(vertico-mode))
;; orderless模糊搜索
(use-package orderless
:custom
(completion-styles '(orderless basic)))
;; marginalia命令注释
(use-package marginalia
:init
(marginalia-mode))
;; consult搜索与导航
(use-package consult
:config
;; everything
(when *is-windows*
(setq consult-locate-args (encode-coding-string "es.exe -i -p -r" 'gbk))
(setq consult-ripgrep-args (encode-coding-string
"rg --null --line-buffered --color=never --max-columns=1000 --path-separator / --smart-case --no-heading --line-number"
'gbk))
(add-to-list 'process-coding-system-alist '("es" gbk . gbk)))
;; mdfind
(when *is-mac*
(setq consult-locate-args "mdfind -name"))
;; plocate
(when *is-linux*
(setq consult-locate-args "plocate --basename --ignore-case")))
;; 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)))))
(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
(use-package embark-consult
:config
(add-hook
'embark-collect-mode-hook
#'consult-preview-at-point-mode))
;; wgrepwritable grep
(use-package wgrep)
;; anzu显示isearch匹配数字
(use-package anzu
:delight
:init
(global-anzu-mode))
;; 启用savehist保存命令顺序
(use-package savehist
: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-ignored-variables '(consult-notes-history)
savehist-autosave-interval 300)
(savehist-mode))
;; 启用saveplace保存光标位置
(use-package saveplace
:init
(save-place-mode))
;; 撤回增强和跨会话历史
(use-package undo-fu)
(use-package undo-fu-session
:init
(undo-fu-session-global-mode))
;; vundo撤回树
(use-package vundo
:init
(setq undo-limit 800000
undo-strong-limit 1200000
undo-outer-limit 12000000))
;; expand-region快速展开选中
(use-package expand-region
:commands
(er/mark-symbol er/mark-word)
:config
(setq expand-region-smart-cursor t))
;; project
(use-package project
:bind
([remap project-vc-dir] . magit-project-status)
:config
(setq project-switch-commands (assq-delete-all 'project-vc-dir project-switch-commands))
(add-to-list 'project-switch-commands '(magit-project-status "Magit" ?v))
(add-to-list 'project-switch-commands '(eat-project "Eat" ?E))
(add-to-list 'project-switch-commands '(consult-ripgrep-project "Ripgrep" ?r)))
;; ibuffer
(use-package ibuffer
:config
(setq ibuffer-saved-filter-groups
'(("Main"
("App" (mode . exwm-mode))
("Scratch" (or
(name . "^*scratch")))
("Shell" (or
(mode . eshell-mode)
(mode . eat-mode)
(mode . vterm-mode)))
("Scripts" (or
(mode . shell-script-mode)
(mode . shell-mode)
(mode . sh-mode)
(mode . lua-mode)
(mode . bat-mode)))
("Config" (or
(mode . conf-mode)
(mode . conf-desktop-mode)
(mode . conf-toml-mode)))
("Elisp" (mode . emacs-lisp-mode))
("Scheme" (or
(mode . scheme-mode)))
("Geiser" (or
(name . "^Geiser")
(mode . geiser-repl-mode)
(mode . geiser-debug-mode)
(mode . geiser-messages-mode)
(mode . geiser-debug-mode)
(mode . geiser-doc-mode)
(mode . geiser-autodoc-mode)))
("gptel" (or
(name . "^\\*gptel")))
("Common-lisp" (or
(mode . common-lisp-mode)
(mode . lisp-mode)))
("Sly" (or
(mode . lisp-data-mode)
(mode . sly-db-mode)
(mode . sly-mrepl-mode)
(name . "\\*sly-compilation\\*")
(name . "^\\*img-cache\\*")))
("Text" (or
(mode . org-mode)
(mode . markdown-mode)
(name . "^\\*\\[D\\] FILE backlinks for")))
("Emacs" (or
(name . "^\\*Help\\*$")
(name . "^\\*Custom.*")
(name . "^\\*EMMS Playlist\\*")
(name . "^\\*Messages\\*$")
(name . "*Chinese-word-segmentation*")
(name . "^*Buffer List*")
(name . "\\*discomfort\\*")))
("Info" (or
(name . "^\\*info")))
("Magit" (or
(mode . magit-blame-mode)
(mode . magit-cherry-mode)
(mode . magit-diff-mode)
(mode . magit-log-mode)
(mode . magit-process-mode)
(mode . magit-status-mode)
(mode . magit-revision-mode)))
("Directories" (or
(mode . dired-mode)
(name . "^*dirvish")))
("Diff" (name . "^*Diff")))))
(add-hook 'ibuffer-hook
(lambda () (ibuffer-switch-to-saved-filter-groups "Main")
(unless (eq ibuffer-sorting-mode 'alphabetic)
(ibuffer-do-sort-by-alphabetic))))
(setq ibuffer-show-empty-filter-groups nil)
(setq ibuffer-use-other-window t)
(setq ibuffer-default-sorting-mode 'filename))
;; avy中文支持
(use-package ace-pinyin
:delight
: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
:delight
(jinx-mode " Jinx" 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))))))
(use-package consult-jinx
:after jinx
:demand t
:straight nil))
;; eat终端
(use-package eat
:straight
(eat :type git
:host codeberg
:repo "akib/emacs-eat"
:files ("*.el"
("term" "term/*.el")
"*.texi"
"*.ti"
("terminfo/e" "terminfo/e/*")
("terminfo/65" "terminfo/65/*")
("integration" "integration/*")
(:exclude ".dir-locals.el" "*-tests.el")))
:hook
((eshell-load . eat-eshell-mode)
(eshell-load . eat-eshell-visual-command-mode))
:config
(setq eat-term-terminfo-directory eat--terminfo-path))
;; general键位绑定
(use-package general)
;; hydra
(use-package hydra
:defines
(consult-imenu-config)
:init
(with-eval-after-load 'consult-imenu
(setq consult-imenu-config
'((emacs-lisp-mode :toplevel "Functions"
:types ((?f "Functions" font-lock-function-name-face)
(?h "Hydras" font-lock-constant-face)
(?m "Macros" font-lock-function-name-face)
(?p "Packages" font-lock-constant-face)
(?t "Types" font-lock-type-face)
(?v "Variables" font-lock-variable-name-face)))))))
;; god-mode模态编辑
(use-package god-mode
:init
(if *is-android* (god-mode-all))
:config
(unless *is-android* (which-key-enable-god-mode-support))
(setq god-mode-enable-function-key-translation nil
god-exempt-major-modes
(delete-dups (append '(diff-mode exwm-mode) god-exempt-major-modes))
god-mode-lighter-string "THANK-GOD-MODE")
(defun my-sync-god-mode-lighter-face (&rest _)
(set-face-attribute 'god-mode-lighter nil
:inherit 'isearch-fail
:background (face-attribute 'mode-line :background nil t)
:weight 'bold))
(my-sync-god-mode-lighter-face)
(add-hook 'enable-theme-functions #'my-sync-god-mode-lighter-face)
(defun my-sync-line-numbers-with-god-mode ()
(let ((desired (if (bound-and-true-p god-local-mode)
'relative
t)))
(unless (or (eq display-line-numbers desired) (bound-and-true-p olivetti-mode))
(setq display-line-numbers desired))))
(add-hook 'post-command-hook #'my-sync-line-numbers-with-god-mode))
;; keycast按键广播
(use-package keycast)
;; perspective工作区管理
(use-package perspective
:bind
("C-x M-b" . persp-list-buffers)
:custom
(persp-mode-prefix-key (kbd "C-c p"))
:init
(persp-mode)
:config
(setq persp-switch-to-buffer-behavior 'switch)
(with-eval-after-load 'consult
(consult-customize consult-source-buffer :hidden t :default nil)
(add-to-list 'consult-buffer-sources persp-consult-source))
(setq switch-to-prev-buffer-skip
(lambda (win buff bury-or-kill)
(not (persp-is-current-buffer buff))))
(setq persp-initial-frame-name "main"))
;; magit
(use-package magit
:config
(setq magit-bind-magit-project-status nil))
;; git-timemachine
(use-package git-timemachine)
;; ediff
(use-package ediff
:config
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
(setq ediff-split-window-function 'split-window-horizontally))
;; emms
(use-package emms
:commands
(emms-playlist-mode-switch-buffer)
:config
(emms-all)
(setq emms-player-list '(emms-player-mpv)
emms-info-functions '(emms-info-native))
(emms-history-load))
(provide 'init-package)
;;; init-package.el ends here