ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Zed 自动补全的坑终于填上了

Zed 自动补全的坑终于填上了 不知道你有没有在Zed写代码的时候被自动补全背刺过。明明光标停在函数参数中间手按Tab选中补全项结果眼前的代码直接被改得面目全非。上一秒还好好的函数调用下一秒原有变量名直接消失留下一段语法不对的代码自己还要回退撤销重新敲一遍。这不是手速的问题是编辑器的补全逻辑悄悄自作主张了。这个坑的根源来自LSP协议本身。有些语言服务返回的补全项只有insertText和label并不附带textEdit也就是没有明确告诉编辑器应该插入还是替换哪一段文字。按照LSP文档的说法insertText交由客户端自行解释。这下难题就丢给Zed这边了。在本次修复之前Zed会自作聪明地向后查找光标后面的单词直接把整个现有单词当作待替换区间。举个例子来说test(value1, ˇvalue2)光标就在逗号后面、value2前面。LSP返回补全value2没有给出编辑范围。旧版Zed直接判定后面整个value2是要被替换掉的内容。一按Tab直接变成test(value1, value2)原有value2直接不见了。很多人以为是LSP服务出bug反复排查后端配置殊不知是Zed本地推断编辑区间的逻辑闯了祸。更让人头疼的是此时你的completions.lsp_insert_mode设置直接形同虚设。不管你配置的是插入模式还是替换后缀模式这一类缺失edit‑range的补全会直接无视该配置强制走替换逻辑。用户的设置完全不起作用相当于你的偏好被编辑器硬覆盖了。这次 zed终于修好了这个bug。核心改动思路很简单当LSP没有给出编辑范围的时候不再盲目的往后吃掉后面完整单词推断的编辑区间终止于光标位置。这么一改之后completions.lsp_insert_mode终于可以生效了。拿默认配置replace_suffix举例。value2并不是value2的后缀编辑器就选择插入最终结果test(value1, value2value2)看到这里有人会疑惑怎么没有直接覆盖这恰恰就是这套逻辑的本意。是否吃掉光标之后的文字现在由后缀校验规则说了算校验现在改用原始LSP的label不再拿菜单上美化过后的显示文字或者filterText去做判断。往后遇到LSP服务偷懒、不返回textEdit的补全项编辑器不再擅自做主删除后面的标识符。补全行为回归用户配置。不要小看这一处修复。日常写Go、Rust以外的第三方LSP时不少语言服务器都习惯只返回insertText。之前在Zed写这类项目时不时就要跟乱删代码的补全斗智斗勇。现在这一块终于理顺以后按Tab补全的时候心里总算踏实一点。
返回列表