Ответ 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