gist

ラベル 開発環境 の投稿を表示しています。 すべての投稿を表示
ラベル 開発環境 の投稿を表示しています。 すべての投稿を表示

2013年12月8日日曜日

Mac OS X 10.9 のRails 4.0.0を4.0.2にアップデートしたときのメモ

2013年7月1日月曜日

Rails4.0とRuby2.0をMountain Lionにインストール

Ruby-2.0.0p247でOpenSSLのコンパイルエラーがなくなったみたいです。Rails 4.0をGemでインストールする前にRdocをアップデートしておくと吉。

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 とか。

この間のNode学園4時限目で同じテーブルになったエンジニアさんから、Sublime Text 2を教えて頂き、気になっていたので入れてみました。

感想。「軽っ!」

以下から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の綺麗なドキュメントを作るためのメモ

githubを散策していたら、こんなReadmeを見つけました。「Beautiful Docs」というタイトルでJavaScriptに限らず、様々なAPIのドキュメントリンク集となっています。流行の技術ばかりです。

ドキュメントが綺麗で読みやすいというのも、普及していく上で重要なファクターなのかもしれませんね。

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が参考になる。

全体の流れ

  1. クライアント側からide.send(message)を使ってJSONでコマンド送信。サーバー側のthis.command(user, message, client)で受信。
  2. サーバ側でspawnCommandでコマンド実行。コールバック内でsendResultでストリーム出力をクライアントへ送信。
  3. クライアント側の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

  1. requireJSをロードする
  2. AMLマークアップextensionをロードする(必要なら)※画面がいるとき
  3. extensionのプロパティを記述する
  4. 変数とメソッドを記述する
  5. ext.registerにextensionのファイルパスを記述する

このextension_templateフォルダをコピーして作っていくと早そうです。

オーバーライドするプロパティ

  1. name ... extension名(必須)
  2. dev ... 開発者名
  3. alone ... 単体動作か、他のextension依存か。boolean指定。
  4. type ... ext.GENERAL なら一般的な extension。 ext.EDITOR ならエディタに対するextension。
  5. markup ... UIを含むなら markup と記述。文字列。
  6. visible ... extensionロード時に表示するかどうか。boolean指定。

オーバーライドするメソッド

  1. init (必須)... 初期設定。hook中に呼び出される。
  2. hook (オプション) ... extensionを登録したとき呼び出される
  3. enable (必須) ... extensionを有効にしたとき呼び出される
  4. disabile (必須) ... extensionを無効にしたとき呼び出される
  5. 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を再起動すると有効になります。

コマンドも有効になりました。

関連ページ

この完成度に震えが止まらない!Node.js史上最高のIDE、Cloud9をインストールしよう。