2012/06/14


zencoding.vim 最近 zencoding.vim を大きく修正しました。とは言ってもこれまで単体テストを作ってきた事もあって、過去の動作を(なるべく)壊さずに大規模な修正が行えました。
これまでは一つのファイルに html, css, haml の処理が全て記述されていたのでとてもスパゲッティなコードになっていて、もう少し放っておくとカオスな状態になりかけていたので、ファイルを分割しインタフェースを揃える事にしました。
これにより、今後新しいフォーマットに対応する際にも、zencoding/lang にあるファイルの真似をして記述すれば実装出来る様になります。

haml に対応した

「えっ?前から対応してたんじゃないの?」と言われる方もいるかもしれませんが、これはあくまで expand abbreviation の haml フィルタとしてだけサポートしていました。
何が変わったかというと zen coding が持っている本来の機能
  • expand abbreviation
  • wrap with abbreviation
  • update image size
  • toggle comment
  • balance tag
  • move next prev
  • split join tag
  • remove tag
といった機能全てが haml でも使える様になりました。ですので html:5>ul>li*3
という入力から <c-y>, !!! 5
%html{:lang => "ja"}
  %head
    %meta{:charset => "UTF-8"}
    %title
  %body
    %ul
      %li
      %li
      %li
こう展開出来るし、コメントのトグルや img タグ上での画像サイズ更新も haml のまま使えます。

slim に対応した

haml 同様に、html で使えていた機能が slim でも使える様になっています。個人的には slim の方が綺麗しいいなーと思ってます。ただし haml にしても slim にしても、そこまで使いこなしていないので、もし変な動作したら教えて下さい。
もちろん、一部で人気の高い anchorizeURL を slim で使う事も出来ます。
http://twitter.com/mattn_jp URL上で <c-y>A とタイプすると blockquote class="quote"
  a href="http://twitter.com/mattn_jp"
    | Twitterの mattn (@mattn_jp)
  br
  p
    | わしがコエンザイムQ10だ about 1 hour ago TwitVim から 最近になってslimいいなーって思う。 about 2 hours ago TwitVim から ディアゴスティーニ...
  cite
    | http://twitter.com/mattn_jp
この様に展開されます。haml でも使えます。

新機能 code pretty

僕はこのブログを書くときに良くコードの断片を TOHtml で整形しているのだけど、TOHtml には html タグや body タグが含まれていて困る。そこで TOHtml の中身だけ抽出してくれる機能を付けた。例えば まずはこのコードを見て欲しい
#include <stdio.h>

void main() {
  puts("hello world");
}
というテキストのコード部を選び <c-y>c をタイプすると、FileType: と聞かれる。コードがC言語なら c でエンター。vim のファイルタイプ名を入力します。分からなくてもファイルタイプで補完が効く様にしてあるので適当に先頭文字入れてタブをタイプすればそれっぽいのが出てきます。デフォルト値は開いているファイルのファイルタイプなので、.pl のファイルを開けば自動で perl になってます。
ファイルタイプを入力したら自動で TOHtml が行われ まずはこのコードを見て欲しい
<span class="PreProc">#include&nbsp;</span><span class="Constant">&lt;stdio.h&gt;</span><br />
<br />
<span class="Type">void</span>&nbsp;main() {<br />
&nbsp;&nbsp;puts(<span class="Constant">&quot;hello world&quot;</span>);<br />
}<br />

となるので、あとは変換された部分をお好きなタグで囲って下さい。この TOHtml を使った機能は TOHtml の設定内容に依存します。僕の場合はpre/font タグを使わず css クラスを吐き出す設定にしています。

最小単位での展開にした

