lsp-bridge -- 速度最快的语法补全插件

不考虑性能之类的,单纯从补全内容的角度来说,citre的优点是可以跨语言补全,同时如果lsp不支持补全的东西,如果能够基于正则去获取关键词,用ctags写一个正则来获取关键词很容易。虽然现在lsp不能补全但是可以用正则进行补全的东西应该很少了吧。

请问如何设置某个mode下启用什么server

主要是我的html文件只启动了vscode-html-language-server而没有emmet

非常感谢🙏🏻,看了 acm-backend-lsp-candidate-expand 函数,大概理解 completion 消息部分的主要几个关键字和解析方式了

1 个赞

收到,谢谢!

lsp-bridge 里基本是用 bounds-of-thing-at-point 来获得光标当前的字符作为 keyword 去匹配候选项词,但这会把中文连着英文的情况都选上,比如输入 “使用emacs“ 这时候尽管 emacs 是文件里已经有的词,但输入时也不会匹配到候选项,因为 prefix 会把 “使用” 也算上,有考虑改吗?如果可以改,有推荐的只获取英文单词的函数吗?

我当前是自己定义一个函数

(defun acm-get-input-prefix-bound ()
  (let ((bound (bounds-of-thing-at-point 'symbol)))
    (when bound
      (let* ((keyword (buffer-substring-no-properties (car bound) (cdr bound)))
             (offset (string-match "[[:ascii:]]+" keyword)))
        (cons (+ (car bound) offset) (cdr bound))))))

然后把 bounds-of-thing-at-point 都替换成这个

我是这么 hack 的. 然后在 project 里用 add-dir-local-variable 设置 mlb-enable-lspacm-enable-citre 的值

(defcustom mlb-enable-lsp t
  "Enable lsp server."
  :local t
  :type 'boolean
  :group 'my)

(put 'mlp-enable-lsp 'safe-local-variable #'booleanp)

(defun mlb-has-lsp-server-p (fn &rest args)
  "Around advice for `lsp-bridge-has-lsp-server-p'."
  (when mlb-enable-lsp
    (apply fn args)))

(advice-add #'lsp-bridge-has-lsp-server-p :around #'mlb-has-lsp-server-p)

可以发个补丁,谢谢。

请问我想根据最后一个输入的字符来决定使用不同的补全方法,应该修改那个函数?就像在company mode中我可以写一个backend来按照prefix 来补全

比如说当我输入“test”时我会提交给lsp server来补全,但当输入"test$"时我会提交给另一个进程来补全。

目前是根据mode来发送不同后端的,如果要做到最后一个字符,需要自己写代码判断。

问一下,为啥有这种需求呢?

谢谢回复,应用场景比较特殊。R的language server不能读取data.frame中的列数据。这部分的补全是由ess的进程提供(I am not getting completeion with $ · Issue #340 · REditorSupport/languageserver · GitHub)。我之前用company+lsp的时候就是自定义了个backend判断prefix最后字符是不是$,如果是$就交给ess进程。

我如果要达到类似效果的话,请问我应该去改写哪个函数?

今天更新后,只要输入非英文,比如中文,就会提示错误

Error in post-command-hook (lsp-bridge-monitor-post-command): 
(wrong-type-argument number-or-marker-p nil)

不知大家是否也遇到这样的问题。

当回滚到 adec95f 就一切正常,没有错误提示,也能正常输入中文。

这个应该是我的提交引入的,抱歉 :sweat:,我先看看 报错之后就无法输入中文了吗?

1 个赞

是的,报错后无法输入中文,其它补全也实效,重启lsp-bridge也无效!

可以回滚你那个补丁,中文过滤在你的后端过滤,不要全局过滤。

应该就不会影响其他补全后端了。

ess进程是啥?另外一个lsp server?

没法完全在后端处理好这个问题,因为 acm 的边框起点用的是

(setq acm-frame-popup-point (or (car bounds) (point)))

而 bounds 原本是直接用 (bounds-of-thing-at-point 'symbol) 获得的,这种情况如果 输入是 “我们使用ema”,得到的边界的起点是 “我”,终点是 “a”, 导致无法对 ema弹出补全候选词 “emacs”, 因为整个前缀是 “我们使用ema” 而不是 “ema”,这对 Search word 乃至所有后端都是失效的

主要问题是因为 bounds-of-thing-at-point 不会对中英文自动分开处理 我在 lsp-bridge -- 速度最快的语法补全插件 - #2103,来自 twiddling 里用 string-match 去找第一个 ascii 字符的位置,然后加上 offset 把中文排除,但如果全是中文,返回的 offset 就是 nil ,而 nil 还要继续参与加法导致报错。

我改成从后往前搜 ascii 子串应该就可以

1 个赞

修改 acm-update-candidates 吧,我自己 hack 了一个和你的想法差不多的 :rofl: demo

2 个赞

是R的REPL

你们玩的太高端了,把我整不会了,发补丁吧

1 个赞