使用 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')Enter或ControlR=getcwd()Enter。
如果您想在当前行中使用它,请尝试,但请记住,该行的旧内容将被删除:
:.!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 上测试