首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将shell命令的stdout和stderr分离干净,并在Vim状态行中显示后者?

如何将shell命令的stdout和stderr分离干净,并在Vim状态行中显示后者?
EN

Stack Overflow用户
提问于 2018-11-14 15:41:57
回答 2查看 264关注 0票数 0

我使用Vim作为我的仪表板,并使用各种外部(过滤)命令监视/更新许多表,这些命令都是从宏运行的。除了错误输出(还不完美,虽然我已经解决了80%的消息集成)之外,它们工作得非常好。见p.s.这类申请的故事)。

例如,下表是“我爱咖啡”游戏:

代码语言:javascript
复制
TYPE  | STAT |    NAME    | GOAL | DONE | TODO | S1 | S2 | S3
drink | .    | Latte      |  250 |  178 |   72 | .  | .  | .
drink | .    | Cocoa      |   99 |   46 |   50 | .  | 3  | .
drink | .    | Mocha      |  250 |  190 |   40 | 12 | 8  | .
drink | .    | Espresso   |   30 |    0 |   20 | 10 | .  | .
drink | .    | Iced Latte |   54 |    8 |   37 | .  | .  | 9
cake  | .    | Egg Tart   |   25 |   15 |    4 | 6  | .  | .
cake  | .    | Tiramisu   |   36 |    6 |   20 | 4  | 6  | .
cake  | .    | Brûlée     |   11 |    0 |    9 | .  | 2  | .
cake  | v    | Pudding    |   20 |   20 |    0 | .  | .  | .

我在寄存器中有以下宏:

代码语言:javascript
复制
'oV}!order-update.pl 2>/tmp/vim.err ^M:if getfsize('/tmp/vim.err')>0|echo join(readfile('/tmp/vim.err'),"\|")|endif ^M'o

(^M是字符ctrl-M),它帮助我在触及Store1/2/3中的数量时更新DONETODO列。(如果完成,将进行v检查,并将该行向下移动到历史区域的顶部。)

S1/S2/S3,的数量出现问题时,重定向2>将从stdout输出中溢出stderr输出,并保存在vim.err文件中。(不要把桌子弄乱)

if...endif块将获得错误输出并将其回显到状态行。当我把Store3 drink: 9 > 8 max放进S3时,它会打印S3。(但S3最多可容纳8杯饮料。)

我的问题是,最后一个前命令行:

代码语言:javascript
复制
:if getfsize('/tmp/vim.err')>0|echo join(readfile('/tmp/vim.err'),"\|")|endif

如果没有发生错误,将留在状态行中。

我该如何改进呢?

附注:

这类申请的故事

上述(简化)示例演示了如何将Vim用作快速电子表格,用于每天更新的许多表。好处是-我不用离开我最喜欢的维姆。

通过一些语法突出显示,Vim可以以比我更好的方式显示这些表。(取决于这些值)

使用相关的筛选器,每个表都可以根据值的依赖关系正确地更新。

多年来,我为各种项目开发了许多语法/过滤器对。最近,我意识到我还没有将过滤器的错误消息集成到Vim的环境中。这些消息将被随机合并到正常输出中,并形成一个混乱的表。(使用Vim的默认设置shellredir=">%s 2>$1")

我的意图是收集过滤器的stderr消息,并将它们安装在Vim的状态行中。

在我的实验中取得了一些成果:

  1. 宏中指定的"2>vim.err“可以推翻默认的"2>&1”,并将stderr拆分为tempfile。
  2. readfile()函数很适合在整个文件中读取。
  3. 对于检测到的小错误,筛选器最好不要以非零值退出。这样的值将使Vim做更多的事情,并引发“点击进入”提示符。

将stderr消息顺利地放入状态线是我的最后一道难题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-02 04:24:33

我不认为“否则的回显”是一个很好的解决方案,可以随时清除状态线。这是丑陋的,没有优化你的宏。

查看tmpfile vim.err的内容,来自过滤器程序的stderr。如果过滤器没有看到任何奇怪的东西,它就不应该包含任何内容。它的空内容将帮助您清除OK条件下的状态栏。我会将您的宏重写为(更简单、更简洁):

代码语言:javascript
复制
'oV}!order-update.pl 2>/tmp/vim.err ^M:echo join(readfile('/tmp/vim.err'),"\|") ^M'o

此外,我不同意Karkat先生的评论:“将宏保存在寄存器中只对一次编辑会议有好处”。实际上,宏保存在.viminfo中,并且可以在会话之间使用。他们永远不会消失,除非你分配空给他们。在我看来,宏和映射一样强大。而且,宏比映射更方便(更容易创建和维护)。至少您可以省去映射的逃避噩梦。只有在宏足够成熟且对全球有用时,我才会将宏转换为映射。

票数 1
EN

Stack Overflow用户

发布于 2018-11-14 16:15:23

将宏保存在寄存器中对于在单个编辑会话中完成的重复任务来说是可以的。对于更经常需要的东西,我会定义一个适当的映射。使用Vim,“升级”很简单:宏内容成为:map命令的右侧( |变成<Bar>^M变成<CR>),并将其放入~/.vimrc中。

代码语言:javascript
复制
:nnoremap <Leader>s 'oV}!order-update.pl ...

如果您使用:nnoremap <silent>,则不会打印这些键,您应该只看到:echo的结果。

要务实地修复宏,只需在末尾添加一个else|echo|endif即可。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53303852

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档