2010-07-08 61 views
4

我有什么至今:如何编写vim函数来输出系统命令的结果?

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

我希望能够做一个:getmarker并让它在我的光标插入系统命令的输出,没有新的生产线。

function!function之间的区别是什么?

编辑:在你们之前,我需要随机字符串来标记代码中的部分,以便我可以通过在我的待办事项维基中引用我的笔记再次找到它们。

回答

5

Edit1。拿两个。试图吸收Luc的反馈。没有临时文件(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不能使用,因为它工作在行方式。我用<C-O>代替<Esc>...<Insert>。我离开了重绘,因为它有助于调用命令生成输出到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> 

尽管是瘸腿的,它的工作原理虽然。

+0

如果您的方法有一个问题,它与临时文件有关。多个用户不能使用相同的脚本。最好使用tempname()。否则,可能会增强一些内容: - 不重绘, - 返回l [0], - 并将其插入' ='以避免与光标位置有关的错误。 – 2010-07-09 09:58:49

+0

@Luc:' =' - 非常非常酷。 'tempname()' - 很好的了解。感谢您的建议。 – Dummy00001 2010-07-09 12:23:29

+0

“命令结束时的感叹号意味着强制执行。”这不是真的。有很多反例。见':g',':delm',':put',... – 2010-07-12 15:36:24

5

您可以修剪/的Chomp与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。

+0

这仍然插入一个新行的散列,有没有办法让它插入光标? – 2010-07-10 19:36:58

+0

是的。你将不得不玩像exe +正常的东西。但命令不是这种文本操作的最佳构造。 - >'命令! -nargs = 0 GetMarker exe“正常\ = s:GetMarker()\ ”' – 2010-07-12 15:39:26

0

我遇到了类似的问题,试图映射热键来插入当前的日期和时间。我通过包括<退格>解决了换行问题,但是当我缩进时退格符会插入换行符(退格键会终止最后一个字符,但是当我缩进时,我得到换行符并且只有选项卡将会消失)。

所以我这样做 - 刚满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 

这似乎是工作。

相关问题