これまではカーソル位置から前の部分を全て式とみなしていましたが、最近修正して最短の式のみを扱う様にしました。なので文中 まずは a[href=http://mattn.kaoriya.net]{Big Sky}| をみて欲しい | の位置で <c-y>, をタイプすると まずは <a href="http://mattn.kaoriya.net">Big Sky</a> をみて欲しい
に変換されます。

おまけ

僕が設定している物の中でちょっと便利そうな物を紹介しようと思います。
let g:user_zen_settings = {
\  'lang' : 'ja',
\  'html' : {
\    'filters' : 'html',
\    'snippets' : {
\      'jq' : "<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js\"></script>\n<script>\n\\$(function() {\n\t|\n})()\n</script>",
\      'cd' : "<![CDATA[|]]>",
\    },
\  },
\  'php' : {
\    'extends' : 'html',
\    'filters' : 'html,c',
\  },
\  'javascript' : {
\    'snippets' : {
\      'jq' : "\\$(function() {\n\t\\${cursor}\\${child}\n});",
\      'jq:json' : "\\$.getJSON(\"${cursor}\", function(data) {\n\t\\${child}\n});",
\      'jq:each' : "\\$.each(data, function(index, item) {\n\t\\${child}\n});",
\      'fn' : "(function() {\n\t\\${cursor}\n})();",
\      'tm' : "setTimeout(function() {\n\t\\${cursor}\n}, 100);",
\    },
\    'use_pipe_for_cursor' : 0,
\  },
\  'css' : {
\    'filters' : 'fc',
\    'snippets' : {
\      'box-shadow' : "-webkit-box-shadow: 0 0 0 # 000;\n-moz-box-shadow: 0 0 0 0 # 000;\nbox-shadow: 0 0 0 # 000;",
\    },
\  },
\  'less' : {
\    'filters' : 'fc',
\    'extends' : 'css',
\  },
\}
zen-coding の味噌は如何にして速くコーディングするかなのですが、例えば jQuery を使う html を書く場合に僕は jq<c-y>, とタイプします。すると <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$(function() {
    
})()
</script>
ここまで展開してくれます。関数の中で、インデントされた位置にカーソルがあるので jq:json>jq:eachという式の後に<c-y> とタイプします。すると <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$(function() {
    $.getJSON(""function(data) {
        $.each(data, function(index, item) {
            
        });
    });
})()
</script>
この様に処理をネストして展開してくれます。まぁ、変数名がバッティングしたりするのであまり行儀は良くないけど、3分間ハッキングしたい時には結構使います。

こんな感じに開発は進んでいます。もし欲しい機能などあれば、気軽に github の issues へ登録して下さい。日本語で構いません。コメント欄などでも構いません。
mattn/zencoding-vim - GitHub https://github.com/mattn/zencoding-vim
ZenCoding.vim

vim plugins for HTML and CSS hi-speed coding.

http://mattn.github.com/zencoding-vim
sonictemplate-vim と併用すると、もっと色んな事が出来ると思います。
mattn/sonictemplate-vim - GitHub https://github.com/mattn/sonictemplate-vim
sonictemplate-vim を使うとこんな感じにコーディング出来ます。
faithandbraveさんのサンプルをvimでコーディングしてみた - Gist https://gist.github.com/2717577
ちょっとらしくない緊張からタイプがひどいですが。
Posted at by



2012/06/07


Vimでギャル文字を打てるプラグイン作った。
mattn/gal-vim - GitHub
https://github.com/mattn/gal-vim
例えば :GalOn と実行したあと はまちおにいちゃん とタイプすると レ£маちぉL=L1ちゃh と入力されます。素晴らしいですね!

無効にするには :GalOff とします。また、既に出来上がった文書をギャル文字にしたい人もいるかと思いましたのでGalReplaceコマンドも用意しました。 :%GalReplace と実行すれば文書内が全てギャル文字になります!先日書いた記事
Big Sky :: シャア「Viをやめろと言ったはずだ。それがVimとはな」

シャア 「Viをやめろと言ったはずだ。それがVimとはな」 セイラ 「兄さんこそ、EmacsユーザにまでなってVimmerに復讐しよう      なんてやることが筋違いじゃなくて?」 シャア 「お前の...

http://mattn.kaoriya.net/etc/20120523191833.htm
だとこんな感じになります!
シャ了 「ViщoャめЗ`⊂言ッ十こレ££〃ナ⊇〃。ζяёヵゞVim`⊂l£ナg」
世ィяа 「兄(十w⊇ξ、Ёm@¢δュ⇒廾〃(二маτ〃ナょッτVimmёгI=復讐ιчoぅ
     十ょhzャゐ=`⊂ヵゞ筋違L丶ι〃ゃナg<〒?」
シャァ 「ぉ前σ兄ヵゞξσ程度σ男ナニ〃`⊂思ッτL丶ゑσヵゝ?ァlレ〒ィシァ」
世ィяа 「ぇ?」
シャ了 「Ёm@¢δュ→廾〃レこ十ょッz小キ旨щo鍛ぇτ來十こσм○、小キ旨τ〃遠レ)Ё∫℃‡⇒щo
     キ甲U†ニカヽッ†ニカゝяа+=〃。Uヵゝι十ょ、了|レ〒ィシ了、禾ム+=〃ッ乙ξяёヵゝяа
     少Uレ£因囚丨ニ十ょッ†ニ」

シャ了 「VimmёгщoЁm@¢δュ→廾〃カゞ倒£ナニ〃(ナτ〃レ£〒≠ス┝工〒〃ィタ界σ真σ
     平和レ£得яаяёナgレ丶`⊂悟ッナ=σ†こ〃」
世ィяа 「†ょ世〃?」
シャァ 「Ё¢liρδёσ逆襲ナ=〃」
世ィяа 「Ё¢liρδёカゞ之〒〃ィタ∪〃ゃ十ょ〈IDЁナ⊇〃カ丶яа?」

フ〃яаィ├ 『Ё¢liρδё?』

シャ了 「ぅ£′、ξσЁ¢liρδёщo敵I=£ゑσl£面白<†ょレ丶。今後l£=яёмατ〃
     培ッナ=変態キ支ヵゞイ吏ぇйu、`⊂L丶ぅ⊇`⊂†こ〃」
世ィяа 「IDЁ推進派レ£、Ё¢liρδёl£開発環境全イ本ヵゞ変wαゐ∧〃L≠王里想σIDЁナ⊇〃、`⊂
     教ぇ〒<яё+=ゎ。ナ=〃ッ十こζ、Ё¢liρδёщo敵丨ニ£ゑ必要(£ナgL1(££〃чo」
    「≠ャスノ|〃lレ兄±ω、兄L+hイ可щo考ぇ〒ゐσ?」
シャ了 「мσぅ変態キ支щoイ吏ぇゐ`⊂言ッ+=。了」レ〒ィシァ(£Vimщoイ吏ぅσщo止めЗ」
世ィяа 「Vim?ぁσ変態工テ〃ィタσ=`⊂?」
シャ了 「ぁぁ。∫@κцг@工〒〃ィタ(ニ乗└丿換ぇゐ〈яаレ)σ移行手川頁書レ£残U乙L丶<。
     Щiйdοщδュ→廾〃丨ニナょッz一生щoмαッ`⊂ぅUЗ。禾ムl£мσぅ、
     ぉ前σ知ッτレ丶ゐ兄±wτ〃(£†ょぃ」
世ィяа 「(⊇、兄±w」
シャ了 「vimδ┣┓ёllщoイ吏ッτレ`ゐ言尺カゞwαカ丶ゑ†ょ?禾ムレ£シェ」レщoキ舎τ十こσナニ〃чo」
素晴らしいですね!ぜひご活用下さい!

eskk.vimの様に、仮入力でバッファが変更される様な入力メソッドを使っている場合は誤動作する可能性があります。
Posted at by



2012/06/06


JSX - a faster, safer, easier alternative to JavaScript

faster JSX performs optimization while compiling the source code to JavaScript. The generated code r...

http://jsx.github.com
DeNAさんがマルチデバイス向けに高速なjavascriptを吐き出せる言語を開発。github上でオープンソースで開発されておられます。
僕も何か作りたいー、という事で作ってみた。

画面内をゴキブリが這い回ります。ソースは大丈夫ですが、デモは閲覧注意かもしれません。
import "js/web.jsx";

final class Roach {
    var x : number;
    var y : number;
    var d : number;

    function constructor(x : number, y : number, d : number{
        this.x = x;
        this.y = y;
        this.d = d;
    }

    function move(view : View) : void {
        this.d += (Math.random() * 3as int - 1;
        if (this.d >= 360this.d = 0;
        if (this.d < 0this.d = 359;
        var a = this.d * 2 * 3.141592 / 360.0;
        this.x += Math.cos(a);
        this.y -= Math.sin(a);
        if (this.x < 0this.x = view.width - 1;
        if (this.y < 0this.y = view.height - 1;
        if (this.x >= view.width) this.x = 0;
        if (this.y >= view.height) this.y = 0;
    }

    function render(view : View) : void {
        view.context.drawImage(
            view.images[((this.d * 24 / 360as int)],
            (this.x - 12as int,
            (this.y - 12as int);
    }
}

final class View {
    var width : number;
    var height : number;
    var count : number;
    var context : CanvasRenderingContext2D;
    var roaches = [] : Roach[];
    var images = [] : HTMLCanvasElement[];

    function constructor(canvas : HTMLCanvasElement, count : number{
        this.context = canvas.getContext("2d"as CanvasRenderingContext2D;
        this.width = canvas.width;
        this.height = canvas.height;
        this.count = count;
    }

    function init() : void {
        for (var i = 0; i < this.count; i++) {
            this.roaches[i] = new Roach(
                (Math.random() * this.width) as int,
                (Math.random() * this.height) as int,
                (Math.random() * 360as int);
        }
        var count = 0;
        var loaded = function(e : Event) : void {
            var image = e.target as HTMLImageElement;
            var canvas = dom.createElement("canvas"as HTMLCanvasElement;
            var context = canvas.getContext("2d"as CanvasRenderingContext2D;
            context.drawImage(image, 00);
            this.images[image.dataset["name"] as int] = canvas;
            if(++count == this.images.length) {
                this.start();
            }
        };
        for (var i = 0; i < 24; i++) {
            var image = dom.createElement("img"as HTMLImageElement;
            var index = ("00" + (i * 15as string).slice(-3);
            image.addEventListener("load", loaded);
            image.src = "img/roach" + index + ".gif";
            image.dataset["name"] = i as string;
        }
    }

    function start() : void {
        dom.window.setInterval(function() : void {
            this.update();
        }50);
    }

    function update() : void {
        this.context.fillStyle = "rgb(255, 255, 255)";
        this.context.fillRect(00this.width, this.height);
        for (var i = 0; i < this.roaches.length; i++) {
            this.roaches[i].move(this);
            this.roaches[i].render(this);
        }
    }
}

final class Application {
    static function main(canvasId : string, count : number) : void {
        var canvas = dom.id(canvasId) as HTMLCanvasElement;
        var view = new View(canvas, count);
        view.init();
    }
}
以下に置いてあります。
mattn/jsxroach - GitHub
https://github.com/mattn/jsxroach
型を拘束する事で安全なコードが出力でき、パターンにハマった高速化が見込めるのでしょうね。

そしてデモです。

お食事中の方はご遠慮下さい。
Posted at by