强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 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 rC-c l r重命名
C-c fC-c l f格式化
TABTAB代码补全
C-c l a代码操作
C-c l g g跳转到定义

常用语言服务器

语言服务器安装命令
PythonPyright / Pylspnpm i -g pyright / pip install python-lsp-server
JavaScript/TypeScriptTypeScript Servernpm i -g typescript typescript-language-server
Rustrust-analyzerrustup component add rust-analyzer
Gogoplsgo install golang.org/x/tools/gopls@latest
C/C++clangdapt install clangd
JavaEclipse JDT自动安装
Lualua-lscargo install --git https://github.com/LuaLS/lua-language-server
Dockerdockerfile-lsnpm i -g dockerfile-language-server-nodejs
YAMLyaml-lsnpm i -g yaml-language-server
JSONvscode-json-lsnpm i -g vscode-langservers-extracted
HTML/CSSvscode-html-lsnpm 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 编程