Может ли vim выводить содержимое регистра без обработки символов перевода строки (^ @) нажатием клавиши «Ввод»? - PullRequest
1 голос
/ 25 марта 2019

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

Я могу заставить это работать нормально с одной строкой текста, но как только добавляется перевод строки / перевода строки, все попытки сделать это терпят неудачу.

Использование файла примера, содержащего:

1 a
2 ab
3 abc
4 abce
5 abcef
6 abcefg

Сначала я помещаю содержимое файла в регистр ("m" через ":% y m" Затем я пытаюсь ": exe '! Echo' @m"

Это выводит первую строку текста на терминал

а

Но vim обрабатывает первую строку / разрыв после следующей буквы "a" как нажатие клавиши Enter, так что выдает следующее сообщение об ошибке

E492: Не является командой редактора: abce ^ @ abcef ^ @ abcefg ^ @ ^ @

Я запускаю следующие команды в режиме ": debug", надеясь заменить символы ^ @ символом новой строки (\ n)

: замена эха (strtrans (@m), "^ @", '\ n', "g")
: замена эха (strtrans (@m), '^ @', '\ n', "g")

Я пробовал двойные и одинарные кавычки и пробовал набирать символ вставки и букв амперсанд, а также использовать специальный символ CTRL-V + CTRL-J К сожалению, в режиме отладки я вижу, что вывод всегда следующий:

a ^ @ ab ^ @ abc ^ @ abce ^ @ abcef ^ @ abcefg ^ @ ^ @

То же самое происходит с printf. Я немного разбирался с неясностями в новых строках, нулевых символах и в том, как vim обрабатывает их в регистрах, но у меня неясно, насколько правдоподобно то, чего я пытаюсь достичь.

Ответы [ 2 ]

3 голосов
/ 26 марта 2019

Я думаю, что вы ищете shellescape():

:execute "!echo " . shellescape(@@, 1)

С ненулевым аргументом в качестве второго аргумента символ <NL> также экранируется.

Для получения дополнительной помощи см .:

:h shellescape()
3 голосов
/ 25 марта 2019

:h nl-used-for-nul объясняет, что символ новой строки '\n' отображается Vim как ^@. Итак, да, как вы уже сказали, вы отправляете фактические символы новой строки в оболочку.

Далее, общая идея замены одного символа '\n' (ASCII 0x0a) на два символа "\n" (0x5c 0x6e) также верна. Вы хотите, чтобы оболочка получила foo\nbar.

:echo substitute(@m, '\n', '\n', 'g')
a
ab
abc
abce
abcef
abcefg

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

:echo substitute(@m, '\n', '\\n', 'g')
a\nab\nabc\nabce\nabcef\nabcefg\n

Это выглядит хорошо! Итак, давайте попробуем всю команду, которую вы имели в виду:

:execute '!echo' substitute(@m, '\n', '\\n', 'g')
anabnabcnabcenabcefnabcefgn

Press ENTER or type command to continue

Хм? Ну, :execute оценивает строки и поэтому потребляет"один уровень строк". Таким образом, мы должны еще раз избежать наших новых строк, тогда как удваиваем количество экранирований для каждого "уровня строк".

Итак, нам не просто нужны a\nab\nabc, нам нужны a\\nab\\nabc:

:echo substitute(@m, '\n', '\\\\n', 'g')
a\\nab\\nabc\\nabce\\nabcef\\nabcefg\\n

:execute '!echo' substitute(@m, '\n', '\\\\n', 'g')
a
ab
abc
abce
abcef
abcefg


Press ENTER or type command to continue

?

Дополнительные примечания:

  • При использовании двойных кавычек, которые обрабатывают escape-символы, в отличие от строк в одинарных кавычках, нам придется снова удваивать количество экранированных символов: substitute(@m, '\n', "\\\\\\\\n", 'g').
  • Если вы хотите удалить завершающий символ новой строки, используйте trim(@).
...