基于 Company 编写了一个带中文注释的英文补全助手

十几年的 predictive 用户, 这个插件帮我这个英语渣渣编写各种英文邮件和文档和国外的开发者交流.

基于 Company 新写了一个英文补全的插件: GitHub - manateelazycat/company-english-helper: English helper base on Emacs company-mode

根据README安装以后, 直接把你喜欢的按键绑定到函数 toggle-company-english-helper 就可以了.

免得自己折腾, 下载下来就可以用.

经过 @tumashu 的帮忙, 现在所有补全对齐了.

默认的词典是从 stardict KDict 这个词典转换出来的, 包括11万单词.

如果你不喜欢默认的词库, 可以用我写的 stardict python 转换库 stardict.py 来转换你喜欢的 stardict 词典.

CompanyEnglishHelper 有简单的使用说明.

选项: 如果你的机器性能够好, 可以通过以下代码开启模糊搜索:

(setq company-english-helper-fuzz-search-p t)
29 个赞

company 已经用了 posframe, 能否让 中文叠加后, 右边的滚动条对齐? @tumashu

Very ok

暂时没有好了思路

词库是怎么来的呢?

就是 company-en-words 项目的, 看我帖子里面的连接

我只是做了一个方便的切换函数, company-en-words 项目提供词库.

调试了三个小时的 company

中文可以对齐了 (我用sqlite3做了数据源 所以搜索的结果可能会不一样)

关键的函数有 fill-propertize safe-substring create-lines clean-strings

关键的点是 length 与 string-width 对中文字符串的返回值不同

在我的机器上默认的会在中文前加上空格,楼主的却没有空格

所以我的解决方法 不一定适用于别的机器(代码我就不贴了)

其实就是简单的把 length 替换成 string-width

1 个赞

贴一下补丁吧, 我觉得层主解决了 company 在中文候选词计算的一个 bug

上面说过了 我的机器上默认会在中文上加空格

之前也有相关的讨论,见 spacemacs下英文写作有哪些技巧

对 company-mode 和 posframe 还不太熟,对不齐可能是因为

(string-width match) 这一行,对中文自动补了相应的 #xfeff(ZWNBSP,ZERO WIDTH NO-BREAK SPACE)。

默认这个字符显示为 thin-space,虽然很窄,还是可见的。

(char-table-range glyphless-char-display #xfeff) ;; => thin-space

可以设置为 zero-width,这样就显示正常了。

(set-char-table-range glyphless-char-display #xfeff 'zero-width)

但是 glyphless-char-display 这个变量是全局有效的,可能会影响其它应用。我试过用 make-local-variablemake-variable-buffer-local 设置好像都没有效果,不知道这个怎么设置。

当然也可以直接改函数 company--clean-stringpropertize 加个 invisible 属性或者用 string-compose 之类的(但我不知道这样改有什么后果):

-       (make-string (1- (string-width match)) ?\ufeff)
+       (propertize (make-string (1- (string-width match)) ?\ufeff) 'invisible t)
2 个赞

我改过clean-string了 在我的机器上会是空格 我直接删掉他了

删掉了之后就会出现 put-text-property error

是因为width越界 在width计算的时候是length

但是在create-lines的时候safe-substring 并使用string-width

期待大神们给 company 打一个完美的 CJK 支持补丁. :slight_smile:

这个问题的本质和 overlay菜单变残是一样的。。。暂时没有找到优美的方法解决。。。

用posframe不应该有overlay的问题啊

Try this hack:

(defun en-words-annotation (s)
  (let* ((str1 (get-text-property 0 :initials s))
         (str2 (replace-regexp-in-string "\\cc" "" str1))
         (w1 (length str1))
         (w2 (length str2))
         (n1 (max 0 (- 15 (- w1 w2)))))
    (format " [%s]" (concat str1 (make-string n1 ?\-)))))

但是他有中英文不等宽,string-width 不同而引起的问题

emacs自身不支持右对齐显示, 想显示在最右边只能想办法把左边填满, 而且是不多不少刚好填满, 等宽字体可以简单地用字符数计算, 非等宽字体(包括汉字)就麻烦了, 每个字符占用(像素)宽度不一样, 很难计算, 也很难填充. 跟overlay问题类似

" [%s]" 第一个空格去掉就完美了, 我在找和 - 等宽的空格 , 但是画出来是一个 下划线, 哈哈哈哈

知道我为什么用下划线了吧 。。。。

@tumashu Add company-en-words-candidate-max-width to control candidates aligment. · manateelazycat/lazycat-emacs@26c72e6 · GitHub

默认改成 30 现在都对齐了, 15 有些单词还不行, 解释太长了.