有时我会将大量数据粘贴到 vim 中(超过 5000 行),然后忘记启用粘贴模式。在这种情况下,vim 会忙上几分钟,试图正确缩进所有文本(对于某些类型的数据,缩进大约 10,000 个字符,性能会非常差)。
有没有办法中止粘贴过程?ESC、CTRL-C 和 CTRL-D 不起作用。
答案1
如果您使用的是 GUI 版本,您实际上应该从剪贴板寄存器 ( "*
) 或 X11 选择 ( "+
) 进行粘贴,正如 echristopherson 所建议的那样。因此,您无需单击鼠标中键或其他操作,而是导航到要粘贴的位置,然后键入"*P,包括初始引文。当通过p或P命令粘贴时,vim 知道您正在粘贴,因此'paste
不需要该选项 — 无论您从哪个寄存器粘贴。
如果您从终端粘贴,vim 实际上对此没有发言权。终端仿真器将转储您指示的任何内容,并且在大多数情况下,vim 无法区分不断输入的字符是您输入的还是您粘贴的。因此,您需要设置'paste
以告诉 vim 它不应该进行缩进等操作。
因此,如果您从终端粘贴,所有要粘贴的字符都会一次性排队,并且基本上已经发送到 vim,因此您无法中断它。从终端仿真器的角度来看,CTRL+c只是一个普通字符,因此它会排在所有其他等待粘贴的内容后面。当 vim 最终看到 + 时CTRL,c已经太晚了,因为没有什么可以中止了。
(更新:取决于终端仿真器,CTRL+c和类似信号可能以优先方式发送。具体来说,我在 Putty 中注意到了这一点,它会立即发出中断信号,并确实允许我中止放错位置的冗长的粘贴操作。不过,我真的不知道这是如何工作的。)
长话短说:如果可能的话,请使用"*P或"+P进行粘贴(如果我没记错的话,这在某些终端仿真器中也可以使用)。这是“正确”的粘贴方式;其他所有方式基本上都是变通方法,会给你带来这些麻烦。
答案2
我只是不小心从 tmux 粘贴了,而不是从 vim 的缓冲区粘贴,而 tmux 恰好有数千行我为其他内容复制的日志。如果没有粘贴模式,vim 的速度可能只有每秒 2 行,这可能需要几个小时。
ctrl+c 没有像预期的那样产生效果。我冒险尝试了一下,kill
并向 vim 进程发送了 SIGINT。这确实有效!一堆文本在底部栏上飞快地掠过,根本无法阅读,然后我又可以控制了,只粘贴了几百行。
我已经能够持续重现这一现象,但却找不到任何地方记录这一行为。
vim 源代码揭示了正在发生的事情。看起来处理程序将设置一个got_int
变量,注释说它将“中断任何循环”。寻找对的进一步引用got_int
,我发现了一个部分,它读取字符流,将在读取之间暂停以检查是否got_int
已设置,如果已设置则中断:https://github.com/vim/vim/blob/master/src/os_unix.c#L5217
答案3
- 打开新的终端窗口
pkill vim