diff --git a/early-init.el b/early-init.el index cef639f..d35ccdd 100644 --- a/early-init.el +++ b/early-init.el @@ -6,14 +6,13 @@ (setq package-enable-at-startup nil) -(setq inhibit-startup-screen t) ; 禁用开始菜单 +(setq inhibit-startup-screen t) (when (fboundp 'tool-bar-mode) - (tool-bar-mode -1) ; 禁用工具栏 - (scroll-bar-mode -1)) ; 禁用滚动条 -(menu-bar-mode -1) ; 禁用菜单栏 -(setq display-line-numbers-type '2) -(setq display-line-numbers-grow-only t) ; 行号栏只增不减 -(setq display-line-numbers-width-start 4) ; 预设4位宽度 + (tool-bar-mode -1) + (scroll-bar-mode -1)) +(menu-bar-mode -1) + +(prefer-coding-system 'utf-8) (setq frame-background-mode 'dark) diff --git a/init.el b/init.el index 28c7021..104ae04 100644 --- a/init.el +++ b/init.el @@ -18,6 +18,8 @@ (load "init-proxy" t) (require 'init-startup) (require 'init-elpa) + (require 'init-base) + (require 'init-edit) (require 'init-package) (require 'init-org) (require 'init-prog) diff --git a/lisp/init-base.el b/lisp/init-base.el new file mode 100644 index 0000000..3ff9079 --- /dev/null +++ b/lisp/init-base.el @@ -0,0 +1,212 @@ +;;; init-base.el --- base config -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; general,键位绑定 +(use-package general) + +;; delight,修改mode-line中的模式名 +(use-package delight + :config + (delight + `((eldoc-mode nil eldoc) + (org-indent-mode nil org-indent) + (desktop-environment-mode nil desktop-environment) + (hs-minor-mode nil hideshow) + (rainbow-delimiters-mode ,(propertize " Rdelimiters" 'face 'rainbow-delimiters-depth-1-face) rainbow-delimiters)))) + +;; gcmh,垃圾回收 +(use-package gcmh + :delight + :init + (setq gcmh-idle-delay 'auto + gcmh-auto-idle-delay-factor 10 + gcmh-high-cons-threshold #x4000000) + (gcmh-mode)) + +;; benchmark-init +(use-package benchmark-init + :init + (benchmark-init/activate) + :hook + (after-init . benchmark-init/deactivate)) + +;; server-mode +(use-package server + :hook + (emacs-startup . (lambda () + (unless server-mode + (server-mode 1))))) + +;; recentf,最近打开的文件 +(use-package recentf + :if + (or (display-graphic-p) *is-android*) + :hook + (after-init . recentf-mode) + :init + (setq recentf-max-saved-items 30) + :config + (if *is-android* + (add-to-list 'recentf-exclude "~/storage/shared/my-org-note/journal/.*\\.org\\'") + (add-to-list 'recentf-exclude "~/org/my-org-note/journal/.*\\.org\\'") + (add-to-list 'recentf-exclude "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org\\.org"))) + +;; 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-ignored-variables '(consult-notes-history) + savehist-autosave-interval 300)) + +;; saveplace,保存光标位置 +(use-package saveplace + :hook + (after-init . save-place-mode)) + +;; restart-emacs +(use-package restart-emacs) + +;; async +(use-package async + :if + (not *is-android*) + :hook + (after-init . dired-async-mode) + (after-init . async-bytecomp-package-mode) + :init + (setq async-bytecomp-allowed-packages '(all))) + +;; autorevert buffer +(use-package autorevert + :delight + :hook + (after-init . global-auto-revert-mode)) + +;; which-key,快捷键提示 +(use-package which-key + :delight + :hook + (after-init . which-key-mode)) + +;; winner-mode,保存窗口布局历史 +(use-package winner + :hook + (after-init . winner-mode)) + +;; 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) + (mode . conf-xdefaults-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"))) + ("Help" (or + (mode . help-mode) + (mode . helpful-mode))) + ("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"))) + ("Grep" (or + (mode . grep-mode) + (mode . rg-mode) + (mode . xref--xref-buffer-mode) + (mode . xref-edit-mode))) + ("Diff" (name . "^*Diff")) + ("Emacs" (or + (name . "^\\*Help\\*$") + (name . "^\\*Custom.*") + (name . "^\\*EMMS Playlist\\*") + (name . "^\\*Messages\\*$") + (name . "*Chinese-word-segmentation*") + (name . "^*Buffer List*") + (name . "\\*discomfort\\*") + (mode . calendar-mode) + (mode . calc-mode) + (mode . calc-trail-mode) + (mode . grep-mode) + (mode . occur-mode)))))) + + (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 + ibuffer-use-other-window t + ibuffer-default-sorting-mode 'filename)) + +(use-package simple + :straight nil + :hook + (after-init . size-indication-mode) + (after-init . column-number-mode) + :config + (setq kill-whole-line t ;kill-line删除换行符 + set-mark-command-repeat-pop t)) ;更方便地pop mark + +(provide 'init-base) + +;;; init-base.el ends here diff --git a/lisp/init-completion.el b/lisp/init-completion.el index d56c0ba..9cfc42c 100644 --- a/lisp/init-completion.el +++ b/lisp/init-completion.el @@ -4,12 +4,118 @@ ;;; Code: +;; vertico,minibuffer补全 +(use-package vertico + :hook + (after-init . vertico-mode)) + +;; orderless,模糊搜索 +(use-package orderless + :custom + (completion-styles '(orderless basic))) + +;; marginalia,命令注释 +(use-package marginalia + :hook + (after-init . marginalia-mode)) + +;; consult,搜索与导航 +(use-package consult + :config + ;; set locate arguments + (cond + (*is-windows* + (setq consult-locate-args (encode-coding-string "es.exe -i -p -r" 'gbk) + 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))) + (*is-mac* + (setq consult-locate-args "mdfind -name")) + (*is-linux* + (setq consult-locate-args "plocate --basename --ignore-case"))) + + ;; set some buffer filter + (setq consult-buffer-filter + (cl-union consult-buffer-filter + '("^\\*dirvish" + "^PREVIEW" + "^\\*helpful" + "^\\*Help" + "Diff" + "straight" + "\\*Messages\\*") + :test 'equal))) + +;; embark,快捷指令 +(use-package embark + :commands + embark-prefix-help-command + :init + (setq prefix-help-command 'embark-prefix-help-command) + :config + (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)) + ;; eglot (use-package eglot - :hook - ((python-mode . eglot-ensure) - ;; (scheme-mode . eglot-ensure) - ) :config (setq eglot-send-changes-idle-time 0.25) (add-to-list 'eglot-server-programs @@ -27,8 +133,6 @@ (use-package corfu :autoload (corfu-quit consult-completion-in-region) - :functions - (persistent-scratch-save) :custom (corfu-auto t) (corfu-auto-prefix 2) @@ -43,14 +147,13 @@ gud-mode vterm-mode) t)) - :init - (global-corfu-mode) - (corfu-popupinfo-mode) - (corfu-history-mode) + :hook + (after-init . global-corfu-mode) + (after-init . corfu-popupinfo-mode) + (after-init . corfu-history-mode) :config ;;Quit completion before saving (add-hook 'before-save-hook #'corfu-quit) - (advice-add #'persistent-scratch-save :before #'corfu-quit) :bind (:map corfu-map ("RET" . nil))) @@ -58,8 +161,8 @@ (use-package corfu-terminal :if (not (and (display-graphic-p) (>= emacs-major-version 31))) - :init - (corfu-terminal-mode)) + :hook + (after-init . corfu-terminal-mode)) ;; 在eshell中使用tab打开补全 (add-hook 'eshell-mode-hook diff --git a/lisp/init-const.el b/lisp/init-const.el index a534ff2..a850fd1 100644 --- a/lisp/init-const.el +++ b/lisp/init-const.el @@ -10,34 +10,6 @@ (defconst *is-windows* (or (eq system-type 'ms-dos) (eq system-type 'windows-nt))) (defconst *is-android* (if (getenv "TERMUX_VERSION") t nil)) -(if *is-windows* - (progn - ;; 设置默认编码环境 - (set-language-environment "UTF-8") - (prefer-coding-system 'utf-8) - (set-default-coding-systems 'utf-8) - (set-terminal-coding-system 'utf-8) - (set-keyboard-coding-system 'utf-8) - (setq default-buffer-file-coding-system 'utf-8) - - ;; 设置进程通信编码 - (setq default-process-coding-system '(utf-8 . utf-8)) - - ;; Windows 文件名 Unicode 支持 - (setq w32-unicode-filenames t) - (setq w32-system-coding-system 'utf-8) - - ;; 为特定程序设置编码 - (add-to-list 'process-coding-system-alist '("rg" utf-8 . gbk)) - (add-to-list 'process-coding-system-alist '("ripgrep" utf-8 . gbk))) - (progn - (add-to-list 'process-coding-system-alist '("rg" utf-8 . utf-8)) - (add-to-list 'process-coding-system-alist '("ripgrep" utf-8 . utf-8)))) -(add-to-list 'process-coding-system-alist '("grep" utf-8 . utf-8)) -(add-to-list 'process-coding-system-alist '("find" utf-8 . utf-8)) -(add-to-list 'process-coding-system-alist '("fd" utf-8 . utf-8)) -(add-to-list 'process-coding-system-alist '("fdfind" utf-8 . utf-8)) - (provide 'init-const) ;;; init-const.el ends here diff --git a/lisp/init-dired.el b/lisp/init-dired.el index 51317f1..f7950f8 100644 --- a/lisp/init-dired.el +++ b/lisp/init-dired.el @@ -116,6 +116,20 @@ trashed-sort-key '("Date deleted" . t) trashed-date-format "%Y-%m-%d %H:%M:%S")) +;; discomfort,挂载硬盘 +(use-package debase + :straight + (debase :type git + :host codeberg + :repo "emacs-weirdware/debase")) + +(use-package discomfort + :commands discomfort + :straight + (discomfort :type git + :host codeberg + :repo "emacs-weirdware/discomfort")) + (provide 'init-dired) ;;; init-dired.el ends here diff --git a/lisp/init-edit.el b/lisp/init-edit.el new file mode 100644 index 0000000..59f74ce --- /dev/null +++ b/lisp/init-edit.el @@ -0,0 +1,100 @@ +;;; init-edit.el --- edit and navigate -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; delete select +(use-package delsel + :hook + (after-init . delete-selection-mode)) + +;; electric-pair,补全括号 +(use-package elec-pair + :config + (setq electric-pair-inhibit-predicate 'electric-pair-conservative-inhibit + electric-pair-pairs (append '((?\~ . ?\~) (?\= . ?\=)) electric-pair-pairs))) + +;; 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) + +;; undo-fu,撤回增强和跨会话历史 +(use-package undo-fu + :config + (setq undo-in-region t + undo-fu-allow-undo-in-region t)) + +(use-package undo-fu-session + :hook + (after-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)) + +;; avy中文支持 +(use-package ace-pinyin + :delight + :hook + (after-init . ace-pinyin-global-mode)) + +;; avy-zap +(use-package avy-zap + :bind + (("M-z" . avy-zap-to-char-dwim) + ("M-Z" . avy-zap-up-to-char-dwim))) + +;; god-mode,模态编辑 +(use-package god-mode + :init + (if *is-android* (add-hook 'after-init-hook '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 + (cl-union '(diff-mode exwm-mode) god-exempt-major-modes :test 'equal) + 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)) + +(provide 'init-edit) + +;;; init-edit.el ends here diff --git a/lisp/init-elpa.el b/lisp/init-elpa.el index a117e07..dbf0652 100644 --- a/lisp/init-elpa.el +++ b/lisp/init-elpa.el @@ -38,32 +38,8 @@ straight-use-package-version t straight-use-package-by-default t) -;; delight -(use-package delight - :init - (delight `((eldoc-mode nil eldoc) - (org-indent-mode nil org-indent) - (desktop-environment-mode nil desktop-environment) - (hs-minor-mode nil hideshow) - (rainbow-delimiters-mode ,(propertize " Rdelimiters" 'face 'rainbow-delimiters-depth-1-face) rainbow-delimiters)))) - -;; gcmh,管理垃圾回收 -(use-package gcmh - :delight - :demand t - :init - (setq gcmh-idle-delay 'auto - gcmh-auto-idle-delay-factor 10 - gcmh-high-cons-threshold #x4000000) - :config - (gcmh-mode 1)) - -;; benchmark-init -(use-package benchmark-init - :init - (benchmark-init/activate) - :hook - (after-init . benchmark-init/deactivate)) +;; 在imenu显示use-package +(setopt use-package-enable-imenu-support t) (provide 'init-elpa) diff --git a/lisp/init-exwm.el b/lisp/init-exwm.el index dd1a731..51e845b 100644 --- a/lisp/init-exwm.el +++ b/lisp/init-exwm.el @@ -6,6 +6,7 @@ (when *is-linux* (use-package exwm + :defer t :config (setq pop-up-windows nil) (setq exwm-workspace-number 1) @@ -112,8 +113,9 @@ (use-package desktop-environment :after exwm + :demand t :init - (desktop-environment-mode) + (add-hook 'exwm-wm-mode-hook 'desktop-environment-mode) :config (advice-add 'desktop-environment-screenshot :after (lambda (&rest _) (message "Saved fullscreen screenshot."))) @@ -143,20 +145,7 @@ (with-eval-after-load 'consult (unless (memq 'xdg-launcher-consult-source consult-buffer-sources) (setq consult-buffer-sources - (append consult-buffer-sources '(xdg-launcher-consult-source)))))) - - (use-package debase - :straight - (debase :type git - :host codeberg - :repo "emacs-weirdware/debase")) - - (use-package discomfort - :commands discomfort - :straight - (discomfort :type git - :host codeberg - :repo "emacs-weirdware/discomfort"))) + (append consult-buffer-sources '(xdg-launcher-consult-source))))))) (provide 'init-exwm) diff --git a/lisp/init-gptel.el b/lisp/init-gptel.el index 5b39294..722bb14 100644 --- a/lisp/init-gptel.el +++ b/lisp/init-gptel.el @@ -111,9 +111,8 @@ from the last 1500 characters of the buffer." (define-key gptel-mode-map (kbd "C-c C-s") #'my-gptel-save-session))) (use-package gptel-agent - :init - (with-eval-after-load 'gptel - (require 'gptel-agent)) + :after gptel + :demand t :config (add-to-list 'gptel-agent-dirs "~/.emacs.d/lisp/" t) (gptel-agent-update)) diff --git a/lisp/init-kbd-func.el b/lisp/init-kbd-func.el index 9fec16c..e694ff6 100644 --- a/lisp/init-kbd-func.el +++ b/lisp/init-kbd-func.el @@ -170,6 +170,24 @@ Disable jinx-mode if it's enable and global-jinx-mode is disable , otherwise tog (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 fix-theme-colors () + "Fix invalid color name in theme files." + (interactive) + (load-file (expand-file-name "~/.emacs.d/lisp/fix-theme-colors.el"))) + (when *is-linux* (defun reboot () "Execute loginctl reboot command." diff --git a/lisp/init-org.el b/lisp/init-org.el index 5d639dc..0393d4b 100644 --- a/lisp/init-org.el +++ b/lisp/init-org.el @@ -4,52 +4,46 @@ ;;; Code: -(use-package org) +(use-package org + :hook + (org-mode . (lambda () + (org-indent-mode) + (visual-line-mode) + (jinx-mode) + (electric-pair-local-mode) + (require 'org-tempo) + (setq-local electric-pair-inhibit-predicate + (lambda (char) + (or (eq char ?<) + (electric-pair-default-inhibit char)))))) + :config + ;; log默认放入drawer中 + (setq org-log-done t + org-log-into-drawer t) -;; 一些随org-mode加载的基础配置 -(add-hook 'org-mode-hook - (lambda () - (require 'org-tempo) - (org-indent-mode) - (visual-line-mode) - (setq-local electric-pair-inhibit-predicate - (lambda (char) - (or (eq char ?<) - (electric-pair-default-inhibit char)))))) + ;; 不要在capture时设置bookmark + (setq org-bookmark-names-plist nil) -;; log默认放入drawer中 -(setq org-log-done t) -(setq org-log-into-drawer t) + ;; 设置todo关键字 + (setq org-todo-keywords + (quote ((sequence "TODO(t)" "STARTED(S)" "|" "DONE(d!/!)") + (sequence "WAITING(w@/!)" "SOMEDAY(s)" "|" "CANCELLED(c@/!)")))) -;; 将系统时间(星期)设为英文,防止中文乱码 -(setq system-time-locale "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")))) -;; 设置todo关键字 -(setq org-todo-keywords - (quote ((sequence "TODO(t)" "STARTED(S)" "|" "DONE(d!/!)") - (sequence "WAITING(w@/!)" "SOMEDAY(s)" "|" "CANCELLED(c@/!)")))) - -;; agenda相关 -(with-eval-after-load 'recentf - (if *is-android* - (add-to-list 'recentf-exclude "~/storage/shared/my-org-note/journal/.*\\.org\\'") - (add-to-list 'recentf-exclude "~/org/my-org-note/journal/.*\\.org\\'") - (add-to-list 'recentf-exclude "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org\\.org"))) - -(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-span 'day) -(setq org-agenda-skip-function-global - '(org-agenda-skip-entry-if 'todo '("COMMENT"))) + (setq org-agenda-span 'day) + (setq org-agenda-skip-function-global + '(org-agenda-skip-entry-if 'todo '("COMMENT")))) ;; org-babel scheme (use-package ob-scheme @@ -64,8 +58,8 @@ ;; denote (use-package denote - :init - (denote-rename-buffer-mode) + :hook + (after-init . denote-rename-buffer-mode) :config (if *is-android* (setq denote-directory "~/storage/shared/my-org-note/") @@ -82,8 +76,8 @@ ;; denote-journal (use-package denote-journal - :init - (add-hook 'calendar-mode-hook #'denote-journal-calendar-mode) + :hook + (calendar-mode . denote-journal-calendar-mode) :config (setq denote-journal-directory (expand-file-name "journal" denote-directory)) (setq denote-journal-keyword nil) @@ -97,8 +91,8 @@ (use-package consult-notes :straight '(consult-notes :fork (:host github :repo "Andsy10/consult-notes")) - :init - (consult-notes-denote-mode) + :hook + (after-init . consult-notes-denote-mode) :config (setq consult-notes-denote-display-keywords-indicator "_") (setq consult-notes-denote-display-id-format 'date) @@ -129,97 +123,110 @@ :config (org-super-agenda-mode)) -;; 自定义agenda视图 -(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" - ((org-ql-block '(closed) - ((org-ql-block-header "Closed TODOs") - (org-super-agenda-groups - '((:auto-ts t))))))) - ("qs" "SOMEDAYs" - ((org-ql-block '(todo "SOMEDAY") - ((org-ql-block-header "SOMEDAYs") - (org-super-agenda-groups - '((:auto-ts t))))))) - ("qS" "STARTEDs" - ((org-ql-block '(todo "STARTED") - ((org-ql-block-header "STARTEDs") - (org-super-agenda-groups - '((:auto-ts t))))))) - ("qt" "TODOs sort by start time" - ((org-ql-block '(todo) - ((org-ql-block-header "TODOs") - (org-super-agenda-groups - '((:auto-ts t))))))) - ("qa" "all TODO entries" - ((org-ql-block '(and (not (done)) (todo)) - ((org-ql-block-header "all TODOs") - (org-super-agenda-groups - '((:name "started" :todo "STARTED") - (:name "priority = A" :priority "A") - (:name "priority = B" :priority "B") - (:name "other priority" :priority< "B") - (:name "someday" :todo "SOMEDAY"))))))))) +;; agenda +(use-package org-agenda + :straight nil + :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" + ((org-ql-block '(closed) + ((org-ql-block-header "Closed TODOs") + (org-super-agenda-groups + '((:auto-ts t))))))) + ("qs" "SOMEDAYs" + ((org-ql-block '(todo "SOMEDAY") + ((org-ql-block-header "SOMEDAYs") + (org-super-agenda-groups + '((:auto-ts t))))))) + ("qS" "STARTEDs" + ((org-ql-block '(todo "STARTED") + ((org-ql-block-header "STARTEDs") + (org-super-agenda-groups + '((:auto-ts t))))))) + ("qt" "TODOs sort by start time" + ((org-ql-block '(todo) + ((org-ql-block-header "TODOs") + (org-super-agenda-groups + '((:auto-ts t))))))) + ("qa" "all TODO entries" + ((org-ql-block '(and (not (done)) (todo)) + ((org-ql-block-header "all TODOs") + (org-super-agenda-groups + '((:name "started" :todo "STARTED") + (:name "priority = A" :priority "A") + (:name "priority = B" :priority "B") + (:name "other priority" :priority< "B") + (:name "someday" :todo "SOMEDAY")))))))))) -;; capture模板 -(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))) - (*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))) - (t nil))) - -(setq org-bookmark-names-plist nil) +;; capture +(use-package org-capture + :straight nil + :config + (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))) + (*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))) + (t nil)))) ;; hugo -(use-package ox-hugo) - -(with-eval-after-load 'org-capture - (defun org-hugo-new-subtree-post-capture-template () - "Returns `org-capture' template string for new Hugo post. +(use-package ox-hugo + :config + (with-eval-after-load 'org-capture + (defun org-hugo-new-subtree-post-capture-template () + "Returns `org-capture' template string for new Hugo post. See `org-capture-templates' for more information." - (let* ((title (read-from-minibuffer "Post Title: ")) ;Prompt to enter the post title - (fname (org-hugo-slug title))) - (mapconcat #'identity - `( - ,(concat "* TODO " title) - ":PROPERTIES:" - ,(concat ":EXPORT_FILE_NAME: " fname) - ":END:" - "\n\n") ;Place the cursor here finally - "\n"))) - (if *is-windows* + (let* ((title (read-from-minibuffer "Post Title: ")) ;Prompt to enter the post title + (fname (org-hugo-slug title))) + (mapconcat #'identity + `( + ,(concat "* TODO " title) + ":PROPERTIES:" + ,(concat ":EXPORT_FILE_NAME: " fname) + ":END:" + "\n\n") ;Place the cursor here finally + "\n"))) + (if *is-windows* + (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 "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" @@ -227,61 +234,48 @@ See `org-capture-templates' for more information." ;; 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 "~/org/hugo/this-is-my-blog/all-blog.org" "Blog Ideas") + (function org-hugo-new-subtree-post-capture-template))))) -;; 快速部署 -(defun my-blog-publish () - "Publish blog , git add/commit/push , generate commit message." - (interactive) - (let* ((blog-dir (if *is-windows* - "h:/emacs/hugo/this-is-my-blog/" - "~/org/hugo/this-is-my-blog/")) - (timestamp (format-time-string "%Y-%m-%d %H:%M:%S")) - (default-directory blog-dir)) + ;; 快速部署 + (defun my-blog-publish () + "Publish blog , git add/commit/push , generate commit message." + (interactive) + (let* ((blog-dir (if *is-windows* + "h:/emacs/hugo/this-is-my-blog/" + "~/org/hugo/this-is-my-blog/")) + (timestamp (format-time-string "%Y-%m-%d %H:%M:%S")) + (default-directory blog-dir)) + ;; save buffer + (save-buffer) + ;; git add + (message "Adding files...") + (eshell-command "git add .") + ;; git commit with timestamp + (message "Committing: %s" timestamp) + (eshell-command (format "git commit -m \"Update: %s\"" timestamp)) + ;; git push + (message "Pushing to remote...") + (let ((exit-code (eshell-command "git push"))) + (if (eq exit-code t) + (message "Push may have failed or nothing to push, check *Messages* buffer for details") + (message "Push successfully %s" timestamp))))) - ;; save buffer + ;; 预览博客 + (defun my-blog-preview () + "Save and preview blog." + (interactive) (save-buffer) - - ;; git add - (message "Adding files...") - (eshell-command "git add .") - - ;; git commit with timestamp - (message "Committing: %s" timestamp) - (eshell-command (format "git commit -m \"Update: %s\"" timestamp)) - - ;; git push - (message "Pushing to remote...") - (let ((exit-code (eshell-command "git push"))) - (if (eq exit-code t) - (message "Push may have failed or nothing to push, check *Messages* buffer for details") - (message "Push successfully %s" timestamp))))) - -;; 预览博客 -(defun my-blog-preview () - "Save and preview blog." - (interactive) - (save-buffer) - (let ((default-directory (if *is-windows* - "h:/emacs/hugo/this-is-my-blog/" - "~/org/hugo/this-is-my-blog/"))) - ;; 启动 Hugo server - (start-process "hugo-server" "*hugo-server*" - "hugo" "server" "-D" "--bind" "0.0.0.0" "--port" "1313") - ;; 等待服务器启动 - (sleep-for 2) - ;; 自动打开浏览器 - (browse-url "http://localhost:1313"))) + (let ((default-directory (if *is-windows* + "h:/emacs/hugo/this-is-my-blog/" + "~/org/hugo/this-is-my-blog/"))) + ;; 启动 Hugo server + (start-process "hugo-server" "*hugo-server*" + "hugo" "server" "-D" "--bind" "0.0.0.0" "--port" "1313") + ;; 等待服务器启动 + (sleep-for 2) + ;; 自动打开浏览器 + (browse-url "http://localhost:1313")))) ;; 农历日历 (use-package cal-china-x diff --git a/lisp/init-package.el b/lisp/init-package.el index f4d5204..d9430c1 100644 --- a/lisp/init-package.el +++ b/lisp/init-package.el @@ -1,356 +1,72 @@ -;;; init-package.el --- major packages -*- lexical-binding: t -*- +;;; init-package.el --- some other 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) - -;; which-key,快捷键提示 -(use-package which-key - :delight - :defer 0 - :config - (which-key-mode)) - -;; ripgrep -(use-package rg) - -;; vertico,minibuffer补全 -(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 - ;; set locate arguments - (cond - (*is-windows* - (setq consult-locate-args (encode-coding-string "es.exe -i -p -r" 'gbk) - 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))) - (*is-mac* - (setq consult-locate-args "mdfind -name")) - (*is-linux* - (setq consult-locate-args "plocate --basename --ignore-case"))) - - ;; set some buffer filter - (setq consult-buffer-filter - (cl-union consult-buffer-filter - '("^\\*dirvish" - "^PREVIEW" - "^\\*helpful" - "^\\*Help" - "Diff" - "straight" - "\\*Messages\\*") - :test 'equal))) - -;; 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)) - -;; wgrep,writable grep -(use-package wgrep) +;; keycast,按键广播 +(use-package keycast) ;; anzu,显示isearch匹配数字 (use-package anzu :delight + :hook + (after-init . global-anzu-mode)) + +;; wgrep,writable grep +(use-package wgrep) + +;; ripgrep +(use-package rg) + +;; hydra +(use-package hydra + :defines + (consult-imenu-config) :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 - :config - (setq undo-in-region t - undo-fu-allow-undo-in-region t)) - -(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 - :config - (setq project-switch-commands (assq-delete-all 'project-vc-dir project-switch-commands)) - (setq project-switch-commands - (seq-uniq (append project-switch-commands - '((magit-project-status "Magit" ?v) - (eat-project "Eat" ?E) - (project-query-replace-regexp "Query Replace" ?R) - (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) - (mode . conf-xdefaults-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"))) - ("Help" (or - (mode . help-mode) - (mode . helpful-mode))) - ("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"))) - ("Grep" (or - (mode . grep-mode) - (mode . rg-mode) - (mode . xref--xref-buffer-mode) - (mode . xref-edit-mode))) - ("Diff" (name . "^*Diff")) - ("Emacs" (or - (name . "^\\*Help\\*$") - (name . "^\\*Custom.*") - (name . "^\\*EMMS Playlist\\*") - (name . "^\\*Messages\\*$") - (name . "*Chinese-word-segmentation*") - (name . "^*Buffer List*") - (name . "\\*discomfort\\*") - (mode . calendar-mode) - (mode . calc-mode) - (mode . calc-trail-mode) - (mode . grep-mode) - (mode . occur-mode)))))) - - (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))) + (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))))))) ;; 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 jinx + :if + (not *is-windows*) + :delight + (jinx-mode " Jinx" jinx) + :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)) +(use-package consult-jinx + :if + (not *is-windows*) + :after jinx + :demand t + :straight nil) ;; eat,终端 (use-package eat + :if + (not *is-windows*) :straight (eat :type git :host codeberg @@ -369,62 +85,14 @@ targets." :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 - (cl-union '(diff-mode exwm-mode) god-exempt-major-modes :test 'equal) - 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) + :hook + (after-init . persp-mode) :config (setq persp-switch-to-buffer-behavior 'switch) (with-eval-after-load 'consult @@ -449,8 +117,19 @@ targets." ;; ediff (use-package ediff :config - (setq ediff-window-setup-function 'ediff-setup-windows-plain) - (setq ediff-split-window-function 'split-window-horizontally)) + (setq ediff-window-setup-function 'ediff-setup-windows-plain + ediff-split-window-function 'split-window-horizontally)) + +;; project +(use-package project + :config + (setq project-switch-commands (assq-delete-all 'project-vc-dir project-switch-commands)) + (setq project-switch-commands + (seq-uniq (append project-switch-commands + '((magit-project-status "Magit" ?v) + (eat-project "Eat" ?E) + (project-query-replace-regexp "Query Replace" ?R) + (consult-ripgrep-project "Ripgrep" ?r)))))) ;; emms (use-package emms diff --git a/lisp/init-prog.el b/lisp/init-prog.el index aeba729..f8c3556 100644 --- a/lisp/init-prog.el +++ b/lisp/init-prog.el @@ -4,10 +4,22 @@ ;;; Code: -;; hs-minor-mode -(add-hook 'prog-mode-hook 'hs-minor-mode) +;; hideshow,折叠代码 +(use-package hideshow + :hook + (prog-mode . hs-minor-mode)) -;; flycheck +;; xref,查找引用 +(use-package xref + :autoload xref-show-definitions-completing-read + :init + (when (executable-find "rg") + (setq xref-search-program 'ripgrep)) + + (setq xref-show-definitions-function #'xref-show-definitions-completing-read + xref-show-xrefs-function #'xref-show-definitions-completing-read)) + +;; flycheck,语法检查 (use-package flycheck) (use-package flycheck-guile @@ -15,7 +27,6 @@ (scheme-mode . (lambda () (require 'flycheck-guile)))) -;; consult-flycheck (use-package consult-flycheck) ;; tree-sitter diff --git a/lisp/init-startup.el b/lisp/init-startup.el index 9746f0f..1bf1441 100644 --- a/lisp/init-startup.el +++ b/lisp/init-startup.el @@ -4,7 +4,22 @@ ;;; Code: -;; mac自动全屏 +;; 编码设置 +(set-selection-coding-system 'utf-8) +(when (fboundp 'set-charset-priority) + (set-charset-priority 'unicode)) +(set-default-coding-systems 'utf-8) +(set-buffer-file-coding-system 'utf-8) +(set-clipboard-coding-system 'utf-8) +(set-file-name-coding-system 'utf-8) +(set-keyboard-coding-system 'utf-8) +(set-next-selection-coding-system 'utf-8) +(set-selection-coding-system 'utf-8) +(set-terminal-coding-system 'utf-8) +(setq locale-coding-system 'utf-8) +(setq system-time-locale "C") + +;; 全屏 (cond (*is-mac* (set-frame-parameter nil 'fullscreen 'fullscreen) @@ -15,7 +30,7 @@ (toggle-frame-maximized)) (t nil)) -;; 配置备份文件和自动保存文件目录 +;; 备份文件和自动保存文件 (setq backup-directory-alist `((".*" . ,(expand-file-name "backup/" user-emacs-directory))) backup-by-copying t @@ -23,23 +38,19 @@ kept-new-versions 6 kept-old-versions 2 version-control t) - (setq auto-save-file-name-transforms `((".*" ,(expand-file-name "auto-save-list/" user-emacs-directory) t))) ;; 开启水平滚动 (put 'scroll-left 'disabled nil) -;; 行号 -(global-display-line-numbers-mode t) - ;; 关闭lock文件 (setq create-lockfiles nil) ;; 关闭提示音 (setq ring-bell-function 'ignore) -;; 同步包管理器目录 +;; 添加包管理器目录 (cond (*is-windows* (add-to-list 'exec-path (expand-file-name "H/appppppppppp/scoop/apps/")) @@ -51,21 +62,7 @@ (add-to-list 'exec-path (expand-file-name "~/.guix-home/profile/bin/")) (setenv "PATH" (concat (expand-file-name "~/.guix-home/profile/bin/") ":" (getenv "PATH"))))) -;; 当文件被外部修改时自动刷新 -(global-auto-revert-mode 1) - -;; 开启recent file mode -(when (or (display-graphic-p) *is-android*) - (recentf-mode) - (setq recentf-max-saved-items 30)) - -;; 启用select delete -(delete-selection-mode) - -;; 启用winner mode -(winner-mode) - -;; 自定义scratch +;; scratch buffer (setq initial-scratch-message "") @@ -75,19 +72,9 @@ (advice-add 'scratch-buffer :after #'my/scratch-set-mode) -;; 开启server mode -(require 'server) -(unless (server-running-p) - (server-start)) - ;; 窗口名 (setq-default frame-title-format '("%b - Emacs")) -;; electirc-pair-mode -(add-hook 'org-mode-hook 'electric-pair-local-mode) -(with-eval-after-load 'elec-pair - (setq electric-pair-pairs (append '((?\~ . ?\~) (?\= . ?\=)) electric-pair-pairs))) - ;; 关闭native compile警告 (setq native-comp-async-warnings-errors-kind 'silent) @@ -99,25 +86,6 @@ ;; 移动到垃圾桶 (setq delete-by-moving-to-trash t) -;; 让xref用rg -(setq xref-search-program - (cond - ((or (executable-find "ripgrep") - (executable-find "rg")) - 'ripgrep) - (t 'grep))) - -(setq switch-to-buffer-obey-display-actions t) - -;; 优化换行规则 -(setq word-wrap-by-category t) - -;; kill-line删除换行符 -(setq kill-whole-line t) - -;; 更方便地pop mark -(setq set-mark-command-repeat-pop t) - (provide 'init-startup) ;;; init-startup.el ends here diff --git a/lisp/init-terminal-package.el b/lisp/init-terminal-package.el index fbc1c43..3264dab 100644 --- a/lisp/init-terminal-package.el +++ b/lisp/init-terminal-package.el @@ -4,6 +4,58 @@ ;;; Code: +(use-package gcmh + :delight + :init + (setq gcmh-idle-delay 'auto + gcmh-auto-idle-delay-factor 10 + gcmh-high-cons-threshold #x4000000) + (gcmh-mode)) + +(use-package benchmark-init + :init + (benchmark-init/activate) + :hook + (after-init . benchmark-init/deactivate)) + +(use-package recentf + :if + (or (display-graphic-p) *is-android*) + :hook + (after-init . recentf-mode) + :init + (setq recentf-max-saved-items 30) + :config + (if *is-android* + (add-to-list 'recentf-exclude "~/storage/shared/my-org-note/journal/.*\\.org\\'") + (add-to-list 'recentf-exclude "~/org/my-org-note/journal/.*\\.org\\'") + (add-to-list 'recentf-exclude "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org\\.org"))) + +(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-ignored-variables '(consult-notes-history) + savehist-autosave-interval 300)) + +(use-package saveplace + :hook + (after-init . save-place-mode)) + +(use-package restart-emacs) + +(use-package autorevert + :delight + :hook + (after-init . global-auto-revert-mode)) + ;; 安装crux (use-package crux) diff --git a/lisp/init-terminal-startup.el b/lisp/init-terminal-startup.el index f6a30e8..b14b2e8 100644 --- a/lisp/init-terminal-startup.el +++ b/lisp/init-terminal-startup.el @@ -8,20 +8,22 @@ (defconst *is-mac* (eq system-type 'darwin)) (defconst *is-linux* (eq system-type 'gnu/linux)) -(defconst *is-windows* (or (eq system-type 'ms-dos) - (eq system-type 'windows-nt))) +(defconst *is-windows* (or (eq system-type 'ms-dos) (eq system-type 'windows-nt))) +(defconst *is-android* (if (getenv "TERMUX_VERSION") t nil)) -(if *is-windows* - (progn - (set-language-environment "UTF-8") - (prefer-coding-system 'utf-8) - (set-default-coding-systems 'utf-8) - (set-terminal-coding-system 'utf-8) - (set-keyboard-coding-system 'utf-8) - (setq default-buffer-file-coding-system 'utf-8) - (setq default-process-coding-system '(utf-8 . utf-8)) - (setq w32-unicode-filenames t) - (setq w32-system-coding-system 'utf-8))) +(set-selection-coding-system 'utf-8) +(when (fboundp 'set-charset-priority) + (set-charset-priority 'unicode)) +(set-default-coding-systems 'utf-8) +(set-buffer-file-coding-system 'utf-8) +(set-clipboard-coding-system 'utf-8) +(set-file-name-coding-system 'utf-8) +(set-keyboard-coding-system 'utf-8) +(set-next-selection-coding-system 'utf-8) +(set-selection-coding-system 'utf-8) +(set-terminal-coding-system 'utf-8) +(setq locale-coding-system 'utf-8) +(setq system-time-locale "C") (setq backup-directory-alist `((".*" . ,(expand-file-name "backup/" user-emacs-directory))) @@ -46,8 +48,10 @@ (setenv "PATH" (concat (expand-file-name "H/appppppppppp/scoop/apps/") ";" (getenv "PATH")))) (*is-mac* (add-to-list 'exec-path (expand-file-name "/opt/homebrew/bin/")) - (setenv "PATH" (concat (expand-file-name "/opt/homebrew/bin/") ":" (getenv "PATH"))))) - + (setenv "PATH" (concat (expand-file-name "/opt/homebrew/bin/") ":" (getenv "PATH")))) + (*is-linux* + (add-to-list 'exec-path (expand-file-name "~/.guix-home/profile/bin/")) + (setenv "PATH" (concat (expand-file-name "~/.guix-home/profile/bin/") ":" (getenv "PATH"))))) (global-auto-revert-mode 1) diff --git a/lisp/init-terminal-ui.el b/lisp/init-terminal-ui.el index 5543624..b24e9bc 100644 --- a/lisp/init-terminal-ui.el +++ b/lisp/init-terminal-ui.el @@ -4,18 +4,6 @@ ;;; Code: -;; 设置系统编码 -(when (fboundp 'set-charset-priority) - (set-charset-priority 'unicode)) - -(if *is-windows* - (progn - (set-language-environment 'chinese-gbk) - (prefer-coding-system 'utf-8-auto)) - (progn - (set-language-environment "UTF-8") - (prefer-coding-system 'utf-8))) - ;; 显示文件大小 (size-indication-mode t) diff --git a/lisp/init-ui.el b/lisp/init-ui.el index d605d55..0738f5d 100644 --- a/lisp/init-ui.el +++ b/lisp/init-ui.el @@ -4,49 +4,6 @@ ;;; Code: -;; 设置系统编码 -(when (fboundp 'set-charset-priority) - (set-charset-priority 'unicode)) - -(if *is-windows* - (progn - (set-language-environment 'chinese-gbk) - (prefer-coding-system 'utf-8-auto)) - (progn - (set-language-environment "UTF-8") - (prefer-coding-system 'utf-8))) - -;; 预览所有可用emacs颜色 -(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))))) - -;; org-mode美化 -(use-package olivetti - :delight - :init - (add-hook 'olivetti-mode-hook - (lambda () - (display-line-numbers-mode -1))) - (add-hook 'org-mode-hook - (lambda () - (olivetti-mode 1)))) - -;; rainbow mode -(use-package rainbow-mode) - -;; rainbow-delimiters -(use-package rainbow-delimiters) - ;; 自定义主题路径 (add-to-list 'custom-theme-load-path "~/.emacs.d/lisp/") @@ -56,22 +13,45 @@ ;; 安装solarized dark (use-package solarized-theme :straight - '(solarized-emacs :fork (:host github :repo "Andsy10/solarized-emacs"))) + '(solarized-emacs :fork (:host github :repo "Andsy10/solarized-emacs")) + :init + ;; 把主题加载延迟到frame创建之后,防止daemon模式下宏不能正常展开 + ;; (if *is-android* + ;; (if (daemonp) + ;; (add-hook 'after-make-frame-functions + ;; (lambda (frame) + ;; (with-selected-frame frame + ;; (load-theme 'my-base16-light t)))) + ;; (load-theme 'my-base16-light t)) + ;; (if (daemonp) + ;; (add-hook 'after-make-frame-functions + ;; (lambda (frame) + ;; (with-selected-frame frame + ;; (load-theme 'my-base16-dark t)))) + ;; (load-theme 'my-base16-dark t))) + (load-theme 'my-base16-dark)) -;; 把主题加载延迟到frame创建之后,防止daemon模式下宏不能正常展开 -(if *is-android* - (if (daemonp) - (add-hook 'after-make-frame-functions - (lambda (frame) - (with-selected-frame frame - (load-theme 'my-base16-light t)))) - (load-theme 'my-base16-light t)) - (if (daemonp) - (add-hook 'after-make-frame-functions - (lambda (frame) - (with-selected-frame frame - (load-theme 'my-base16-dark t)))) - (load-theme 'my-base16-dark t))) +;; 行号 +(use-package display-line-numbers + :hook + (after-init . global-display-line-numbers-mode) + :config + (setq display-line-numbers-type '2 + display-line-numbers-grow-only t + display-line-numbers-width-start 4)) + +;; org-mode美化 +(use-package olivetti + :delight + :hook + (org-mode . olivetti-mode) + (olivetti-mode . (lambda () (display-line-numbers-mode -1)))) + +;; rainbow mode +(use-package rainbow-mode) + +;; rainbow-delimiters +(use-package rainbow-delimiters) ;; 很多主题 ;; (use-package doom-themes) @@ -79,24 +59,25 @@ (use-package naysayer-theme) (use-package ef-themes) -(if *is-android* - (use-package simple-modeline - :init - (simple-modeline-mode))) +(use-package simple-modeline + :if + *is-android* + :hook + (after-init . simple-modeline-mode)) ;; eshell高亮 (use-package eshell-syntax-highlighting :hook - (eshell-mode . eshell-syntax-highlighting-global-mode)) - -(add-hook 'eshell-mode-hook - (lambda () - (setenv "TERM" "xterm-256color") - (setenv "COLORTERM" "truecolor") - (add-to-list 'eshell-output-filter-functions 'eshell-handle-ansi-color t) - (setq-local eshell-prefer-lisp-functions nil) - (setenv "LS_COLORS" - "di=34:ln=35:so=32:pi=33:ex=31:bd=34;46:cd=34;43:su=30;41:sg=30;46"))) + (eshell-mode . eshell-syntax-highlighting-global-mode) + :config + (add-hook 'eshell-mode-hook + (lambda () + (setenv "TERM" "xterm-256color") + (setenv "COLORTERM" "truecolor") + (add-to-list 'eshell-output-filter-functions 'eshell-handle-ansi-color t) + (setq-local eshell-prefer-lisp-functions nil) + (setenv "LS_COLORS" + "di=34:ln=35:so=32:pi=33:ex=31:bd=34;46:cd=34;43:su=30;41:sg=30;46")))) ;; 缩进线 (use-package indent-bars @@ -111,46 +92,41 @@ (indent-bars-prefer-character t)) ;; 高亮当前行 -(global-hl-line-mode t) - -;; 显示文件大小 -(size-indication-mode t) - -;; 显示行号列号 -(column-number-mode t) +(use-package hl-line + :hook + (after-init . global-hl-line-mode)) ;; 显示时间 -(unless (or *is-linux* *is-android*) +(use-package time + :if + (not *is-android*) + :init + (if *is-linux* + (add-hook 'exwm-wm-mode-hook 'display-time-mode) + (add-hook 'after-init-hook 'display-time-mode)) + :config (setq display-time-default-load-average nil display-time-string-forms '((propertize (concat (propertize (format-time-string " %I:%M") 'face 'display-time-date-and-time) (propertize (format-time-string "-%p") 'face 'font-lock-comment-face)) - 'help-echo (format-time-string "%A, %B %d, %Y")))) - (display-time-mode)) - -;; 添加个人字体到 cnfonts -(setq cnfonts-personal-fontnames - '(("Sarasa Fixed TC") ; 英文字体 - ("Sarasa Fixed TC") ; 中文字体 - nil ; Ext-B 字体(可选) - nil ; Symbol 字体(可选) - nil)) ; 装饰字体(可选) + 'help-echo (format-time-string "%A, %B %d, %Y"))))) ;; 安装cnfonts脚本,用于修复中英文对齐 (use-package cnfonts + :hook + (after-init . cnfonts-mode) :init - (add-hook 'after-init-hook 'cnfonts-mode) + (setq cnfonts-personal-fontnames + '(("Sarasa Fixed TC") ;英文 + ("Sarasa Fixed TC") ;中文 + nil ;ext-B + nil ;symbol + nil)) ;装饰 :config (cnfonts--select-profile "profile1")) -;; 主题修复脚本 -(defun fix-theme-colors () - "Fix invalid color name in theme files." - (interactive) - (load-file (expand-file-name "~/.emacs.d/lisp/fix-theme-colors.el"))) - (provide 'init-ui) ;;; init-ui.el ends here diff --git a/lisp/init-window.el b/lisp/init-window.el index f9e1d87..47d7026 100644 --- a/lisp/init-window.el +++ b/lisp/init-window.el @@ -4,13 +4,18 @@ ;;; Code: +(use-package window + :straight nil + :config + (setq switch-to-buffer-obey-display-actions t)) + (use-package popper :defines popper-echo-dispatch-actions :commands popper-group-by-directory :hook - (emacs-startup . popper-mode) + (after-init . popper-mode) :init (setq popper-reference-buffers @@ -90,9 +95,9 @@ (when (display-grayscale-p) (setq popper-mode-line '("[POP]"))) - (setq popper-echo-dispatch-actions t) (setq popper-group-function nil) + :config (popper-echo-mode 1)