许多人使用空格而不是制表符。我两者都使用。在行首使用制表符,在第一个非空白字符处使用空格。新建文档时没有问题,如果必须修改文档,则最好适应使用格式。但有时仍需要解决空格问题。
根据搜索和替换,我只需执行
根据搜索和替换,我只需执行
:%s / spaces_for_tab / tab / g
。这很简单,并且可以适用于许多情况。但是我只想重构行首的空格。:%s / spaces_for_tab / tab / g
。这很简单,并且可以适用于许多情况。但是我只想重构行首的空格。这更像是一个正则表达式问题。要锚定到行首,使用“caret”,例如:
s/^ /\t/
或者使用vim的内置功能实现:
:set tabstop=4 "four spaces will make up for one tab
:set noexpandtab "tell vim to keep tabs instead of inserting spaces
:retab "let vim handle your case
顺便说一下,我也更喜欢使用制表符进行缩进,空格用于对齐。不幸的是,vim 处理这个问题不太好(我不知道其他编辑器的情况),所以我主要使用 :set expandtab
命令(也许可以尝试使用 :set softtabstop
命令)。
retab!
而不是 retab
。 - Chris Morganfu! Fixspaces()
while search('^\t* \{4}') != 0
execute ':%s/^\t*\zs \{4}/\t/g'
endwhile
endfu
retab
与noexpandtab
结合使用。 - s gretab
命令单独使用时不能按预期工作,而retab!
命令会将行内任意位置(即使是字符串字面值内部)的空格转换为制表符。实际上只有行首空白应该被转换为制表符才更合适。 - David SandersDavid的回答非常优雅,但它没有解决包含制表符和空格混合的前导空格的问题。例如,要将这样一行转换为:
<SPACE><SPACE><TAB>something...
你必须知道制表符的位置,以确定需要替换<TAB>
并到达下一个制表位所需的空格数。我的解决方案虽然不像David的那样紧凑,但它解决了这个问题。它还允许我选择使用前导空格的方式,而不依赖于&expandtab。我会感激任何改进代码的建议...
function! TabsToSpaces(...)
let ts = &tabstop
let pos = getpos('.')
while search('^ *\zs\t', "w") != 0
let l:curpos = getcharpos('.')
" The number of spaces needed depends upon the position of the <TAB>
let numsp = 1 + ts - ( curpos[2] % ts )
if numsp == 9
let numsp = 1
endif
silent execute ':s/^ *\zs\t/'.repeat(' ', numsp).'/'
endwhile
if a:0 == 0
echo 'Changed leading tabs to spaces'
endif
call setpos('.', pos)
endfunction
function! SpacesToTabs(...)
let ts = &tabstop
let pos = getpos('.')
" First normalize all tabs to spaces
call TabsToSpaces("quiet")
while search('^\t* \{'.ts.'}') != 0
silent execute ':%s/^\t*\zs \{'.ts.'}/\t/g'
endwhile
if a:0 == 0
echo 'Changed leading spaces to tabs'
endif
call setpos('.', pos)
endfunction
" Some keystrokes to implement the spaces/tabs functions
nmap <Leader>st :execute SpacesToTabs()<CR>
nmap <Leader>ts :execute TabsToSpaces()<CR>
我借鉴了Martin的回答,并稍作改进,如果有人有兴趣:
function Fixspaces()
let ts = &tabstop
let pos = getpos('.')
if &expandtab
while search('^ *\t') != 0
silent execute ':%s/^ *\zs\t/'.repeat(' ', ts).'/g'
endwhile
echo 'Changed tabs to spaces'
else
while search('^\t* \{'.ts.'}') != 0
silent execute ':%s/^\t*\zs \{'.ts.'}/\t/g'
endwhile
echo 'Changed spaces to tabs'
endif
call setpos('.', pos)
endfunction
expandtab
和tabstop
的值执行适当操作,并记住光标的位置。