I noticed that when in fundamental-mode or prog-mode (basically any mode without an indent-line-function) the TAB key will jump between columns. For example if I have

foo   bar   baz
fot   bat|

with the cursor at the | and I hit TAB it will move my cursor to align with baz.

foo   bar   baz
fot   bat   |

This is really nice when doing something like adding ports to a port list in Verilog. However in verilog-mode (and every other programming major mode I have tested) hitting TAB will just indent the line.

My question is, what is this fundamental-mode mechanism called and how can I add it to another major mode?

  • Start by seeing what the <tab> key is bound to in fundamental-mode, using C-h k.
    – Drew
    Commented Mar 30, 2018 at 23:48
  • It’s bound to indent-for-tab-command in both cases Commented Mar 31, 2018 at 0:04
  • I misspoke, they are bound to different commands. Commented Mar 31, 2018 at 4:00

1 Answer 1


I noticed that when in ... any mode without an indent-line-function ... the TAB key will jump between columns.

I think you've noticed and ignored the answer to your own question.

Those modes are not "without an indent-line-function". In fact if you were to set indent-line-function to nil you would trigger an error.

In those modes indent-line-function is set to indent-relative -- which is the function that provides the behaviour you're looking for.

So to make another major mode behave the same way, you could use its mode hook to set that value:

(add-hook 'foo-mode-hook 'my-foo-mode-hook)

(defun my-foo-mode-hook ()
  "Custom `foo-mode' behaviours."
  (setq-local indent-line-function 'indent-relative))

That won't necessarily do the trick, mind (depending on the mode, TAB might not result in indent-line-function ever being used), so you can always fall back to something like:

(defun my-foo-mode-hook ()
  "Custom `foo-mode' behaviours."
  (local-set-key (kbd "TAB") 'indent-relative))
  • As you suspected, setting the indent-line-function did not do anything. verilog-mode rebinds the TAB key to another function. However that was easy to override and gave me the behavior that I wanted. Thanks! Commented Mar 31, 2018 at 4:02

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.