neovim auto-indentation nuances - vim

I've just switched from vim to neovim. The following vim config settings get the behaviour I want from indentation:
set tabstop=4
set shiftwidth=4
set softtabstop=4
set autoindent
set backspace=indent,eol,start
The relevant part here is the autoindent:
set autoindent
On each newline, this causes vim to match the indentation of the previous line:
def demo_autoindent():
a = 'This line was manually indented'
····
The declaration of a was manually indented one step, but the second line was auto-indented to the same level. Here I have represented the auto-indent with a series of · characters.
Neovim matches this behaviour. However, Neovim tries to be a bit clever with blocks, or in this case declaring dictionaries in python:
def example_neovim():
b = {
············
Note that Neovim has not auto-indented this line. If it had, it would have the same 4-space indent as the declaration of b. Instead, Neovim has added an extra two indents, bringing the total to 12-spaces.
Clearly what it intends to do is add one further indent:
def example_neovim_intention():
c = {
········
How do I configure Neovim to either:
Match the behaviour of vim, just auto-indent to the same level.
Add a single (rather than a double) extra indent when declaring e.g. a dict.

I was facing exactly the same issue, I used VIM for quite a long time and recently I switch to NeoVim.
Auto indention on for every other languages except "python" works well. I found this document quite useful: https://neovim.io/doc/user/indent.html#ft-python-indent .
:h ft-python-indent
NeoVim will check this variable g:python_indent, if it is not defined a default one will be created, and it would be something like this (NeoVim 0.8.2):
{
'disable_parentheses_indenting': v:false,
'closed_paren_align_last_line': v:true,
'searchpair_timeout': 150,
'continue': 'shiftwidth() * 2',
'open_paren': 'shiftwidth() * 2',
'nested_paren': 'shiftwidth()'
}
Change these properties continue,open_paren and closed_paren_align_last_line as follows.
{
'disable_parentheses_indenting': v:false,
'closed_paren_align_last_line': v:false,
'searchpair_timeout': 150,
'continue': 'shiftwidth()',
'open_paren': 'shiftwidth()',
'nested_paren': 'shiftwidth()'
}
Another Approach (Recommended)
This can fix the weird indention issue easier.
Setup nvim-treesitter/nvim-treesitter and turn on tree-sitter's indention feature.
require('nvim-treesitter/nvim-treesitter').setup {
...
indent = { enable = true },
...
}

The issue was that neovim has filetype-indentation enabled by default:
:filetype
filetype detection:ON plugin:ON indent:ON
Adding the following to my neovim init restored the basic auto-indent functionality:
filetype indent off
This is unsatisfactory. I suspect that the file-type detection is conflicting (or doubling) some other indent config that I have, but I haven't missed it since disabling it.

Related

Half-working Graphviz dot behavior in vim

I'm using Vim 7.4 on Windows and Vim's indentation of Graphviz dot files seems to be half-working.
If I unindent the whole file, highlight all, and use =, everything indents fine. But while I'm typing, everything automatically goes to the leftmost column (no indentation).
Here's a sample file just in case I'm typing something wrong:
digraph "test" {
"node1" -> "node2";
"node2" -> "node3";
}
Syntax highlighting of the dot files works fine, as does indentation in other files (Java, XML, etc.).
This is probably because you are not setting smartindent or cindent.
Check the output of
:set smartindent?
:set cindent?
If they return nosmartindent and nocindent respectively, then adding
set smartindent
(or set cindent) will fix the issue.
From :h smartindent :
Do smart autoindenting when starting a new line. Works for C-like
programs, but can also be used for other languages.
Then why is the indentation working for other filetypes? This is because special functions designed to tell vim how to indent given lines called indentexpr is set for these filetypes (try :verb set indentexpr? when editing java files). :h indentexpr :
It is used when a new line is created, for the |=| operator and
in Insert mode as specified with the 'indentkeys' option.
When this option is not empty, it overrules the 'cindent' and
'smartindent' indenting.
Why is the indentation works with =? From :h =:
Filter {motion} lines through the external program
given with the 'equalprg' option. When the 'equalprg'
option is empty (this is the default), use the
internal formatting function |C-indenting| and
|'lisp'|. But when 'indentexpr' is not empty, it will
be used instead.

Disable autoindent in vim

I use vim since almost 20 years and recently someone told me about the usage of = key for indenting a block of code. Sometimes I try a new vim key but stop using it because it isn't doing exactly what I want or I just don't need the feature. But in this case I find its a nice feature.
So I downloaded vim script 1120 (PHP-correct-Indenting) and installed it. My .vimrc contains:
filetype indent on
set smartindent
Now I can use = to indent a visually marked code block.
But I do NOT want vim to automatically indent code while I am typing. This is just irritating me as I am usually doing indentation myself and I am very much used to it ...
So how can I stop vim from automatically indenting my code while typing but can still continue to use = for indenting a visually marked block of text.
PS: Use hjkl for moving around in vim. It will make you about 1.5 times faster :)
My complete vimrc:
syntax on
set tabstop=3
set shiftwidth=3
execute pathogen#infect()
filetype indent on
set smartindent
Commenting the last two lines stops autoindenting but also using "=" does not use the mentioned vim script anymore
The plugin sets 'indentexpr', which controls both explicit reindenting via = as well as indenting-as-you-type. Fortunately, you can control the triggering of the latter via the 'indentkeys' option, so clearing that should work.
Put the following into ~/.vim/after/indent/php.vim; this way, it'll apply after the plugin:
setlocal indentkeys=
The effect I want can get achieved using:
:set paste
This is exactly(?) the mode I wanted to switch into. No autoindenting at all. But the "=" key works to indent a marked block of text.
Maybe I will add "set paste" to my .vimrc :)
Thanks for your support anyways.

