用 LSP 补全来做输入法的体验

这几天实现了一个简单的 LSP 后端,用拼音输入法来提供中文补全,借助 lsp-bridge,基本不用写太多代码就能用了,效果如下,就是用 tab 和 enter 选词不习惯,想和大家讨论一下对用补全做中文输入的看法。

wen_completion

自己关于中文 LSP 服务的想法以及这个 LSP 的实现(比想象中简单很多)可以参考中文语言服务(language server)的畅想和基础实现

代码仓库见 GitHub - metaescape/Wen: 面向 orgmode 个人 知识管理的语言服务试验场

现在还用不了,因为 lsp-bridge 的补丁还没有合入,而且本地还有一些修改没提交 应该可以使用了

正好中秋,祝:

图片预览由 https://emacs-china.org/t/org-imagine-org/ 强力驱动,:smile:

18 个赞

lsp-bridge的补丁已经合并。

lsp-bridge要说贡献,其实是写了很多研究lsp协议的中文资料,让大家更方便理解lsp协议后,一起完善client的能力。

楼主已经在研究lsp server怎么实现的中文资料,不管server好不好用,其中的思考和讲解都能鼓励更多的同学加入实现新型lsp server的道路,大好事一件,给楼主点赞!

6 个赞

楼主这个想法,我在实现acm的过程中,就有想过中文补全的想法,下面是我的一些个人意见,还不成熟,供楼主参考。

  1. LSP的实现最有意义的是根据用户输入上下文进行长句语义分析接下来要输入的内容,通过长句预测提高输入命中概率,其实各个输入法本身都在做词库,词频和长句预测,如果LSP能做好,相当于统一接口,大家可以形成协力,而不是开发各种输入法框架
  2. 第二个优势和楼主想的一样,不用来回切换中英文,当然前提是server能力要完全可以替代输入法体验
  3. 最近在学国学,深刻理解中文输入法不好做的一个原因是,每个专业的词库和思维方式不一样,更复杂的是人在写文章的时候,脑袋里有一个场景或者词库习惯,但是机器不知道这些想法,想从当前场景推断出词库权重很难,真正难的是考察输入法作者的文学功底,既要饱读诗书又要有非凡的编程技巧,所以输入法做到60分以后就很难提高了

为什么会有这样的想法,就是想通过lsp server的方法来重写english backend,最终实现英文补全速度提升,甚至是语义级别的英文纠错和英文语法长句输入。

4 个赞

我发了一个新的补丁,合上应该就可以体验上了。

做这个尝试最主要就是想看看补全里用输入法是什么体验。

先是看到 lsp-bridge wiki 很丰富了,再看到 pygls 文档说可以很简单地实现一个 LSP server, 接着去 github 搜了一个公开的 python 输入法,竟然很快能用起来。 于是觉得这个做起来应该不会很麻烦。在此之前,不懂 LSP,也不懂输入法,所以有想法也不知道怎么动手。

blog 里的畅想是在看 LSP 的接口说明过程中,发现之前逛论坛看到的许多帖子提到的想法似乎都可以用一个面向中文解析的 LSP 服务统一来提供(像 blog 里说的,以前只是模糊的想法,因为不看说明的话, language server 这个名字很容易让人以为它是提供类似 grammarly 一样的英文写作辅助功能的软件),因为 LSP 协议接口里就定义了它所要服务的功能,比如 新人报到,写了个中文词性高亮的小功能,请各位前辈批评 - #19,来自 cireu 的中文分词, 腾讯AI编辑器Effidit体验 - #13,来自 yanyang 里内置的输入法,词汇替换,另外 tabnine 这些产品也很容易让人想到是否可以补全中文。emacs 或许可以和 LSP 结合起来产生新的可能,而且越想越觉得 emacs 这种功能面很广的编辑器很适合有一个本地的智能编辑助手来辅助,于是就整理写下来了。

至于输入法,中文补全能做到什么程度,得看 AI 发展水平了,比如是否能把规模做小放到本地,根据用户的数据方便地进行训练,很赞同你说的每个专业的思维方式都不样的看法,每个人可能有自己的私人语言,但我不太认同说输入法作者需要很强的文学功底的看法,因为我觉应该让输入法(或者 language server)根据本地的数据自己学,就和 rime 输入法使用久了会“学习”到常用词频一样,当然学的东西更复杂和抽象。

这个是不是可以作为数据源!

