From 5e25bc7ef1918830a1cae3b6e468c2f82dc5640b Mon Sep 17 00:00:00 2001 From: Cytrogen Date: Wed, 11 Mar 2026 19:16:05 -0400 Subject: [PATCH] =?UTF-8?q?feat(dev):=20=E6=B7=BB=E5=8A=A0=20LSP=E3=80=81T?= =?UTF-8?q?ree-sitter=E3=80=81=E7=BB=88=E7=AB=AF=E5=92=8C=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BC=96=E8=BE=91=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LSP: Eglot 自动检测已安装服务器(JS/TS/Python/CSS/HTML), 仅在服务器可用时启用 Tree-sitter: 语法树精确高亮(level 4),自动 remap 到 -ts-mode (js-ts-mode、python-ts-mode 等) 终端: Eat 终端模拟器,适配 Darcula 主题 16 色 ANSI 调色板, 128KB 回滚缓冲区,Semi-char 模式 C-c 前缀滚动 代码编辑: Rainbow-delimiters 彩色括号 + Symbol-overlay 符号高亮 (M-i)+ Multiple-cursors 多光标 + Move-dup 移动/复制行 + Whole-line-or-region 整行操作 + Whitespace-cleanup-mode + Highlight-escape-sequences + Show-paren + Electric-pair + Flymake 语法检查 + Eldoc 文档提示 + Restclient HTTP 测试 + Rainbow-mode 颜色预览 + Origami 代码折叠 + Regex-tool + Consult-eglot LSP 符号搜索 --- config/pkg-dev.el | 169 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 168 insertions(+), 1 deletion(-) diff --git a/config/pkg-dev.el b/config/pkg-dev.el index a2368e709c8de4b74bd699aed7d439cb64e22eec..339c050a72c232cbbf7d6c889c91dde1796ca8a1 100644 --- a/config/pkg-dev.el +++ b/config/pkg-dev.el @@ -1,6 +1,9 @@ ;;; pkg-dev.el --- Development tools and programming support -*- lexical-binding: t -*- -;; Copyright (C) 2024 Cytrogen +;; Copyright (C) 2026 Cytrogen + +;; Many package selections and configurations adapted from +;; Steve Purcell's emacs.d: https://github.com/purcell/emacs.d ;; This file contains: ;; - Rainbow delimiters for code readability @@ -31,8 +34,172 @@ (setq show-paren-delay 0) (setq show-paren-style 'parenthesis) +;; JS/TS/JSON 缩进 2 格 +(setq js-indent-level 2) +(setq typescript-ts-mode-indent-offset 2) + ;; Development Utilities ;; Helper functions for programming +;; Avy — 2-3 键跳转到屏幕任意位置 +(unless (package-installed-p 'avy) + (package-refresh-contents) + (package-install 'avy)) +(require 'avy) +(setq avy-timeout-seconds 0.3) + +;; Multiple Cursors — 多光标编辑 +(unless (package-installed-p 'multiple-cursors) + (package-install 'multiple-cursors)) +(require 'multiple-cursors) + +;; Symbol Overlay — 高亮/跳转当前符号所有出现 +(unless (package-installed-p 'symbol-overlay) + (package-install 'symbol-overlay)) +(require 'symbol-overlay) +(add-hook 'prog-mode-hook #'symbol-overlay-mode) + +;; Move-dup — 移动/复制行 +(unless (package-installed-p 'move-dup) + (package-install 'move-dup)) +(require 'move-dup) +(global-move-dup-mode 1) +(add-hook 'org-mode-hook (lambda () (move-dup-mode -1))) + +;; Whole-line-or-region — 无选区时 C-w/M-w 操作整行 +(unless (package-installed-p 'whole-line-or-region) + (package-install 'whole-line-or-region)) +(require 'whole-line-or-region) +(whole-line-or-region-global-mode 1) + +;; Whitespace-cleanup-mode — 保存时只清理改过的行的空白 +(unless (package-installed-p 'whitespace-cleanup-mode) + (package-install 'whitespace-cleanup-mode)) +(require 'whitespace-cleanup-mode) +(global-whitespace-cleanup-mode 1) + +;; Highlight-escape-sequences — 代码中转义序列高亮 +(unless (package-installed-p 'highlight-escape-sequences) + (package-install 'highlight-escape-sequences)) +(require 'highlight-escape-sequences) +(add-hook 'prog-mode-hook 'hes-mode) + +;; Flymake(内置)— 实时语法检查 +(add-hook 'prog-mode-hook 'flymake-mode) + +;; 行号(仅编程模式) +(add-hook 'prog-mode-hook 'display-line-numbers-mode) + +;; 代码中 URL 可点击 +(add-hook 'prog-mode-hook 'goto-address-prog-mode) + +;; 注释拼写检查(需系统安装 aspell 或 hunspell) +(add-hook 'prog-mode-hook 'flyspell-prog-mode) + +;; Eat — 现代终端模拟器 +(unless (package-installed-p 'eat) + (package-install 'eat)) + +(with-eval-after-load 'eat + ;; 关闭闪烁文本,减少视觉干扰 + (setq eat-enable-blinking-text nil) + ;; 增大回滚缓冲区(默认 131072),方便查看长输出 + (setq eat-term-scrollback-size (* 128 1024)) + + ;; Semi-char 模式下用 C-c 前缀滚动回看(不会被 zsh 拦截) + (define-key eat-semi-char-mode-map (kbd "C-c C-p") #'scroll-down-command) + (define-key eat-semi-char-mode-map (kbd "C-c C-n") #'scroll-up-command) + + ;; ANSI 调色板适配 darcula 主题 (bg #2B2B2B) + (custom-set-faces + '(eat-term-color-0 ((t (:foreground "#1e1e1e" :background "#1e1e1e")))) ; black + '(eat-term-color-1 ((t (:foreground "#ff6b68" :background "#ff6b68")))) ; red + '(eat-term-color-2 ((t (:foreground "#a8c023" :background "#a8c023")))) ; green + '(eat-term-color-3 ((t (:foreground "#d6bf55" :background "#d6bf55")))) ; yellow + '(eat-term-color-4 ((t (:foreground "#6a76db" :background "#6a76db")))) ; blue + '(eat-term-color-5 ((t (:foreground "#b877db" :background "#b877db")))) ; magenta + '(eat-term-color-6 ((t (:foreground "#56b6c2" :background "#56b6c2")))) ; cyan + '(eat-term-color-7 ((t (:foreground "#a9b7c6" :background "#a9b7c6")))) ; white + '(eat-term-color-8 ((t (:foreground "#6c6c6c" :background "#6c6c6c")))) ; bright black + '(eat-term-color-9 ((t (:foreground "#ff8785" :background "#ff8785")))) ; bright red + '(eat-term-color-10 ((t (:foreground "#c0d868" :background "#c0d868")))) ; bright green + '(eat-term-color-11 ((t (:foreground "#ffe680" :background "#ffe680")))) ; bright yellow + '(eat-term-color-12 ((t (:foreground "#88aacc" :background "#88aacc")))) ; bright blue + '(eat-term-color-13 ((t (:foreground "#b89ad6" :background "#b89ad6")))) ; bright magenta + '(eat-term-color-14 ((t (:foreground "#6ed8c8" :background "#6ed8c8")))) ; bright cyan + '(eat-term-color-15 ((t (:foreground "#e8e8e8" :background "#e8e8e8")))))) ; bright white + +;; Restclient — 在 buffer 中测试 HTTP 请求 +(unless (package-installed-p 'restclient) + (package-install 'restclient)) + +;; Rainbow-mode — CSS/Hex 颜色值直接显示对应颜色 +(unless (package-installed-p 'rainbow-mode) + (package-install 'rainbow-mode)) +(add-hook 'css-mode-hook 'rainbow-mode) +(add-hook 'html-mode-hook 'rainbow-mode) +(add-hook 'emacs-lisp-mode-hook 'rainbow-mode) + +;; Origami — 代码折叠 +(unless (package-installed-p 'origami) + (package-install 'origami)) +(add-hook 'prog-mode-hook 'origami-mode) + +;; Regex-tool — 交互式正则表达式测试 +(unless (package-installed-p 'regex-tool) + (package-install 'regex-tool)) + +;; Eldoc — 函数签名/文档自动提示(minibuffer 多行显示) +(setq eldoc-echo-area-use-multiline-p t) + +;; Eglot(内置)— LSP 支持(JS/TS/Python/CSS/HTML) +;; 前置: pnpm add -g typescript-language-server typescript +;; 前置: pnpm add -g vscode-langservers-extracted +;; 前置: uv tool install python-lsp-server +(with-eval-after-load 'eglot + (setq eglot-autoshutdown t)) + +(defvar my/eglot-server-programs + '((js-mode . "typescript-language-server") + (js-ts-mode . "typescript-language-server") + (typescript-ts-mode . "typescript-language-server") + (tsx-ts-mode . "typescript-language-server") + (python-mode . "pylsp") + (python-ts-mode . "pylsp") + (css-mode . "vscode-css-language-server") + (css-ts-mode . "vscode-css-language-server") + (html-mode . "vscode-html-language-server") + (html-ts-mode . "vscode-html-language-server")) + "模式与对应 LSP 服务器可执行文件的映射.") + +(defun my/eglot-ensure-if-server () + "只在对应 LSP 服务器存在时启用 eglot." + (when-let* ((server (alist-get major-mode my/eglot-server-programs))) + (when (executable-find server) + (eglot-ensure)))) + +(dolist (entry my/eglot-server-programs) + (add-hook (intern (concat (symbol-name (car entry)) "-hook")) + #'my/eglot-ensure-if-server)) + +(unless (package-installed-p 'consult-eglot) + (package-install 'consult-eglot)) + +;; Tree-sitter(内置)— 语法树精确高亮 +;; 安装语法: M-x treesit-install-language-grammar RET javascript/typescript/python/... +(setq treesit-font-lock-level 4) + +(defvar my/treesit-mode-remap + '((javascript-mode . (js-ts-mode . javascript)) + (js-json-mode . (json-ts-mode . json)) + (python-mode . (python-ts-mode . python)) + (css-mode . (css-ts-mode . css))) + "Tree-sitter 模式映射: (旧模式 . (新模式 . 语言)).") + +(setq major-mode-remap-alist + (cl-loop for (old-mode . (new-mode . lang)) in my/treesit-mode-remap + when (treesit-language-available-p lang) + collect (cons old-mode new-mode))) + (provide 'pkg-dev) ;;; pkg-dev.el ends here \ No newline at end of file