~cytrogen/.emacs.d

.emacs.d/config/pkg-dev.el -rw-r--r-- 7.7 KiB
e2b51cc0 — Cytrogen chore: 更新 gitignore 和数据文件 a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
;;; 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