在不进入插入模式的情况下插入换行符,vim

98

我想在vim中使用Shift-EnterCtrl-Enter键来在正常模式下插入新行。我尝试了一些解决方案,并从Vim Wikia - Insert newline without entering insert mode混合了一些解决方案,但是Shift-EnterCtrl-Enter没有反应:

" put a new line before or after to this line
nnoremap <S-CR> m`o<Esc>``
nnoremap <C-CR> m`O<Esc>``

" reverse J command
nnoremap <C-J> vaW<Esc>Bi<CR><Esc>k:s/\s\+$//<CR>$

你的 $TERM 是什么(如果是 *nix)? - timss
echo $TERM -> xterm 为什么? - helq
如何解释键值可能是相关的。您是否也使用screen或tmux?话虽如此,我尝试了几种替代方案,但只有在这里才能使用“map <CR> o<Esc>”命令。 - timss
好的,我不使用screen或tmux与vim。是的,map <CR> o<Esc>可以工作。但是,如何映射O<Esc>?对于我的糟糕英语,我感到抱歉。 - helq
9个回答

92

我的替代方案是使用 oo(或 OO) 通过以下映射在当前行下方(或上方)插入新行: nmap oo o<Esc>k (或 nmap OO O<Esc>j


6
好的回答。只需按下'o'键即可进入插入模式。谢谢。 - jpincheira
其他答案中困扰我的问题是快捷方式。这个更符合我的偏好。 - Canella
1
我执行了 nmap <C-S-J> o<Esc>k 由于 Shift+J 删除换行符。 - Mo2
11
另一个改进方法是使用nmap oo m`o<Esc>nmap OO m`O<Esc>来保留光标位置,当在不同的缩进级别插入换行时,具体描述可以参考这些评论 - MilesF
11
您可能希望将超时时间设置为比默认的1秒更短的值,以便通过oO快速进入插入模式。我喜欢使用set timeoutlen=200。您只需要足够快地按下双重 oo 即可缩小窗口并执行其他非阻塞超时命令序列。 - MilesF

29

拿走一个空行并将其粘贴:

从光标位于空行开始:

yy + (shift + p)

"yy" 拷贝当前行,"shift + p" 在当前行下方粘贴,无需进入插入模式。


1
(按下 shift + y 然后再按 p) 作为替代方案。 - stanley

10
由于键盘输入的内部处理方式,这种情况通常不可能实现。(在GVIM中应该可以。)一些键组合,例如Ctrl+非字母键无法映射,而Ctrl+字母键Ctrl+Shift+字母键无法区分。(除非您的终端发送一个不同的termcap代码,大多数终端都没有。)在插入或命令行模式下,尝试键入键组合。如果没有发生任何事情/插入,您将无法使用该键组合。这也适用于<Tab>/<C-I><CR>/<C-M>/<Esc>/<C-[>等。(唯一的例外是<BS>/<C-H>。)这是已知的痛点,并且是vim_dev和#vim IRC频道上各种讨论的主题。

一些人(尤其是Paul LeoNerd Evans)希望解决这个问题(即使是在支持此功能的终端中的控制台Vim),并提出了各种建议

但是,截至今天,还没有补丁或志愿者站出来,尽管许多人表示希望在未来的Vim 8主要版本中实现这一点。


这主要是由于历史原因,但不幸的是很难改变。 - Ingo Karkat

3
如果您不想按ESC键,那么这个怎么样?
yypd$

2
因为我有D删除到行尾,所以我的是 yypD - DrBeco
这样做的缺点是你会失去剪贴板中的任何内容(yankboard?不确定在vi(m)中叫什么)。 - zshift
yypdd在不同的环境下表现良好。 - Ahmad Yoosofan

2
这是我使用的内容:
nmap <CR> :a<CR><CR>.<CR>

我尝试了nmap <CR> o<Esc>,但它会导致UI出现故障,因为它会在插入模式和非插入模式之间切换。

2

我使用的是:s/\n/\r\r/g命令(将换行符替换为两个换行符,与"o"相同)。


需要对这个chained cabbrev进行编程才能实现。 - zzapper

0

你可以将一个空行复制到寄存器中并使用它。我已经养成了将新行复制到n寄存器的习惯。 你可以将新行复制到寄存器中,例如n,使用以下命令: "ny 你可以在不离开正常模式的情况下将新行粘贴到任何地方,例如: "np


0
如果你想在不让光标跳动的情况下添加一个换行符,你可以:
(这是用Lua编写的Neovim代码,但你也可以将其转换为Vim脚本。)
vim.keymap.set("n", "<CR>", "mao<esc>0<S-d>`a<cmd>delmarks a<cr>", { desc = "Add new line below" })
vim.keymap.set("n", "<S-CR>", "maO<esc>0<S-d>`a<cmd>delmarks a<cr>", { desc = "Add new line above" })

这个使用标记来保留你的行和列位置。并删除在打开新行时自动添加的任何字符(例如注释字符)。

  1. ma:标记当前光标位置。
  2. o:打开新行并进入插入模式。
  3. <esc>:进入正常模式。
  4. 0<S-d>:跳转到行的开头并清空它。
  5. `a:跳转到原始标记的光标位置。
  6. <cmd>delmarks a<cr>:删除该标记。

请注意,如果你想避免在非正常窗口中映射回车键(例如在快速修复列表中按下回车键仍然会带你到文件),你可以:

-- Set keymap for normal windows only (e.g. not quickfix)
local normal_window_keymap = function(mode, lhs, rhs, opts)
  local merged_opts = vim.tbl_extend("force", { noremap = true, expr = true }, opts or {})

  vim.keymap.set(mode, lhs, function()
    local buftype = vim.fn.win_gettype()
    return buftype == "" and rhs or lhs
  end, merged_opts)
end

-- Open new line (like o/O) without moving the cursor, without entering insert mode and removing any characters
normal_window_keymap("n", "<CR>", "mao<esc>0<S-d>`a<cmd>delmarks a<cr>", { desc = "Add new line below" })
normal_window_keymap("n", "<S-CR>", "maO<esc>0<S-d>`a<cmd>delmarks a<cr>", { desc = "Add new line above" })

-3

你可以使用一个技巧来实现这个。

在编辑模式下,你可以使用p来粘贴当前的剪贴板。由于o会添加一个新行,你可以使用o<ESC>ddp在光标下方添加一个新行;从那里开始,p将添加新行,直到你删除其他内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接