Существуют (как минимум) три метода замещения, относящиеся к этому делу.
Первый использует синтаксис сопоставления предыдущего атома для
естественно определить шаг отступа. Согласно постановке вопроса,
шаг отступа - пара соседних пробелов, перед которыми ничего не стоит
но пробелы с начала строки. Следуя этому определению, можно
построить фактический шаблон замещения справа налево.
:%s/\%(^ *\)\@<= /\t/g
Действительно, шаблон обозначает вхождение двух буквенных пробелов
после совпадения нулевой ширины \@<=
предыдущего атома, который является
шаблон ^ *
, заключенный в круглые скобки \%(
/ \)
. Эти не захватывая
вместо обычных фиксирующих скобок используются \(
/ \)
, так как
нет необходимости далее ссылаться на совпадающие начальные пробелы Из-за g
флаг, указанная выше команда :substitute
проходит через пару начальных пробелов
пара, и заменяет каждый из них одним символом табуляции.
Вторая техника использует другой подход. Вместо сопоставления отдельных
уровни отступа, можно разбить каждую строку, начиная с пробелов
вниз на две части: одна содержит отступы исходной строки,
другой держит остальное. После этого его легко заменить
все пары пробелов в первой строке и конкатенировать строки обратно
вместе.
:g/^ /s/^ \+/&\r/|-s/ /\t/g|j!
Третья идея - обрабатывать начальные пробелы с помощью сценариев Vim.
язык. Удобный способ сделать это - использовать замену с
особенность выражения команды :substitute
(см. :help sub-replace-\=
).
Помещение в строку замены команды \=
, позволяет подставить
совпадения шаблона с результатами оценки выражения
указывается после \=
.
:%s#^ \+#\=repeat("\t",len(submatch(0))/2)