如何用空格替换制表符?


85

可以在保持文本对齐的同时将制表符转换为空格吗?

仅当没有前导字符时,仅替换才有用。


如果您已安装vim-faq,则可以在那里找到离线答案::h vim-faq并搜索/tab characters。难记的标签是:h faq-14.16
Hotschke

Answers:


98

您可以使用该:retab命令。从 :help :retab

<Tab>使用给定的新tabstop值,用新的空白字符串替换所有包含a的空白序列。如果您未指定新的制表位大小或为零,则Vim使用当前值'tabstop'。[...] 'expandtab'启用后,Vim用适当数量的空格替换所有制表符。

请注意,该命令接受一个范围,因此您可以进行视觉选择,然后仅:retab选择行。


凉!快速简便地工作!
DenisKolodin

2
举个例子如何?
彼得

23

您可以:retab按照所述使用,但是,这会将所有选项卡更改为空格,不仅仅是行首的选项卡

所以这(一个制表符):

if :; do
⇥echo "⇥hello"
end

更改为(空格字符在哪里):

if :; do
␣␣echo "␣␣hello"
end

在某些情况下,这可能会产生意想不到的副作用,而将空格更改为制表符时,这甚至成为更大的问题!

因此,我在行的开头编写了一个更改制表符/空格的小函数:

" :retab changes *everything*, not just start of lines
fun! Retab(expandtab)
    let l:spaces = repeat(' ', &tabstop)

    " Replace tabs with spaces
    if a:expandtab
        silent! execute '%substitute#^\%(' . l:spaces . '\)\+#\=repeat("\t", len(submatch(0)) / &tabstop)#e'
    " Replace spaces with tabs
    else
        silent! execute '%substitute#^\%(\t\)\+#\=repeat("' . l:spaces . '", len(submatch(0)))#e'
    endif
endfun

在此版本中,您必须expandtab在函数调用中手动指定(即:call Retab(1),将制表符更改为空格),但您也可以像对其一样进行修改,以采用&expandtab(即已使用&tabstop)的当前值:retab。(我碰巧更喜欢手动指定它)。


6
SO上也有一个答案,该答案仅包括在行首重新制表。值得链接,因为该解释很清楚。
jalanb 2015年

有人可以解释字母aif a:expandtab意思吗?
约翰cj

同样,情况似乎相反(开玩笑:D?)。如果您set expandtab在.vimrc中,则autocmd BufWritePre * :call Retab(&expandtab)-缩进将更改为制表符,而不是空格。
约翰cj

11

Vim提供了使用给定的新tabstop(例如)值!retab将所有序列替换为<Tab>新的空白字符串的命令:set tabstop=2,但是字符串内的所有制表符都可以修改(例如,在C程序中,应\t避免使用此命令)!

因此,也可以使用以下命令将所有选项卡更改为空格:

:%s/\t/  /g

@Shahbaz建议:

:%s/^\t\+/ g

因此,仅缩进中使用的制表符被转换。

说明:

  • %代表整个缓冲区/文件(:help :%
  • s代表替代品(:help sub-replace-special
  • \t,或^I代表标签
  • -每个选项卡使用所需数量的空格
  • g -代表全局,它将转换同一行中出现的多个制表符

然后校正整个文件的压痕,您可以尝试:gg=G。检查:重新缩进严重缩进的代码以获取更多详细信息。

要默认使用空格而不是制表符,您需要在.vimrc文件中添加以下设置:

set tabstop=2     " (ts) width (in spaces) that a <tab> is displayed as
set expandtab     " (et) expand tabs to spaces (use :retab to redo entire file)
set shiftwidth=2  " (sw) width (in spaces) used in each step of autoindent (aswell as << and >>)

替代解决方案是使用 tidy


有关:


1
我至少会这样做,%s/^\t\+/ g以便仅转换缩进中使用的制表符。同样,gg=G对于像python这样的语言可能会造成灾难性的后果。
Shahbaz

3

尝试使用:

expand -t 4 input_filename output_filename

expand是用于将制表符转换为空格的命令行工具,您可以从Shell或使用来运行它们:!expand

在POSIX中,因此它应该在大多数系统上都可用。unexpand顺便说一句,相反。


2
什么expand
muru

Expand是一个内置的终端命令,用于将制表符复制到空格。请在以下链接中找到详细说明。computerhope.com/unix/uexpand.htm
Ankit Shah

2
如果这些是外部命令,则应提及。
muru

添加了进一步的描述。请查看
Ankit Shah 2016年

5
您也可以:%!expand -t 4在vim内部进行操作。更好的是,您还可以使用当前的偏移宽度选项::exe '%!expand -t ' . &shiftwidth
EvergreenTree

1

为了完整=起见,在您指定制表符替换为空格之后,也可以用于修复缩进。在普通模式下,您可以通过键入来进行操作:set expandtab。然后=可以以两种方式使用:

  • 在可视模式下,单个=将修复所选代码块的缩进。
  • 在正常模式下,gg=G将修复整个文件,gg将光标移至文件的开头,然后=应用,然后G将光标移至文件的末尾。

参考:链接


假设vim可以正确地重新计算当前的缩进(可能不是这种情况) -甚至对于非结构化文件或用不同的缩进规则在不同的编辑器中编写的代码。
ideaman42 '18年

谢谢@ ideasman42; 我已经添加了答案,以使其更加完整。
塞缪尔·李
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.