在选定文本上运行一系列命令(或函数)的Vim操作

4

我有一系列的vim命令,它们将选定的块写入临时文件,在该文件上运行一个函数(knitcite),然后读取另一个文件:

w! ~/.vbuf <CR> 
!knitcite ~/.vbuf ~/.vbuf <CR> 
r ~/.vbuf <CR>

如果在运行第一个命令之前,在可视模式下选择了一段文本,则它会变成
:'<,'>w! ~/.vbuf <CR>

将所选内容传递到文件中,这是我需要的。我可以将其放入我的.vimrc文件中的一个简单vim函数中,但无法弄清楚如何将视觉选择的内容传递给该函数。如果这是一个单个命令而不是三个命令,我可以使用视觉映射来完成此操作,但不确定如何在三个命令中执行此操作。类似于:

command knitcite call Knitcite()
func! Knitcite()  
exec "w! ~/.vbuf <CR>"
exec "!knitcite ~/.vbuf ~/.vbuf <CR> "
exec "r ~/.vbuf <CR>"
func

但是这并没有从可视块中传递任何数据。我猜我需要给我的Knitcite函数一个参数,但是无法弄清楚应该是什么。 (似乎这可能与这个SO问题有关,但我无法从那个答案中推广。)

1个回答

3

最简单的方法是使用过滤器:

:'<,'>!knitcite

如果knitcite在过滤模式下无法使用(通常它使用-表示stdin为文件名,其他选项也可能适用),您可以将其包装在shell脚本中:
#!/bin/bash
tmpname="/tmp/$(basename "$0").tmp$RANDOM"

trap "rm -f '$tmpname'" ERR INT EXIT
knitcite <(cat) "$tmpname"
cat "$tmpname"

否则,看起来你想用输出替换视觉选择:
:'<,'>w! ~/.vbuf
:'<,'>d _
:silent! !knitcite ~/.vbuf ~/.vbuf.out
:'<-1r ~/.vbuf.out

注意

  1. 为输出使用单独的临时文件:否则,在大多数平台上可能会在读取输入之前截断输出文件!
  2. 利用:delete命令中的黑洞寄存器"_),以避免覆盖任何寄存器。

感谢您提供直接回答问题和通过包装shell脚本提出更好方法的建议。太棒了。 - cboettig
@cboettig 谢谢。注意,我刚刚从信号陷阱中删除了多余的引用。 - sehe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接