;;; pkg-dev.el --- Development tools and programming support -*- lexical-binding: t -*- ;; 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 ;; - Programming mode configurations ;; - Development utilities ;;; Commentary: ;; Tools and configurations for software development and programming. ;; Includes syntax highlighting and code editing enhancements. ;;; Code: ;; Rainbow Delimiters ;; Color-coded parentheses and brackets (unless (package-installed-p 'rainbow-delimiters) (package-refresh-contents) (package-install 'rainbow-delimiters)) (add-hook 'prog-mode-hook #'rainbow-delimiters-mode) (add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode) (add-hook 'lisp-interaction-mode-hook #'rainbow-delimiters-mode) ;; Programming Mode Enhancements ;; Built-in features for code editing (show-paren-mode 1) (electric-pair-mode 1) (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