高效地非交互式使用vim

3

我使用vim来非交互式地将一个C语言函数写入文件中。 首先使用ctags创建一个tags文件。 然后使用以下命令将main()函数写入文件func.c中:

vim -R -U NONE -u NONE -c ":ta main" -c ":.,/^}/w!func.c" -c :q

换句话说,这个命令可以非交互式地运行3个vim命令:
  1. :ta main跳转到main()
  2. :.,/^}/w!func.c 从当前行写入到下一个起始位置为换行的闭合大括号
  3. :q退出
我尝试通过不浪费时间读取用户或系统启动文件(-U NONE -u NONE)并避免创建.swp文件(-R)来使其更加高效。
但有两个问题我无法解决:
  1. 如果将此命令作为管道的一部分运行,则会收到“Vim: Warning: Output is not to a terminal”警告和(显然)1秒的延迟。
  2. 如果保存此命令的标准输出,仍会看到使用了大量终端转义序列,生成了像“"func.c" 58 lines, 1707 characters written”这样的消息。
有没有办法避免这些问题?

你在标准输出上看到的是终端代码,用于“绘制”编辑器、移动光标并进行编辑。 - Some programmer dude
3
既然vim基本上是在ex之上的用户界面,那么使用纯粹的老旧ex怎么样? - Ruud Helderman
由于您实际上不会在“main”函数内嵌套代码块,因此您可能可以使用“sed”或“awk”来完成类似于此的任务。 - Some programmer dude
@JoachimPileborg 我已经尝试过 sed/awk 了;而且额外的复杂性在于标签文件搜索正则表达式不能直接传递给 sed,因为它包含未转义的元字符,如 *。此外,需要告诉它们文件,而 vim/ctags 已经内置了所有这些知识。 - Jens
@Ruud +1 我会试一下! - Jens
显示剩余2条评论
1个回答

9
这听起来像是您的用例可以使用“静默批处理模式”(:help -s-ex)进行操作。否则,您无法避免全自动化(并且其中一些缺点正如您所描述的那样)。

静默批处理模式

针对非常简单的文本处理(即使用Vim像增强版的“sed”或“awk”,也许仅从一个:substitute命令中受益于增强的正则表达式),请使用Ex模式
REM Windows
call vim -N -u NONE -n -i NONE -es -S "commands.ex" "filespec"

注意:静默批处理模式(:help -s-ex)会破坏Windows控制台,因此您可能需要在Vim运行后执行cls来清理。
# Unix
vim -T dumb --noplugin -n -i NONE -es -S "commands.ex" "filespec"

注意:如果"commands.ex"文件不存在,Vim将挂起等待输入;最好事先检查其是否存在!或者可以从stdin读取命令。您还可以使用-参数从stderr读取命令,并用从stdin读取的文本填充新缓冲区。

完全自动化

对于涉及多个窗口的更高级处理以及Vim的实际自动化(您可能需要与用户交互或让Vim运行以让用户接管),请使用:

vim -N -u NONE -n -c "set nomore" -S "commands.vim" "filespec"

以下是使用的参数摘要:
-T dumb           Avoids errors in case the terminal detection goes wrong.
-N -u NONE        Do not load vimrc and plugins, alternatively:
--noplugin        Do not load plugins.
-n                No swapfile.
-i NONE           Ignore the |viminfo| file (to avoid disturbing the
                user's settings).
-es               Ex mode + silent batch mode -s-ex
                Attention: Must be given in that order!
-S ...            Source script.
-c 'set nomore'   Suppress the more-prompt when the screen is filled
                with messages or output to avoid blocking.

感谢 -c "set nomore" 的想法 - 这帮助我修复了从 Ansible 调用 vim 的错误。 - jamesc

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