ATOM
EditorConfig

行末の空白は EditorConfig で始末しましょう

More than 1 year has passed since last update.

最近は作業の8割くらいは ATOM でまかなえるようになって,だいぶ手に馴染んできた。で,相変わらず秀丸にあって ATOM にない機能をちょこちょこと補完してるんだけど,その中で「行末の空白を削除する」パッケージとかマクロ(他のエディタね)とかが目につきだした。みんな苦労してるんだねぃ。

でも,昔はともかく,今は EditorConfig に対応しているエディタなら余計なパッケージやマクロなど不要である。

たとえば統合環境の IntelliJ IDEA はネイティブに EditorConfig に対応してるし,プラグイン対応でなら Visual Studio や NetBeans も対応している。普通のエディタでも ATOM や Sublime Text はもちろん,みんな大好き(私は使わないけど) Emacs や Vim も EditorConfig に対応可能である。つまり EditorConfig を使わない手はないのである。

EditorConfig による設定

EditorConfig を使うには(既にプラグイン等は導入済みであると仮定して)プロジェクト管理下のトップ・フォルダに .editorconfig ファイルを設置する。(前にも紹介したけど)私の場合はこんな感じ。

.editorconfig
root = true

[*]
end_of_line = lf
charset = utf-8
indent_style = tab
indent_size = 4
trim_trailing_whitespace = false
insert_final_newline = false

[*.md]
insert_final_newline = true

[*.{js,java,go,c,cpp,tex}]
trim_trailing_whitespace = true
insert_final_newline = true

[*.{md,c,cpp,tex}]
indent_style = space
indent_size = 4

EditorConfig はフォルダを遡って .editorconfig ファイルを探し,フォルダの上から順番に評価していく。 root = true の記述がないとどこまでも上の階層に遡っていくので,プロジェクトのトップ・フォルダの .editorconfig には必ずこれを記述すること。

  • [*] は対象となるファイルを指定している。 [*] なら全てのファイルが対象である。 [*.{md,c,cpp,tex}] は拡張子が md, c, cpp, tex のファイルが対象となる。
  • end_of_line では改行コードを指定する。 lf, cr, crlf から選択できる。
  • indent_style はインデント(タブ)のスタイルを指定する。 tab または space を指定する。 space にすると,いわゆる「ソフトタブ」になる。
  • indent_size はタブの幅を指定する。 indent_styleindent_size は常にセットで指定すると間違いがない。
  • trim_trailing_whitespacetrue にすると行末の空白文字を削除してくれる。残念なことに ATOM の場合は,いわゆる「全角空白」を空白文字と見なしてくれない。まぁ全角空白を空白文字と見なす設計のほうが少ないけど。
  • insert_final_newlinetrue にするとファイルの末尾が改行文字ではない場合に補完してくれる。でもこれって使いどころが難しいのよね。

文字エンコーディングについて残念なお知らせ

charset では文字エンコーディングを指定するが,標準では latin1, utf-8, utf-8-bom, utf-16be, utf-16le しかサポートしていない。それ以外の文字エンコーディングは実装依存ということになる。

しかも ATOM の場合,ファイルを新規作成する場合にこの設定が効かないようで,たとえば ATOM 側の “File Encoding” が shiftjis.editorconfig ファイル側が charset = utf-8 の場合,新規作成ファイルは shiftjis にセットされ,そのまま保存される。しかも次にそのファイルを開く場合は(.editorconfig ファイル側の設定が効いてしまうので) utf8 で開いてしまい,結果派手に文字化けする(ctrl-shift-U で文字エンコーディングを変更すれば元に戻るけど)。

ファイル読み込み時に文字エンコーディングを自動判別する

新規作成時の初期の文字エンコーディングは今のところどうしようもないが,プロジェクトごとに “File Encoding” を変更して対応するか,新規作成ファイルが開いた直後に ctrl-shift-U で文字エンコーディングを変更することで何とかなるだろう(ダサいけど)。

もうひとつの緩和策としては,既存ファイル読み込み時に文字エンコードを自動判別するようにすることだ。ただし,この機能を持つ Package は今のところ存在しないようなので自前で何とかするしかない。

この設定を行うには node.js のフルパッケージが必要。

(Linux や Mac な人は依存関係で node.js がインストールされると思うけど, Windows では ATOM インストール時に一部機能が同梱されているだけなので(しかもバージョンが古い),フル機能を使うには別途インストールする必要あり)

Windows の場合は %USERPROFILE%\.atom フォルダに移動する。その後, npm コマンドを使って iconv-litejschardet をインストールする。

C:>cd C:\Users\username\.atom
C:\Users\username\.atom>>npm install iconv-lite
iconv-lite@0.4.10 node_modules\iconv-lite

C:\Users\username\.atom>>npm install jschardet
jschardet@1.1.1 node_modules\jschardet

すると %USERPROFILE%\.atom\node_modules フォルダが作成され,その中に iconv-litejschardet がインストールされているはずである。

次は %USERPROFILE%\.atom\init.coffee ファイルに以下の記述を追加する。

init.coffee
fs = require('fs')

atom.workspace.onDidOpen ->
  editor = atom.workspace.getActiveTextEditor()

  try
    filePath = editor.getPath()
  catch error
    return
  return unless fs.existsSync(filePath)

  jschardet = require 'jschardet'
  iconv = require 'iconv-lite'
  fs.readFile filePath, (error, buffer) =>
    return if error?
    {encoding} = jschardet.detect(buffer) ? {}
    encoding = 'utf8' if encoding is 'ascii'
    return unless iconv.encodingExists(encoding)

    encoding = encoding.toLowerCase().replace(/[^0-9a-z]|:\d{4}$/g, '')
    editor.setEncoding(encoding)

ATOM でファイルを開いたら自動文字コード判定を行う」によると,これは encoding-selector からの流用らしい。ただし現在, encoding-selector は Core Package に入ってるので atom フォルダをひっくり返してもソースコードは見当たらない。ので,GitHub にある atom/encoding-selector にある lib/encoding-list-view.coffee を参考にするといいだろう。 detectEncoding: のあたりである。

これで ATOM を起動して既定の文字エンコーディングでない適当なファイルを読み込ませてみれば確認できる。ただし,自動判別は万能じゃない(たまに間違う)ので,その辺は悪しからずってことで。

一番いいのは encoding-selector がファイル読み込み時に自動判別する機能を付けてくれることなんだけど。誰かやらないかな。個人的には ATOM 開発に積極的に commit する気はないので,完全に他人任せなのだが。

あとは文字変換か...

ブックマーク