Подтвердить что ты не робот

Force Vi/Vim использовать ведущие вкладки только для retab!

Есть ли способ заставить vim использовать вкладки для выполнения начального отступа, но при запуске retab! команда НЕ заменяет внутренний интервал слова на вкладки?

4b9b3361

Ответ 1

По моему опыту, лучший способ сделать это - с помощью специальной функции:

" Retab spaced file, but only indentation
command! RetabIndents call RetabIndents()

" Retab spaced file, but only indentation
func! RetabIndents()
    let saved_view = winsaveview()
    execute '%[email protected]^\( \{'.&ts.'}\)\[email protected]\=repeat("\t", len(submatch(0))/'.&ts.')@'
    call winrestview(saved_view)
endfunc

Затем вы можете использовать:

:RetabIndents

заменить все ведущие пробелы на вкладки, но не влиять на вкладки после других символов. Он предполагает, что "ts" установлен правильно. Вы можете пройти долгий путь, чтобы сделать файлы, которые были неправильно смещены, выполнив что-то вроде этого:

:set ts=8     " Or whatever makes the file looks like right
:set et       " Switch to 'space mode'
:retab        " This makes everything spaces
:set noet     " Switch back to 'tab mode'
:RetabIndents " Change indentation (not alignment) to tabs
:set ts=4     " Or whatever your coding convention says it should be

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

Изменить

Объяснение строки 'exe':

execute '%[email protected]^\( \{'.&ts.'}\)\[email protected]\=repeat("\t", len(submatch(0))/'.&ts.')@'

" Execute the result of joining a few strings together:

%s               " Search and replace over the whole file
@[email protected]@      " Delimiters for search and replace
^                " Start of line
\(...\)          " Match group
 \{...}          " Match a space the number of times in the curly braces
&ts              " The current value of 'tabstop' option, so:
                 " 'string'.&ts.'string' becomes 'string4string' if tabstop is 4
                 " Thus the bracket bit becomes \( \{4}\)
\+               " Match one or more of the groups of 'tabstop' spaces (so if
                 " tabstop is 4, match 4, 8, 12, 16 etc spaces
@                " The middle delimiter
\=               " Replace with the result of an expression:
repeat(s,c)      " Make a string that is c copies of s, so repeat('xy',4) is 'xyxyxyxy'
"\t"             " String consisting of a single tab character
submatch(0)      " String that was matched by the first part (a number of multiples 
                 " of tabstop spaces)
len(submatch(0)) " The length of the match
/'.&ts.'         " This adds the string "/4" onto the expression (if tabstop is 4),
                 " resulting in len(submatch(0))/4 which gives the number of tabs that
                 " the line has been indented by
)                " The end of the repeat() function call

@                " End delimiter

Ответ 2

Из моего ответа на этот другой (*) вопрос:

Чтобы решить эту небольшую проблему, я рекомендую поиск вместо retab.

:%s/^\(^I*\)␣␣␣␣/\1^I/g

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

Чем вам нужно повторить поиск с помощью @: или [email protected]:

Это лучше объясняется в приведенной ниже ссылке.

(*) Как преобразовать пробелы в вкладки в Vim или Linux?