In vim, how can I modify all existing indents to be 2? - vim

In vim, I set shiftwidth=2, but all my previous indents are still at the default 8. How can I change the previous indents from 8 to 2?

You can reindent the whole file with gg=G. gg goes to the first line, = indents (taking a movement), G goes to the last line.

If you're using set expandtab (like you should), you can modify the indentation in a file with
:%s/^ */ /
The settings affect how changes are made, but do not themselves make changes to the file.

If your original indents were achieved using hard tabs stops, then one trick you can do is this. Set the hard tab stop to 2:
:set ts=2
Now you have the two-space indentation (but achieved with hard tabs).
Now, do
:retab 8
This means, roughly, change the hard tab size to 8 (as if by :set ts=8) but at the same time edit all the tabbing in the buffer so that the indentation's appearance does not change.
So now the buffer is still indented to two spaces, but now :ts is back to 8.
If you have :expandtab set, then the indentation is now all spaces, otherwise it is a combination of 8-space tabs and spaces.
Even if this doesn't apply to your situation, retab is good to know because it's handy for dealing with sources that use hard tabs and that you'd like to convert to use spaces and a different indentation level at the same time.

Related

Could someone elucidate why softtabstop is not working and other gaps in understanding?

I've read the following articles:
http://vimcasts.org/episodes/tabs-and-spaces/
https://medium.com/#arisweedler/tab-settings-in-vim-1ea0863c5990
To try and understand what things like tabstop, shiftwidth and softtabstop mean.
Here's what I get so far:
tabstop sets the way that tab appears on the vim editor. If you have set ts=4, then it will look like you have 4 spaces whenever you press on the tab key on your keyboard. If you have set ts=50, then it will look like each time you press Tab, you get 50 spaces. In the case that you have set expandtab, the characters will be 50 spaces, otherwise you will just have 1 tab character that seems like 50 spaces (so just 1 byte from ASCII?, seems a bit weird).
shiftwidth sets the amount of indentation for things like <<, >>, ==, and also autoindent. So this means that you know, if you have set sw=5, and say ts=4, then when >> is typed, it puts in 1 tab and 1 space and does some math as such.
softtabstop I'm not so sure about. From what I have read, the sources seem to have different explanations.
Source 1 says:
If you prefer to work with tab characters then it is a good idea to
ensure that tabstop == softtabstop. This makes it less likely that
you’ll end up with a mixture of tabs and spaces for indentation.
If you prefer to work with spaces, then it is preferable to ensure
that softtabstop == shiftwidth. This way, you can expect the same
number of spaces to be inserted whether you press the tab key in
insert mode, or use the indentation commands in normal/visual modes.
Source 2 says:
softtabstop: Referred to for the tab key and backspace key. How much
whitespace should be inserted when the tab key is pressed? And how
much whitespace should be removed when the backspace key is pressed?
First of all, I don't really know how to reconcile Source 1 and Source 2. Why does shiftwidth matter (source 1), if we only do it for the tab key and backspace key (source 2). The shiftwidth character should control how much space is added during >>, etc, right? Why does it matter for spaces?
"If you prefer to work with tab characters then it is a good idea to ensure that tabstop == softtabstop.": this sort of makes sense. softtabstop determines how much space each keypress of Tab makes, and if there is discord between tabstop and softtabstop then we could end up using spaces to make things even out.
Lastly, I was trying out some of the examples in Source 2 at the bottom. (Note in my vimrc I have the following lines and only this line affecting whitespace: set tabstop=4 shiftwidth=4 expandtab)
I made the following changes in a new file:
:set ts=5 sts=3
:retab
When I pressed the Tab key, contradictory to what the author of article 2 said, I was getting 4 spaces, not 3. So did he say something wrong? I then set shiftwidth to 3, and NOW I was getting 3 spaces when I pressed the tab key (and also when I did >>). I don't know the meaning of this. Was he wrong?
Based on these observations, can anyone tell me what sts is actually doing? When we have a tab character no matter what the ts is it always 1 byte? Does sw affect Tab key presses? Is there any other misunderstanding I have about these parameters? Vim is hard.
If you have set ts=50, then it will look like each time you press Tab, you get 50 spaces.
Nope. While inserting new tabs by Vim it's the softtabstop option which comes to play. But sts value is recalculated into ts one. So if you have ts=50 and sts=100 (and also noexpandtab, of course) then you get 2 hard tabs (\x9 byte) in the buffer.
To disable this feature you can set sts=0. In this case a tab will be just a tab / tabstop.

Always indent in vim

So far I've always used xemacs for source code editing (C++), but for several reasons i'd like to switch to or at least try out vim. One of the very basic things is indentation, where I'm super happy with xemacs behaviour. However I have yet to find a solution for having this behaviour in vim.
What I'm talking about is basically the ability to press Tab in any position of a line, and the line will always be indented to the correct level. This means:
1) pressing Tab multiple times will not indent multiple times, instead the text will be (re-)aligned to the indentation level suitable for the current code
2) pressing Tab e.g. in the middle of a word will not insert spaces or a tab in between this word, but rather indent the whole line
Is it possible to achieve this with vim?
Currently I have:
filetype indent plugin on
set cident
set autoindent
set shiftwidth=3
set softtabstop=3
set expandtab
In normal mode, pressing == should fix the indentation of the current line.
You can fix the indentation of several lines by:
selecting them and pressing =,
using a motion, =},
using a text-object, =ip.
In insert mode, you can fix the indentation of the current line with <C-o>== but the insertion point moves as well. You are not supposed to do that kind of thing in insert mode anyway.

