Smart Wrap в Vim

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

Например, вместо

<p>
    <a href="#" onclick="location.href='http://www.example.com'; return false;">
        This is a bogus link, used to demonstrate
an example
    </a>
</p>

он будет выглядеть как

<p>
    <a href="somelink">
        This is a bogus link, used to demonstrate
        an example
    </a>
</p>

Ответ 1

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

:help breakindent
:help breakindentopt

Выдержки из справки vim ниже:

'breakindent'     'bri'   boolean (default off)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Every wrapped line will continue visually indented (same amount of
        space as the beginning of that line), thus preserving horizontal blocks
        of text.

'breakindentopt' 'briopt' string (default empty)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Settings for 'breakindent'. It can consist of the following optional
        items and must be seperated by a comma:
                  min:{n}     Minimum text width that will be kept after
                              applying 'breakindent', even if the resulting
                              text should normally be narrower. This prevents
                              text indented almost to the right window border
                              occupying lot of vertical space when broken.
                  shift:{n}   After applying 'breakindent', wrapped line
                              beginning will be shift by given number of
                              characters. It permits dynamic French paragraph
                              indentation (negative) or emphasizing the line
                              continuation (positive).
                  sbr         Display the 'showbreak' value before applying the 
                              additional indent.
        The default value for min is 20 and shift is 0.

Для этого также showbreak параметр showbreak котором сумма смены будет showbreak указанным вами символам.

Пример конфигурации

" enable indentation
set breakindent

" ident by an additional 2 characters on wrapped lines, when line >= 40 characters, put 'showbreak' at start of line
set breakindentopt=shift:2,min:40,sbr

" append '>>' to indent
set showbreak=>>   

Обратите внимание на поведение

Если вы не указываете sbr вариант, любой showbreak любые символы положить прилагается к отступа. Удаление sbr из приведенного выше примера приводит к эффективному отступу в 4 символа; с этим параметром, если вы просто хотите использовать showbreak без дополнительных отступов, укажите shift:0.

Вы также можете showbreak отрицательный сдвиг, который приведет к перетаскиванию символов showbreak и showbreak текста обратно в любое доступное пространство отступа.

При указании min значения смещенное количество будет сдавлено, если ширина терминала showbreak, но символы showbreak всегда сохраняются.

Ответ 2

Есть патч для этого, но он задерживался в течение многих лет, и последний раз, когда я проверял, не применялся чисто. См. Запись "Корректно отступы завернутые строки" в http://groups.google.com/group/vim_dev/web/vim-patches - Я действительно хочу, чтобы это попало в магистраль.

Обновление: эта ссылка, похоже, имеет bitrotted. Вот более актуальная версия патча.

Обновление 2: слияние вверх по течению (с 7.4.345), так что теперь вам нужно только :set breakindent.

Ответ 3

Я не думаю, что возможно иметь точно такой же отступ, но вы все равно можете получить лучший обзор, установив опцию "showbreak".

:set showbreak=>>>

Пример:

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
>>>an example
    </a>
</p>

Реальная вещь выглядит лучше, чем примерный код выше, потому что Vim использует другой цвет для " → > ".

Ответ 4

UPDATE: в июне 2014 года патч поддерживающий опцию breakindent, был объединен с Vim (версия 7.4.346 или новее для лучшая поддержка).


Вы также можете попробовать :set nowrap, который позволит vim отображать длинные строки, прокручивая вправо. Это может быть полезно для изучения общей структуры документа, но может быть менее удобным для редактирования.

Другие параметры, близкие к тем, которые вы ищете, это linebreak и showbreak. С помощью showbreak вы можете изменить то, что отображается в левом поле строк, которые обернуты, но, к сожалению, он не допускает отступ переменной в зависимости от текущего контекста.

Ответ 5

Единственный способ узнать, что вы могли бы сделать это, - использовать символ возврата (как упоминается Cfreak) и объединить опцию textwidth с различными параметрами отступов. Если ваш отступ настроен правильно (как и по умолчанию с синтаксисом html, я полагаю, но в остальном смотрите опции autoindent и smartindent), вы можете:

:set formatoptions = tcqw
:set textwidth = 50
gggqG

Если вы настроили настройку formatoptions, лучше просто сделать:

:set fo += w
:set tw = 50
gggqG

Что это делает:

:set fo+=w  " Add the 'w' flag to the formatoptions so 
            " that reformatting is only done when lines
            " end in spaces or are too long (so your <p>
            " isn't moved onto the same line as your <a...).
:set tw=50  " Set the textwidth up to wrap at column 50
gg          " Go to the start of the file
gq{motion}  " Reformat the lines that {motion} moves over.
G           " Motion that goes to the end of the file.

Обратите внимание, что это не то же самое, что и мягкая оболочка: она будет обертывать строки как в исходном файле, так и на экране (если вы не сохраните его, конечно!). Существуют и другие параметры, которые можно добавить в formatoptions, которые будут автоматически форматироваться по мере ввода: подробности в :help fo-table.

Для получения дополнительной информации см.

:help 'formatoptions'
:help fo-table
:help 'textwidth'
:help gq
:help gg
:help G
:help 'autoindent'
:help 'smartindent'

Ответ 6

:set smartindent
:set autoindent

Я думаю, вам все равно придется использовать возврат, хотя

Ответ 7

Если ваш HTML достаточно хорошо сформирован, запуск его через xmllint может помочь:

:%!xmllint --html --format

Ответ 8

Макро-решение:


Edit:

Работает gq{motion} автоматически, независимо от переменной "textwidth". Это проще/лучше, чем использование 80lBi^M для моего макроса.


Если у вас включен режим автоматического включения

:set autoindent

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

установите регистр z в:

gg/\v^.{80,}$^[email protected] (change 80 to whatever length you want your text to be)

и установите регистр x в:

80lBi^M^[[email protected] (change 80 to whatever length you want your text to be)

Тогда do

@x   

для активации макросов. Через несколько секунд вы будете полностью напечатаны в строках с строкой 80 символов или меньше.

Пояснение:

Здесь раскрытие макросов:

Часть 1 (макрос z):

gg/\v^.{80,}$^[email protected]

gg - start at the top of the file (this avoids some formatting issues)
/  - begin search
\v - switch search mode to use a more generic regex input style - no weird vim 'magic'
^.{80,}$ - regex for lines that contain 80 or more characters
^M - enter - do the search (don't type this, you can enter it with ctrl+v then enter)
@x - do macro x

Часть 2 (макрос x):

80lBi^M^[[email protected]

80l - move right 80 characters
B   - move back one WORD (WORDS include characters like "[];:" etc.)
i^M - enter insert mode and then add a return (again don't type this, use ctrl+v)
^[  - escape out of insert mode (enter this with ctrl+v then escape)
@x  - repeat the macro (macro will run until there are no more lines of 80 characters or more)

Предостережение:

  • Этот макрос будет разбит, если там есть WORD, длина которого составляет 80 символов.

  • Этот макрос не будет делать интеллектуальные вещи, такие как отступы, проходящие мимо тегов.

  • Используйте параметр lazyredraw (: set lazyredraw), чтобы ускорить это.