Vim: создание строкового литерала C вокруг блока текста с вертикально выровненными кавычками? - PullRequest
1 голос
/ 30 июня 2010

Я хотел бы создать макрос или скрипт в Vim, который выполняет следующие действия:

  1. обернуть блок текста в двойные кавычки
  2. экранирование любых кавычек, которые появляются в самом тексте
  3. иметь кавычки с правой стороны в вертикальном выравнивании

Например:

<html>
<head></head>
<body>
<h1>High Score Server</h1>
<table>
ROWS
</table>
</body>
</html>

станет:

"<html>                    "
"<head></head>             "
"<body>                    "
"<h1>High Score Server</h1>"
"<table>                   "
"ROWS                      "
"</table>                  "
"</body>                   "
"</html>                   ";

Я могу добиться этого с помощью макроса, но без вертикального выравнивания кавычек с правой стороны. Может ли кто-нибудь помочь мне с этим?

Ответы [ 7 ]

5 голосов
/ 01 июля 2010

Что бы я сделал:

С плагинами "round "и" Align ":

1) с курсором в первой строке (0,0), введите <C-V>)$s" 2)затем <S-V>):Align " и <Enter>.

Другое решение без плагинов:

1) установить виртуальный режим

:set ve=all

2) <C-V> чтобы перейти к блочному выделению, с курсором в позиции 0,0

3) перейдите вниз текста, затем Shift-I, введите " и Esc.Это должно предшествовать кавычкам.

4) теперь идите на левый конец (так как ve = all, вы можете пойти туда, где нет текста) 5) <C-V>, спуститься вниз, набрать r"

Это долго объяснять, но легко сделать и воспроизвести.Также полезно во многих случаях.

2 голосов
/ 01 июля 2010
function Enquote()
    let [startline, endline]=sort([line("'<"), line("'>")])
    let lines=getline(startline, endline)
    let lengths=map(copy(lines), 'len(split(v:val, ''\zs''))')
    let maxlen=max(lengths)
    call map(lines, '''"''.v:val.repeat(" ", maxlen-lengths[v:key]).''"''')
    return setline(startline, lines)
endfunction

Объяснение:

line("'<") и line("'>") получают номера строк начала и конца последнего визуального выбора.

sort([...]) сортирует номера строк, так как вы можетеначали выделять строки с конца выделения.

let [a, b]=[c, d] - это параллельное присваивание: sort создаст отсортированный список из двух элементов, где первый элемент меньше или равен второму элементу.Очевидно, что меньше - это первая выбранная строка.

len(split(v:val, '\zs')) - это расширенный strlen(), который поддерживает юникод.

max(list) находит максимальное значение.Очевидно.

Итак, map(copy(lines), 'len(split(v:val, ''\zs''))') применяет это strlen ко всем элементам в списке.copy() требуется, поскольку мы не хотим, чтобы наш список был изменен.

map(lines, '''"''.v:val.repeat(" ", maxlen-lengths[v:key]).''"''') изменяет строки так, как вам нужно.Я переключился с printf на repeat, потому что printf неправильно обрабатывает многобайтовые символы (под «правильно» я подразумеваю, что «¥» имеет длину один символ, в то время как printf считает его длиной два байта).1032 * фактически изменяет буфер.

1 голос
/ 07 июля 2010

Использование Unix-программы "par" для этого вполне может решить вашу проблему. Vimcast показывает, как интегрировать его в vim на http://vimcasts.org/episodes/formatting-text-with-par/

0 голосов
/ 24 сентября 2013

Во что бы то ни стало прислушайтесь к предыдущим ответам и приведите ваш vim-fu в форму. Или установите / измените / проклейте автора этого плагина:

http://www.vim.org/scripts/script.php?script_id=4727

Со страницы плагина:

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

Если вам нужно внести изменения, используйте репозиторий исходного кода:

https://bitbucket.org/dsign/stringliteral.vim

0 голосов
/ 01 июля 2010

в два прохода:

let l = max(map(getline("'<", "'>"), 'strwidth(v:val)'))
'<,'>s/.*/\=('"'.submatch(0).repeat(' ', l-strwidth(submatch(0)) )).'"'
0 голосов
/ 01 июля 2010

лучшее, что я получил, это 3-проходное регулярное выражение.

выберите блок в визуальном режиме, затем используйте:

:'<,'>s#^#"#
:'<,'>s#$#                                                #
:'<,'>s#\(.\{28\}\).*#\1"

с длиной 28, равной длине вашей самой длинной строки.

0 голосов
/ 30 июня 2010

Можно ли сделать два прохода по списку строк в скрипте vim? Тогда вы можете сделать что-то вроде этого (псевдокод):

let N = length of longest line
for each line L:
    insert a " character at the beginning
    append N - len(L) spaces
    append a " character
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...