Cindent options seem to do nothing when editing .scm file

I am trying to use cindent to automatically indent a scheme/racket file. What I am currently getting with these options: set cino=(s,U1,)0,m1 is:
(test
(myStuff 1)
)
Also, I would expect (myStuff 1) code to be indent 1 shiftwidth from (test, but it is not. In fact, changing the shiftwidth seems to have no impact on this. I have already verified that cindent is on.
What I really want is:
(test
'shiftwidth'(myStuff 1)
) <---- This is aligned with '(' in (test.
My .vimrc file looks like this:
set nocompatible
set ai
set shiftwidth=3
set tabstop=3
filetype off
filetype plugin indent on
Here is another example of what I am getting:
; This is what my indentation currently looks like...
(this is
(not what) ; shifted over to line-up with the "i" in is.
(I want)
(to happen)
) ; closing paren does NOT line up with opening.
; This is what I want my indentation to look like...
(this IS
(what) ;This is shifted over by SHIFT width
(I want)
(to happen)
) ; This is on the same column as opening paren
As far as I can tell, this is loading the lisp syntax rules. And just to be sure, I have forced it to be lisp using :set syntax=lisp. As another note, whenever I set the syntax to ANY syntax type, this never changes the way these lines are indented. I've tried this list of syntax rules and all of them indent the same way:
:set syntax=cpp
:set syntax=php
:set syntax=lisp
:set syntax=ruby
... etc.
Why is this not changing with any syntax that I change to? I'm at the point now where I feel like I just need to write a python or perl script to do my formatting because I can't seem to configure vim to do the proper formatting here.
'cindent' is really only meant for indenting C or C-like languages. Scheme is not even remotely c-like, it is lisp.
Try setting 'lisp' and 'autoindent' instead of 'cindent'. Even better, use the filetype-specific indent rules defined in Vim, by adding filetype indent plugin on to your .vimrc.
Note that filetype plugins often override settings you've set in your .vimrc. 'cindent' especially will almost always be overridden by filetype indent scripts, and sometimes 'cino' as well.

vim does remove indent for all lines starting with # character

I have already read this:
Vim automatically removes indentation on Python comments
I have tried everything that is mentioned there without success:
I have smartindent off
I use filetype indent on
I tried the trick with :inoremap # X^H#
None of the above helps: Whenever i start a indented line with a # the indentation is removed and the cursor is moved to column 0.
Here's the output of :set: https://gist.github.com/mikehaertl/5387743
And here's the vimrc.local that i use on Ubuntu 12.10: https://gist.github.com/mikehaertl/1612035
So i'm clueless what else i could try. I don't want my cursor to be moved to column 0 whenever i type an indented #. Any suggestions?
UPDATE
So i found out this is caused by cindent. Still this is very obscure to me: Why does vim do that and how can i prevent that from happening if i still want to use cindent?
If you are using cindent, it probably contains the 0# part which comes by
default. You just have to remove it, for example by using an auto command to
be triggered when the file type changes to the type(s) you want with this
indentation disabled.
Is it PHP? If so, adding this line to your .vimrc may help:
autocmd FileType php set cinkeys-=0#
The 'formatoptions' option governs that behavior. What is the output of :set fo?
croql is a good value, see :h fo-table.

Disable all auto indentation in vim

In TeX vim usually screws up my indentation. Mainly when I'm in a displayed equation which I think should look like this:
\[
x=\frac{y}{z}
\]
where the whitespace infront of the x is one tab.
When I start type the equation I type the \[ and \] marks first and then go back between them, typing the tab and then the rest of the equation.
Vim doesn't do anything wrong until I have to use something that incorporates curly braces (\frac{} for example). When I type the closing } vim automatically shifts the indentation for the whole line to the left, which undoes my typed tab.
This is very anoying, how do I disable it?
my .vimrc contains:
"indentation
set smartindent
set autoindent
set tabstop=5
set shiftwidth=5
filetype indent on
I just spent a few hours working through indentation pains with javascript, and the conclusion I came to is don't remove filetype indent on from your vimrc!
This setting provides the best smart indentation for multiple file types. If you're getting bad results with this, there's likely a configuration issue at hand.
File Specific Indent Settings
So if you're like me, you probably had filetype indent on in your vimrc and had no idea what it was doing.
All this setting does is tell vim to look for files with filetype-specific indent rules. There are a few places it looks, but there are probably only two that you'd be interested in.
$VIMRUNTIME/indent/
~/.vimrc/after/indent/
The first place holds the default indent rules that come with vim. If you were to set filetype indent on on a fresh vim installation, this is where all the smart indenting would come from. For example, when you open a file called index.html in would get the rules from $VIMRUNTIME/indent/html.vim.
In my experience, these default rules are pretty darn good, but they can get messed up by other settings.
The second place (the after directory) allows you to add settings that will supercede those in the first place. This is nice because you don't have to edit the default files in order to customize them.
Flavors of Indentation
There are a few different indentation options as you've seen, and they don't all play nice together. From the Vim wiki:
autoindent
'autoindent' does nothing more than copy the indentation from the previous line, when starting a new line. It can be useful for structured text files, or when you want to control most of the indentation manually, without Vim interfering. 'autoindent' does not interfere with other indentation settings, and some file type based indentation scripts even enable it automatically.
I use filetype indent on and set autoindent in my vimrc, since they work well together. I don't have the others set.
smartindent & cindent
'smartindent' automatically inserts one extra level of indentation in some cases, and works for C-like files. 'cindent' is more customizable, but also more strict when it comes to syntax.
'smartindent' and 'cindent' might interfere with file type based indentation, and should never be used in conjunction with it.
When it comes to C and C++, file type based indentations automatically sets 'cindent', and for that reason, there is no need to set 'cindent' manually for such files. In these cases, the 'cinwords', 'cinkeys' and 'cinoptions' options still apply.
Generally, 'smartindent' or 'cindent' should only be set manually if you're not satisfied with how file type based indentation works.
indentexpr
Runs filetype indent scripts found in (vimfolder)\indent\\(indentscripts). It is mentioned in the vim documentation for filetype, alongside the others just mentioned (also, it was the cause of the problem I was having):
Reset 'autoindent', 'cindent', 'smartindent' and/or 'indentexpr' to disable indenting in an opened file.
Troubleshooting
There's a chance that some rogue plugin is changing your indent settings and that's why you're getting poor results. Luckily verbose will tell you which file was the last to change the option in question.
:verbose set autoindent?
:verbose set cindent?
:verbose set smartindent?
:verbose set indentexpr?
You may get a result such as
indentexpr=SomeMessedUpValue
Last set from ~/.vim/bundle/some_plugin/indent/plaintex.vim
If that happens, you can move that file, close and open vim, and see if it fixes your problem.
Turning Off Indent Settings for TeX
Maybe the defaults just aren't doing it for you, and you want to disable the indent settings for TeX, but leave all other file types alone. You can easily do so by setting these values to their defaults in a file in the after directory.
I don't know much about Tex or LaTex, but when I created a file with the .tex extension and ran :filetype it had the filetype as plaintex. Assuming that this is correct, you'd want to create a file, ~/.vim/after/indent/plaintex.vim. In that file:
set autoindent&
set cindent&
set smartindent&
set indentexpr&
This will set all these values to their defaults whenever you open a .tex file.
There seem to be a little mix of terms in your question. In vim the term autoindent points to a special kind of indentation that simply follows the indent level of the previous line (which is quite handy sometimes). To remove it set noautoindent by hand, or write it in your _vimrc.
There are two other automatic kinds of indentation, cindent and smartindent. Similarly, if you wish to disable them go with set nocindent and set nosmartindent
If you look in help (help autoindent, ...) they are all quite nicely explained. Which one you prefer (or don't) is mostly determined by your programming style and habits. So, try them out and see which you like most.
Unfortunatelly, I don't use LaTeX that much anymore, so I'm not familiar with its internal filetype indentation rules.
For anyone else having a similar problem, a solution that worked for me was:
Use :verbose set indentexpr? to find what file was causing the de-indentation
Find where indentexpr is changed (for me it was setlocal indentexpr=GetTeXIndent())
Change that line to setlocal indentexpr& to turn indentexpr off
This removed all de-indenting from brackets, parentheses, and braces.
Remove the lines set autoindent and set smartindent to remove all vim autoindentation.
The following command finally stopped VIM from pretending it knows how to indent files for me and only do what I explicitly tell it:
:setl noai nocin nosi inde=
Courtesy https://vim.fandom.com/wiki/How_to_stop_auto_indenting
If you are using the vim-latex plugin, set this option:
let g:tex_indent_brace=0
For other plugins, if you don't want to turn off indentexpr as in the above answers, you can find where indentkeys is set and comment out those lines. This should stop triggering re-indent when you type a closing brace.
:verbose set indentkeys?

Resources