0

I want to move the cursor to the indentation of the line above.

As seen from the example below, when I move the cursor down (j or arrow-down), it goes to the start of the line. This is both true for insert and normal mode.

However, if I'm in normal mode and press o to insert a line below the current line, then Vim knows it should move the cursor to the indentation of the line above.

enter image description here

  • 1
    It doesn't make sense to go to the "indent" column while in Normal mode. You can "keep column" in Normal mode with set virtualedit=all, and you can also start editing on "indent" column with S or cc. – Matt Jan 15 at 18:59
  • @Matt - S and cc deletes the line for me? set virtualedit=all doesn't go to the indentation level, i.e. fmt.Println(..) in my GIF. – Shuzheng Jan 15 at 19:56
  • 2
    @Shuzheng Matt means press S or cc when you are on the blank line. The problem is, as Matt suggests, there is nothing there for the cursor to be on, but there will be spaces/tabs inserted when entering insert mode (in some cases). set list listchars^=trail:. is useful for seeing this. virtualedit allows your cursor to move even where there is not text – D. Ben Knoble Jan 15 at 20:39
  • 1
    Do you really want to be at that position in Normal mode or is your intention to start adding text immediately after navigation? If the latter than you could just use a mapping like, for example, nnoremap <leader>j ^y0jpa. (That's a quick approach that works if the next line is really blank...ie. not filled with whitespace.) – B Layer Jan 16 at 5:15
  • 1
    @Matt The code in the gif isn't Python. – Rich Jan 16 at 11:19
2

The reason that o works the way it does is that, with autoindent or smartindent set, it will insert whitespace in order to match the indentation of the previous line.

When you move downwards in normal mode without entering insert mode, the line remains empty and no text is added, so the cursor moves to the start of the line.

The simplest way to achieve your goal is to:

  1. Accept the fact that when you move to an empty line in normal mode the cursor will move to the start of the line, and

  2. Use a more sophisticated method of auto indentation, and start editing the line by typing either S or cc. For the language in your screenshot (Go?) 'cindent' should work fine, and when it is set S or cc on an empty line will insert indent as you desire, but even better than this would be to use Vim's included 'indentexpr' for this language. You can do this by allowing Vim to set up indentation when it sets the filetype, which you can achieve by adding the following line to your .vimrc:

    filetype plugin indent on
    

    With this in place, 'indentexpr' will be set to GoIndent(v:lnum) when you start editing a Go file, and using cc or S on an empty line will insert the appropriate indent.

See :help 30.3 for more details on automatic indenting.

  • @Rich - yes, the language is Go. I haven’t used indentexpr or cindent in my .vimrc. Why is it better than cindent? – Shuzheng Jan 18 at 6:10
  • @Shuzheng You don’t need to set indentexpr yourself. You just need to allow Vim to set it automatically with the filetype command I suggested. indentexpr is better than cindent because it is specifically tailored for whichever language you are using. cindent is designed for C so it will work in places where Go syntax is the same as C but will fail when there are differences. – Rich Jan 18 at 8:44
  • @Rich - thanks for this! I can’t believe that such indentation is not the default behavior. – Shuzheng Jan 18 at 9:51
  • @Rich - reading the documentation for filetype plugin indent on nothing is mentioned of indentexpr - why is that? – Shuzheng Jan 18 at 10:28
  • 1
    @Shuzheng Possibly you just missed it? At the end of :h filetype-indent-on, there's a link to :h indent-expression which explains and links to :h 'indentexpr'. – Rich Jan 31 at 11:48

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.