gist
2013年12月8日日曜日
2013年7月1日月曜日
Rails4.0とRuby2.0をMountain Lionにインストール
2012年10月14日日曜日
Mac OS X Mountain Lion (10.8.2) に Rails 3.2.8 をインストールする
約100日ぶりの更新です。
RailsとiOS/Androidアプリとクラウド3点セットのお仕事が増えてきましたので、少しNode.jsから離れて、更新を続けようと思います。
Moutain LionにRailsをインストールしたときの作業のログです。
Rubyのバージョン管理ツールにrbenvを使用しています。
事前準備
- AppStoreでXcode 4.5.1 をインストールしておく
- Xcode 4.5.1の設定からCommand Line Tools をインストールしておく
Homebrewをインストールする
rbenvをインストールする
.bash_profileを編集して以下の一行を追加します。
$ vim ~/.bash_profile再読込を忘れずに
ruby-buildをインストール
rbenv install -l でインストール可能なバージョンのリストが表示されればOKです。
Rubyをインストールする
使用しているrubyのバージョンが1.9.3-p194でパスが変更されていればOK。
Railsをインストールする
Railsアプリを作成する
ブラウザから http://localhost:3000/ にアクセスして以下の画面が表示されたRailsのインストールは完了です。
2012年3月20日火曜日
軽量で高機能なテキストエディタ「SublimeText2」で CoffeeScript とか。

