Mac版Sublime Text 3でGoogle日本語入力とSublimeMozcInputを使い入力を高速化する方法

![Screen Shot 2016-02-22 at 3.01.46 AM.png](https://qiita-image-store.s3.amazonaws.com/0/38578/4ff22819-3e4b-d07e-32f9-fefaf2105594.png)

Mac版Sublime Text 3でGoogle日本語入力等のIMEを使用してテキストを入力する際、入力が非常にもたつく現象が知られています。[SublimeMozcInputを使うことでこの現象を回避する](http://futago-life.com/sublime-text3-wiki/how-to/mozc-input)ことができますが、Mozc (Google日本語入力のOSS版) を使うため、以下の問題が生じます。

* 公式版よりも変換精度が低下してしまう。
* 公式版とOSS版が同時に起動するため、メモリを無駄に消費する。
* 公式版で登録したユーザ辞書が使用できない。

そこで、Mozcを修正することで、`mozc_emacs_helper` を公式版Google日本語入力で使えるようにしました。

利点
----

本手法により日本語入力を行うと、標準機能で行う場合と比べて次の利点が得られます。

- 入力がもたつかない。処理能力を食わないので電池が劇的に減らなくなる。
- 検索バー等でEnterキーで変換確定すると検索バーが消える問題が起きない。

必要なもの
---------

`mozc_emacs_helper` をビルドするには次のものが必要となります。

* Gitが必要です。
* [GYP](https://chromium.googlesource.com/external/gyp) を適当な場所に `git clone` しておいて下さい。
* [Ninja](https://ninja-build.org/)ビルドシステムが必要になります。ソースコードからビルドするか、MacPortsやHomebrew等によりインストールして下さい。

Mozcのソースコードは[GitHubで入手](https://github.com/google/mozc)できます。Download ZIP では submodule が持ってこれませんので、`git clone --recursive` で入手して下さい。

手順
---

手順の概要は以下の通りです。

1. [こちらのパッチファイルを適用](https://gist.github.com/yvt/496152f868598e58bcd1)して、公式版Google日本語入力で使えるバージョンの mozc_emacs_helper がビルドできるようにmozcに修正を加えます。修正点は一番下のセクションで詳しく説明していますので、興味のある方はご覧ください。
2. `mozc_emacs_helper` をビルドします。
3. SublimeMozcInputをインストールします。

### 1. パッチの適用

[パッチファイル](https://gist.github.com/yvt/496152f868598e58bcd1)を入手後、以下のコマンドでパッチを適用して下さい。

```bash
patch -p0 < mozc-officialize.patch
```

**2017年3月27日 追記:** 現時点での最新版 ([4767ce2](https://github.com/google/mozc/commit/4767ce2f2b6a63f1f139daea6e98bc7a564d5e4e)) では `packed_data_manager.gyp` が見つからないという警告が出ますが、その部分のパッチはスキップしても問題無さそうです。

```
can't find file to patch at input line 17
Perhaps you used the wrong -p or --strip option?
< 中略 >
File to patch: [エンターキー押下]
Skip this patch? [y] [エンターキー押下]
Skipping patch.
1 out of 1 hunk ignored
```

### 2. `mozc_emacs_helper` のビルド

最初に次のコマンドでビルドに必要なファイルを生成します。 `--gypdir` にはGYPのディレクトリを指定します。 

```bash
GYP_DEFINES="mac_sdk=10.11 mac_deployment_target=10.11" python build_mozc.py gyp --noqt --gypdir PATH_TO_GYP --branding GoogleJapaneseInput
```

続いて、`mozc_emacs_helper` のビルドを行います。

```bash
python build_mozc.py build -c Release unix/emacs/emacs.gyp:mozc_emacs_helper
```

これで、 `out_mac/Release` ディレクトリに `mozc_emacs_helper` が生成されたはずです。`/usr/local/bin` など好きなディレクトリにインストールしておきます。

```bash
sudo install out_mac/Release/mozc_emacs_helper /usr/local/bin/
```

### 3. SublimeMozcInputをインストールする

[SublimeMozcInputの公式サイト](http://yasuyuky.github.io/SublimeMozcInput/)のヘッダーにダウンロードボタンがあるので、ダウンロードし、Sublime Text 3のパッケージディレクトリ(Preferences » Browse Packages… から開けます)に展開し、`Mozc Input`というディレクトリ名にしておきます。

このままですと SublimeMozcInput が mozc_emacs_helper を見付けられず、動作しませんので、Preferences » Package Settings » Mozc Input » Settings - User から設定ファイルを開き、次のようにして `mozc_emacs_helper` のパスを指定します。

```json
{
	"mozc_emacs_helper": "/usr/local/bin/mozc_emacs_helper"
}
```

もし違うディレクトリにインストールした場合は適宜変更して下さい。

以上の手順で、SublimeMozcInput が使えるようになっているはずです。デフォルトのキーバインディングは Ctrl+¥ になっているはずですので、試してみてください。


mozcの修正点の詳細
----------------

### mozc_emacs_helper がビルドされるようにする

mozc_emacs_helper はMozcのソースコードと一緒に添付されていますが、ビルドスクリプト `build_mozc.py` ではLinux専用という扱いになっており、Macではビルドできません。このため、Macでも `mozc_emacs_helper` がビルドできるように修正を行います。

```diff
   gyp_file_names.extend(glob.glob('%s/rewriter/*/*.gyp' % SRC_DIR))
   # Include subdirectory of win32 and breakpad for Windows
+  gyp_file_names.extend(glob.glob('%s/unix/emacs/*.gyp' % SRC_DIR)) # add mozc_emacs_helper
   if options.target_platform == 'Windows':
     gyp_file_names.extend(glob.glob('%s/win32/*/*.gyp' % SRC_DIR))
```

### 公式版Google日本語入力を使えるようにする

Mozcはクライアント・サーバ方式となっており、mozc_emacs_helperはIPCによりサーバーと通信を行い、変換をサーバに任せるようになっています。MozcはGoogle日本語入力のオープンソース版であり、プロトコルが同じであればmozc_emacs_helperからGoogle日本語入力のサーバと通信できるはずです。

通信は、Mozcのクライアントライブラリ(`src/client`)によって行われます。`src/client/system_util.cc`を見ると、OSS版と公式版によってサーバのパスを切り替えていることが分かります。

```cpp
string SystemUtil::GetServerDirectory() {

 // (中略)

#elif defined(OS_MACOSX)
  return MacUtil::GetServerDirectory();

#elif defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_NACL)
#if defined(MOZC_SERVER_DIRECTORY)
  return MOZC_SERVER_DIRECTORY;
#else
  return "/usr/lib/mozc";
#endif  // MOZC_SERVER_DIRECTORY

#endif  // OS_WIN, OS_MACOSX, OS_LINUX, ...
}
```

Macの場合は `MacUtil::GetServerDirectory()` でサーバパスを取得しています。呼出しを辿って行くと、 `mac_util.mm` にサーバパスの定義を見付けることが出来ます。

```objc++
const char kServerDirectory[] =
    "/Library/Input Methods/" kProductPrefix ".app/Contents/Resources";
const unsigned char kPrelauncherPath[] =
    "/Library/Input Methods/" kProductPrefix ".app/Contents/Resources/"
    kProductPrefix "Prelauncher.app";
```

`kProductPrefix` は `src/base/const.h` で次のとおり定義されており、OSS版と公式版で切り替わることが確認できます。

```cpp
#ifdef GOOGLE_JAPANESE_INPUT_BUILD
const char kProductNameInEnglish[] = "Google Japanese Input";
// "Google 日本語入力"
const char kProductNameLocalized[]
    = "Google \xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE5\x85\xA5\xE5\x8A\x9B";
#define kProductPrefix "GoogleJapaneseInput"
#else  // GOOGLE_JAPANESE_INPUT_BUILD
const char kProductNameInEnglish[] = "Mozc";
const char kProductNameLocalized[] = "Mozc";
#define kProductPrefix "Mozc"
#endif  // GOOGLE_JAPANESE_INPUT_BUILD
```

したがって、ビルドオプションを変更して公式版としてビルドすることで、mozc_emacs_helperで公式版Google日本語入力が使えるようになると考えられますが、配布されているソースコードには公式版に必要なものが不足しており`build_mozc.py`が失敗するため、いくつか修正を行います。

最初に `src/data_manager/packed/packed_data_manager.gyp` を修正しました。Mozcと公式版で単語のデータセットを切り替えているようですが、公式版のデータは含まれておらず、公式版用のGYPターゲット記述もないため、エラーになります。そこで、公式版でもMozcのデータセットを使うように修正します。

```diff
-    ['branding=="Mozc"', {
+    ['branding=="GoogleJapaneseInput" or branding=="Mozc"', {
```

続いて `src/mac/mac.gyp` を修正します。公式版ではコードの署名を行うようですが、必要なターゲットが見つからずエラーになってしまうので、依存関係を削除します。

```diff
-          'conditions': [
-            ['branding=="GoogleJapaneseInput"', {
-              'dependencies': [
-                'DevConfirmPane',
-                'codesign_client',
-              ],
-            }],
-          ],
```

以上の修正により、`mozc_emacs_helper` で公式版Google日本語入力が使えるようになります。