vim r!在光标位置

jua*_*blo 21 vim

使用 vim,如果我使用

:r!date
Run Code Online (Sandbox Code Playgroud)

vim 在下一行插入日期,类似于

:r!pwd
Run Code Online (Sandbox Code Playgroud)

如何在光标位置下插入输出命令,而不在新行中插入?

Hep*_*ite 21

使用 " :read" Vim 将始终在新行上插入输出。不幸的是,解决方案并不简单。

当您处于插入模式时,您可以通过按ControlR然后键入在当前光标位置插入命令的输出=system('command')Enter。不幸的是,如果命令的输出有一个尾随换行符(大多数情况下)也会被插入,那么你的行将被破坏。

这可以通过添加substitute()对删除尾随换行符的调用来解决,但这会使命令比手动输入更麻烦。

最终的解决方案是创建某种映射,但由于 Vim 处理它所谓的“提前输入”的方式,这变得更加复杂;虽然您可以执行以下操作:

:nmap \e i<c-r>=substitute(system('date'),'[\r\n]*$','','')<cr><esc>
Run Code Online (Sandbox Code Playgroud)

如果命令在映射中是“硬连线”,则不能执行以下操作:

:nmap \e i<c-r>=substitute(system(input('Command: ')),'[\r\n]*$','','')<cr><esc>
Run Code Online (Sandbox Code Playgroud)

您尝试提示用户运行命令的地方,因为 Vim 只会感到困惑、发出哔哔声并进入插入模式。

所以你必须先提示命令运行,将它存储在一个变量中,然后插入处理后的输出。在这一点上,可能需要一个辅助函数来防止映射本身变得难以管理的混乱,所以我们最终得到了这样的结果:

function InlineCommand()
    let l:cmd = input('Command: ')
    let l:output = system(l:cmd)
    let l:output = substitute(l:output, '[\r\n]*$', '', '')
    execute 'normal i' . l:output
endfunction

nmap <silent> \e :call InlineCommand()<CR>
Run Code Online (Sandbox Code Playgroud)

请注意,nmap创建仅在正常模式下键入时执行的映射。

顺便说一句,如果您只想插入日期或当前工作目录,我给出的初始答案是可行的。只需进入插入模式并输入ControlR=strftime('%c')EnterControlR=getcwd()Enter


Cri*_*oot 5

如果您想在当前行中使用它,请尝试,但请记住,该行的旧内容将被删除:

:.!date

如果您想要确切的光标位置,您可以:

:let a=system("date") | let b=substitute(a,"[\r\n]*$","","g") | exec 'normal i'.b

长话短说:你需要替换,因为你想去掉 ^@(空字符),你也可以用 .s/\%x00//g 替换它。这是一个较短的版本,管道较少:

:exec 'normal i'.substitute(system("date"),"[\n]*$","","")

如果你想在同一行的不同点替换,你也可以设置标签:

鉴于此第 1 行:

1 Date: <datehere> and also <datehere>

执行:

:let a=system("date") | exec ".s/<datehere>/".a."/g" | .s/\%x00//g

更换后:

1 Date: jue ago 9 02:34:52 ART 2012 and also jue ago 9 02:34:52 ART 2012

在 Vim 7.2 上测试