:+1: 是可以作为一个模块,提供语义检索,数据还是本地自己的。 这类功能我现在想的就是通过 find-symbol-reference 一类的接口来发请求,但具体效果还是得尝试一下,得找个支持中文特征的,有的话可以告诉我

我感觉这个超级有用,解决了模式输入以及写代码的最大痛点:切换输入法非常痛苦!以及写代码如果使用了中文变量名,自动补全非常痛苦。 这个如果做成一个lsp客户端的话,可以port到vim和vscode上啊哈哈哈。

一直想要的东西,大佬说的 专业词库,词频和长句预测,这些应该只是拼音输入法需要吧,形码以及某些音形输入法应该不需要这个,专注于单字输入的如三郑输入法应该就更不需要这个了。

3 个赞

coc-rime,vim也有个类似的这种方式的补全,和其他补全一起出现好奇怪。

是的,都是按 LSP 协议标准写的,理论上分别在不同编辑器适配一下前端就可以用。但用中文做变量名这我是没想到的😸

我最近自己使用也感觉到了,尤其是候选词多的时候会挤掉其他的补全,当然我只在 org 里用,因此其他补全项都是同文本里正则匹配的单词,这种情形不频繁(因为一个字符串即可以解释成英文单词又能解释成拼音的情形似乎比较少,不过在输入过程中,短的英文会被解释成拼音的前缀,导致输入英文时一直有中文候选词),但出现时确实有点奇怪。

另外我觉得直接用 rime 或其他现有输入法无法发挥 LSP 服务获得上下文这个特点,比如想打 “输入法” 这几个字,假设先打了 “输入” 后就选词了, 接着打 fa, 当前就是 “输入fa”,此时如果有上下文,这个 fa 的第一个选项就应该是 “法” 而不是 “发”, 但 rime 只拿到当前的 fa 这个拼音,按词频最高的可能就是 “发”。

或许至少对 rime 包装一下,读到 输入fa 后把 shurufa 传给 rime, 然后删掉返回的前两个字后返回 “法” 这个字

感谢 @manateelazycat 合入lsp-bridge 补丁,现在参照 github 链接安装好 LSP 后端应该就可以用了。 先说一下我自己这两天使用的体会:

对于使用者:

  • 如果在 org mode 下主要写英文,偶尔有中文,那基本是开箱即用
  • 在已经有其他 lsp 后端的编程环境下当前估计用不了,因为涉及多 lsp 后端的融合问题
  • 中文标点输入不太方便,这和 coc-rime/README.zh_cn.md at master · tonyfettes/coc-rime · GitHub 提到的问题类似,在 emacs 中可以绑定按键来切换全半角(例如 M-u )
  • 由于我只了解全拼输入,因此当前找的是公开的拼音输入法,如果是形码或其他的非全拼输入法,得自己动手了,见后文。

对于有时间折腾,又对输入法实现有兴趣的 hacker:

  • 当前用的输入法实现参考(这是我从网上找到的少有的有文档说明又有开源代码还能马上跑起来的拼音输入法): 如何从头开始实现一个中文拼音输入法? | Whatbeg's blog , 作者也说这只是一个课程项目,有很多可以改进的地方,比如使用中就遇到拼音切分的问题,如果输入 guniang, 由于是贪心的匹配,拼音切分结果是 “gun” “iang”, 导致打不出 “姑娘” 这个词,需要一个一个字输入,但应该可以通过添加词表来解决;或者把各种切分方式都考虑,不过这得重新训练模型。

  • 对于非拼音输入法,可以看一下 trans(prefix, pos): 函数,接口很简单,根据英文字符串和当前光标的位置(如果需要利用上下文的话),返回候选词列表,只要符合这个接口就行,而且用 python 读取任何纯文本的编码表都很方便,做成一个字典应该就能用了。

  • 可以尝试其他类似 tabnine 用大模型实现的开源算法,充分利用上下文, 比如不久前刚发了论文的 GitHub - VisualJoyce/Transformers4IME: Transformers for Input Method Engine

1 个赞

分词看看拼音库是否支持英文单引号手动分词?

不管输入法概率预测多准都不如用户手动分词体验好。

基于作者的博客,这个拼音算法不知道长句输入体验是否更好?

为了方便用户使用, 可以给wenls做一个pip包

1 个赞

感觉还是词库的来源有关, 如果说的话命中词库的风格, 长句输入就很好用。

歪楼问一下,猫哥用的什么字体?

代码用的文泉驿, org-mode/markdown 用的京楷

我也来试试,挺好看的。