Get tab width from file - vim

I have tabstop=4 and expandtab set in my vimrc. Is there a way of making Vim automatically set the tab width value based on what is used in the file that is currently being edited, or do I have to set it manually each time I edit something that doesn't use 4 spaces per tab?

You can try vim-sleuth.
This plugin automatically adjusts 'shiftwidth' and 'expandtab' heuristically based on the current file, or, in the case the current file is new, blank, or otherwise insufficient, by looking at other files of the same type in the current and parent directories. In lieu of adjusting 'softtabstop', 'smarttab' is enabled.

Another plugin, YAIFA
This plug-in will automatically try to detect the kind of indentation in your file and set Vim's options to keep it that way. It recognizes three types of indentation:
1.- Space: Only spaces are used to indent.
2.- Tab: Only tabs are used.
3.- Mixed: A combination of tabs and space is used. e.g.: a tab stands for 8 spaces, but each indentation level is 4 spaces.
The values of 'expandtab' and 'shiftwidth' set in your vimrc will be used as the default values.
It works like a charm.

autotab.c analyzes an up to 5000 line sample of a file to determine the expandtab, tabstop and shiftwidth parameters.
It uses a fairly elaborate algorithm which actually renders the sample using different tab sizes to figure out which one produces the nicest line-over-line alignment based on various heuristics.
Written in C, it's very fast (no noticeable delay when loading a file) and has no dependencies other than a few functions in the standard C library.

Related

Gvim does not write tabs

In C++ files that I edit with Gvim I have noticed that code lines which are in inside blocks
(curly braces {})
although are being shown on the screen with the correct amount of tabs in Gvim
(i.e. plus one tab from the code which is outside of this code block)
when I open the same files with an another editor
like sublime text
that extra tab that must exist in every line inside the code block does not exist.
So after opening these files with a hex editor I noticed that Gvim does not write those extra tabs in the code blocks?
Why does this happen?
Is it because of cindent?
Also how can I fix this rather than auto-reformat every time?
I am pretty sure that vim will faithfully save all the characters that are in the buffer. Various options affect how tabs are displayed, and whether actual tab characters or spaces are used for indenting. You can check their values, and see where they were set (default, in your vimrc file, or by some plugin) with
:verbose set ts? sts? et? sw? sta? ci? pi?
(These and more related options are grouped together if you open an options window with :options and look at Section 15.) If you want to visually check where you have tab characters rather than spaces, you can :set hls and then search for tab characters (or :match Search '\t') or you can :set list.
If you try all that and you still think that vim is not saving what is in the buffer, then there are odd things to check, like whether you have any BufWrite or related autocommands.

How to configure Vim word wrap options vimrc

I'm trying to configure Vim so that it always wraps at x-number of columns automatically, at all times such as in this other editor that I provided a screenshot of-
Use :set wrap and :set textwidth=N . For permanent effect add the wrap settings to the vim start-up file .vimrc
set wrap
set textwidth=X
To apply the wrapping to an existing file, move to the start of the file (you can use gg to do this). Then type gqG to apply the re-formatting to the entire file.
Also setting a margin may be useful:
set wrapmargin=0
If you want hard wrapping, i.e. real reformatting of the text by inserting newline characters, the 'textwidth' setting (as outlined in suspectus's answer) is the key. You need to reformat existing text, e.g. via the gq command.
For soft wrapping, i.e. where long lines just appear to be broken in the editor window, :set wrap will always fill the entire available window space; you cannot restrict that to take less. Either resize the Vim window, or add a padding buffer to the right that restricts the available space to the current window. For the latter, my LimitWindowSize plugin may be helpful.
Judging from the second screenshot, you seemed to want soft-wrap. This answer suggests a way to achieve a soft-wrap effect .
I'm generalizing the solution a bit compared to the one I referred to, but basically
use :set nuw to see how many columns the line numbers are occupying, let's call this nuw.
then use :set columns=x where x = (the number of columns you want + nuw).
Note that the columns is automatically reset to window width once you resize the window, so this manual setting is not persistent.

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

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.

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