给那些没有弹出文档功能的company补全后端把这个功能给加上去

这只是一个尚不成熟的初步设想,发出来避免自己闭门造车,也许还有更好的解决方案

开始想自己写一个补全后端自用,但能力有限难以做到,又发现lsp以外的各种补全后端其实也是相当好用的,只要解决数据源问题在加上弹出文档功能就行了。

数据源问题不知如何解决,这里说下目前我是如何加上弹出文档功能的。

1、定义弹出文档数据源

(defun company-my-doc-buffer (arg modename) ;;arg值是补全项,第二个参数是major-mode
  "定义弹出文档显示的数据源"
  (with-current-buffer (get-buffer-create "*my-doc*")
    (erase-buffer)
    (when arg
      (save-excursion
        ;;(insert arg)
        ;;(insert (shell-command-to-string (format "php.exe -f d:/www/emacs.php -- %s %s" 
            ;; (url-encode-url arg) modename ) ))
        (url-insert-file-contents 
         (format 
          "http://localhost/emacs.php?p=%s&mode=%s"
          (url-encode-url arg) modename ))
    (current-buffer)))
))

我主要就写点js,css,php,个人习惯是把所有数据都保存在数据库里而不是保存在文本文件里。

数据库主要用mysql,sqlite因为在持续不间断写入数据时会锁表导致做不了数据查询操作,不知道怎么解决这个问题,现在不怎么用了。

这里为了能尽快上手,就没用elisp来连接mysql读取文档数据。而是用了其它语言先写好,elisp用shell-command-to-string或者url-insert-file-contents调用(目前还没遇到性能问题和卡emacs情况).

2、找一个没见有弹出文档功能但是好用的company后端把这个函数加进去。

比如@redguardtoo大佬的company-ctags,找到安装包位置,我的是~./emacs.d/elpa/company-ctags-20201121.1116/company-ctags.el

在第476左右找到(candidates (company-ctags--candidates arg))这句后面加上(doc-buffer (company-my-doc-buffer arg major-mode)),然后光标移到最外层括号c-x c-e

要重启emacs后也能用需要m-x byte-compile-file编译出company-ctags.elc文件

这个方法不太好,应该有更好的方法可以不用改动el源文件的,如果有人知道请告知。

companpy自带的company-abbrev-code,company-keywords等我也用一样的方法加上了弹出文档功能。

当然要具备弹出文档功能还要装上company-quickhelpcompany-posframe否则需要在候选项上按c-h或f1才会有弹出文档。

效果图

剩下的就是数据源问题了…

8 个赞

不好意思,一开始没太注意标题。

我觉得这个想法不错。

数据源就用dash. 现成的方案有。这样集成是很不错,好主意。

可能可以使用 dash.el 的API

company-box挺好使啊,当然要加上其他第三方数据源就需要自己做了

不过我觉得我并不会在补全的时候看文档,我觉得靠补全列表找文档是个很不合理的事。如果真的要找文档,应该是用搜索的方式,特别是针对文档的内容。

5 个赞

用counsel-etags好像能把网上的document作为tag存起来以作查找, 但我还没自己去实现过.

补全列表文档肯定不能取代找文档的功能,有时候一些函数、api的用法要讲清楚,是需要长篇大论的,补全项弹出文档只适合放一些简短的内容。

代码写多了总会遇到某些函数、api名字比较长的那种,把简写展开都可以组成一句英文的,这时一般做不到看到函数名就能想起函数的用法,需要有个提示语在旁边看下才能想得起来,弹出文档功能充当这个提示语应该是比较合适的。

给company的补全后端加advice? 给它们加个doc-buffer的处理。

类似给补全前端加advice(这里是不想让doc一直显示)

(use-package company-quickhelp
  :bind
  (:map company-active-map
        ([remap company-show-doc-buffer] . company-quickhelp-manual-begin))
  :hook (global-company-mode . company-quickhelp-mode)
  :config
  (setq company-quickhelp-delay nil)
  (defun +company-quickhelp-may-hide-on-move-a (fn command)
    (if (eq command 'update)
        (unless company-quickhelp-delay
          (company-quickhelp--hide)))
    (funcall fn command))
  (advice-add #'company-quickhelp-frontend :around #'+company-quickhelp-may-hide-on-move-a))