Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tab Vs Space preferences in Vim

Vim is very accommodating when it comes to tab Vs. space preferences. As I understand it, the tabstop setting indicates the width of a tab character. The shiftwidth setting specifies how many columns to increment/decrement when using the << and >> commands, whereas the softtabstop setting influences the amount of whitespace to be inserted when you press the Tab key in insert mode. If expandtab is on, the tab key inserts softtabstop number of space characters. Whereas with expandtab switched off, pressing the Tab key inserts a the smallest possible number of tab+space characters that matches softtabstop. (Please correct me if I'm wrong.)

This final point makes me wonder: is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop? I can't think of one. As far as I am concerned, it would be most convenient if I could set all 3 of these to the same value, in one single assignment. e.g. calling:

:set stab=4 

which would be equivalent to running:

:set tabstop=4 softtabstop=4 shiftwidth=4  

Can anyone suggest how this could be done?


UPDATE

Thanks for the replies so far from too much php, hobbs and kaiser.se. Rather than reply to each individually, I'm updating the question here.

Softtabstop with expandtab switched off

I said above that with expandtab switched off, pressing the Tab key inserts a the smallest possible number of tab+space characters that matches softtabstop. I stand by that, but I think I need to explain what I meant. I shall attempt to do so by way of a few examples. To follow along, run :set list so that you can see tab characters.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

In insert mode, pressing the tab key inserts 2 space characters. Press the tab key a second time, and instead of inserting two more space characters (for a total of 4 space characters) it replaces the previous 2 spaces with a single tab character. Tabstop is set to 4, so a single tab character has the same width as 4 spaces.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

In insert mode, pressing the tab key inserts 1 tab character plus 2 spaces. The tab character has a width of 4, so the total width is 6, and this is achieved using 3 characters. Pressing the tab key a second time inserts two tab characters, and removes the two spaces that were inserted previously. The total width is 12, and this is achieved using 3 characters.

In both of these examples, Vim inserts the minimum possible number of tab+space characters that matches softtabstop.

If I am working with expandtab switched off, I can't see myself wanting the extra granular control that can be achieved by setting softtabstop to a different value from tabstop. It would still be useful for me to be able to set tabstop, softtabstop and shiftwidth to the same value with a single command.

Does expandtab make softtabstop redundant?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

In insert mode, pressing the tab key inserts 4 spaces. Pressing the delete key deletes a single space - so you have to backspace 4 times if you hit the tab key by accident.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

In insert mode, pressing the tab key inserts 4 spaces. Pressing the backspace key deletes 4 spaces.

If I am working with expandtab switched on, I would prefer the delete key to remove the same amount of whitespace as the tab key inserts. So in this case, too, I feel that it would be useful to be able to assign the same value to tabstop, softtabstop and shiftwidth simultaneously.

A shortcut would still be useful

It's great that Vim provides so much flexibility, but I can't see myself needing it. I just want to be able to choose the width of a tab, and whether it is a 'hard' tab (using a tab character) or a 'soft' tab (made up of spaces). Toggling between hard and soft tabs is easy enough (:set expandtab!), but I wish it was more straightforward to set the width of tab, without having to fiddle with 3 different parameters.

So my proposed suggestion for something like :set stab=4 still sounds good to me.

like image 593
nelstrom Avatar asked Oct 13 '09 19:10

nelstrom


People also ask

Does vim use tabs or spaces?

There are four main ways to use tabs in Vim: Always keep 'tabstop' at 8, set 'softtabstop' and 'shiftwidth' to 4 (or 3 or whatever you prefer) and use 'noexpandtab'. Then Vim will use a mix of tabs and spaces, but typing and will behave like a tab appears every 4 (or 3) characters.

What is the difference between space and tab?

The main purpose of the space bar is to enter the space during the typing. The main difference between both the keys is that tab is the smallest key that are present on the left side of the keyboard. On the other hand, the tab is the longest type of key on the bottom side of the keyboard.

How do I make 4 spaces in tab vim?

As for tabs, there are two settings. Within Vim, type a colon and then "set tabstop=4" which will set the tabs to display as four spaces. Hit colon again and type "set expandtab" which will insert spaces for tabs.

How do I show tabs and spaces in vim?

If you don't want to show all the whitespaces of the text on the Vim editor of your system, you need to turn the “hls” command off. For that purpose, go to the normal mode first. Press the “;” character, and you will be in the command mode.


1 Answers

Creating a stab option in Vim itself would not be easy, but I've whipped up this command/function that you can drop in your .vimrc (or a plugin file if you're super-organized). Use :Stab and you will be prompted for an indent level and whether or not to use expandtab. If you hit enter without giving it a new indent level, it will just print the current settings.

 " put all this in your .vimrc or a plugin file command! -nargs=* Stab call Stab() function! Stab()   let l:tabstop = 1 * input('set shiftwidth=')    if l:tabstop > 0     " do we want expandtab as well?     let l:expandtab = confirm('set expandtab?', "&Yes\n&No\n&Cancel")     if l:expandtab == 3       " abort?       return     endif      let &l:sts = l:tabstop     let &l:ts = l:tabstop     let &l:sw = l:tabstop      if l:expandtab == 1       setlocal expandtab     else       setlocal noexpandtab     endif   endif    " show the selected options   try     echohl ModeMsg     echon 'set tabstop='     echohl Question     echon &l:ts     echohl ModeMsg     echon ' shiftwidth='     echohl Question     echon &l:sw     echohl ModeMsg     echon ' sts='     echohl Question     echon &l:sts . ' ' . (&l:et ? '  ' : 'no')     echohl ModeMsg     echon 'expandtab'   finally     echohl None   endtry endfunction 
like image 150
too much php Avatar answered Oct 16 '22 16:10

too much php