[個人メモ] IntelliJ IDEA 設定ファイルマニアックス

# 概要

チーム内でIntelliJの設定を共有するため、IntelliJの設定ファイルの仕組みをいろいろ調べた。
この設定ファイルの仕組みが非常に複雑だったので(ほぼ丸2日調査にかかった)、後々のためにここへメモを残しておく。

# 調査環境

* IntelliJ Idea 14 Ultimate
* Ubuntu Linux 14.10 64bit
* OpenJDK 1.8.0_40

# 箇条形式で得られた経験を列挙

* [Scala - [Intellij IDEAヘルプ 日本語訳] プロジェクト設定とIDE設定 - Qiita](http://qiita.com/bigwheel/items/5ac690a722ccf9661090)を見るとIDE設定は各サブディレクトリをそのまま共有すればいいように読めるが、実際にはIDEの起動毎に変更されるファイルやIDEの設定を含んでいないファイルがある。そのためすべてのファイルをバージョン管理へ追加するのはおすすめしない
    * 例えば ~/.IntelliJIdea14/config/options/statistics.application.usages.xml はjetbrainsへ送られる統計情報ファイルで、起動毎に更新される上なんの設定も持ってなかったりする
* **ウェルカム画面 | Configure | Project Defaults | Settings**と**ウェルカム画面 | Configure | Settings**は後者が前者を包括する関係にある
    * 言い換えると、プロジェクト設定のデフォルト設定にIDE設定を付け加えたものが**ウェルカム画面 | Configure | Settings**
* keymapsやcode styleのSchemeなど、IDE標準の設定セットがread onlyな項目がいくつかある。たとえばcode styleのschemeは**Default**を変更したつもりでも保存した瞬間に**Default (1)**というschemeが作成され、そちらが変更される(keymapも同様)。
    * **Default (1)**の保存後、デフォルト設定のSchemeは**Default**から**Default (1)**へ変更されるため、デフォルト設定の変更は意図通りされる
    * この動作が初見時に非常にわかりづらいため注意。いつのまにか**Default (1)**という設定ができておりそちらが使用されている？と困惑しやすい
* 全体的にIntelliJの設定の仕組みは非常に分かりづらい。もうちょいリファクタリングしてほしい
    * Schemaがread onlyだとか、しかもそれが直接変更できたように見えてそのタイミングでスキーマの複製を作ってる点とか
    * プロジェクト設定とIDE設定のダイアログが一緒である点
    * ウェルカム画面から変えられるデフォルトプロジェクト設定の仕組みがいまいちわかりにくい。
        * ただでさえデフォルト設定(プロジェクト)を変更してることがわからないのに(Settingsダイアログは完全に一緒)、それを変更する方法が2パスある
    * デフォルト設定のデフォルト値(ややこしいな、なにもデフォルト設定を設定しなかった場合にプロジェクト設定の初期値として使われる値のこと)は~/.IntelliJIdea14/以下には存在しない。おそらくダウンロードしてきた実行ファイルまたはライブラリ内に情報がある模様。
        * そのためデフォルト設定ファイルを直接編集するようなことはできない
* 特にSchemeがある系の設定は非常にわかりづらい。基本的に次のような構造になっている
    1. 各プロジェクトはどのスキーマを参照するかの設定のみを持つ
    2. プロジェクト固有スキーマの場合、プロジェクト固有スキーマは**.idea**ディレクトリ内に設定が置かれる。他のプロジェクトからそれを参照することはできない
    3. 他のスキーマの場合、**Default**スキーマはアプリケーションデフォルトの読み込み専用のもので書き換えができない
    4. それ以外のスキーマは実体が**~/.IntelliJIdea14/**内に保存されている。また(試してはいないが)あるプロジェクトから参照されているスキーマはウェルカム画面や他のプロジェクトの設定画面から変更することができる
* (code style)Schemeの実体ファイルについて
    * 基本的にSchemeの実体ファイルは単独で完結しない。Defaultスキーマと異なる項目のみ書き出される差分方式になっている
        * この設定ファイルは真の意味でDefaultと異なる項目のみ書き出すようになっている。例えば一度Defaultと異なる設定値にしたのち、もう一度その値をDefaultと同じに戻すとSchemeファイルからはその項目はなくなる(手動でSchemeファイルを編集してあえてDefaultと同じ値にした時の動作は未検証。だがおそらく正常に動くと思う)
    * つまり、どのようにやってもデフォルト値は基本的に参照されるということ
* **File and Code Templates**などで変更後に初めて**~/.IntelliJIdea14/config/**以下にファイルができたことを見るに、このデフォルト値というのはSchemeやプロジェクト設定に限らずすべての設定に存在する模様
    * つまりIDE設定にすらデフォルト値は存在する。それから変更した値のみが**~/.IntelliJIdea14/**以下に作成される
* デフォルト値は一律リードオンリー、と思ったのか？ https://www.jetbrains.com/idea/help/customizing-profiles.html
    * profileのDefault値は書き換え可能。この統一感のなさよ。無秩序に各々設定や機能を増やしていった経緯が目に浮かぶ。
* デフォルトのプロジェクト設定を表現するファイルがないと言ったな、あれは嘘だ。**~/IntelliJIdea14/options/project.default.xml**がそれに当たる。ただしプロジェクト下.ideaと同じ構造ではなく単一のXMLであり、要素も同じかどうかはわからん
* https://www.jetbrains.com/idea/help/inspections.html のShare profileの説明を見る限り、デフォルト設定でのprofileのShareは動作が怪しい、というよりこの説明とは違った挙動をする。
    * share profileを切っていると**~/IntelliJIdea14/options/inspection/XXXXX.xml**という形でinspection単独のファイルができる。これをshare profile ONにすると単独のファイルにならず前述のproject.default.xmlに同梱される。
* IDEをインストールした直後、inspection profileには**Default**と**Project Default**の2つがあるんだけど、これの違いがわからない。
    * ~~試して見る限り、デフォルトのプロジェクト設定でプロファイルの選択を切り替えるとデフォルトのプロファイルもきっちり切り替わる。~~
    * ~~それらを踏まえて考えると、どうやら**Project Profile**はプロファイルのデフォルト値として標準で用意された値？~~
        * ~~これを変えればプロファイルを増やさずインスペクション設定を変更できそうだが、デフォルト値・かつ削除できないのでそのまま流用するのにはリスクがある。~~
            * ~~っと思ったが、デフォルト設定画面から追加したインスペクションプロフィールはプロジェクトを何か開いた瞬間に削除されてるっぽい？そういう仕様だからこそ**Project Default**が必要なのかもしれない。~~
    * もう一度試してみると、デフォルト設定画面でプロファイルを作ってドロップダウンメニューから選択状態にしても、新規作成したプロジェクトへ適応されるプロファイルは**Project Profile**固定。つまりそういう意味でこのプロファイルは特別だし、これから偏向スルことも出切ない。
        * ちなみに**Project Profile**のshare profileをOFFにすると、再起動後にshare profileがONの**Project Profile**という新しいプロファイルができて、2つ同じ名前が並んでいた。つまりこのshareチェックボックスを操作することはできない模様。
* ide.general.xmlの要素などを見るに、静的な設定項目と実行回数や最後に開いたプロジェクトのような動的な項目が入り混じっている。ここから、jetbrainsはこの.IntelliJIdea14がバージョン管理されることを十分に想定できてないことがわかる
    * 言い換えると、~/.IntelliJIdea14をバージョン管理ないし共有しようとするとどうしてもどこかに歪みが発生してしまう。たとえば前述のide.general.xmlはIDE実行時のtips表示のON/OFFのような共有したい設定項目があるが、最後に開いたプロジェクトのパスを含んでしまっているためそのまま共有することは大いに問題がある。
        * 現実的にバージョン管理を実践するなら、そのような動的項目を手動でXMLから削り、バージョン管理へ追加する方法があるだろう
            * しかし、それで正常に動くかどうかはIntelliJの実装任せである上、かならずファイルが変更されてしまうためgitリポジトリ的にはそのファイルを無視指定した上でforce addするのが管理の正道になる。しかしこの管理方法はそもそも邪道・・・

# 参考URL

* [IntelliJヘルプ翻訳に関する投稿 - Qiita](http://qiita.com/tags/intellij%e3%83%98%e3%83%ab%e3%83%97%e7%bf%bb%e8%a8%b3)