R – Insert spaces instead of TAB in Emacs viper-mode


I am long time-vim user and recently discovered that emacs has viper-mode, offering best of both worlds (at least for me). However one thing is really bothering me since I am mostly coding in python and mixing of tabs and spaces is a big deal.

When in insert mode I would like to insert viper-shift-width spaces instead of TAB when I press TAB. How can I do this? I suppose some simple lisp function/setting is the solution.

I didn't find anything in viper-mode settings that could do this.


I have (setq-default indent-tabs-mode nil) in my .emacs but this doesn't work when I am in insert mode (in vim meaing of insert mode) in viper-mode

Best Solution

First, you should ensure the default value of 'indent-tabs-mode is nil, like so:

(setq-default indent-tabs-mode nil)

Then, in viper-mode, it also depends on your viper-expert-level. At level 1 or 2, TAB appears to be bound to 'self-insert-command via the mode map viper-insert-diehard-minor-mode (which is enabled when the expert level is either 1 or 2). I guess that it is trying to provide maximal vi compatibility, which means you sacrifice some Emacs features, including the use of some pretty basic customizations.

So... you can up your expert level to 3 or higher:

(setq viper-expert-level 5)        ; really, why use anything less?

If you really want level 1 or 2, but want TAB to not be a self inserting command, then add this to your .viper file:

(define-key viper-insert-diehard-map (kbd "TAB") 'viper-insert-tab)

That does the trick for me, even on level 1.