Transitioning to vim. Having issues with indentation - vim

I am recovering from a surgery, thusly, I am transitioning to VIM. As I starting point, I've opted to use the vim-sensible plugin as the foundation of my configuration. Additionally, I've installed the 'vim-rails' and 'vim-ruby' plugins. These are all loaded via Pathogen.
For whatever reason, the plugins are not adjusting indentation settings in accord with filetype. Tabs seem locked to 9 columns. I am able to set them manually, but obviously this is not ideal.
Here is my .vimrc. As you can see, it is very basic.
execute pathogen#infect()
syntax on
filetype plugin indent on

Vim provides the following buffer local options for managing indention: 'softtabstop', 'shiftwidth', 'tabstop', and 'expandtab'. The idea is to set these options for a specific filetype, e.g. ruby either by using an autocommand or using the after ftplugin directory (my preference).
After directory approach
Add the following to your ~/.vim/after/ftplugin/ruby.vim file:
setlocal softtabstop=2
setlocal shiftwidth=2
setlocal tabstop=2
Autocommand approach
Add the following to your ~/.vimrc file:
augroup MyIndentSettings
autocmd!
autocmd FileType ruby setlocal softtabstop=2 shiftwidth=2 tabstop=2
augroup END
Learn more
As you are just starting to vim it is best to learn how to query these options so you can track down future bugs. Querying an option is as simple as :verbose set {option}?, e.g. :verbose set expandtab?.
You may also be interested in Tim Pope's vim-sleuth which heuristically sets indent settings.
For more help see:
:h :set
:h 'softtabstop'
:h 'shiftwidth'
:h 'tabstop'
:h 'expandtab'
:h after-directory

In my vimrc I have the following:
set autoindent
set expandtabs
set shiftwidth=4
set tabstop=4
Actually I just have
set ai et sw=4 ts=4
You can change the specific settings using FileType or BufEnter:
autocmd BufEnter *.py ai et sw=4 ts=4

Related

don't apply current options to new opened file vim

I frequntly open many files in vim. The problem is some files have their own options. For example:
settings for make files
set noexpandtab tabstop=4 shiftwidth=4 softtabstop=4
set list listchars=eol:¬,tab:→⠀,trail:~,extends:>,precedes:<
hi SpecialKey ctermfg=243
hi NonText ctermfg=243
settings for C files
set colorcolumn=100 tabstop=4 shiftwidth=4 softtabstop=4
So, if I open makefile first and then :tabe main.c I can see invisble character that were turned on from makefile.
I understand that I can :set nolist but imagine if I have many other options inherit from many other files. How can I tell vim not to inherit them when I :tabe anotherFile?
Well there is setlocal to set this things for a buffer only.
But that does of course not work for a .vimrc. There you have two possibilities, autocmds or filetype plugins:
autocmd BufRead,BufNewFile *.{c} setlocal colorcolumnt=100
This does set the settings local to any oppened buffer of a file ending with .c
Or you can add the settings to a filetype-plugin. See :h filetype-plugin for more information on that. Basically just add the settings to a specific file. In your case most likely under .vim/ftplugin/c.vim

vim tab indentation for tex document

I am trying to configure my vimrc so that tabs are 2 spaces when editing tex documents.
In my vimrc file, I have
au BufNewFile,BufRead *.py:
\ set tabstop=4
\ set softtabstop=4
\ set shiftwidth=4
\ set textwidth=79
\ set expandtab
\ set autoindent
\ set fileformat=unix
au BufNewFile,BufRead *.js, *.html, *.css, *.tex:
\ set tabstop=2
\ set softtabstop=2
\ set shiftwidth=2
However, when I edit a document in vim, it ignores the tabstop. Tabs are much longer than 2 spaces. Vim does not throw out any errors. I do not understand why it ignores the tabstop=2 line when I am editing a tex document. I have to run :set tabstop=2 while editing.
Can anyone see how my configuration file is wrong?
In case this is relevant, I am using the vimtex plugin.
Thank you.
The file globs need to be separated by commas without whitespace in between; cp. :help autocmd-patterns.
Drop the : colon after the pattern.
Instead of :set, better use :setlocal, otherwise the indent settings will be inherited to any new buffer that is created from within one of those.
You can combine the arguments of all :set command into one.
au BufNewFile,BufRead *.js,*.html,*.css,*.tex
\ setlocal tabstop=2 softtabstop=2 shiftwidth=2
Instead of the :autocmd, I would prefer to put this into ~/.vim/after/ftplugin/{filetype}.vim. (This requires that you have :filetype plugin on; use of the after directory allows you to override any default filetype settings done by $VIMRUNTIME/ftplugin/{filetype}.vim.) The small downside is that you have to duplicate the :setlocal commands for every filetype, but to me, the fact that you would like to have the same indent settings for those languages is accidental, and there's no connection between those configurations.
Alternatively, you could define an :autocmd FileType {filetype} ... directly in your ~/.vimrc. With this, you at least wouldn't duplicate the built-in filetype detection and the file glob patterns used by it:
au FileType javascript,html,css,tex
\ setlocal tabstop=2 softtabstop=2 shiftwidth=2

