タブをスペースに置き換える方法は?


85

テキストの配置を維持しながら、タブをスペースに変換することは可能ですか?

単純な置換は、先行文字がない場合にのみ有効に機能します。


vim-faqをインストールしている場合は、そこでオフラインの回答を取得できます::h vim-faqおよび検索/tab characters。覚えにくいタグは:h faq-14.16です。
ホットシュケ

回答:


98

この:retabコマンドを使用できます。から :help :retab

<Tab>指定された新しいtabstop値を使用して、a を含むすべての空白のシーケンスを新しい空白の文字列に置き換えます。新しいタブストップサイズを指定しない場合、またはゼロの場合、Vimはの現在の値を使用します'tabstop'。[...] 'expandtab'onにすると、Vimはすべてのタブを適切な数のスペースに置き換えます。

このコマンドは範囲を受け入れるため、視覚的に選択してから:retab、選択した行だけを選択できることに注意してください。


クール!高速かつ簡単に動作します!
デニスコロディン

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

誰かが手紙を何説明してもらえaif a:expandtab意味ですか?
ジョンcj

また、条件が逆転しているようです(冗談:D?)。あなたが持っている場合はset expandtab、あなたの.vimrcにし、その後autocmd BufWritePre * :call Retab(&expandtab)-インデントはスペースの代わりに、タブに変更されます。
ジョンcj

11

Vimは、指定された新しいタブストップ(たとえば)の値を使用して、!retabすべてのシーケンスを<Tab>空白の新しい文字列に置き換えるコマンドを提供しますが、文字列内のすべてのタブは変更できます(たとえば、Cプログラムでは、これを避けるために使用する必要があります)!:set tabstop=2\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=GPythonのような言語では壊滅的です。
-Shahbaz

3

使用してみてください:

expand -t 4 input_filename output_filename

expandは、タブをスペースに変換するコマンドラインツールです。これは、シェルから、またはで実行できます:!expand

それはだPOSIXで、それはほとんどのシステムで利用可能であるべきであるようにします。unexpandところで、逆になります。


2
なにexpand
ムル

Expandは、タブ文字をスペースにコピーする組み込みのターミナルコマンドです。次のリンクで詳細な説明を見つけてください。computerhope.com/unix/uexpand.htm
アンキットシャー

2
これらが外部コマンドである場合、それについて言及する必要があります。
ムル

詳細な説明が追加されました。確認してください
アンキットシャー

5
:%!expand -t 4vimの内部で行うこともできます。さらに良いことに、現在のシフト幅オプションを使用することもできます :exe '%!expand -t ' . &shiftwidth
EvergreenTree

1

完全を=期すために、タブをスペースに置き換えることを指定した後、インデントを修正するためにも使用できます。通常モードでは、を入力してこれを行うことができます:set expandtab。次に=、2つの方法で使用できます。

  • Visualモードでは=、選択したコードブロックのインデントが修正されます。
  • 通常モードでgg=Gは、ファイル全体を修正しgg、カーソルをファイルの先頭に移動してから=適用し、Gカーソルをファイルの末尾に移動します。

参照:リンク


これは、vimが現在のインデントを正しく再計算できることを前提としています(そうでない場合もあります) -非構造化ファイル、またはわずかに異なるインデントルールを持つ異なるエディターで記述されたコードについても同様です。
ideasman42

ありがとう@ ideasman42; より完全になるように回答に追加しました。
サミュエルリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.