这是我为自己创建的,面临同样的问题。它来自公司模式的Emacs Wiki页面,但进行了大量扩展:
(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)
基本上,这使大多数时间<tab>做正确的事情。按选项卡将
- 缩进当前行
- 如果有要扩展的Yasnippet,请展开它,即使这意味着中止公司完成(我并没有使用太多缩写,因此尚无缩写支持),
- 如果正在进行公司完成,请填写所选项目,
- 否则,请尝试使用公司开始自动完成,
- 如果没有要自动完成的内容,并且我们位于yasnippet占位符中,请跳至下一个占位符。
请注意,如果有机会自动完成,并且您当前正在代码段占位符中进行编辑,则情况就很模糊了。作为一种妥协,我必须C-<tab>直接跳到下一个占位符。
不幸的是,该片段的名称未出现在公司菜单中,并且该片段的存在以无提示方式修改了Tab键的行为,这一事实并不是特别好,尽管至少可以键入<return>以获取完成内容的摘要。
tab
forcompany
和C-o
foryasnippet
。如果您有兴趣,我可以进一步描述。