Проблемы с stdio/piping при использовании vim в дочернем процессе в node.js

Я использую node.js для написания интерфейса командной строки, который генерирует файлы модульных тестов. Я использовал inquirer для получения пользовательского ввода, однако есть одно поле, в котором пользователь, скорее всего, захочет скопировать-вставить и/или отредактировать большие многострочные фрагменты данных JSON. Поэтому моя цель: открыть vim в определенной точке CLI -> разрешить ввод-> закрыть vim -> записать в файл tmp -> обработать результат.

Проблема в том, что ввод в vim также идет на родительский stdin, и когда нажата клавиша возврата, программа продолжает работу поверх vim (беспредел). Я совершенно уверен, что stdio/in/out/err не настроены должным образом, но я нигде не могу найти точное решение. Каждая итерация моего манипулирования потоками кажется ближе, но я знаю, что есть небольшое недостающее звено.

я пробовал много вещей по линии:

var vim = child_process.spawn('vim', [path], {stdin: 'pipe', stdout: 'pipe', stderr: 'pipe'});

var vim = child_process.spawn('vim', [path], {stdio: 'inherit'}); //{stdio: ['pipe','pipe','pipe']}

Наконец, я выполнил множество манипуляций со stdio из этого примера, js">Как мне открыть терминальное приложение из node.js?, но все еще остается небольшая недостающая ссылка, с которой мне нужна помощь

Примечания:

  • Я на 99% уверен, что мои асинхронные обещания в порядке.
  • это не обязательно должен быть vim, так как я сначала проверяю ENV для редактора
  • Я сравниваю это с git commit, где появляется редактор и позволяет вводить данные перед закрытием.
  • в небольшой тестовой программе я могу получить идеальную функциональность, но при попытке сделать это поверх другого процесса ничего не получается

tl;dr : я хочу игнорировать родительский процесс, пока ввод идет только в vim (child_process), но я не могу разделить их, и из-за этого программа выходит из строя

Если есть что-то, что я могу прояснить, пожалуйста, дайте мне знать. Спасибо!


person walker_e_23    schedule 20.11.2014    source источник
comment
Почему бы вам не сделать это, как Git, Subversion или Mercurial? Запишите то, что вы хотите, чтобы ваш пользователь отредактировал во временном файле, откройте Vim с этим файлом, отредактируйте его содержимое, напишите, достаточно, используйте содержимое этого временного файла для следующего шага.   -  person romainl    schedule 20.11.2014
comment
Это очень похоже на то, что я хочу сделать ... проблема в том, как я получаю их ввод, потому что он работает в другой программе, а потоки, так сказать, очень запутаны. Кроме того, они бы вставили текст, я бы не дал им что-то редактировать   -  person walker_e_23    schedule 20.11.2014


Ответы (1)


Я знаю, что это старо, но в любом случае 6 дней назад они выпустили функцию с версией 0.12.0 (Stable) 2015.02.06, которая делает это очень простым.

var spawnSync=require("child_process").spawnSync;
spawnSync("vim",[__filename],{stdio:"inherit"});

Это, конечно, заблокирует цикл событий, но в такой ситуации вы, вероятно, захотите дождаться пользователя. В противном случае вы можете столкнуться с записью узла в стандартный вывод и чтением стандартного ввода во время редактирования, что, очевидно, очень сбивает с толку, и это проблема, с которой вы столкнулись.

Если вам все еще нужны асинхронные вещи во время редактирования, вероятно, проще потребовать("child_process").fork, чтобы вы не путали stdin/stdout. Я предполагаю, что вы могли бы сделать что-то необычное, чтобы удалить всех слушателей и добавить их позже, но, вероятно, это не стоит усилий.

person Alexander Hansen    schedule 13.02.2015