How to go back to previous indentation level in insert mode? - vim

Sometimes vim's smartindent does not pick the correct level of indentation for the next line once you hit enter and you'd like to go back to the indentation level of the previous line and just go from there. I know that you can hit ctrl-d a few times to achieve this but it would be more useful for a key that immediately goes to the indentation level of the line above.

I don't know if it's pure coincidence, but Alexey Radev has just published the prev_indent plugin, which provides an insert mode mapping and :PrevIndent command to move the current line to the previous indentation level.

If you can't be bothered to install a plugin for such a simple task (I couldn't), try this simple mapping:
:inoremap <C-D> <Esc>:call setline(".",substitute(getline(line(".")),'^\s*',matchstr(getline(line(".")-1),'^\s*'),''))<CR>I
Now CtrlD in insert mode will do the deed: indent the current line like the previous line.
This works best before you start typing on the new line, because it will reset the cursor to just past the indentation.

In normal mode you can use < and > to increase or decrease indentation. They work as expected with movements, visual selection and >> << for the current line. You can also use = to chose the "correct" indentation level, again it works as expected with regards to movements etc.
So what I usually do is fix indentation errors in normal mode after I'm done editing, by a combination of block selecting and using =, and then fixing individual lines with << and >>.

You can use <C-O>=G to indent from cursor to end of file in insert mode. Or <C-O><< to remove one indentation level.

Related

Add whitespace to current line in vim

I fairly often find myself in a situation like this:
I'd like to start typing on the line on which my cursor is currently. However, in order to get to the correct indentation level, I'd have to press TAB several times.
Usually I'd press ddO (delete current line and insert a new one above the cursor), which resets my indentation position to the right place:
But that seems like an odd way to go about adding the correct amount of whitespace.
Is there a better way that I'm overlooking?
When in normal mode, you can use cc or its synonym S. If you are already in insert mode, Ctrlf is the default key for this, but that can be changed by altering cinkeys (see :h cink for details).
See also this answer on the Vi/Vim stack
Kevin mentioned some shortcuts, but another method is <C-i> (indent) and <C-d> (dedent) in insert mode.

Always indent in vim

So far I've always used xemacs for source code editing (C++), but for several reasons i'd like to switch to or at least try out vim. One of the very basic things is indentation, where I'm super happy with xemacs behaviour. However I have yet to find a solution for having this behaviour in vim.
What I'm talking about is basically the ability to press Tab in any position of a line, and the line will always be indented to the correct level. This means:
1) pressing Tab multiple times will not indent multiple times, instead the text will be (re-)aligned to the indentation level suitable for the current code
2) pressing Tab e.g. in the middle of a word will not insert spaces or a tab in between this word, but rather indent the whole line
Is it possible to achieve this with vim?
Currently I have:
filetype indent plugin on
set cident
set autoindent
set shiftwidth=3
set softtabstop=3
set expandtab
In normal mode, pressing == should fix the indentation of the current line.
You can fix the indentation of several lines by:
selecting them and pressing =,
using a motion, =},
using a text-object, =ip.
In insert mode, you can fix the indentation of the current line with <C-o>== but the insertion point moves as well. You are not supposed to do that kind of thing in insert mode anyway.

Opposite of newline in vim

