Yasnippet和company mode结合的问题

搞了半天,按照子龙山人的配置,可以手动调用 company-yasnippet 补全,但无法实现tab补全, tab好像集合了太多功能,难道非要自己写tab的绑定方法?初学,完全不会,困扰了一下午,无解. 我的理解是company-mode是不需要使用tab的,但是为何始终无法列出yasnippet? 另外:子龙山人第十天的视频,看了好像还是很迷糊.补全我认为就三点必须有,一个是根据api补全,二是根据现有文件,三是根据自定义的snippet.snippet code这个东西如果用的好可以省掉很多枯燥无味的代码.浅见 如果有哪位高手对snippet和company-mode结合的问题有研究的话,烦请不吝赐教.

我的配置现在是用 CMD+/ 来补全snippets,使用的是 hippie-expand.

如果要在 company-mode 的补全选项中列出 snippet,可以 参考文档:

https://github.com/syl20bnr/spacemacs/tree/master/layers/auto-completion#show-snippets-in-auto-completion-popup

是不是没有把 company-yasnippet 添加到 company-backends 里面去?

还有个地方值得注意: 最好将 company-yasnippet 和其他的后端作为组合添加到 company-backends ,参见 company-yasnippet 帮助文档。

原因没找到,后来我用原生的spacemacs 问题解决了,不需要任何配置.但是有个问题,webmode的时候,style 补全会很卡,问题真不少.最近项目紧,先停几天,暂时还达不到工作的标准.谢谢回复

搭车问一下,默认是Meta-/绑定为hippie-expand的,这个我发现了,我想把tab绑给hippie-expand,默认按tab也会expand,但是输入之后会出现自动补全下拉菜单,这时候tab会给它吃掉(按tab下拉菜单高亮条目向下),左右移动一下光标让菜单消失之后按tab就正常。我尝试加了(define-key evil-insert-state-map (kbd "<tab>") 'hippie-expand),没能解决问题。求教。

可以参考Emacs Stack Exchange上的回答来设置,绝大部分情况下Emacs都能知道TAB应该做什么事情,已亲测。

1 个赞

@knightgu 关于tab snippet模式冲突的问题,有个奇怪的问题,这个设置用不了,初始化提示yas-keymap为空

(defun check-expansion ()
  (save-excursion
(if (looking-at "\\_>") t
  (backward-char 1)
  (if (looking-at "\\.") t
(backward-char 1)
(if (looking-at "->") t nil)))))

(defun do-yas-expand ()
  (let ((yas/fallback-behavior 'return-nil))
(yas/expand)))

(defun tab-indent-or-complete ()
  (interactive)
  (cond
   ((minibufferp)
(minibuffer-complete))
   (t
(indent-for-tab-command)
(if (or (not yas/minor-mode)
(null (do-yas-expand)))
(if (check-expansion)
(progn
  (company-manual-begin)
  (if (null company-candidates)
  (progn
    (company-abort)
    (indent-for-tab-command)))))))))

(defun tab-complete-or-next-field ()
  (interactive)
  (if (or (not yas/minor-mode)
  (null (do-yas-expand)))
  (if company-candidates
  (company-complete-selection)
(if (check-expansion)
  (progn
(company-manual-begin)
(if (null company-candidates)
(progn
  (company-abort)
  (yas-next-field))))
  (yas-next-field)))))

(defun expand-snippet-or-complete-selection ()
  (interactive)
  (if (or (not yas/minor-mode)
  (null (do-yas-expand))
  (company-abort))
  (company-complete-selection)))

(defun abort-company-or-yas ()
  (interactive)
  (if (null company-candidates)
  (yas-abort-snippet)
(company-abort)))

(global-set-key [tab] 'tab-indent-or-complete)
(global-set-key (kbd "TAB") 'tab-indent-or-complete)
(global-set-key [(control return)] 'company-complete-common)

(define-key company-active-map [tab] 'expand-snippet-or-complete-selection)
(define-key company-active-map (kbd "TAB") 'expand-snippet-or-complete-selection)

(define-key yas-minor-mode-map [tab] nil)
(define-key yas-minor-mode-map (kbd "TAB") nil)

(define-key yas-keymap [tab] 'tab-complete-or-next-field)
(define-key yas-keymap (kbd "TAB") 'tab-complete-or-next-field)
(define-key yas-keymap [(control tab)] 'yas-next-field)
(define-key yas-keymap (kbd "C-g") 'abort-company-or-yas)

stackexchange上面这段代码很棒,不过稍微有点过时,我记得有一些namespace/func-name函数已经被删掉了,现在都是namespace-func-name这样。
为空因为很多包都是lazy-load的,要用到了才加载(进入包对应的mode、调用包里的函数等)。要用

(with-eval-after-load 'yasnippet
    (define-key yas-keymap [tab] 'tab-complete-or-next-field)
  )

山人的视频里都有,快去看。。 spacemacs的layer的文档也详细讲了emacs加载包的过程,不过篇幅也很长。。

这个链接失效了唉。。具体该怎么做,google半天一头雾水

谢谢你的帮助!