Why does x>> in vim have another indent than when im pressing tab?

When im using the vim command 4>> in vim to indent four lines of code vim indents the lines with 8 spaces, but if i indent these lines manually but pressing tab in front of them they are indented with 4 spaces which is what i have configured in my .vimrc file. It seems like the 4>> command is somehow bypassing my configuration..does someone know why this is happening..
Also, does someone know if there is a way to ident the other way as well and not just indent to the right but also to the left.
You seem to have inconsistent values of 'shiftwidth' (which governs the >> behavior and seems to be 8 in your case) and 'tabstop' / 'softtabstop' (which control the amount of spaces inserted when pressing Tab in insert mode; either 8/4 or 4/4 or 4/0 in your case).
Hitting TAB indents to the next multiple of the tabstop value.
Using >> indents by the value of the shiftwidth variable.
Also, does someone know if there is a way to ident the other way as well and not just indent to the right but also to the left.
<< is the opposite of >>

My tab spaces do not align properly - VIM

I'm currently collaborating with a colleague on a project and we both use Vim to code.
However I've noticed that my code does not align the same way as his does and this causes some extra work on his part to re-indent the code.
So I turn on :set list to see to see the differences in tab space marked with (^I) and line endings marked with $.
For some reason when I type in (:list) mode my text does not indent or even show traces of tab markers (^I) similarly to his code. Why is this?
Here's an example of what I mean:
^I^I$this->greeting('Hello world');$
Whilst my code would show up like this in the same file:
$this->reply('Hello you');$
Notice the uneven space?
These are my vimrc settings:
set expandtab
set softtabstop = 4
set tabstop = 4
set shiftwidth = 4
I hope I'm on the right track, there may be some other problem that I haven't considered. Please do share your knowledge on the matter.
Sincerely,
Why
set expandtab means that typed tabs become spaces. This is fine, as long as you both agree on what a tab is; chances are they're using the Unix- (and, I think for historical reasons, vim-) default set tabstop=8.

How to avoid indentation error after changing tab stops in Vim?

I used to have 8-space tabs in Vim. Then I changed to 4 spaces, but now whenever I add a line to some code I had written before changing to 4 spaces, it gives me an indentation mismatch error even though everything is lining up nicely. Is there any way to avoid this problem?
Have you done a :%retab ...?
Have you changed just the tabstop option?
I use 4 spaces (fill with spaces when I hit tab, to insert actual tab hit ctrl-v tab). Here are the tab related settings from .vimrc:
" tabs
set tabstop=4
set shiftwidth=4
set expandtab
When you fill tab with spaces you will always insert spaces instead of tab and your code will always look the same.
When you use tabs each tool displays tab differently and you end up spending your time setting up how many spaces should be displayed for tab (8,4,3.5) instead of doing productive work.
Or choose one of these (from vim 7.1 help tabstop):
Note: Setting 'tabstop' to any other value than 8 can make your file
appear wrong in many places (e.g., when printing it).
There are four main ways to use tabs in Vim:
1. 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 <Tab> and <BS> will
behave like a tab appears every 4 (or 3) characters.
2. Set 'tabstop' and 'shiftwidth' to whatever you prefer and use
'expandtab'. This way you will always insert spaces. The
formatting will never be messed up when 'tabstop' is changed.
3. Set 'tabstop' and 'shiftwidth' to whatever you prefer and use a
|modeline| to set these values when editing the file again. Only
works when using Vim to edit the file.
4. Always set 'tabstop' and 'shiftwidth' to the same value, and
'noexpandtab'. This should then work (for initial indents only)
for any tabstop setting that people use. It might be nice to have
tabs after the first non-blank inserted as spaces if you do this
though. Otherwise aligned comments will be wrong when 'tabstop' is
changed.
For python code, you are probably best off with the following:
:set tabstop=8
:set shiftwidth=4
:set expandtab
That way you are still using the 'industry standard' 8 space tabs, but you won't be putting any of them into your file. That should keep your old code clean as well, although you'll have to go back through and manually move everything left over time. You'll definitely want to :retab everything too.
If you want to replace everything with 4 space indents do
:set tabstop=4
:retab
:set tabstop=8
This will re-indent everything using spaces at 4 spaces per tab, and set you back to sane defaults.
Obvously, this is subject to opinion, but in my book using tabs set to anything other than what you get when you cat the file is asking for trouble.
The best way to visualise a mismatch is to :set list which will show whitespace issues.
set listchars=tab:>-,trail:-,nbsp:+ "This is terminal friendly but you can make fancy
set list
I'd say this is an essential setting for python editing when spaced indents are the norm. Especially when a file is edited by a co worker.
I also double checked the style guideunder "Code lay-out". theres a python -tt option you might want to use as specified in http://www.python.org/dev/peps/pep-0008/. That will throw warnings and errors if you mix tabs with spaces.
You could incorporate this into your unit testing. It seems the pep is recommending 4 spaces for newer code. You might want to consider changing if you intend on contributing to open source projects.
also to be extra tidy I have for deleting whitespace at eol
nnoremap <leader>wd :%s/\s\+$//<cr>

Resources