前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 eglot 代替 lsp-mode

使用 eglot 代替 lsp-mode

作者头像
飞驰的西瓜
发布2022-07-26 16:48:37
7010
发布2022-07-26 16:48:37
举报
文章被收录于专栏:EmacsTalk

LSP 是当前使用最广泛的一套协议,用于给文本编辑器提供类似 IDE 的功能,比如:自动补全、定义跳转等。对于 Emacs 来说,主要有两个实现:

•emacs-lsp/lsp-mode,主打功能丰富

•joaotavora/eglot,主打小巧精悍

笔者本人在使用 lsp-mode 多年后转到了 eglot,主要觉得 lsp 太占用内存,很多功能华而不实。

下面是笔者在使用 lsp-mode 几天后,执行 memory-report 后的数据(完整版):

代码语言:javascript
复制
Largest Variables

   1.8 GiB  lsp-clients
   1.8 GiB  lsp--session
   1.8 GiB  lsp--last-active-workspaces
   4.6 MiB  package-archive-contents
   4.5 MiB  elfeed-db

Largest Buffers

   3.6 GiB  database.rs
   3.6 GiB  source.rs
   3.6 GiB  history-backup/main.rs
   1.8 GiB  datafusion-5.0.0/src/logical_plan/expr.rs
   1.8 GiB  prometheus.rs
   1.8 GiB  libsqlite3-sys-0.23.2/src/error.rs

可以看到,占内存最高的变量都与 lsp-mode 有关,而且在用 lsp-mode 进行 Rust 开发时,能明显感到卡顿,根本不敢用 rust-analyzer 来进行补全,之前笔者都是用 tabnine 来进行 Rust 代码的补全,只用 lsp 来进行『查找定义』。

在替换成 eglot 后,内存使用就没有这么夸张了,用 rust-analyzer 进行补全时,之前的卡顿感没有了,和在 VSCode 中的体验无异。而且 eglot 的依赖很少,会尽量复用 Emacs 内置的模块,比如采用 flymake,而不是 flycheck,也有相关 issue 讨论如何用在 eglot 中使用 flycheck:

•How to configure eglot to use flycheck? · Issue #42

笔者使用 eglot 的配置如下,主要进行了下面三点的改进:

1.eldoc 高度限制为 3 行,太大了影响阅读代码

2.修改高亮『当前变量』的字体,默认的不是很明显

3.增加 Rust 宏展开的命令,lsp-mode 默认支持,这里给出了 eglot 的实现

代码语言:javascript
复制
(use-package eglot
  :defer t
  :commands (eglot-ensure my/rust-expand-macro)
  :config
  (progn
    (setq eldoc-echo-area-use-multiline-p 3
          eldoc-echo-area-display-truncation-message nil)
    (set-face-attribute 'eglot-highlight-symbol-face nil
                        :background "#b3d7ff")

    (defun my/rust-expand-macro ()
      "Expand macro at point, same as `lsp-rust-analyzer-expand-macro'.
https://rust-analyzer.github.io/manual.html#expand-macro-recursively"
      (interactive)
      (jsonrpc-async-request
       (eglot--current-server-or-lose)
       :rust-analyzer/expandMacro (eglot--TextDocumentPositionParams)
       :error-fn (lambda (msg) (error "Macro expand failed, msg:%s." msg))
       :success-fn
       (lambda (expanded-macro)
         (cl-destructuring-bind (name format expansion result) expanded-macro
           (let* ((pr (eglot--current-project))
                  (buf (get-buffer-create (format "*rust macro expansion %s*" (cdr pr)))))
             (with-current-buffer buf
               (let ((inhibit-read-only t))
                 (erase-buffer)
                 (insert result)
                 (rust-mode)))
             (switch-to-buffer-other-window buf))))))
    ))

Rust 宏展开示意图

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 EmacsTalk 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档