タブ文字はもう使うべきではない (Python + vim編)

2014-04-29 01:29 JST by kcrt

 

Ubuntu 12.04 LTSからUbuntu 14.04 LTSにアップグレードしたところ、vimの設定ファイルが変わったのか、自分の.vimrcの設定に関わらず、tabstopが8で表示されるようになってしまいました。

tab8

まず、pythonでのタブ文字の使用ですが、公式ドキュメントにはこうあります

First, tabs are replaced (from left to right) by one to eight spaces such that the total number of characters up to and including the replacement is a multiple of eight (this is intended to be the same rule as used by Unix). The total number of spaces preceding the first non-blank character then determines the line’s indentation. (snip)

Cross-platform compatibility note: because of the nature of text editors on non-UNIX platforms, it is unwise to use a mixture of spaces and tabs for the indentation in a single source file. It should also be noted that different platforms may explicitly limit the maximum indentation level.

2. Lexical analysis / 2.1.8. Indentation

(意訳)

タブ文字はまずストップ位置が8の倍数になるように空白文字で置換されます。これはUnixで行われているのと同じルールです。行頭の空白文字の数に基づいてインデントを決定します。(略)

クロスプラットフォーム互換性情報: 非Unix環境でのエディタのことを考えると、空白とスペースを一つのソースコードで混在させるのはあまり賢いこととは思えません。プラットフォームが違えば最大のインデントレベルも制限されることがあることも併せてお知らせしておきます。

なるほど、とりあえずpythonではタブ文字が"8スペース"を基本として扱われることがわかりました。いままでは.vimrcに

set tabstop=4

があれば、そちらが使われていましたが、Ubuntu 14.04 LTSのvimではどうやらあらかじめ用意されているファイルタイプの設定が優先され、こちらは考慮されないようです。

もちろん、タブ文字が"8 スペース"として表示されるのは苦痛でしかありません。autocmdを使って無理矢理タブ文字が"4 スペース"と表示して、従来のタブ文字を使用し続けることもできますが、今後はタブ文字を使わずスペース 4文字でのインデントを使っていくことにしましょう。現在のpythonライブラリは標準的に スペース4文字をインデントに使用しています。(試しに、/usr/lib/pythonXXX/dist-packagesにあるファイルをどれか見てみてください。)

まずは旧来のソースコードの変換。変換にはexpandコマンドが便利です。-t4オプションを指定してタブ文字が"4 スペース"であることを知らせます。

expand -t4 tab_letter_indent_file.py > new_indent_file.py

これで、新しくできたファイルを再度開くと、従来通りの見た目のタブ文字が"4 スペース"として表示されたと思います。

tab4

開いてみるとスペースに置換されインデントは4文字で元通りの見た目です。

新しいvimの設定ファイルでは、expandtabの設定もきちんとされていて、このままで[Tab]キーと[Backspace]キーが問題なく使えるようになっています。

expandtabの設定がなければ

....__filename = ""
....def __init__(self):
........self.__filename = "sample.txt"

この状態で[Backspace]を押せば

....__filename = ""
....def __init__(self):
.......self.__filename = "sample.txt"

と、単純にスペースが一つ消えるだけです。expandtabの設定があれば

....__filename = ""
....def __init__(self):
....self.__filename = "sample.txt"

と、ちゃんと従来通りのタブと同じように使用することができます。

新しいvimではpythonファイルに関してはこの辺の設定が標準でされているようです。