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

我才推送了一个补丁

增加了自定义函数 lsp-bridge–get-language-id-func

你看符合你意不? :smile:

我看了 add all supported languageId for tailwindcss.json and emmet-ls.json by liuyinz · Pull Request #950 · manateelazycat/lsp-bridge · GitHub 这个补丁

从我的理解看, 只要你自定义 lsp-bridge–get-language-id-func 函数, 你基本上可以随心所欲的根据 project-path file-name server-name extension-name 来自定义传递给 LSP Server 的 languageId。

langserver/*.json 下的JSON文件不用填这些 languageId 列表, 写死了反而跟不上 TailwindCSS 这种动态的 LSP Server 的发展。

可问题在于python端需要去检测返回的string是否是合法值,比如tailwindcss不支持python,如果用户返回”python“,lsp也要做检验的吧

(defun lsp-bridge--get-language-id-func (project-path file-name server-name extension-name)
  ;; Some LSP server, such as Tailwindcss, languageId is a dynamically field follow with file extension,
  ;; we can't not receive respond to `completionItem/resolve` request if send wrong languageId to tailwindcss.
  ;;
  ;; Please reference issue https://github.com/tailwindlabs/tailwindcss-intellisense/issues/925.
  (when (string-equal server-name "tailwindcss")
    (if (string-equal extension-name "jsx")
        "javascriptreact"
      extension-name)))

你看lsp-bridge–get-language-id-func默认的实现只是对 TailwindCSS 做了特殊处理, 大部分语言的 languageId 判断还是在 lsp-bridge Python端根据 langserver/*.json 的JSON文件定义来的。

这样的好处是兼顾了99%语言的预先定义 languageId, 用户又可以自定义 lsp-bridge–get-language-id-func 函数来实现最大程度的自定义。

至于你说的用户反馈一个错的 lanaugeId 故意去迷惑 LSP Server, lsp-bridge 管不着哇。

那这样的话,languageId 就保持空白,也许可以在id-func 给一些tailwindcss fiiletype的参考链接 :grinning:

建议保持一致的风格,和single/multi-server-by-project 一样 传入一个方程

(defcustom lsp-bridge-get-languageid-func
  #'lsp-bridge--get-language-id-func-by-default
  "Function to get language id for multi-server.
Some lsp like emmet-ls or tailwindcss need to get language id dynamicly
according to different framework and project. When server start, lsp-bridge
would call this function to get returned string value as
languageID. If return nil, server start failed.")

目前的逻辑优先级是:

  1. 根据 lsp-bridge–get-language-id-func 函数来返回的 lanaugeId
  2. 然后再看 langserver/*.json 中是否定义了 languageIds, 比如 vscode-css-language-server.json
  3. 最后再看 langserver/*.json 中是否定义了 languageId, 这个99%的语言都可以满足
  4. 万一 languageId 是空字符串就返回扩展名 (这一步完全是逻辑保险, 这一步应该触发不了)

而且第四个参数好像是多余的,extension-name用户自己就可以用filepath推断出来

传入 filepath比filename更好啊,要不然的话我还是无法准确定位文件的

你说的这几个问题, 等我一并写补丁, extension-name 这一块 Python 写了就不用 elisp 再计算一遍了。

按照你的逻辑优先级,其实single server的languageID也是可以覆盖的,不是完全写死的,这个我倒是没想到。

我有点强迫症。。

是的, 只是目前还没有发现那个单语言服务器需要这种级别的自定义。

无所谓吧,应该增加不了太多耗时,反正pcase我 server-name 只匹配到tailwind/emmet,要不然直接返回 nil 了,

我添加了一下文档, 其实Python端传过来的就是 file-path, lsp-bridge–get-language-id-func 的形参写错名字了。

从设计流程来说, 不会对性能有什么影响, 因为只会在打开文件的时候调用一下, 频率非常低,但是依然要注意这个自定义函数不要卡死, 卡死会导致 lsp-bridge 无法发送 textDocument/didOpen 请求给 LSP server。

虽然 lsp-bridge 的设计永远不会因为 Elisp 自定义函数卡住Emacs, 但是如果 textDocument/didOpen 请求没法正常发送, 后续也没法收到LSP Server返回的补全消息。

我开头提到的 git-init 问题 project-path 该怎么解决? 默认返回值还真的不如返回nil 来表明它是单文件模式,更直观,反正有另一个filepath,完全不需要两个相同的值,我写函数判断也好判断是单文件模式。 :sweat_smile:

我给你举一个例子: Python 在 lsp-bridge 默认是用多个服务器 pyright 和 ruff 来分别提供补全和诊断功能的, 但是 Python 这两个服务器都是支持单文件直接用的。

所以, 我没法为了满足 TailwindCSS 的需求就强制报错, 强制报错就会对 Python 用户造成很大的困扰。

好吧,那我就加一层判断函数来判断吧 :smiling_face_with_tear:

vscode-eslint-language-server 好像也支持多种语言,我把他的id也设为空了,你看一下