Atomエディタに独自の補完候補を追加する(2)

今回は前回に引き続き、Atomエディタ上で独自の入力補完候補を追加する方法を解説します。今回は当初の目的だったCocos2d-JS(JavaScriptCocos2d-x)向けの実用的なパッケージ作成を行っていきます。

ところで、自分向けのまとめではあるのですが、この解説のニーズって世の中にどれだけあるんでしょうね…。

Cocos2d-JS補完パッケージの利用方法

早速ですが、今回作成したパッケージはautocomplete-cocos2d-jsという名前で、すでにAtomパッケージとして公開されています。

今すぐAtomでCocos2d-JS向けに補完がしたいという方は、Atom上でSettingsInstallを選んでcocos2dで検索すれば、今回作成したautocomplete-cocos2d-jsパッケージをインストールできます。機会がありましたらご利用ください。

f:id:tkitao:20151114231554p:plain

自動補完パッケージ作成の流れ

前回は、自動補完パッケージを作成するための以下のステップについて解説しました。

  • Generate Atom Packageコマンドで基本となるパッケージを作成する
  • 自動補完に不要なファイルやディレクトリを削除する
  • package.jsonをautocomplete-plus向けに設定する
  • 補完候補を返すgetSuggestionsメソッドを実装する

最後のgetSuggestionsメソッドでは、前回は決まった語を一語返すだけの実装でしたが、今回はそのあたりを中心に修正していきます。

なお、今回作成した全コードは以下のリポジトリから確認できます。

github.com

ファイル構成を変更する

まずは、前回main.coffee1ファイルに実装していたコードを管理しやすくするため、パッケージ管理用の処理(main.coffee)と補完候補を作成する処理(provider.coffee)の2つのファイルに分割します。

また、補完候補リストは数千行の規模になるため、completions.jsonという名前の別ファイルとして読み込む形にします。

最終的なファイル構成は以下のようになります。

f:id:tkitao:20151114232015p:plain

分割した後のmain.coffeeのコードはこちらです。

provider = require './provider'

module.exports =
  activate: -> provider.loadCompletions()
  getProvider: -> provider

ここでは、activateメソッドとして初期化時にproviderにcompletions.jsonファイルを読み込ませる処理を、getProviderメソッドでautocomplete-plusにproviderを渡す処理を実装しています。

補完方法を設定する

次にprovider.coffeeを実装していきます。

まずは、補完対象となるファイルタイプと、表示時の順序を決めるための優先度、補完候補の自動的な絞り込みの有無を次のように指定します。

module.exports =
  selector: '.source.js, .source.coffee'
  suggestionPriority: -1
  filterSuggestions: true

suggestionPriorityは数字が大きくなるほど、他の補完候補よりも先に表示されます。今回は通常の補完候補(優先度0)よりも後にしたかったので、-1としました。

またfilterSuggestionstrueにすると、getSuggestionsメソッドで返した候補からその時の入力内容に応じて自動的に絞り込みが行われるようになります。自前で入力内容の絞り込みを行うのが面倒な場合に有効です。

補完候補リストを読み込む

続いて補完候補リストのcompletions.jsonを読み込みます。

fs = require 'fs'
path = require 'path'

module.exports =
  /* 省略 */

  loadCompletions: ->
    fs.readFile(
      path.resolve(__dirname, '..', 'completions.json'),
      (err, data) => @completions = JSON.parse(data) unless err?)

completions.jsonはCocos2d-JSのAPI ReferenceRubyスクレイピングして、以下のような形式で作成しています。

{
  "class": [
    "SomeClassName"
  ],
  "property": [
    "somePropertyName"
  ],
  "method": [
    "someMethodName"
  ]
}

スクレイピングの方法は今回解説しませんが、こちらでコードを確認できます。

補完候補を作成する

引き続いて、getSuggestionsメソッドで補完候補の作成処理を実装します。

1文字打つだけ補完候補が出てくるとちょっと邪魔そうなので、今回は3文字以上入力されたら候補を表示するようにします。補完候補はcompletions.jsonから読み込んだデータをautocomplete-plusの形式に変換することで作成します。

getSuggestions: ({prefix}) ->
  return [] if prefix.length < 3

  completions = []
  for type, names of @completions
    for name in names
      completions.push({type: type, text: name})
  completions

getSuggestionsメソッドで返した補完候補はautocomplete-plusによって書き換えられてしまうため、毎回作成し直す必要があることに注意してください。

動作確認

作成したprovider.coffeeの全コードは以下になります。

fs = require 'fs'
path = require 'path'

module.exports =
  selector: '.source.js, .source.coffee'
  suggestionPriority: -1
  filterSuggestions: true
  completions: {}

  loadCompletions: ->
    fs.readFile(
      path.resolve(__dirname, '..', 'completions.json'),
      (err, data) => @completions = JSON.parse(data) unless err?)

  getSuggestions: ({prefix}) ->
    return [] if prefix.length < 3

    completions = []
    for type, names of @completions
      for name in names
        completions.push({type: type, text: name})
    completions

AtomのコマンドパレットからWindow: Reloadを実行してパッケージを再読み込みし、適当なJavaScriptファイルを開くと、Cocos2d-JSの補完候補が表示されることが確認できます。

f:id:tkitao:20151114232112p:plain

Atom用拡張パッケージ作成のTips

最後に補足として拡張パッケージ作成の際に使えるTipsをいくつか書いておきます。

  • 拡張パッケージのコードを更新した際は、コマンドパレットからWindow: Reloadを実行することで、更新内容を反映できます。
  • 作成している拡張パッケージはAtom上でUninstallしてもパッケージへのリンクがなくなるだけでコード自体は削除されません。
  • Uninstallした拡張パッケージは、パッケージのディレクトリに移動してapm linkを実行することでInstallされた状態に戻ります。
  • 拡張パッケージ編集中に、コマンドパレットからWindow: Run Package Specsを実行することでspecフォルダにあるテストコードを実行できます。

最後に

2回にわたってAtomのautocomplete-plus向けの拡張パッケージの作成方法を解説してみました。

久々にVim以外のエディタと真面目に向き合ってみましたが、AtomはモダンなアーキテクチャでWeb技術との相性も良く、習得に時間を割くのに値するエディタだと思いました。引き続き開発にAtomを使ってみようと思っています。