company-box-doc 与 robe / 让 company-box 读取 buffer local value

robe 在查找方法的文档的时候,会询问你要看哪一个 module 或者 class 下的方法。这在手动触发的时候当然是没问题的。但是在使用 company-box-doc 的时候,它会去调用文档,就会自动触发询问,打断了补全的过程。

完美的解决方案是直接提供所有的同名方法,这样就不用询问了。但是这样要修改 robe 的源码,超出了我的能力范围。
于是我试图在 robe 模式下关闭 company-box-doc。company-box-doc 中有一个值 company-box-doc-enable

但是这么设置却没有用!

(setq-local company-box-doc-enable nil)

经过探索,我发现 company-box 中 current-buffer 并不是当前所在的 buffer,而是用于显示 company-box 的内部的一个 buffer,由 company-box--get-buffer 这个函数生成。大概是 #<buffer *company-box-92274867*> 这个样子。

所以 company-box 是读取不到当前编辑所在的 buffer local value 的!

为了让它能够读取到,就需要把当前 buffer 传过去。可以这么处理:

(defun company-box-set-current-buffer (orig-fun &rest args)
    (let ((company-box-buffer (apply orig-fun args))
          (from-buffer (current-buffer))) ;; 由于是打算 advice-add company-box--get-buffer,所以这里的 current buffer 还是当前编辑所在的 buffer
      (with-current-buffer company-box-buffer ;; 把当前 buffer 传给 company-box 内部 buffer 的 local value
        (setq-local company-box--from-buffer from-buffer)) 
      company-box-buffer))
 
(advice-add 'company-box--get-buffer :around #'company-box-set-current-buffer)

然后在需要读取 buffer local value 的函数 hack 一下。控制显示 doc 的函数原来是这么写的:

(defun company-box-doc (selection frame)
  (when company-box-doc-enable 
   ;; 注意这里是读不到编辑所在的 buffer local value 的
   ;; 因为 current buffer 并不是编辑所在的 buffer
   ... ;; 以下代码省略

然后这么给它包装一下:

(defun hack-company-box-doc (orig-fun &rest args)
  (with-current-buffer company-box--from-buffer ;; 上一步传进来的编辑所在的 buffer
    (apply orig-fun args)))
  
(advice-add 'company-box-doc :around #'hack-company-box-doc)

这样就可以读取到了。以下配置就可以生效了:

(setq-local company-box-doc-enable nil)