I use company for completion and I have company-indent-or-complete-common bound to tab for certain modes. In org mode, tab is bound to org-cycle, which either cycles visibility or calls the global binding for tab depending on context. I would like to have org-cycle call company-indent-or-complete-common instead of the global binding for tab, but I don't know how to do this. Is there a simple way to trick org-cycle into having this behavior?

Edit: I managed to find a solution on my own (for some reason @tjg's answer doesn't work for me). At first I was using

(defun org-cycle-advice (old-fn &rest r)
  (let ((old-tab (global-key-binding (kbd "TAB"))))
    (global-set-key (kbd "TAB") 'company-indent-or-complete-common)
    (apply old-fn r)
    (global-set-key (kbd "TAB") old-tab)))

(advice-add 'org-cycle :around 'org-cycle-advice)

but that didn't generalize to outshine-cycle well, so now I am using

(defun company-outline-cycle-indent-or-complete-common ()
  (if (not (outline-on-heading-p))
      (if (string= major-mode "org-mode")
        (if (bound-and-true-p outshine-mode)

1 Answer 1


My approach to this has been to define a minor-mode to put expansion on tabs, which Org will then use as the "default" if TAB is called somewhere not cyclable.

(defvar org-expand-on-tab-minor-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "TAB") 'company-indent-or-complete-common)
  "Redefine the tab key locally")

(define-minor-mode org-expand-on-tab-minor-mode
  "Minor mode to put expansion on TAB"
  :init-value nil
  :lighter " expand-on-tab")

(add-hook 'org-mode-hook '(lambda () (org-expand-on-tab-minor-mode t)))
  • Sorry, I should have tried before I accepted - it's not actually working for me. If I use it the way you wrote it, tab simply calls org-cycle in every situation. And if I change (kbd "TAB") to (kbd "<tab>"), tab always calls company-indent-or-complete-common. I'm also using evil mode, not sure if that complicates things
    – smith
    Feb 1, 2019 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.