感想。「軽っ!」
以下からDownloadできます。
![]() |
CoffeeScript。フォルダを開くと左側にツリーが表示されます。 |
![]() |
package.jsonを表示したところ |
![]() |
IntelliSenseもあります |
![]() |
シンタックスたくさん。 |
CoffeeScriptのシンタックスは、手動でインストールします。
$ cd ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/ $ git clone git://github.com/jashkenas/coffee-script-tmbundle CoffeeScript
vimもいいけど、こんだけ軽いと浮気しそうです。vimのキーバインドもできるのね。(それでもまたvimに戻るのでしょうけど。)
参考:
プログラミングエディタ Sublime Text2 を使ってみよう!
http://d.hatena.ne.jp/mizchi/20111021/1319167480
2012年2月16日木曜日
イヌ型ドキュメントで開発効率アップ!? JSDogを使ってみよう。
JavaScriptのドキュメント生成ツールと言えば、JSDoc Toolkitが有名です。
でも何か、物 足 り な い。
そこでJSDogです。
JSDogは、JSDocの書き方で「犬」のドキュメントが生成されます。
インストールはnpmで。
$ sudo npm install -g jsdog
書き方はこんな感じです。
/** ++*[npmtools.js]*++ - npmのpackage.jsonを読み込むプログラム * * @version 0.0.1 * @author Tomoyuki Inoue */ var fs = require('fs'); /** * 指定したパスからpackage.jsonファイルを探索します。 * @method readPackageJson * @param {string} path 読み込みを開始するパスを指定します。 * @param {function} cb 読み込み完了かエラー時のコールバックを指定します。 */ var readPackageJson = function(path, cb){ // パスの読み込み開始 var path = path + "/node_modules"; fs.readdir(path, function(err, dirs){ if(err) cb(err, null); // dirsには指定したパスのファイル名・ディレクトリ名の一覧が入っている for(var i = 0; i < dirs.length; i++){ var dir = dirs[i]; // 頭文字が.の場合読み込まない if(dir.charAt(0) === '.') continue; // package.jsonのパスを指定 var jsonPath = path + "/" + dir + "/package.json"; // package.jsonを読み込み開始 fs.readFile(jsonPath, function(err, data){ if(err) cb(err, null); // dataには読み込んだBufferが入っている // toString('utf8')で文字列にする var jsonStr = data.toString('utf8'); // JSONをパースしてコールバック cb(null, JSON.parse(jsonStr)); }); } }); }; readPackageJson(".", function(err, json){ if(err) throw err; console.log(json.name +"@" + json.version ); });
使い方はコマンドラインで。
$ jsdog -s npmtools.js > index.html
見事に文字化けします。
テンプレートの最初の数行を修正します。
テンプレートはJadeで書かれています。ファイルは、/usr/local/lib/node_modules/jsdog/default.jade あたりにあると思います。
修正前
!!! 5 html(lang="en") head title= pageTitle
修正後(lang属性削除、メタcharset追加)
!!! 5 html head meta(charset="utf-8") title= pageTitle
もう一度実行すると文字化けが解消。
まだまだ不安定ですが面白いですね。
テンプレートもJade形式なので簡単です。ちょっと修正すると・・・
な事もできます。
2012年2月14日火曜日
JavaScriptの綺麗なドキュメントを作るためのメモ
ドキュメントが綺麗で読みやすいというのも、普及していく上で重要なファクターなのかもしれませんね。
JavaScriptのドキュメント生成ツールは、JSDocというのが有名のようです。(若干Activeでないような気もします。)
面白そうなのは、docco というツール。リンク先のようにコメントとコードを同時に見れるようなHTMLを生成します。
今週はJavaScriptのドキュメントをやってみようと思います。
関連ページ
イヌ型ドキュメントで開発効率アップ!? JSDogを使ってみよう。2012年2月12日日曜日
今すぐできる!Cloud9 IDEカスタマイズ! npmインストーラを作ってみよう。
Cloud9 IDEを拡張して、npmのインストーラを作ってみました。npm installとnpm listができるようになりました。
まず、クライアントのViewです。
cloud9/client/ext/npmtools/npmtools.xml
<a:application xmlns:a="http://ajax.org/2005/aml"> <a:window id = "winDatagrid" title = "NPM Packages" icon = "" center = "true" resizable = "true" buttons = "close" modal = "false" skin = "bk-window" width = "660" height = "400" kbclose = "true" draggable = "true"> <a:vbox anchors="0 0 0 0" edge="0 0 0 0"> <a:hbox> <a:textbox id="tbPackage" flex="1"> </a:textbox> <a:button id="btnInstall" caption="Install"> </a:button> </a:hbox> <a:datagrid id="dgList" flex="1"> <a:each match="[packages]"> <a:column caption="Name" value="[@name]" width="50%" /> <a:column caption="Version" value="[@version]" width="50%" /> </a:each> </a:datagrid> </a:vbox> </a:window> </a:application>
クライアントのロジック。
cloud9/client/ext/npmtools/npmtools.js
define(function(require, exports, module) { var ide = require('core/ide'); var ext = require('core/ext'); var panels = require("ext/panels/panels"); var markup = require('text!ext/npmtools/npmtools.xml'); var util = require("core/util"); module.exports = ext.register('ext/npmtools/npmtools', { name : "NPM Tools", dev : "Tomoyuki Inoue", alone : true, type : ext.GENERAL, markup : markup, command : "npmtools", desp : [panels], nodes : [], hook : function(){ var _self = this; this.nodes.push( mnuWindows.insertBefore(new apf.item({ caption : "NPM Tools", onclick : function(){ ext.initExtension(_self); // モデルを作成 var model = new apf.model(); // datagridのmodel属性にmodelを設定 dgList.setModel("model", model); // data要素を作成 var data = winDatagrid.ownerDocument.createElement("data"); // dataをロード model.load(data); // modelを設定 dgList.setModel(model); _self.listPackages(); // ボタンクリック時のイベントハンドラ btnInstall.addEventListener("click", function(e){ if(tbPackage.value.length > 0){ tbPackage.clear(); btnInstall.disable(); _self.installPackage(tbPackage.value); } }); // datagridを表示 winDatagrid.show(); } }) ), mnuWindows.firstChild); // サーバから受信した時の処理を記述。 ide.addEventListener("socketMessage", this.onMessage.bind(this)); }, onMessage: function(e) { var message = e.message; // datagrid_test以外なら何もしない。 if(message.type !== "result" && message.subtype !== "npmtools") return; if(message.body.subcommand === "list"){ this.addPackageToDatagrid(message.body.name, message.body.version); } if(message.body.subcommand === "install"){ m.clear(); this.listPackages(); } }, listPackages: function(){ // npm listの実行結果を取得 ide.send({ command: "npmtools", subcommand: "list" }); }, installPackage: function(packageName){ var data = { command: "npmtools", subcommand: "install", packagename :packageName }; // サーバにデータを送信。 ide.send(data); }, addPackageToDatagrid: function(packageName, version){ // モデルを取得 var m = dgList.getModel(); // packages要素を作成 var member = winDatagrid.ownerDocument.createElement('packages'); // name属性を設定 member.setAttribute('name', packageName); // version属性を設定 member.setAttribute('version', version); // data要素の子要素としてpackages要素を追加 m.data.appendChild(member); btnInstall.enable(); }, init : function(apfNode){}, enable : function(){ if (!this.disabled) return; this.nodes.each(function(item){ item.enable(); }); this.disabled = false; }, disable : function(){ if (this.disabled) return; this.nodes.each(function(item){ item.disable(); }); this.disabled = true; }, destroy : function(){ this.nodes.each(function(item){ item.destroy(true, true); }); this.nodes = []; } }); });
サーバ側のプラグインです。
cloud9/server/cloud9/ext/npmtools/npmtools.js
var Plugin = require("cloud9/plugin"); var sys = require("sys"); var fs = require("fs"); // 初期設定 var DataGridTestPlugin = module.exports = function(ide) { this.ide = ide; // hooksに「command」を追加する this.hooks = ["command"]; // 自分の名前 this.name = "npmtools"; }; // Pluginクラスを継承する。 sys.inherits(DataGridTestPlugin, Plugin); (function() { // command を実装。workspaceから実行される。 this.command = function(user, message, client) { // 自分以外のコマンドは受け付けない。 if(message.command != "npmtools") return false; var _self = this; // サブコマンドがlistの場合、作業フォルダのpackage.jsonを探索。 if(message.subcommand === "list") { this.listPackages(this.ide.workspaceDir, function(err, json){ if(err) throw err; console.log(json.name + "," + json.version); _self.sendResult(0, message.command, { subcommand: message.subcommand, name: json.name, version: json.version }); }); return true; } if(message.subcommand === "install"){ var args = [message.subcommand, message.packagename]; // npm installを実行 this.spawnCommand("npm", args, this.ide.workspaceDir, function(err) {}, function(out) {}, function(code, err, out) { // クライアントに送信 _self.sendResult(0, message.command, { subcommand: message.subcommand, packagename: message.packagename }); } ); return true; } return false; }; // サーバ終了時に起動。 this.dispose = function(callback) { // TODO kill all running processes! callback(); }; // NPMパッケージのリストを取得する this.listPackages = function(path, cb) { // パスの読み込み開始 var path = path + "/node_modules"; fs.readdir(path, function(err, dirs){ if(err) cb(err, null); // dirsには指定したパスのファイル名・ディレクトリ名の一覧が入っている for(var i = 0; i < dirs.length; i++){ var dir = dirs[i]; // 頭文字が.の場合読み込まない if(dir.charAt(0) === '.') continue; // package.jsonのパスを指定 var jsonPath = path + "/" + dir + "/package.json"; // package.jsonを読み込み開始 fs.readFile(jsonPath, function(err, data){ if(err) cb(err, null); // dataには読み込んだBufferが入っている // toString('utf8')で文字列にする var jsonStr = data.toString('utf8'); // JSONをパースしてコールバック cb(null, JSON.parse(jsonStr)); }); } }); }; }).call(DataGridTestPlugin.prototype);
実行結果はこんな感じ。テキストボックスにパッケージ名を入力してInstallボタンで、npmでインストールできます。
関連ページ
2012年2月9日木曜日
コツコツ拡張Cloud9。フォームの入力を受け取ってグリッドに表示する。
Cloud9 IDEを拡張して、テキストボックスなどのフォームから受け取った文字列をグリッドに表示してみます。
まずはビューにテキストボックス(a:textbox)とボタン(a:button)を追加します。
cloud9/client/ext/datagrid_test/datagrid_test.xml
<a:application xmlns:a="http://ajax.org/2005/aml"> <a:window id = "winDatagrid" title = "放課後ティータイム" icon = "" center = "true" resizable = "true" buttons = "close" modal = "false" skin = "bk-window" width = "660" height = "400" kbclose = "true" draggable = "true"> <a:vbox anchors="0 0 0 0" edge="0 0 0 0"> <a:hbox> <a:textbox id="tbPackage" flex="1"> </a:textbox> <a:button id="btnInstall" caption="インストール"> </a:button> </a:hbox> <a:datagrid id="dgList" flex="1"> <a:each match="[member]"> <a:column caption="メンバー名" value="[@name]" width="50%" /> <a:column caption="CV" value="[@cv]" width="50%" /> </a:each> </a:datagrid> </a:vbox> </a:window> </a:application>
次にロジックにイベントハンドラを追加してみます。
cloud9/client/ext/datagrid_test/datagrid_test.js
define(function(require, exports, module) { var ide = require('core/ide'); var ext = require('core/ext'); var markup = require('text!ext/datagrid_test/datagrid_test.xml'); module.exports = ext.register('ext/datagrid_test/datagrid_test', { name : "Datagrid Test", dev : "Tomoyuki Inoue", alone : true, type : ext.GENERAL, markup : markup, nodes : [], hook : function(){ var _self = this; this.nodes.push( mnuWindows.insertBefore(new apf.item({ caption : "Datagrid Test", onclick : function(){ ext.initExtension(_self); // モデルを作成 var model = new apf.model(); // datagridのmodel属性にmodelを設定 dgList.setModel("model", model); // data要素を作成 var data = winDatagrid.ownerDocument.createElement("data"); // dataをロード model.load(data); // modelを設定 dgList.setModel(model); // ボタンクリック時のイベントハンドラ btnInstall.addEventListener("click", function(e){ if(tbPackage.value.length > 0){ // モデルを取得 var m = dgList.getModel(); // member要素を作成 var member = winDatagrid.ownerDocument.createElement('member'); // name属性を設定 member.setAttribute('name', tbPackage.value); // cv属性を設定 member.setAttribute('cv', 'CV1'); // data要素の子要素としてmember要素を追加 m.data.appendChild(member); } }); // datagridを表示 winDatagrid.show(); } }) ), mnuWindows.firstChild); }, init : function(apfNode){}, nable : function(){ if (!this.disabled) return; this.nodes.each(function(item){ item.enable(); }); this.disabled = false; }, disable : function(){ if (this.disabled) return; this.nodes.each(function(item){ item.disable(); }); this.disabled = true; }, destroy : function(){ this.nodes.each(function(item){ item.destroy(true, true); }); this.nodes = []; } }); });
モデルに追加すると、勝手にdatagridが更新されます。
実行結果はこんな感じ。テキストボックスに文字列入れてインストールボタンをクリックすると、データグリッドに追加されます。
2012年2月8日水曜日
コツコツ拡張Cloud9。APFの仕様 ui.ajax.org はChromeで見よう。
apfのドキュメント、ありました。
APFは、Ajax.orgで開発されているフレームワークです。
2012/02/08現在、Ajax.org にアクセスすると、Cloud9(c9.io)に飛ばされます。
ui.ajax.org でドキュメントを公開している、ということでアクセスすると、SafariでLoading...と表示されたまま進まず。ドキュメントが無いものと諦めておりました。
で、Chromeで見れた、というオチ。
公式サイトでの最終バージョンは2009年2月で2.1。只今2010年2月で3.0 Beta2 Stable。2年経ってもBeta取れてないように見えますが、GitHubのほうは、そこそこ活発です。Cloud9もGitのAPFを使っているようです。
早速ドキュメントを見つつ、昨日の続き。
まずビューから。変更なし。
cloud9/client/ext/datagrid_test/datagrid_test.xml
<a:application xmlns:a="http://ajax.org/2005/aml"> <a:window id = "winDatagrid" title = "放課後ティータイム" icon = "" center = "true" resizable = "true" buttons = "close" modal = "false" skin = "bk-window" width = "660" height = "400" kbclose = "true" draggable = "true"> <a:vbox anchors="0 0 0 0" edge="0 0 0 0"> <a:datagrid flex="1"> <a:each match="[member]"> <a:column caption="メンバー名" value="[@name]" width="50%" /> <a:column caption="CV" value="[@cv]" width="50%" /> </a:each> </a:datagrid> </a:vbox> </a:window> </a:application>
コントローラを修正。
cloud9/client/ext/datagrid_test/datagrid_test.js
define(function(require, exports, module) { var ide = require('core/ide'); var ext = require('core/ext'); var markup = require('text!ext/datagrid_test/datagrid_test.xml'); module.exports = ext.register('ext/datagrid_test/datagrid_test', { name : "Datagrid Test", dev : "Tomoyuki Inoue", alone : true, type : ext.GENERAL, markup : markup, nodes : [], hook : function(){ var _self = this; this.nodes.push( mnuWindows.insertBefore(new apf.item({ caption : "Datagrid Test", onclick : function(){ ext.initExtension(_self); // モデルを作成 var model = new apf.model(); // Documentノードを取得 var doc = winDatagrid.ownerDocument; // data 要素を作成 var data = doc.createElement('data'); // 思い切って1000件追加 for(var i=0; i<1000; i++) { // member要素を作成 var member = doc.createElement('member'); // name属性を設定 member.setAttribute('name', 'なまえ' + i); // cv属性を設定 member.setAttribute('cv', 'CV' + i); // data要素の子要素としてmember要素を追加 data.appendChild(member); } // data要素をmodelに読み込む model.load(data); // datagridのmodel属性にmodelを設定 winDatagrid.setAttribute("model", model); // datagridを表示 winDatagrid.show(); } }) ), mnuWindows.firstChild); }, init : function(apfNode){}, nable : function(){ if (!this.disabled) return; this.nodes.each(function(item){ item.enable(); }); this.disabled = false; }, disable : function(){ if (this.disabled) return; this.nodes.each(function(item){ item.disable(); }); this.disabled = true; }, destroy : function(){ this.nodes.each(function(item){ item.destroy(true, true); }); this.nodes = []; } }); });
結果
これで取得したJSONデータをマッピングできそうです。APFにはJSONとAMFの変換ないのかしら。
2012年2月7日火曜日
コツコツ拡張。Cloud9 IDEのDataGridでモデルとビューを切り離す。
コツコツ拡張。昨日のエントリーで出来なかった、モデルとビューを分離してみます。
まずはViewから。
cloud9/ext/datagrid_test/datagrid_test.xml
<a:application xmlns:a="http://ajax.org/2005/aml"> <a:window id = "winDatagrid" title = "放課後ティータイム" icon = "" center = "true" resizable = "true" buttons = "close" modal = "false" skin = "bk-window" width = "660" height = "400" kbclose = "true" draggable = "true"> <a:vbox anchors="0 0 0 0" edge="0 0 0 0"> <a:datagrid flex="1"> <a:each match="[member]"> <a:column caption="メンバー名" value="[@name]" width="50%" /> <a:column caption="CV" value="[@cv]" width="50%" /> </a:each> </a:datagrid> </a:vbox> </a:window> </a:application>
コントローラにモデルを書くとこんな感じ。
cloud9/ext/datagrid_test/datagrid_test.js
define(function(require, exports, module) { var ide = require('core/ide'); var ext = require('core/ext'); var markup = require('text!ext/datagrid_test/datagrid_test.xml'); module.exports = ext.register('ext/datagrid_test/datagrid_test', { name : "Datagrid Test", dev : "Tomoyuki Inoue", alone : true, type : ext.GENERAL, markup : markup, nodes : [], hook : function(){ var _self = this; this.nodes.push( mnuWindows.insertBefore(new apf.item({ caption : "Datagrid Test", onclick : function(){ ext.initExtension(_self); // モデルを記述 var model = new apf.model(); model.load( "<data>" + "<member name=\"平沢 唯\" cv=\"豊崎 愛生\"></member>" + "<member name=\"秋山 澪\" cv=\"日笠 陽子\"></member>" + "<member name=\"田井中 律\" cv=\"佐藤 聡美\"></member>" + "<member name=\"琴吹 紬\" cv=\"寿 美菜子\"></member>" + "<member name=\"中野 梓\" cv=\"竹達 彩奈\"></member>" + "</data>"); winDatagrid.setAttribute("model", model); winDatagrid.show(); } }) ), mnuWindows.firstChild); }, init : function(apfNode){}, nable : function(){ if (!this.disabled) return; this.nodes.each(function(item){ item.enable(); }); this.disabled = false; }, disable : function(){ if (this.disabled) return; this.nodes.each(function(item){ item.disable(); }); this.disabled = true; }, destroy : function(){ this.nodes.each(function(item){ item.destroy(true, true); }); this.nodes = []; } }); });
次はコントローラとモデルを切り離してみます。
2012年2月4日土曜日
[Node.js] Cloud9 IDEを拡張してnpmのインストーラを作ってみる
Cloud9 IDEには、NideのようなNPM Managerがありません。expressをインストールするには、コマンドラインを使う必要があります。IDEからnpmインストールできるといいですよね。
ローカル環境にインストールしたCloud9 IDEを拡張してみます。
ポイント
- npmコマンドは結局サーバ側のコマンドなので、クライアントとサーバの両方を拡張する必要がある。
- gittoolsが参考になる。
全体の流れ
- クライアント側からide.send(message)を使ってJSONでコマンド送信。サーバー側のthis.command(user, message, client)で受信。
- サーバ側でspawnCommandでコマンド実行。コールバック内でsendResultでストリーム出力をクライアントへ送信。
- クライアント側のonMessageで出力を受信。クライアントinit内でideのsocketMessageイベントとバインドしておく。
とりあえずで出来上がったのが、これ。
有効化するとEditからNPM Managerを選択できます。
ダイアログが開いて、パッケージ名を入力。
コンソールにNPMがインストール結果が表示されます。
もう少し理解を深めたらgithubに公開しようと思います。今回は一部だけ。サーバ側のコマンドの実装です。
this.command = function(user, message, client) { if (message.command != "npmtools") return false; var _self = this; var subcommand = message.subcommand; if(subcommand !== "install") return false; var packagename = message.packagename; var argv = [subcommand, packagename]; var npmRoot = "."; this.spawnCommand("npm", argv, npmRoot, function(err) { // Error _self.sendResult(0, message.command, { code: 0, err: err, out: null }); }, function(out) { }, // Data function(code, err, out) { // Exit _self.sendResult(0, message.command, { code: code, err: null, out: out }); } ); return true; };
あとは、コマンドラインからnpm打てるようにするのと、画面からパッケージの一覧、アンインストールできるようにしたいと思います。
2012年2月3日金曜日
[Node.js] Cloud9 IDEを拡張するメモ。Hello Worldを表示してみよう。
Cloud9 IDEを拡張する手順
ここに書いてあります。
cloud9/client/ext/extension_template/extension_template.js
- requireJSをロードする
- AMLマークアップextensionをロードする(必要なら)※画面がいるとき
- extensionのプロパティを記述する
- 変数とメソッドを記述する
- ext.registerにextensionのファイルパスを記述する
このextension_templateフォルダをコピーして作っていくと早そうです。
オーバーライドするプロパティ
- name ... extension名(必須)
- dev ... 開発者名
- alone ... 単体動作か、他のextension依存か。boolean指定。
- type ... ext.GENERAL なら一般的な extension。 ext.EDITOR ならエディタに対するextension。
- markup ... UIを含むなら markup と記述。文字列。
- visible ... extensionロード時に表示するかどうか。boolean指定。
オーバーライドするメソッド
- init (必須)... 初期設定。hook中に呼び出される。
- hook (オプション) ... extensionを登録したとき呼び出される
- enable (必須) ... extensionを有効にしたとき呼び出される
- disabile (必須) ... extensionを無効にしたとき呼び出される
- destroy (必須) ... 後処理。extensionを無効化したとき呼び出される。
extensionを有効化する手順は2通り。
Extension Managerを使う場合
Extension Managerを起動
User Extensionsを選択して、入力欄に ext/extension_template/extension_template と入力。
Addボタンをクリックすると有効になります。
試しに実行。Editから Extension Template Window を選択。
Hello World! とWindowが表示されます。
または、cloud9/server/cloud9/ide.jsに記述
2012年2月2日木曜日
[Node.js] Cloud9 IDEにショートカットを追加しよう
Cloud9 IDEにショートカットを追加してみます。
画面左のファイル一覧(Project Files)ですが、時々上手く更新されないようで、いつもボタンでリフレッシュしていました。そこで今回はCtrl+Rでリフレッシュするようにショートカットを追加してみます。ついでにコマンドラインでもリフレッシュできるようにしてみます。
キーバインドを追加するには、cloud9の拡張機能を少し修正します。修正は2ヶ所です。
keybindings_defaultは、Cloud9のキーバインドの実装です。ここのdefault_mac.jsの最後の方にバインディングを追加します。
cloud9/client/ext/keybindings_default/default_mac.js
return keys.onLoad({ "ext" : { "console" : { "switchconsole": "Shift-Esc" }, "save" : { "quicksave": "Command-S", "saveas": "Command-Shift-S", "reverttosaved": "Command-Shift-Q" }, ..... // 最後の方に追加。 "tree" : { "refresh" : "Ctrl-R" } } });
treeというのが、ファイル一覧(Project Files)の実装です。ここにcommandsとhotitemsを追加し、hookメソッドにキーバインドを追加します。
cloud9/client/ext/tree/tree.js
module.exports = ext.register("ext/tree/tree", { name : "Project Files", dev : "Ajax.org", alone : true, type : ext.GENERAL, markup : markup, ....... // コマンドを追加。これで画面下のコマンドラインに追加されます commands : { "refresh" : {hint : "Refresh Project Files Tree"} }, // hotitemsオブジェクトを生成 hotitems : {}, ....... hook : function(){ panels.register(this, { position : 1000, caption: "Project Files", "class": "project_files" }); // キーバインドを追加します this.hotitems.keybindings = [this.nodes[0]]; },
cloud9を再起動すると有効になります。
コマンドも有効になりました。