在 Vim 中,如何在光标所在的位置插入换行符而不进入插入模式?

是否可以在光标处于 Vim 的位置插入一个换行符而不进入插入模式?下面是一个例子([x]表示光标在 x上) :

if (some_condition) {[ ]return; }

有时候,我可能需要输入更多的代码。所以我会按 i进入插入模式,按 Enter插入换行符,然后删除额外的空格。接下来,我将进入普通模式,将光标定位在关闭大括号之前,然后执行相同的操作,将其放在自己的行上。

我已经做了一段时间了,但肯定有更好的方法吗?

45158 次浏览

For the example you've given, you could use rEnter to replace a single character (the space) with Enter. Then, fspace. to move forward to the next space and repeat the last command.

Depending on your autoindent settings, the above may or may not indent the return statement properly. If not, then use sEnterTabEsc instead to replace the space with a newline, indent the line, and exit insert mode. You would have to replace the second space with a different command so you couldn't use '.' in this case.

Here's how to create a macro that inserts a newline at the cursor whenever you press 'g' while not in insert mode:

From within vim, type:

:map g i[Ctrl+V][Enter][Ctrl+V][Esc][Enter]

Where:

  • [Ctrl+V] means hold the Ctrl key and press 'v'
  • [Enter] means press the Enter key
  • [Esc] means press the Esc key

You'll see the following at the bottom of your vim window until you press the final Enter:

:map g i^M^[

Explanation:

[Ctrl+V] means "quote the following character" -- it allows you to embed the newline and escape characters in the command.

So you're mapping the 'g' key to the sequence:

i [Enter] [Escape]

This is vim for insert a newline before the cursor, then exit insert mode.

Tweaks:

  • You can replace the 'g' with any character that's not already linked to a command you use.
  • Add more to the command, e.g. f}i^M^[O -- This will find the } and insert another newline, then escape from insert mode and Open an empty line for you to enter more code.
  • You can add the command to your .vimrc or .exrc file to make it permanent. Just omit the colon from the beginning, so the command starts with "map"

Enjoy!

Vim will automatically kill any whitespace to the right of the cursor if you break a line in two while autoindent (or any other indentation aid) is enabled.

If you do not want to use any of those settings, use s instead of i in order to substitute your new text for the blank rather than just inserting. (If there are multiple blanks, put the cursor on the leftmost and use cw instead.)

This mapping will break up any one-line function you have. Simply put your cursor on the line and hit 'g' in normal mode:

:map g ^f{malr<CR>`a%hr<CR>`a

This assumes that you have a space after the opening brace and a space before the closing brace. See if that works for you.

If you're usually expanding a one line block to three lines, try substitution. Change the opening bracket into bracket/return, and the closing bracket into return/bracket.

The command for substituting bracket/return for bracket looks like this:

:s/{/{\r/

Since you want to use this often, you could map the full sequence to an unused keystroke like this:

:map <F7> :s/{/{\r/ ^M :s/}/\r}/ ^M

Where you see ^M in the sequence, type [Ctrl-V], then press enter.

Now with your cursor anywhere on your sample line, press the mapped key, and the carriage returns are added.

Check :help map-which-keys for advice on selecting unused keystrokes to map.

A simple mapping to break the line at the cursor by pressing Ctrl+Enter:

:nmap <c-cr> i<cr><Esc>

essentially enters 'insert' mode, inserts a line break and goes back to normal mode.

put it in your .vimrc file for future use.

Set this key mapping in your vimrc

:map <C-m> i<CR><Esc>h

Then press Ctrl+m if you want to use it in your vim.

IMHO, the built-in mapping gs is not a useful mapping (put vim to sleep), one could use this for splitting:

nmap gs i<CR><ESC>

In Vrapper you can use gql which will split a line without entering insert mode, but may not always maintain indentation.

Basically, when you split a line you either want to just insert a carriage return, or in the case that you're on a space, replace that with a carriage return. Well, why settle for one or the other? Here's my mapping for K:

"Have K split lines the way J joins lines
nnoremap <expr>K getline('.')[col('.')-1]==' ' ? "r<CR>" : "i<CR><Esc>"

I use the ternary operator to condense the two actions into one key map. Breaking it down, <expr> means the key map's output can dynamic and in this case hinges on the condition getline('.')[col('.')-1]==' ' which is the long winded way to ask vim if the character under the cursor is a space. Finally, the familiar ternary operator ? : either replaces the space with linebreak (r<CR>) or inserts a new one (i<CR><Esc>)

Now you have a lovely sister key map to the J command.

Assuming you're okay with mapping K to something else (choose a different key of your liking), and using marker ' as a temporary marker is okay why not do this?

:nmap K m'a<CR><Esc>`'

now pressing K in normal mode over the character after which you want the line break to occur will split the line and leave the cursor where it was.

In fact you need the following combined operations:

  1. Press v to enter Visual Mode
  2. Select the line you want to split
  3. Press : to enter in Command Mode
  4. s/\s/\r/g
  5. Done

If you have the input:

aaa bbb ccc ddd

and want to output

aaa
bbb
ccc
ddd

You can use the command

f r<ENTER>;.;.

I found this to be the most faithful implementation of what I'd expect the opposite behaviour to J

nnoremap S i<cr><esc>^mwgk:silent! s/\v +$//<cr>:noh<cr>`w

It does the simplistic new line at cursor, takes care of any trailing whitespace on the previous line if there are any present and then returns the cursor to the correct position.

i <cr> <esc> - this is one of the most common solutions suggested, it doesn't delete non-whitespace characters under your cursor but it also leaves you with trailing whitespace

^mw - goto start of new line and create a mark under w

gk - go up one line

:silent! s/\v +$//<cr> - regex replace any whitespace at the end of the line

:noh<cr> - Clear any search highlighting that the regex might have turned on

`w - return the the mark under w

Essentially combines the best of both r<esc><cr> and i<cr><esc>

Note: I have this bound to S which potentially overwrites a useful key but it is a synonym for cc and since I don't use it as often as I do splits I am okay with overwriting it.

o ESC command will do it for you.