JavaScript
Plugin
cloud9
Ikezawathon

Cloud9のプラグインを作ってみた

Cloud9のプラグインを作ってみる

最近の開発は可能な限りCloud9でやってます。
(まだawsじゃない方を使ってます)

プラグインが作成できることを見つけたのでやってみます。

https://cloud9-sdk.readme.io/docs/the-cloud9-cli
公式ドキュメントを参照します。
"Create Your First Package"が途中からTodo、、、

環境設定

Plugin Manager を有効化

メニューから Cloud9/Preferences を開き、
Experimental/SDKPlugin Manager を on にします。

image.png

プラグインのプロジェクト作成

メニューから File/New Plugin/Empty Plugin を選択すると、
空プロジェクトのフォルダとかファイルとか作成されます。

今回のプラグインはikezawaという名前にすることにしました。
(後日なんらか関係するネタにする予定)

image.png

pluginsフォルダ内のフォルダ名を変更します。
(画像は変更後です)

plugin.jsの3行目と38行目あたりの mypluginikezawa に変更します。
(最後に plugin.js の全体を記載します)

プラグイン開発

プラグインのプログラムに必要な依存を追加するために、2行目を次のように変更します。

main.consumes = ["Plugin", "commands", "tabManager"];
名前 説明
Plugin プラグインのコンストラクタ
tabManager タブを開いたり操作したりする機能を提供
commands コマンドを作成する機能を提供

使いやすいように7~9行目辺りに変数を追加します。

var Plugin = imports.Plugin;
var commands = imports.commands;
var tabs = imports.tabManager;

新しいコマンドを作成

今回のプラグインを実行するトリガーをコマンドとして追加します。
Command-Shift-J(Ctrl-Shift-J)をトリガーとし、execで定義された関数が実行されます。

/***** Add Command *****/
commands.addCommand({
  name: "ikezawa_insert",
    bindKey: { 
      mac: "Command-Shift-J", 
      win: "Ctrl-Shift-J" 
    },
    exec: function(){ 
      alert("ikezawa!");
    }
}, plugin);

実行可能かどうかを判断するメソッドを追加

先程のaddCommandに渡したオブジェクトに以下を追記します。

isAvailable: function(editor) {
  if (editor && editor.ace)
    return !editor.ace.selection.isEmpty();
  return false;
 }

このコマンドはエディタが存在して何かが選択されている場合のみ動作します。

実行を確認

Tools/Developer/Start in Debug Mode でデバッグモードを開きます。

image.png

Cloud9がデバッグモードで別タブ(ウィンドウ)に新しく立ち上がります。

image.png

Open Plugin Explorerをクリックし自分が作ったプラグイン ikezawa を選択すると有効化されます。

Command-Shift-Jを押すと実行されアラートが表示されます。
image.png

ノーマルモードでプラグインを読み込む方法

Cloud9/Open Your Init Scriptを選択します。
init.jsが開くので以下のように記述します。

services.pluginManager.loadPackage([
    "~/.c9/plugins/ikezawa/package.json",
]);

ブラウザをリロードするとプラグインが読み込まれます。

もうちょっと書いてみる

さすがにこれだけでは面白くないので、選択しているテキスト内にikezawaという文字列が入っているか判定するものを実装してみました。

plugin.js
define(function(require, exports, module) {
  main.consumes = ["Plugin", "commands", "tabManager"]
  main.provides = ["ikezawa"]
  return main

  function main(options, imports, register) {
    var Plugin = imports.Plugin
    var commands = imports.commands
    var tabs = imports.tabManager

    /***** Initialization *****/
    var plugin = new Plugin("Ajax.org", main.consumes);
    var emit = plugin.getEmitter()

    function load() {

    }

    /***** Add Command *****/
    commands.addCommand({
      name: "ikezawa_insert",
      bindKey: {
        mac: "Command-Shift-J",
        win: "Ctrl-Shift-J"
      },
      isAvailable: function(editor) {
        if (editor && editor.ace)
          return !editor.ace.selection.isEmpty()
        return false
      },
      exec: function() {
        // フォーカスされているタブから選択範囲と行ごとの文字列を取得
        const range = tabs.focussedTab.editor.ace.selection.getRange()
        const lines = tabs.focussedTab.editor.ace.selection.doc.$lines
        // 文字列を作成
        var str = lines.slice(range.start.row, range.end.row + 1).join('\n')
        str = str.slice(range.start.column, str.length - (lines[range.end.row].length - range.end.column))
        // 結果表示
        console.log(str) //普通にブラウザコンソールに表示される
        const result = str.toLowerCase().indexOf('ikezawa') >= 0 ? 'Yes!' : 'No...'
        alert(result + '\n\n-- Your selection --\n' + str)
      }
    }, plugin)

    /***** Methods *****/



    /***** Lifecycle *****/

    plugin.on("load", function() {
      load()
    })
    plugin.on("unload", function() {

    })

    /***** Register and define API *****/

    plugin.freezePublicAPI({

    })

    register(null, {
      "ikezawa": plugin
    })
  }
})

修正したら、デバッグモードで開いているCloud9環境の右上にあるReload ikezawaをクリックしてプラグインをリロードします。

image.png

選択した文字列とikezawaが入っているかどうかの判定が表示されるようになりました。

image.png

image.png

感想

比較的簡単にプラグインを作ることができました。開発やデバッグがそれなりにスムーズにできるのが良いところです。

ただ、ドキュメントは揃っているようで揃ってない(記述が古かったり)するので、APIリファレンスとコンソールやデバッガとにらめっこしながら開発する覚悟は必要そうです。

引き続きさわってみてikezawaの名に恥じない何かを作れたらいいなー。

昔、友人らと勢いで作ったものへのリンクをペタリ。
「池澤」とつぶやくだけで癒されるslackチャンネル