共217行
2026-07-11 22:14:48
Emacs29 内置 eglot,无需额外安装包,搭配内置 tree-sitter、completion-at-point、flymake、eldoc,开箱即用,兼顾性能、自动适配、轻量现代化体验。
eglot、tree-sitter、flymake、eldocorderless 模糊补全、consult 跳转、cape 增强补全(现代化补全栈);; ====================== 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多余文字
eglot-sync-connect nil:异步启动LSP,打开大文件不卡顿eglot-autoshutdown t:关闭项目自动销毁LSP进程,减少内存占用company,基于内置 completion-at-point + cape 轻量补全flymake 替代 flycheck,不用额外安装检查插件tree-sitter 精准语法解析,比旧font-lock高亮更智能eldoc 悬浮文档,无需lsp-ui等臃肿包预置主流语言服务:
# 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(setq eglot-format-on-save nil)xxx-ts-mode . eglot-ensure hook行即可(setq eglot-display-help-on-popup t)(setq eglot-highlight-references nil)如果只需要基础eglot,删掉 cape、orderless、consult-eglot 三段配置即可,仅保留eglot+treesit基础部分,功能完整无冗余依赖。