如何编写vim函数来输出系统命令的结果?

时间:2010-07-08 22:14:40

标签: vim

到目前为止我所拥有的:

function! GetMarker()
    return system('echo $random `date` | md5sum | cut -d" " -f1')
endfunction

我希望能够做:getmarker并让它在我的光标处插入该系统命令的输出,没有新行。

function!function之间有什么区别?

编辑:在你问任何人之前,我需要随机字符串来标记我的代码中的部分,以便通过在我的todo wiki中引用我的笔记再次找到它们。

3 个答案:

答案 0 :(得分:5)

您可以使用matchstr()substitute[:-2]等修改/缩小上一个换行符

function s:GetMarker()
  let res = system('echo $random `date` | md5sum | cut -d" " -f1')
  " then either
  let res = matchstr(res, '.*\ze\n')
  " or
  let res = res[:-2]
  " or
  let res = substitute(res, '\n$', '', '')
  return res
endfunction
command! -nargs=0 GetMarker put=s:GetMarker()

敲击函数/命令定义(带'!')将允许您多次定义脚本,从而更新您正在维护的函数/命令,而不必退出vim。

答案 1 :(得分:5)

EDIT1。拿两个。试图吸收吕克的反馈。没有临时文件(readfile()在VIM 6.x中不可用,我在某些系统上有。)

:function InsertCmd( cmd )
:       let l = system( a:cmd )
:       let l = substitute(l, '\n$', '', '')
:       exe "normal a".l
:       redraw!
:endfunction

:imap <silent> <F5> <C-O>:call InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>
:map <silent> <F5> :call InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>

:put无法使用,因为它按行工作。我用更好的<Esc>...<Insert>替换了<C-O>。我留下了重绘,因为它有助于调用命令的情况产生输出到stderr。

或使用<C-R>=

:function InsertCmd( cmd )
:       let l = system( a:cmd )
:       let l = substitute(l, '\n$', '', '')
:       return l
:endfunction

:imap <silent> <F5> <C-R>=InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>
  

function!function之间有什么区别?

命令结束时的感叹号大部分时间意味着强制执行。 (建议查看:help,因为不同的命令以不同的方式使用!,但VIM会尝试记录所有形式的命令。)在function的情况下,它告诉VIM覆盖以前的功能的定义。例如。如果你把上面的代码放到func1.vim文件中,第一次:source func1.vim可以正常工作,但是第二次失败并且错误已经定义了函数InsertCmd。


在尝试实施something similar here之前,我曾做过一次。我不擅长VIM编程,因此它看起来很蹩脚,Luc的建议应该优先考虑。

无论如何它仍然存在:

:function InsertCmd( cmd )
:       exe ':silent !'.a:cmd.' > /tmp/vim.insert.xxx 2>/dev/null'
:       let l = readfile( '/tmp/vim.insert.xxx', '', 1 )
:       exe "normal a".l[0]
:       redraw!
:endfunction

:imap <silent> <F5> <Esc>:call InsertCmd( 'hostname' )<CR><Insert>
:map <silent> <F5> :call InsertCmd( 'hostname' )<CR>

尽管跛脚,但它确实有效。

答案 2 :(得分:0)

我在尝试映射热键以插入当前日期和时间时遇到了类似的问题。我通过包含一个&lt; backspace&gt;解决了换行问题,但是当我缩进时仍然插入换行符(退格会杀死最后一个字符,但是当我缩进时,我得到了换行符+制表符,只有标签会消失)。

所以我做了这个 - 只是关闭smartindent,插入字符串,然后再打开它:

imap <F5> <esc>:set nosmartindent<CR>a<C-R>=system('echo $random `date` \| md5sum \| cut -d" " -  f1')<CR><Backspace><esc>:set smartindent<CR>a

...有效,但如果你坐在一条新的自动缩进线上,它会缩进。要绕过它,插入一个角色来保持你的位置,然后逃脱,关闭smartindent,摆脱额外的角色,然后做其余的事情:

imap <F5> x<esc>:set nosmartindent<CR>a<backspace><C-R>=system('echo $random `date` \| md5sum \|  cut -d" " -f1')<CR><Backspace><esc>:set smartindent<CR>a

这似乎有效。