设置粘贴选项,但仅一次插入


16

我想有一种快速的方法来设置Vim 'paste'选项,插入一些文本,并恢复为以前的值'paste'

一个典型的用例是按字面意义插入OS剪贴板内容,而不考虑任何可能处于活动状态的插入方式重写(例如自动缩进),并且不更改Vim的状态。另一个用例是允许OS宏功能将击键注入Vim,并将其解释为文本。

显然,这可以归结为其他选项-总体思路是设置一些选项,但仅在通过插入模式进行一次旅行的持续时间内。

基本上,我想将键序列(例如_i)绑定到执行此操作的宏

:set paste
i…<Esc>
:set nopaste

在这里,i…<Esc>我的意思是切换到插入模式(与i命令一样)并在返回命令模式时恢复宏,除非我想以'paste'仍然处于活动状态(如果事先处于活动状态)而结束。我怎样才能做到这一点?

注意:OS剪贴板的内容已映射到"*register。在这种情况下,该'paste'选项不是很有用。这个问题的动机场景是在那些"*不满足注册支持条件的情况下— Vim没有使用该+xterm_clipboard功能进行编译,或者它运行在诸如Screen或通过SSH的终端中,从而将其与环境X服务器隔离。


1
我喜欢你的问题(我本人已经去过很多次)。但是,从+*注册粘贴起来难道不是很容易吗?
2015年

@yo' 只有当他们工作时。就我使用Vim而言,通常并非如此。
吉尔斯(Gillles)“所以-别再邪恶了”

Answers:


15

试试看:

function! Paste_Func()
    let s:inPaste = &paste
    if !s:inPaste
        set paste
    endif

    echom s:inPaste
    augroup paste_callback
        autocmd!
        autocmd InsertLeave <buffer> call Paste_End()
    augroup END

    startinsert
endfunction

function! Paste_End()
    augroup paste_callback
        autocmd!
    augroup END
    augroup! paste_callback

    if !s:inPaste
        set nopaste
    endif
endfunction

map _i :call Paste_Func()<cr>

它将您当前的粘贴状态存储在inPaste变量中,并设置粘贴(如果尚未设置)。然后,它会为您退出插入模式设置一个autocmd,然后将您置于插入模式。

当您退出插入模式时,它将运行autocmd,该操作将首先删除autocmd(因此,当您以其他方式退出插入模式时,它不会运行),最后,如果您最初未处于粘贴模式,则将其设置为nopaste。

另外,如果您在终端中使用vim,则可能需要看一下vim-bracketed-paste,它使用了几个终端仿真器提供的带括号的粘贴模式功能来检测您是否粘贴并自动设置模式。

编辑:修复脚本


这似乎是在正确的轨道上(特别是,我不知道如何通过普通的世界命令来“包围”一段插入内容)。谢谢。但是,这还不太正确,我看不出问题出在哪里:after之后_i,该paste选项已关闭,即使它在之前也处于启用状态。
吉尔斯(Gilles)'所以别再邪恶了'

你是对的!我很确定自己已经测试过了,但是我必须做些改动。我已经更新了帖子中的脚本,看看它现在是否对您有用。
2015年

4

除了我想以'paste'仍然处于活动状态而结束(如果它事先处于活动状态)。

'paste'应该在尽可能短的时间内处于活动状态。它禁用了许多功能(包括地图),因为它的唯一目的是避免误解所粘贴的文本。因此,我认为引用的要求实际上不是必须的。

话虽如此,实际上无需粘贴即可粘贴'paste'。如果您正在运行gvim或+xterm_clipboard在控制台vim中运行,则只需使用"+p从OS剪贴板粘贴即可。

仅在粘贴时自动缩进的问题实际上发生在两种情况下。在插入模式(<C-r>+)或用鼠标单击中键时插入寄存器的内容。

与其在插入模式下不插入寄存器的内容,不如在正常模式下从寄存器粘贴将避免重新格式化的问题。

如果要用鼠标单击鼠标中键,请使用该'mouse'选项让Vim代替终端处理鼠标中键。然后,Vim将按原样插入内容,而不是将输入的文本解释为已键入。


2
这些都不能回答我的问题。我提出明确的要求是有原因的!通常'paste'确实确实没有事前活动,但我不想考虑这一点。我经常在无法访问X剪贴板或鼠标的Vim中工作,或者是因为我的Vim版本没有该xterm_clipboard功能,或者是因为我正在例如当前正附加到Screen会话的Screen会话中工作。 X终端。
吉尔斯(Gilles)'所以别再邪恶了'

@Gilles然后您能解释一下如何粘贴吗?这是相关信息,能够提供答案,从而可以将该操作与您要执行的操作一起包装起来。
jamessan 2015年

1
我的基本用例是使用鼠标中键或Shift + Insert粘贴。但是,这并不真正相关:问题的核心是如何设置选项,切换到插入模式(使用i,我不是在问如何参数化),以及从插入模式返回时恢复选项的值。
吉尔(Gilles)'所以别再邪恶了'

1
@Gilles此评论中所述问题的核心对我而言比原始问题清楚得多。谢谢。
jamessan 2015年

1
@Gilles与无关,但可能与将来的访客有关。因此,您可以将其放在问题本身中(“我知道我可以使用,"*p"+p可以从剪贴板中粘贴,但我不想使用系统的粘贴功能”),然后不需要此答案。或您不知道,然后我认为这个答案在这里有位置。
2015年

4

我个人使用 yo正是出于这个原因来自Tim Pope出色的vim-unimpaired插件键绑定。从他的文档中:

没有为“粘贴”提供切换功能,因为包装单独插入的典型用例非常浪费:您切换了两次,但只粘贴了一次(YOPO)。而是按yoyO调用|o||O|已设置“粘贴”。离开插入模式会自动设置“ nopaste”。

仅针对您的问题安装插件可能会过大,但我发现它也提供了许多其他有用的键绑定(有关详细信息,请参见README)。


1

使用Linux或Mac上的Vim 8+,您现在可以简单地使用终端机的本机粘贴(例如,ctrl+shift+VGnome 中的鼠标中键,cmd+V如果终端支持带括号的粘贴在Mac上)。请勿按i进入插入模式。

它将粘贴操作系统剪贴板的内容,保留空格和制表符,而无需添加自动缩进。这相当于老:set pasteictrl+shift+Vesc:set nopaste方法。

您甚至不再需要安装+clipboardor或+xterm_clipboardvim功能。此功能称为“包围式粘贴”。有关更多详细信息,请参见/programming/2514445/turning-off-auto-indent-when-pasting-text-into-vim/56781763#56781763

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.