elpy有一个补全比较好的地方就是,在jedi没有返回结果的时候,会去获取dabbrev的结果:elpy-company-backend
                 (cond
                  ;; The backend returned something
                  (result
                   (elpy-company--cache-completions arg result))
                  ;; Nothing from the backend, try dabbrev-code.
                  ((> (length arg) company-minimum-prefix-length)
                   (elpy--sort-and-strip-duplicates
                    (company-dabbrev-code 'candidates arg)))
                  ;; Well, ok, let's go meh.
                  (t
                   nil))
 
我把backend设成(company-lsp company-dabbrev-code) 这样子是没办法自动触发company-dabbrev-code的。
把backend设成((company-lsp company-dabbrev-code))或((company-lsp :with company-dabbrev-code))这样,补全的时候有轻微卡顿,并且结果也没有合并,重复选项非常多,排序也怪怪的。
我期待的是和elpy一样的结果,就是当lsp完全没有结果返回时才使用company-dabbrev-code。但是(company-lsp company-dabbrev-code)这样为什么不会自动触发company-dabbrev-code?输入一个lsp不会有结果的词,company-diag也显示的是Used backend: company-lsp。对这个词手动company-dabbrev-code是有结果的。
是否必须通过像(company-dabbrev-code 'candidates arg)这样注入代码到company-lsp才能达到效果?
             
            
               
               
               
            
                
           
          
            
              
                yicao  
                
               
              
                  
                    2019 年1 月 26 日 04:12
                   
                   
              2 
               
             
            
              我用ccls也遇到了这个问题,我自己的方案是,默认使用company-dabbrev-code,这样速度比较快,company-lsp绑定了一个快捷键 (Ctrl+Tab) ,在需要的时候手动触发,目前使用没啥障碍,速度也没什么影响
             
            
               
               
               
            
           
          
            
            
              多个backend和group的backends从来就没搞彻底懂过。。company-backends下面那一大段文档读了,实际多个backends使用时触发还是像谜的一样,难怪issue里那么多人也不懂backends的相互关系。。
我是想把它搞得稍微智能一点点。。因为不太喜欢手动触发。。哪怕需要配置。。曾经用过一位大神的hippie expand的配置,效果非常好,但是因为要手动触发,渐渐就不用了。。隔壁贴说模糊匹配之类的,我已经不敢指望了。。
             
            
               
               
               
            
           
          
            
            
              '(A B)这样的时候不重复还是可以做到的吧,是不是因为lsp有自动snippet之类的所以没有把相同的项识别出来?那大概需要自己手动把两个backend合并一下,感觉很难……
             
            
               
               
               
            
           
          
            
            
              对于lsp与dabbrev这种主力的backend,我是比较倾向于当一个backend完全没有结果的时候才使用下一个。不然的话排序也是个问题。所以elpy也是直接在callback里做(使用另一个backend)这件事。
我有个地方不太明白,输入一个不存在的prefix,例如:“haha”,company-lsp里返回的prefix是"haha",但此时其实它不能补全,为什么没办法把控制交给下一个backend?是因为它是个async的backend的缘故?company-backends的文档里说要返回nil才把控制交给下一个backend。
我看了一些别的一些backend也会有这样的,这样的意思是不是要求每一个company-backends里面的元素都是一“类”backend?因为不同“类”才会使触发prefix不一样(比如company-files不在字符串里会自动不补全)。否则,prefix不是nil,但又不能补全,company-backends里塞一大堆那有什么用。。
文档里说Only one backend is used at a time。好奇为什么没法做到一个backend没结果了,就按顺序触发下一个,哪怕此时prefix不是nil?
             
            
               
               
               
            
           
          
            
            
              
如果一个后端没有补全结果,compnay就会按顺序启用下一个。这个跟prefix返回的结果没关系。
             
            
               
               
               
            
           
          
            
            
              似乎并不会。例如在一个elisp buffer里如果company-backends的值为(company-elisp company-dabbrev-code),文件内容为:
(defun hahahaha ()
  )
haha*
 
此时光标在*处的话,是不会触发company-dabbrev-code的。因为文档里说当一个backend调用prefix时返回nil,才会触发下一个。但此时company-elisp返回的prefix是haha,所以不会触发下一个。
也就是说“应不应该补全”和“能不能补全”不太一样。但“不能补全”时如果prefix不是nil的话,应该是不会触发下一个的。
Returning nil from this command passes
control to the next backend.  The function should return stop if it
should complete but cannot (e.g. when in the middle of a symbol).
 
             
            
               
               
               
            
           
          
            
            
              之前遇到同样问题, 并提了一个issue: For a backend group, if the first backend gives candinates, how to discard candinates from the second backend? · Issue #806 · company-mode/company-mode · GitHub 
我的想法跟LZ稍微不同, 我是想让两个后端同时开工, 这样(理论上)响应速度快, 如果第一个backend有返回结果, 就把第二个的丢弃, 用第一个, 如果第一个没有返回结果, 就用第二个的.
company目前不支持这样, 不过issue里面最后提供的方法也很接近想要的效果, 可以试试.
             
            
               
               
               
            
           
          
            
            
              lsp补全的工作大部分在外部的lsp服务器, 所以可以并行. company目前就相当于并行的, 因为backend很多都是异步, 只需要提供上面提到的丢弃的功能即可.
             
            
               
               
               
            
           
          
            
            
              :separate那种方法,结果不会合并。。好多重复
             
            
               
               
               
            
           
          
            
            
              你可以看下那个issue的跟帖, 里面就是在讨论这个问题, 最后有一个方法还可以
             
            
               
               
               
            
           
          
            
            
              
里面本来也没说会合并啊, 最后的效果是让补全项按backend的顺序显示, 比如company-lsp的补全项显示在前面, 另外一个的显示在后面, 这样保证了你优先看到company-lsp的补全项
             
            
               
               
               
            
           
          
            
            
              这个问题有办法了吗,company-lsp为什么会在没结果的时候阻止后面的backends触发啊?
这个问题的影响不算非常大,因为company-lsp会给出当前scope可用的变量、函数等符号,基本算是包括了company-dabbrev-code的功能,只剩关键字之类的没法补全。
             
            
               
               
               
            
           
          
            
              
                SGNH  
                
               
              
                  
                    2019 年10 月 20 日 04:12
                   
                   
              18 
               
             
            
              可以在补全结果增加一个后端标识符,选候选时可以输入后端标识符列出该后端的匹配项,参考vscode不知道行不行