I am dissatisfied with current behaviour of Emacs in CC Mode. I'm not sure if this applies to other major modes, but that's one I'm currently struggling with. Here are my problems:

  1. When I press tab, instead of inserting just one tab, Emacs either inserts enough space to match last line indentation level.
  2. I also can't insert tab when on empty line.

I believe those are caused by c-indent-line-or-region function, according to C-h l, but I don't know what I can do with it. Neither of possible values for c-tab-always-indent change this situation.

I found something about tab-to-tab-stop, and using it helped, however, it disabled expanding snippets from yasnippet or <s in org-mode.

My setup consists of Evil-mode, Company-mode, LSP-mode, and following directives in init.el:

(setq-default indent-tabs-mode t)
(setq tab-width 8)
(defvaralias 'c-basic-offset 'tab-width)

(setq-default c-default-style "linux"
              c-basic-offset 8
              c-tab-always-indent nil
              indent-tabs-mode t)

tab-to-tab-stop has something related to expanding in it's source:

  (and abbrev-mode (= (char-syntax (preceding-char)) ?w)

but it doesn't help.

I thought I found solution in using tab-to-tab-stop with c-tab-always-indent to 'complete, and it worked, for some time, but after I restarted emacs, it, again, has no effect.

(setq-default c-tab-always-indent 'complete)
;; in configuration for evil mode
(define-key evil-insert-state-map (kbd "TAB") 'tab-to-tab-stop)

So is there a way for me to make tabs stupid, i.e. having pressing Tab just insert \t (or N spaces if configured so), while keeping the ability to expand snippets using it?

EDIT: After disabling tab-to-tab-stop and seeing with C-h l what exactly causes snippets to expand (org-cycle and yas-expand), I'm starting to suspect that there is some kind of function that tries to understand the context and apply specific action, and my evil-state map interferes with it, taking priority or something? Are my guesses wrong?

2 Answers 2


If your goal is to insert a tab character, you can use C-q <tab>, and let the default binding for tab key as is.

With C-q you invoke quoted-insert, so the next key is not interpreted as a command, but inserted "verbatim" in the buffer.

C-q is also useful in other contexts. For example, to search for tabs character you can type C-s C-q <tab>.

(setq-default c-tab-always-indent 'complete)


;; don't do this:
;; (define-key evil-insert-state-map (kbd "TAB") 'tab-to-tab-stop)

;; also don' this:
;; (global-set-key (kbd "TAB") 'tab-to-tab-stop)
;; (global-set-key [tab] 'tab-to-tab-stop)

;; do this
(define-key c-mode-base-map (kbd "<tab>") 'tab-to-tab-stop)
(define-key c-mode-base-map [tab] 'tab-to-tab-stop)

  • this works? Not working with normal completion at point for me.
    – RichieHH
    Commented Jul 6, 2021 at 8:19
  • Yeah, does not work with lambdas either. Commented Jun 15, 2022 at 7:26

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.