VIM filetype plugin does not take expandtab option

Here's my .vimrc what I expect is expandtab to work on every mentioned
filetype, except make where it is explicitly disabled. et used to work as a non-filetype set command, but detecting the filetype is important.
" vundle Config
set nocompatible " be iMproved, required
filetype off " required
" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'vim-syntastic/syntastic'
Plugin 'Shougo/vimproc'
" All of your Plugins must be added before the following line
call vundle#end()
filetype on
filetype plugin on
filetype indent on
" Remove whitespace
autocmd BufWritePre * %s/\s\+$//e
autocmd FileType cpp,html,css set et paste tabstop=4 shiftwidth=4 backspace=2 matchpairs+=<:>
autocmd FileType haskell,go,js,erlang,vim,tex set et paste tabstop=4 shiftwidth=4 backspace=2
autocmd FileType make set noexpandtab paste shiftwidth=8 softtabstop=0
syntax on
What I observe is that some options are set, some are not. The expandtab is the one that I can't get to work specifically. Here's the output of :set when opening my .vimrc file (filetype=vim).
backspace=2 filetype=vim keywordprg=:help paste shiftwidth=4 tabstop=4 ttymouse=sgr
commentstring="%s helplang=en laststatus=2 scroll=21 syntax=vim ttyfast
Ah, that's a tricky one. Have a look at :help 'paste':
When the 'paste' option is switched on (also when it was already on):
mapping in Insert mode and Command-line mode is disabled
abbreviations are disabled
'autoindent' is reset
'expandtab' is reset
[...]
Note how the option is introduced:
This is useful if you want to cut or copy some text from one window and paste it in Vim.
This option only is meant to be temporarily enabled when pasting into the terminal. Usually via a key configured in the 'pastetoggle' option. (GVIM doesn't need it; it can detect pastes. If you have X selection and clipboard enabled, you can also use the * and + registers instead.)
additional comments
The three :filetype commands can be condensed into a single filetype plugin indent on.
If you put this around your :autocmds, you'll remove the risk that some plugin clobbers them, and you can also safely reload your ~/.vimrc without defining duplicates:
augroup myCustomizations
autocmd!
autocmd ...
augroup END

How to prevent global defaults from overriding 'filetype=vim' specific settings in .vimrc when automatically sourcing .vimrc?

Context
I have my .vimrc automatically being sourced with:
autocmd! BufWritePost ~/.vimrc source ~/.vimrc
I also set defaults for spacing:
set tabstop=2 softtabstop=2 shiftwidth=2 expandtab
Later on, I use the FileType event to override the spacing default above with filetype-specific spacing:
" Syntax of these languages is fussy over tabs & spaces¬
autocmd FileType make setlocal ts=8 sts=8 sw=8 noexpandtab¬
autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab¬
" Customisations based on house-style (arbitrary)
autocmd FileType sh setlocal ts=4 sts=4 sw=4 expandtab
autocmd FileType vim setlocal ts=4 sts=4 sw=4 expandtab
Problem
The problem I am having is that sourcing my .vimrc will set the default values, but will not trigger the FileType event. This means that when I do a :write to my .vimrc while editting a file with filetype-specific spacing, the filetype-specific spacings get overridden by the defaults!
UPDATE: As pointed out by Ingo, the issue only arises in .vimrc and does not occur in any other files.
Example
As an example, when I am working on my .vimrc, initially the file-specific spacing (ts=4 sts=4 sw=4 expandtab) is enabled, but after I make some arbitrary change in my .vimrc, the default spacing (tabstop=2 softtabstop=2 shiftwidth=2 expandtab) is loaded but my file-specific spacing is NOT loaded (since the FileType event was not triggered by a write to my .vimrc) leaving me with the default spacing!
My question(s)
How can I override the default spacing with filetype specific spacings and preserve these even when auto-sourcing .vimrc?
If possible, I would like to accomplish this without getting rid of the autocmd's. Is that possible?
My hunch is that I should somehow manually trigger the FileType event when sourcing .vimrc Can this be done and is this the recommended approach?
Though you've very clearly described the problem, I doubt that this is happening.
As you're correctly using :setlocal for the filetype-specific settings, and :set in your ~/.vimrc, the sourcing of the latter will only affect the global defaults (and the current buffer, which is your .vimrc during the BufWritePost event). To affect other buffers, there would need to be a :bufdo command in your .vimrc.
You can check this with
:verbose set ts? sts? sw? et?
To avoid that your .vimrc settings are overridden with the global settings, you can append this:
if expand('%:t') ==# '.vimrc'
setlocal filetype=vim
endif
I ended up solving this issue by grouping the sourcing autocmd with another autocmd with the same event
" Reload changes to .vimrc automatically
autocmd BufWritePost ~/.vimrc source ~/.vimrc | setlocal filetype=vim
I had tried this earlier, but I was also using the AirlineRefresh command for vim-airline as such:
autocmd BufWritePost ~/.vimrc source ~/.vimrc | AirlineRefresh | setlocal filetype=vim
which was giving me this error:
E488: Trailing characters: AirlineRefresh | setlocal filetype=vim
Switching the order of AirlineRefresh and set local filetype=vim fixed the error and results in the desired behavior:
autocmd BufWritePost ~/.vimrc source ~/.vimrc | setlocal filetype=vim | AirlineRefresh
:bufdo e will do it but I couldn't just add it to my .vimrc. It will also remove syntax highlighting which is not so good.
:h bufdo execute the command in each buffer in the buffer list
:h :e re-edit the current file

Vim autocommand not triggering on search?

I use Vim 7.3, and have this in my .vimrc (and nothing else):
filetype plugin indent on
autocmd FileType java :setlocal sw=4 ts=4 sts=2 noet
autocmd BufNewFile,BufReadPost ~/testdir/* setlocal sw=2 ts=2 sts=2 et
I have a directory ~/testdir which only contains a subdirectory p and the file ~/testdir/p/A.java which contains this:
class A {
}
If I open A.java by saying :e ~/testdir/p/A.java then :set et? reports that expandtab is currently ON.
On the other hand, if I start a new instance of Vim and go :vim A ~/testdir/** then this search will open A.java, but now :set et? tells me expandtab is OFF.
How do I make my intended indentation settings always apply for files under ~/testdir/?
The event BufReadPost should be being fired. Check that writing a message. This is:
autocmd BufNewFile,BufReadPost $HOME/git/repo/* echom "Reading buffer " . expand("<afile>")
Look for the messages with:
:messages
If the messages are there, then you know you are setting those options for the buffer. So, if the options have changed when the buffer is displayed, perhaps a plugin is setting them to some other thing. Check who is the culprit by showing who last changed the option with
:verbose set sw?
If that doesn't lead you to a solution, try using BufWinEnter instead of BufReadPost. That would probably work.
Vim explicitly recommends using ~ for the user home.
The help at :h autocmd-patterns says that you can use environment variables in the event patterns ...
... [a]nd ~ can be used for the home directory (if $HOME is defined):
:autocmd BufWritePost ~/.vimrc so ~/.vimrc
:autocmd BufRead ~archive/* set readonly
The environment variable is expanded when the autocommand is defined, not when
the autocommand is executed. This is different from the command!
So, change $HOME to ~ in your autocommand.
Even if your problem turns out to be unrelated it's good to follow the practice recommended in the docs.
The autocmd does work but probably not the way you expect since you did not set softtabstop.
autocmd BufNewFile,BufReadPost ~/git/repo/* setlocal sw=2 ts=2 sts=2 et
If you do not set softtabstop it will keep its old value. If this value is not 0 (which seems to be the case) when you press tab you will get the number of softtabstop spaces inserted into the file. And it will look like its not working.
It is generally a good idea to set shiftwidth, tabstop, and softtabstop to the same value if you ever change it.
Its also probably a good idea to make the set command local to the buffer by using setlocal.
Take a look at :h softtabstop
You can see that the autocmd "works" when softtabstop is set to its default value (of 0) if you run the command like this. And then run your :vim command
vim -u NONE -N -c'autocmd BufNewFile,BufReadPost $HOME/git/repo/* set sw=2 ts=2 et'

Resources