1

In Vim, I want to bind a key which will insert a newline and indent that newline up to the column where the cursor used to be. It's a little strange, so let me illustrate:

Example: before and after, with the cursor at |

Before:

a = str "Hello |World"

After:

a = str "Hello 
               |World"

This concept is not related to vim's 'copyindent' nor 'preserveindent' settings (these settings concern themsevles with the leading indentation of the previous line, not the column of the cursor).

Ein
  • 337

2 Answers2

1

Try this mapping.

:inoremap <F2> <CR><C-R>=repeat(' ',col([line('.')-1,'$'])-col('.'))<CR><C-O>:.retab<CR>

When you type F2 (or whatever key you choose for the mapping), Vim will insert a newline (<CR>) followed by a number of spaces (<C-R>=repeat(' ',...)) equal to the difference between the column number of the end of the previous line (col([line('.')-1,'$'])) and the current column number (col('.')), then will execute :retab on the current line to replace those spaces by tabs and/or spaces according to your setting of 'expandtab'.

Edit

That mapping requires that you be in insert mode. I was thinking that you would type the map key after typing Hello and before typing World. To go back and insert that newline in normal mode, use this mapping.

nnoremap <F2> i<CR><C-R>=repeat(' ',col([line('.')-1,'$'])-col('.'))<CR><Esc>:.retab<CR>
garyjohn
  • 36,494
0

I don't have access to a copy of vim (or even vi) at the moment to test this, but try something like

iEnterEsc-Yp:s/./ /gEnterJ

What it does:

  • Insert a line break (no-brainer).
  • Go back up to the a = str "Hello line and make a copy of it.
  • Change every character in the copied line to a space -- so you should now have 15 spaces.
  • Join this line (15 spaces) to the |World" line, so it is now indented 15 spaces.

You might need to delete one space (because the join operation might add one).  If there may be tabs in the line, you might want to add !_expandEnter to expand tabs to spaces in the copy of the first part of the line.  And you might also want to add !_unexpandEnter to compress spaces to tabs.