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

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

这显然可以推广到其他选项-一般想法是设置一些选项,但仅针对

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

:set paste
i…<Esc>
:set nopaste


其中i…<Esc>的意思是切换到插入模式(与i命令一样),并在返回命令模式时恢复宏,除非我想以'paste'预先处于活动状态而结束。我该怎么办?


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


评论

我喜欢您的问题(我本人曾去过很多次)。但是,从+或*寄存器粘贴是否更容易?

@yo'仅当他们工作时。就我使用Vim而言,通常不是这种情况。

#1 楼

试试看:

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,它使用了多个终端仿真器提供的包围式粘贴模式功能来检测您是否正在使用vim。粘贴并自动设置模式。

编辑:修复了脚本

评论


这似乎是在正确的轨道上(特别是,我不知道如何通过普通的世界命令来“包围”一段插入内容)。谢谢。但是,这不太正确,我也看不出问题出在哪里:在_i之后,粘贴选项处于关闭状态,即使之前处于打开状态也是如此。

–吉尔斯'所以-不再是邪恶的'
15年2月4日在21:16

你是对的!我敢肯定,我已经测试过了,但是我必须做些改变。我已经更新了帖子中的脚本,现在来看它是否对您有用。

–乍得
15年2月4日在22:53

#2 楼


如果要事先使'paste'仍然处于活动状态,则结束。


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

话虽如此,实际上粘贴起来很容易,而无需设置'paste'。如果您正在运行gvim或在控制台vim中使用+xterm_clipboard,则只需使用"+p从操作系统剪贴板中进行粘贴。

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

代替在插入模式下插入寄存器的内容,而在普通模式下从寄存器粘贴将避免重新格式化的问题。

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

评论


这些都不能回答我的问题。我提出明确的要求是有原因的!通常,“粘贴”确实事先没有激活,但我不想考虑这一点。我经常在无法访问X剪贴板或鼠标的Vim中工作,或者因为我的Vim版本没有xterm_clipboard功能,或者因为我正在例如当前恰好附加到X终端的Screen会话。

–吉尔斯'所以-不再是邪恶的'
15年2月4日在17:30

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

–詹姆斯
15年2月4日在17:55

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

–吉尔斯'所以-不再是邪恶的'
15年2月4日在18:35

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

–詹姆斯
15年2月4日在19:48

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

–吗?
15年2月4日在19:51

#3 楼

就我个人而言,正是出于这个原因,我使用了Tim Pope出色的vim-unimpaired插件中的yo键绑定。在他的文档中:


没有为“粘贴”提供切换,因为通常的用法
包裹单独插入的情况非常浪费:您切换
两次,但只粘贴一次(YOPO)。相反,请按yoyO,以
在已设置“粘贴”的情况下调用|o||O|。自动离开插入模式集
'nopaste'。


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

#4 楼

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

它将粘贴OS剪贴板的内容,保留空格和制表符,而无需添加自动缩进。它等效于旧的:set pasteictrl+shift+Vesc:set nopaste方法。

您甚至不需要安装+clipboard+xterm_clipboard vim功能。此功能称为“包围式粘贴”。有关更多详细信息,请参见https://stackoverflow.com/questions/2514445/turning-off-auto-indent-when-pasting-text-into-vim/56781763#56781763