Как правильно разделить вывод команды stdout и stderr оболочки и отобразить последний в строке состояния Vim? - PullRequest
0 голосов
/ 14 ноября 2018

Я использую Vim в качестве панели мониторинга и отслеживаю / обновляю множество таблиц с помощью различных внешних (фильтрующих) команд, запускаемых из макросов. Они работают потрясающе, за исключением вывода ошибок (еще не идеально, хотя я решил 80% этой интеграции сообщений. См. Статью для такого приложения).

Например, следующая таблица для игры «Я люблю кофе»:

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 | .  | .  | .

У меня есть следующий макрос в регистре s:

'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), который помогает обновить столбцы DONE и TODO, когда я коснулся количества в Store1 / 2/3. (А если закончите, сделайте проверку v и переместите линию вниз к вершине исторической области.)

Если в числах S1 / S2 / S3 что-то не так, перенаправление 2> перенаправит вывод stderr из вывода stdout и сохранит в файле vim.err. (не портить стол)

Блок if...endif вернет ошибку и вернет ее в строку состояния. Он напечатает Store3 drink: 9 > 8 max, когда я введу 9 в S3. (Но S3 может вместить максимум 8 напитков.)

Моя проблема в том, что последняя бывшая командная строка:

:if getfsize('/tmp/vim.err')>0|echo join(readfile('/tmp/vim.err'),"\|")|endif

останется в строке состояния, если не возникнет ошибка.

Как я могу улучшить это?


p.s.

История такого приложения

Приведенный выше (упрощенный) пример демонстрирует, как я использую Vim в качестве быстрой электронной таблицы, для многих таблиц, которые я обновляю каждый день. Преимущество в том, что мне не нужно покидать мой любимый Vim.

С некоторой подсветкой синтаксиса Vim может представлять эти таблицы так, как это лучше всего подходит для моих глаз. (в зависимости от этих значений)

При использовании связанных фильтров каждая таблица может корректно обновляться в соответствии с зависимостями значений.

За многие годы я разработал множество пар синтаксис / фильтр для различных проектов. И недавно я узнал, что я еще не интегрировал сообщения об ошибках фильтра в среду Vim. Такие сообщения будут случайным образом объединены в обычный вывод и составят испорченную таблицу. (с настройкой Vim по умолчанию shellredir = ">% s 2> $ 1")

Мое намерение - собрать сообщения фильтра stderr и разместить их в строке состояния Vim.

В моих экспериментах были достигнуты некоторые результаты:

  1. Указанный в макросе "2> vim.err" может отменять значения по умолчанию "2> & 1" и разбивать stderr на временный файл.

  2. Функция readfile () отлично подходит для чтения всего файла.

  3. Фильтр лучше не выходить с ненулевым значением для обнаруженных незначительных ошибок. Такое значение заставит Vim делать больше вещей и вызовет приглашение «Hit-enter».

И плавное размещение сообщений stderr в строке состояния - моя последняя часть головоломки.

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Я не думаю, что "else | echo" является хорошим решением для очистки строки состояния все время. Это некрасиво и не оптимизировано для вашего макроса.

Посмотрите на содержимое вашего tmpfile vim.err из stderr вашей программы-фильтра. Он не должен содержать ничего, если фильтр не видит ничего странного. Его пустое содержимое поможет вам очистить строку состояния в состоянии ОК. Я бы переписал ваш макрос так (намного проще и чище):

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

Кроме того, я не согласен с комментарием г-на Карката: «Макрос, хранящийся в реестре, подходит только для одного сеанса редактирования». Фактически макросы хранятся в .viminfo и доступны от сеанса к сеансу. Они никогда не исчезнут, если вы не назначите их пустыми. На мой взгляд, макрос так же силен, как отображение. Кроме того, макрос удобнее (проще создавать и поддерживать), чем отображение. По крайней мере, вы можете спасти убегающий кошмар картографирования. Я переписал бы макрос в отображение только тогда, когда он достаточно зрел и полезен для всего мира.

0 голосов
/ 14 ноября 2018

Хранение макроса в регистре прекрасно подходит для повторяющихся задач, выполняемых в течение одного сеанса редактирования.Для вещей, которые вам нужны чаще, я бы определил правильное отображение .С Vim «обновление» становится простым: содержимое макроса становится правой стороной команды :map| становится <Bar> и ^M становится <CR>), которую вы помещаете в свой ~/.vimrc:

:nnoremap <Leader>s 'oV}!order-update.pl ...

Если вы используете :nnoremap <silent>, ключи не будут напечатаны, и вы должны увидеть только результат :echo.


Прагматически исправитьваш макрос, просто добавьте else|echo|endif в конец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...