共217行

emacs29, eglot 介绍和配置

2026-07-11 22:14:48

Emacs 29 现代化 Eglot 完整配置

Emacs29 内置 eglot,无需额外安装包,搭配内置 tree-sitter、completion-at-point、flymake、eldoc,开箱即用,兼顾性能、自动适配、轻量现代化体验。

前置说明

  1. Emacs ≥29.1,自带 eglottree-sitterflymakeeldoc
  2. 需自行安装对应语言 LSP Server(eglot 自动检测,部分需手动配置路径)
  3. 依赖可选:orderless 模糊补全、consult 跳转、cape 增强补全(现代化补全栈)

完整配置(可直接写入 init.el)

;; ====================== Eglot 全局基础配置 ======================
(use-package eglot
  :hook
  ;; 主流编程语言自动启用 eglot,按需增删
  ((c-ts-mode . eglot-ensure)
   (c++-ts-mode . eglot-ensure)
   (python-ts-mode . eglot-ensure)
   (js-ts-mode . eglot-ensure)
   (typescript-ts-mode . eglot-ensure)
   (rust-ts-mode . eglot-ensure)
   (go-ts-mode . eglot-ensure)
   (bash-ts-mode . eglot-ensure)
   (json-ts-mode . eglot-ensure)
   (yaml-ts-mode . eglot-ensure)
   (toml-ts-mode . eglot-ensure)
   (markdown-ts-mode . eglot-ensure)
   (html-ts-mode . eglot-ensure)
   (css-ts-mode . eglot-ensure)
   (java-ts-mode . eglot-ensure)
   (lua-ts-mode . eglot-ensure))
  :init
  ;; 全局开关
  (setq eglot-autoshutdown t)          ; 无buffer自动关闭LSP进程,节省内存
  (setq eglot-connect-timeout 10)      ; LSP连接超时10秒
  (setq eglot-sync-connect nil)         ; 异步连接LSP,不阻塞打开文件
  (setq eglot-event-log nil)           ; 关闭冗余日志,提升性能
  (setq eglot-wait-for-server-ready 3) ; 等待服务就绪最大时长

  ;; 补全行为优化
  (setq eglot-completion-annotation-format "%s")
  (setq eglot-completion-show-signature t) ; 补全时显示函数签名
  (setq eglot-expand-snippet t)             ; 支持LSP代码片段snippet

  ;; 代码格式化
  (setq eglot-format-on-save t)     ; 保存自动格式化代码
  (setq eglot-format-async t)      ; 异步格式化,不卡顿编辑器

  ;; Flymake 诊断(内置语法检查,无需flycheck)
  (setq eglot-flymake-show-buffer-diagnostics t)
  (setq flymake-fringe-indicator-position 'left) ; 左侧显示错误标记
  (setq flymake-no-changes-timeout 0.5)           ; 修改0.5s后刷新诊断

  ;; Eldoc 文档悬浮提示
  (setq eldoc-echo-area-use-multiline-p t)        ; 多行文档提示
  (setq eldoc-idle-delay 0.3)                     ; 光标停留0.3s显示文档
  (setq eldoc-minimum-maximum-width 80)

  ;; 代码折叠
  (setq eglot-folding-mode t)

  ;; 符号高亮(光标同变量高亮)
  (setq eglot-highlight-references t)

  :config
  ;; 全局快捷键绑定
  (define-key eglot-mode-map (kbd "M-.") #'eglot-find-definition)       ; 跳定义
  (define-key eglot-mode-map (kbd "M-,") #'eglot-find-implementation)  ; 跳实现
  (define-key eglot-mode-map (kbd "M-?") #'eglot-find-references)      ; 查找引用
  (define-key eglot-mode-map (kbd "C-c r") #'eglot-rename)              ; 符号重命名
  (define-key eglot-mode-map (kbd "C-c a") #'eglot-code-actions)        ; 代码修复/操作
  (define-key eglot-mode-map (kbd "C-c f") #'eglot-format-buffer)       ; 手动格式化
  (define-key eglot-mode-map (kbd "C-c s") #'eglot-show-documentation)   ; 查看文档
  (define-key eglot-mode-map (kbd "C-c o") #'eglot-organize-imports)    ; 整理导入

  ;; 禁用弹窗式提示,改用echo area轻量提示
  (setq eglot-display-help-on-popup nil)

  ;; LSP Server 自定义映射(路径/参数覆盖,按需修改)
  (add-to-list 'eglot-server-programs
               '(python-ts-mode . ("pyright"))) ; Python pyright
  (add-to-list 'eglot-server-programs
               '(rust-ts-mode . ("rust-analyzer")))
  (add-to-list 'eglot-server-programs
               '(typescript-ts-mode js-ts-mode . ("typescript-language-server" "--stdio")))
  (add-to-list 'eglot-server-programs
               '(c-ts-mode c++-ts-mode . ("clangd")))
  (add-to-list 'eglot-server-programs
               '(go-ts-mode . ("gopls")))
  (add-to-list 'eglot-server-programs
               '(yaml-ts-mode . ("yamlls")))
  (add-to-list 'eglot-server-programs
               '(bash-ts-mode . ("bash-language-server" "start")))

  ;; 自定义 clangd 参数(C/C++)
  (cl-loop for server in '((c-ts-mode . "clangd") (c++-ts-mode . "clangd"))
           do (setf (cdr (assoc (car server) eglot-server-programs))
                    '("clangd" "--background-index" "--clang-tidy" "--header-insertion=never")))

  ;; rust-analyzer 专属配置
  (setq eglot-workspace-configuration
        '((rust-analyzer . ((checkOnSave . ((command . "clippy"))))))))

;; ====================== 现代化补全栈(cape + orderless) ======================
;; 替代老旧 company,Emacs29 原生 completion-at-point 增强
(use-package cape
  :init
  ;; 组合 LSP、文件、关键字补全源
  (add-to-list 'completion-at-point-functions #'cape-dabbrev)
  (add-to-list 'completion-at-point-functions #'cape-file)
  (add-to-list 'completion-at-point-functions #'cape-elisp-symbol)
  :config
  (cape-completion-at-point-setup))

;; orderless 模糊匹配补全
(use-package orderless
  :init
  (setq completion-styles '(orderless basic))
  (setq completion-category-defaults nil)
  (setq orderless-matching-styles '(orderless-literal orderless-flex)))

;; ====================== Consult 增强 LSP 跳转(可选,体验大幅提升) ======================
(use-package consult-eglot
  :after eglot consult
  :config
  ;; 替换原生查询,交互式预览跳转
  (define-key eglot-mode-map (kbd "M-?") #'consult-eglot-references)
  (define-key eglot-mode-map (kbd "M-.") #'consult-eglot-definitions)
  (define-key eglot-mode-map (kbd "C-x c") #'consult-eglot-symbols)) ; 当前文件符号搜索

;; ====================== Tree-sitter 配套(Emacs29 内置,语法高亮) ======================
(use-package treesit
  :init
  (setq treesit-auto-install t) ; 自动下载语法解析器
  (setq treesit-font-lock-level 4) ; 最高层级语法高亮
  :config
  (treesit-auto-add-missing))

;; ====================== Flymake 美化诊断提示 ======================
(use-package flymake
  :init
  ;; 诊断列表快捷键
  (global-set-key (kbd "C-c n") #'flymake-goto-next-error)
  (global-set-key (kbd "C-c p") #'flymake-goto-prev-error)
  :config
  (flymake-mode-line-lighter "")) ; 清空mode-line多余文字

核心特性说明(现代化亮点)

1. 性能优化

2. Emacs29 原生生态,无重型第三方依赖

3. 开箱即用多语言LSP映射

预置主流语言服务:

4. 现代开发功能

  1. 保存自动格式化代码(异步不卡顿)
  2. 变量/符号实时高亮
  3. LSP代码片段snippet支持
  4. 代码折叠、导入自动整理
  5. 符号重命名、一键代码修复
  6. 交互式引用/定义预览(搭配consult-eglot)

配套安装提示(系统层面)

各语言LSP服务安装示例

# Python pyright
npm install -g pyright
# TS/JS tsserver
npm install -g typescript-language-server typescript
# Yaml
npm install -g yaml-language-server
# Bash
npm install -g bash-language-server
# C/C++ clangd
# Ubuntu: apt install clangd
# Mac: brew install llvm
# Rust-analyzer
# 官网下载二进制或rustup组件
rustup component add rust-analyzer
# Go gopls
go install golang.org/x/tools/gopls@latest

可选扩展微调

  1. 关闭自动格式化
    (setq eglot-format-on-save nil)
  2. 单独关闭某语言自动启用eglot
    删除对应 xxx-ts-mode . eglot-ensure hook行即可
  3. 弹窗文档(喜欢悬浮窗口可开启)
    (setq eglot-display-help-on-popup t)
  4. 禁用符号同高亮
    (setq eglot-highlight-references nil)

极简轻量版(不想装cape/consult)

如果只需要基础eglot,删掉 capeorderlessconsult-eglot 三段配置即可,仅保留eglot+treesit基础部分,功能完整无冗余依赖。