In vim, is there a command to delete the newline, and all empty space behind the cursor?
Say I stand in the middle of a text in insert mode and press Enter, what command would the reverse what I just did?
A) An example:
"some code{ in here }"
B) After pressing Enter:
"some code{
in here }"
Now pressing backspace will delete one space of the indentation. I would rather have it delete all indentation, and jump back to A.
Can this be done in a command or by doing some remapping to the backspace key?
It's tragic how unknown the J command is. It joins lines in normal mode.
In insert mode, you can press <C-U> twice; first, it'll delete the indent before the cursor, then it'll join with the previous line. Note that this requires
:set backspace=indent,eol,start
did you try J (uppercase) ? it will give exactly what you want.
"some code{ cursor on this line, pressJ
in here }"
You can do ᴇꜱᴄ, K, Shift+J.
K jumps up to the previous line and Shift+J joins the two lines.
However, with properly configured indentation and syntax, a backspace doesn’t just delete a space, it deletes the full previous indentation block.
One easy way is up one line, to end of that line and just delete. As long as you still are in insert mode it will do the same thing as J when deleting at the last position - like most other editors. For me that is the quickest alternative because I'm used to it from other editors.
That is: ↑, End, Delete (when still in insert mode)
One quick alternative (the VIM-way) is (when still in insert mode):
↑, Ctrl+o, J (when still in insert mode)
(Ctrl+o is used in insert mode to enter one normal mode command.)
It's also possible to use a remapping of the backspace key:
inoremap <expr> <bs> getline('.')[:col('.')-2]=~'^\s\+$' ? "<c-u><c-u>" : "<bs>"
Note that this mapping completely overrides the normal behavior the backspace key. This will only be useful when you don't intend to use its normal behavior. This is not recommended if you can easily access the other options (c-u or J)
However, (as far as I know) there's no way to distinguish between manually added leading white spaces and auto indent. If you use noexpandtab, you can edit the regex to only match tabs.
This also does not work in some modes of auto-indent (for example, in block comment in C, vim automatically start a new line starts with *)

how to unindent in vim without leaving edit mode?

I'm writing a lot of python code recently, and i used the tab-to-space mode in vim. I was just wondering how would i unindent in vim without leaving edit mode for example after i finished if...: block. Normally I can just type << to unindent, but it takes too many keystorkes, anyone have a better idea?
Type Ctrl-D on your keyboard, removes one tabstop at a time, works for space-replaced tabs.
In Vim in Linux you can unindent multiple lines by using V to select your first line. Press the down arrow to select multiple lines. Then type < to unindent all of the lines.
If you want to indent, type > instead
Backspace will remove one level of indent at a time.
You can press Ctrl-U it will delete backwards to the beginning of line.

Issue with smartindent in Vim

In vim with smartindent on:
Press Enter after say an if-statement
Type in {
Press Enter twice
Type in }
If you hit ↑ and go to the previous line, indentation is removed from the blank line.
Even the vim documentation says that:
If you do not type anything on the new line except <BS> or CTRL-D and then type <Esc>, CTRL-O or <CR>, the indent is deleted again.
Is there any way to keep this indentation and not have it deleted?
Use Shift+S to start editing on a blank line (from command mode, obviously). This will start your cursor off with the expected level of indentation.
Another doesn't-answer-the-question-as-asked-but-is-a-better-solution-overall:
When typing an opening brace in insert mode, this will insert a matching set of braces
and leave the cursor on a new line in the middle.
:imap { {<CR>}<Esc>O
Similarly, this will auto-insert matching parens and square brackets.
:imap ( ()<Left>
:imap [ []<Left>
(Strip off the leading : when adding to vimrc.)
As I commented on Victor's answer, changing Vim's indentation behavior will leave "empty" lines containing extraneous spaces throughout your files. IMO, this is completely intolerable.
When this happens to me, I sometimes use ddko (or ddO) to delete the line without enough spaces and open a new line with the correct indent. Or, I'll just press A and then Tab enough times to get to the correct indent.
the article here talks about you're very same problem, and what to put in vimrc to fix it.
inoremap <CR> <CR><Space><BS>
nnoremap o o<Space><BS>
nnoremap O O<Space><BS>
I havn't exactly tested this tho.
also the same article links to a shorter alternate solution.
My preferred method is {<CR>}<esc>shift+o as it outpaces {<CR><CR>}<esc>k shift+s by several strokes. I get in a rut with it, though, and end up just using o or O to grab new, properly-indented lines off an empty when I should be using S.
That is, set up your bracing structure and open line-above:
if (true) {
}//cursor here, press shift-o
And you get the indenting you expect.
The open-above trick isn't any fewer keypresses than <up><end><cr>, but with escape remapped and shift being chorded, you can throw it in quite fast.
Also, don't forget your manual indent reset and block-movement. If you're inside a mangled curly brace block, simply use ={ (or =i{ if you're on top of one of the braces). I use that when I have a Good Idea that needs to see text asap, and I don't worry about any formatting frippery until I take a breather.

Resources