2

There is this feature or module in Vim which auto back-indents words during writing if/else statements. For example:

if a == 1:
   xx   <-- here when I press enter cursor goes right below end of word "xx".
else   <-- however as soon as I fully type word "else" this line gets automatically indented backwards

What module/feature allows this auto-back-indent when typing word 'else'? As in, how do I enable this functionality?

8

Let's start from the beginning. There are quite a few (local to buffer) options in Vim to work with indenting.

autoindent is the most basic setting; it simply makes a new line to have an equivalent number (influenced by copyindent and preserveindent options) of leading spaces/tabs as in a previous line;

smartindent is a "lightweight" thing for a C-like language. It indents/unindents braces and hashes, and also indents after a few keywords, such as "if", "while" etc. (See :h 'cinwords') But it lacks an unindent for keywords, such as "else";

cindent option (and the corresponding VimScript function cindent()) is a full-featured builtin C/C++ indenter; it's also used as a fallback by many C-like languages, such as Java, Rust and so on; however, it's of a little use for Python and such;

also, there's a builtin indenter for LISP language, but it's probably of a little interest now;

indentexpr is the most flexible option; it could be set to a VimScript expression (normally, a function call) to be evaluated in runtime;

So, as one may guess, for almost all programming languages Vim computes indents by re-evaluating an expression stored in indentexpr. But, of course, an ordinary vimmer doesn't want to implement function GetPythonIndent() himself, so it's written as a part of standard plugin shipped with Vim.

The core Vim command to enable this functionality is :h filetype. If entered without arguments, it prints the current state:

:filetype<CR>
filetype detection:ON plugin:ON indent:ON

So there are (at least) three subsystems designed to work together: filetype detection, filetype settings and indent settings. But let's focus only on indent. Concerning ftdetect it's enough to say that the file type must be somehow detected before a relevant indent subplugin can do its job.

So, if indent:ON then Vim simply sources $VIMRUNTIME/indent.vim which sets a trap for all subsequent FileType events (see :h :autocmd). Then if we got some x.y.z filetype the code in indent.vim sources all indent/x.vim, indent/y.vim and indent/z.vim found on :h 'runtimepath'. A standard implementation for setlocal indentexpr=GetPythonIndent(v:lnum) is then found in $VIMRUNTIME/indent/python.vim

In $VIMRUNTIME/defaults.vim (note: Vim8+ only) there's a line filetype plugin indent on, so if you source the recommended defaults for Vim (e.g. runtime defaults.vim on top of your vimrc), then you don't have to enable ftplugin functionality manually. In Neovim, filetype plugin indent on is a builtin default setting.

| improve this answer | |
  • 1
    +1 Amazing how you (and several others in this community) are willing and able to turn the answer to a question into an extensive tutorial. Thx a ton :-)) – guntbert Mar 8 at 18:48
  • Thanks for this explicit answer. Nonetheless, perhaps i missed it, but how do i enable such feature? (that was my initial question). – user1880405 Mar 8 at 18:49
  • 2
    @guntbert Well, I'm rather a lazy person who hates writing long texts in a foreign language, but for this particular case, I believe, such deep inside is very essential. There's at least a couple of new questions and/or problems arising every week in this site that directly connected to ftplugin and stuff. – Matt Mar 8 at 18:55
  • 1
    @user1880405 Normally, it should work out-of-the-box. Try entering :filetype and see the output. If it's off, read the answer carefully and try to find out how that came the plugins are switched off in your setup. – Matt Mar 8 at 18:57
  • 3
    @Matt IKR? This is a topic for which it seems a short answer is rarely possible or appropriate...kudos for taking this one on.:) I confess that I've surrendered to my lazy gene a time or two in the past as it compelled me to steer clear of such questions. ;) – B Layer Mar 8 at 21:49
2

@Matt has already given a correct (and good) answer, but here's answer from someone who is old enough to have learned to love vi in it's original form, without fancy bits. I keep boring people stiff with this subject, so beware.

Indentation discipline is, of course, a really good idea, as it helps the eye see how the code is structured, logically. And it is mildly annoying that you have to use ^D to 'outdent' (?) - 'backdent' (?) - whatever the word may be, so my solution has been to simply do what some of the early IDEs later adopted: write the end-of-block marker as soon as you write the start of the block - so, when you write '{' in C, you write '}' on the next line, at the same indentation, when you write 'then' in ksh, you immediately add a 'fi;' on the next line, etc. That way, don't forget to close your blocks, and the indentation works coveniently as well.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.