Emacs 完全指南 / 第 10 章:编程环境
第 10 章:编程环境
10.1 编程基础配置
通用编程设置
;; 编程模式钩子
(add-hook 'prog-mode-hook
(lambda ()
(display-line-numbers-mode 1) ; 行号
(electric-pair-mode 1) ; 括号配对
(show-paren-mode 1) ; 括号高亮
(hs-minor-mode 1) ; 代码折叠
(setq-local show-trailing-whitespace t) ; 显示尾部空白
(flyspell-prog-mode 1))) ; 拼写检查(注释和字符串)
;; 缩进设置
(setq-default indent-tabs-mode nil) ; 使用空格
(setq-default tab-width 4) ; Tab 宽度
;; 不同语言的缩进
(setq c-basic-offset 4)
(setq js-indent-level 2)
(setq css-indent-offset 2)
代码折叠
;; hs-minor-mode(内置)
;; C-c @ C-h → 隐藏当前块
;; C-c @ C-s → 显示当前块
;; C-c @ C-M-h → 隐藏所有
;; C-c @ C-M-s → 显示所有
;; 使用 hideshowvis(在侧边栏显示折叠标记)
(use-package hideshowvis
:hook (prog-mode . hideshowvis-minor-mode))
;; 使用 vimish-fold(更灵活的折叠)
(use-package vimish-fold
:after evil
:config
(vimish-fold-global-mode 1))
10.2 Tree-sitter(语法树)
Tree-sitter 是一个增量解析器,提供精确的语法高亮和代码结构分析。Emacs 29+ 内置了 Tree-sitter 支持。
安装 Tree-sitter 语法
# Emacs 29+ 自动安装语法
# 或手动安装:
M-x treesit-install-language-grammar RET python RET
M-x treesit-install-language-grammar RET javascript RET
M-x treesit-install-language-grammar RET rust RET
;; Tree-sitter 语言模式映射
(setq major-mode-remap-alist
'((python-mode . python-ts-mode)
(js-mode . js-ts-mode)
(typescript-mode . typescript-ts-mode)
(json-mode . json-ts-mode)
(css-mode . css-ts-mode)
(c-mode . c-ts-mode)
(c++-mode . c++-ts-mode)
(rust-mode . rust-ts-mode)
(go-mode . go-ts-mode)
(yaml-mode . yaml-ts-mode)))
;; 结构化编辑(基于 Tree-sitter)
(use-package treesit
:config
(setq treesit-font-lock-level 4)) ; 最详细的语法高亮
Tree-sitter 功能
| 功能 | 说明 |
|---|---|
| 精确语法高亮 | 基于语法树而非正则 |
| 结构化导航 | 基于 AST 的移动 |
| 结构化编辑 | 基于 AST 的编辑 |
| 代码折叠 | 基于语法结构的折叠 |
| 增量解析 | 只重新解析修改的部分 |
10.3 LSP(Language Server Protocol)
LSP 让 Emacs 获得与 VS Code 类似的智能代码补全、跳转、重构等功能。
Eglot(内置 LSP 客户端)
Emacs 29+ 内置了 Eglot,无需额外安装。
;; Eglot 基本配置
(use-package eglot
:hook ((python-mode . eglot-ensure)
(js-mode . eglot-ensure)
(typescript-mode . eglot-ensure)
(rust-mode . eglot-ensure)
(go-mode . eglot-ensure)
(c-mode . eglot-ensure)
(c++-mode . eglot-ensure))
:config
;; 配置语言服务器
(add-to-list 'eglot-server-programs
'(python-mode . ("pyright-langserver" "--stdio")))
(add-to-list 'eglot-server-programs
'(rust-mode . ("rust-analyzer")))
(add-to-list 'eglot-server-programs
'(go-mode . ("gopls")))
;; 保存时自动格式化
(setq eglot-autoshutdown t
eglot-events-buffer-size 0))
LSP Mode(第三方 LSP 客户端)
;; lsp-mode(功能更丰富但更重)
(use-package lsp-mode
:hook ((python-mode . lsp-deferred)
(js-mode . lsp-deferred)
(typescript-mode . lsp-deferred)
(rust-mode . lsp-deferred))
:commands (lsp lsp-deferred)
:config
(setq lsp-idle-delay 0.5
lsp-log-io nil
lsp-keymap-prefix "C-c l")
:bind (:map lsp-mode-map
("C-c l r" . lsp-rename)
("C-c l f" . lsp-format-buffer)
("C-c l a" . lsp-execute-code-action)))
(use-package lsp-ui
:after lsp-mode
:config
(setq lsp-ui-doc-enable t
lsp-ui-doc-show-with-cursor t
lsp-ui-sideline-enable t
lsp-ui-sideline-show-diagnostics t))
;; lsp-pyright(Python)
(use-package lsp-pyright
:hook (python-mode . (lambda ()
(require 'lsp-pyright)
(lsp-deferred))))
LSP 核心功能
| 快捷键(Eglot) | 快捷键(LSP Mode) | 功能 |
|---|---|---|
M-. | M-. | 跳转到定义 |
M-, | M-, | 返回 |
M-? | M-? | 查找引用 |
C-c r | C-c l r | 重命名 |
C-c f | C-c l f | 格式化 |
TAB | TAB | 代码补全 |
| — | C-c l a | 代码操作 |
| — | C-c l g g | 跳转到定义 |
常用语言服务器
| 语言 | 服务器 | 安装命令 |
|---|---|---|
| Python | Pyright / Pylsp | npm i -g pyright / pip install python-lsp-server |
| JavaScript/TypeScript | TypeScript Server | npm i -g typescript typescript-language-server |
| Rust | rust-analyzer | rustup component add rust-analyzer |
| Go | gopls | go install golang.org/x/tools/gopls@latest |
| C/C++ | clangd | apt install clangd |
| Java | Eclipse JDT | 自动安装 |
| Lua | lua-ls | cargo install --git https://github.com/LuaLS/lua-language-server |
| Docker | dockerfile-ls | npm i -g dockerfile-language-server-nodejs |
| YAML | yaml-ls | npm i -g yaml-language-server |
| JSON | vscode-json-ls | npm i -g vscode-langservers-extracted |
| HTML/CSS | vscode-html-ls | npm i -g vscode-langservers-extracted |
10.4 语法检查
Flymake(内置)
;; Emacs 内置的 Flymake
(add-hook 'prog-mode-hook 'flymake-mode)
;; 导航错误
;; M-g M-n → 下一个错误
;; M-g M-p → 上一个错误
;; C-c ! l → 列出所有错误(使用 consult-flymake)
Flycheck(第三方)
(use-package flycheck
:diminish flycheck-mode
:hook (prog-mode . flycheck-mode)
:config
(setq flycheck-check-syntax-automatically '(save mode-enabled)
flycheck-display-errors-delay 0.3))
;; 导航
;; C-c ! n → 下一个错误
;; C-c ! p → 上一个错误
;; C-c ! l → 错误列表
;; C-c ! v → 当前位置的错误信息
10.5 调试(DAP)
DAP Mode
(use-package dap-mode
:after lsp-mode
:config
(dap-auto-configure-mode)
;; Python 调试
(require 'dap-python)
(setq dap-python-debugger 'debugpy)
;; JavaScript 调试
(require 'dap-node)
;; 调试操作绑定
:bind (("<f5>" . dap-continue)
("<f6>" . dap-next)
("<f7>" . dap-step-in)
("<f8>" . dap-step-out)
("<f9>" . dap-breakpoint-toggle)
("C-c d d" . dap-debug)
("C-c d r" . dap-debug-restart)))
调试工作流
1. 设置断点:<f9> 或 M-x dap-breakpoint-toggle
2. 启动调试:C-c d d 或 <f5>
3. 调试控制:
<f5> → 继续执行
<f6> → 单步跳过
<f7> → 单步进入
<f8> → 单步跳出
4. 查看变量:在 DAP UI 窗口中查看
5. 调试控制台:M-x dap-ui-repl
10.6 常见语言配置
Python
;; Python 配置
(use-package python
:config
(setq python-indent-offset 4
python-shell-interpreter "python3"))
;; 虚拟环境
(use-package pyvenv
:hook (python-mode . pyvenv-mode)
:config
(pyvenv-tracking-mode 1))
;; 代码格式化
(use-package blacken
:hook (python-mode . blacken-mode))
;; 代码整理
(use-package isort
:hook (python-mode . isort-on-save-mode))
JavaScript/TypeScript
(use-package js2-mode
:mode "\\.js\\'"
:config
(setq js2-basic-offset 2
js2-highlight-level 3))
(use-package typescript-mode
:mode "\\.ts\\'"
:config
(setq typescript-indent-level 2))
;; Prettier 格式化
(use-package prettier-js
:hook ((js-mode . prettier-js-mode)
(typescript-mode . prettier-js-mode)
(web-mode . prettier-js-mode)))
Rust
(use-package rust-mode
:config
(setq rust-format-on-save t))
;; Cargo 集成
(use-package cargo
:hook (rust-mode . cargo-minor-mode))
Go
(use-package go-mode
:config
(add-hook 'go-mode-hook
(lambda ()
(setq tab-width 4
indent-tabs-mode 1))))
;; Go 模板
(use-package go-template-mode
:mode "\\.tmpl\\'")
10.7 本章小结
| 功能 | 工具 | 说明 |
|---|---|---|
| 语法高亮 | Tree-sitter | 基于语法树的精确高亮 |
| 智能补全 | Eglot / LSP | 跳转、重构、补全 |
| 语法检查 | Flymake / Flycheck | 实时错误提示 |
| 调试 | DAP Mode | 断点、单步、变量查看 |
| 格式化 | 各语言专用 | 保存时自动格式化 |
10.8 扩展阅读
← 上一章 第 09 章:Org-mode 进阶 | 下一章 → 第 11 章:Elisp 编程