This is what I created for myself, facing the same issue. It is from company-mode's Emacs Wiki page, but heavily extended:
(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)
Basically, this makes <tab> do the right thing most of the time. Pressing tab will
- Indent the current line,
- If there is a yasnippet to expand, expand it, even if this means aborting a company completion (I don't use abbreviations much, so no abbreviation support yet),
- If a company completion is ongoing, complete with the selected item,
- Otherwise try to use company to start autocomplete,
- If there is nothing to autocomplete and we're in a yasnippet placeholder, skip to the next placeholder.
Note that if there is an opportunity to autocomplete and you are currently editing in a snippet placeholder, the situation is ambigous. As a compromise, I bound C-<tab> to skip to the next placeholder directly.
The fact that the snippet's name does not appear in the company menu and the existence of a snippet silently modifies the behaviour of the tab key is not particularly nice, unfortunately... Although at least it is possible to type <return> instead to get the completion instead of the snippet.
tabforcompanyandC-oforyasnippet. I can describe further if you're interested.tab. So I would not like to change the binding.C-ocould expand abbrevs and snippets and open lines etc. if you're not interested.