markdown2impress を Guard で監視する guard-markdown2impress

markdown2impress を Guard で監視するだけのものを書いてみた。
hoge.md を保存したタイミングで、markdown2impress.pl が走ります。

$ gem install guard-markdown2impress


markdown2impress 自体は作者の記事で


導入は @glidenote さんの記事が詳しい


markdown2impress すごい便利。
(Guard 使わなくても他に方法もある気もしますが...)

JS リーディング@20120217

今日は社内で毎週開かれている JS リーディングに参加しました。今日の参加者は僕も含めて4人。
今日は The Little Book on CoffeeScript をみんなで読んでみようということになりました。
まぁ本当はこれくらいは一人で週末とかでさくっと読めよ、という話なんですが、わいわい言いながら読むのはまた違う趣があります。


今日は 2.文法 のフローコントロールの最後まで読みました。
該当の箇所を読めば全部分かるので、書くほどでもないですが、気になったところをいくつか。

  • コメント
    • 一行のコメントは生成された JS には残らない。複数行のコメントは残る
  • Coffee は空白 (インデント) に意味を持つ (Python のように)
  • 変数とスコープ
    • JavaScript GoodParts で推奨されていたような、全て var 宣言された変数が生成された一番上に列挙される
    • グローバル変数は基本的には作られない
      • グローバル変数を使いたい場合は Window オブジェクトのプロパティとして代入するか、以下のようなイディオムで使う
exports = this
exports.MyVariable = "foo-bar"
  • 関数
    • -> が function
func = -> "bar" // は以下のようになる

var func;
func = function() {
      return "bar";
};
-> "bar" // で無名関数

(function() {
      return "bar";
});
  • 関数引数
times = (a, b) -> a * b 
times = (a = 1, b = 2) -> a * b // デフォルト引数が持てる。通常の JS ではできない。
# でも生成される JS は泥臭いですね^^
var times;
times = function(a, b) {
  if (a == null) {
    a = 1;
  }
  if (b == null) {
    b = 2;
  }
  return a * b;
};
    • 可変長引数は ... (スプラットと読むらしい、知らなかった) で表現できる
sum = (nums...) ->
  result = 0
  nums.forEach (n) -> result += n
  result
    • これは以下のように生成される
var sum;
var __slice = Array.prototype.slice;
sum = function() {
  var nums, result;
  nums = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  result = 0;
  nums.forEach(function(n) {
    return result += n;
  });
  return result;
};
  • __slice (__*) は coffee の予約語になり宣言できない
    • Array.prototype.slice を なぜ __slice に一度いれなければいけないかは分からなかった
      • __ でメソッドを定義して、生成する感じ、utility 関数的に宣言を行って可読性をあげるため?
    • nums = 1 <= arguments.length ? __slice.call(arguments, 0) : []; で arguments オブジェクトではなく、本物の配列として扱う
  • 関数の実行
    • 以下3つはすべて同じ。最低でも一番下の例のような inspect の実行には括弧を付けることを推奨
alert inspect a
alert(inspect(a))
alert inspect(a)
  • 関数コンテキスト
    • => (ファットアロー) を使うことで、関数のコンテキスト (this) をローカルに紐付けることが可能になる
this.clickHandler = -> alert "clicked"
element.addEventListener "click", (e) => this.clickHandler(e)

// 上の例は以下のように出力されるとあるが
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
this.clickHandler = function() {
  return alert("clicked");
};
element.addEventListener("click", __bind(function(e) {
  return this.clickHandler(e);
}, this));

// http://coffeescript.org/ で試すと、出力される結果が異なる __bind を出さなくなった?
var _this = this;

this.clickHandler = function() {
  return alert("clicked");
};

element.addEventListener("click", function(e) {
  return _this.clickHandler(e);
});
  • CoffeeScriptを使うべきか、使わざるべきか? - にのせき日記 でもファットアロウについて言及があるが、もし jQuery を使っているなら $.proxy を普通に使うことも可能
  • オブジェクトの構文と配列の定義
    • 中括弧なしで書ける。User.create(name: "John Smith") これはいい。
    • 配列はインデントをカンマの区切りとして使える。Ruby の %w のような。
  • フローコントロール
    • 三項演算子はなくて、if 1 > 0 then "Ok" else "Y2K!" if/else 文を使う必要がある
      • Python2.5 からの記法とちょっと似てる A = Y if X else Z
a = if foo then "bar" else "baz" # が以下のようになる

var a;
a = foo ? "bar" : "baz";

a = foo ? "bar" : "baz" // 三項演算子を上のように coffee で書くとは以下のように出力される
a = typeof foo !== "undefined" && foo !== null ? foo : {
  "bar": "baz"
};
  • 後置演算子や unless もある
    • == と Coffee で書くと === に変換される
      • != も !== になる
        • JS で書かれたスクリプトを Coffee に変換する時は、== で書いてても、=== になる? バグがでそう

dotcloud + S3 でバックアップのメモ

dotcloud で DB (MySQL) のバックアップを取らないとなーと思ってて、試したらすぐできた。


ドキュメントがすごい分かりやすい。

  • dotcloud では簡単なバックアップスクリプトを用意している
  • バックアップスクリプトMySQL, PostgreSQL, Riak (はじめて聞いた), data (通常のファイルを tar で固める) に対応していて、それぞれ FTP, SSH 経由でどこかのサーバへ送るかもしくは Amazon S3 へと送信することが可能


FTPSSH でもいいけど S3 をまだ使ったことなかったので使ってみる。
S3 でアカウントを取って、コンパネの使い方が分からなくて迷ってたけど、
My Account / Console -> Security Credentials で
Access Key ID と Secret Access Key を確認する。


あとはドキュメントの通りやっていけば何も迷わずできた。


cron の記述で、

dotcloud@ramen-default-sql-0:~$ crontab - <<EOF
MAILTO=""
$[$RANDOM%60] $[$RANDOM%24] * * * ~/backup.sh mysql ftp ramenbackups:chowmein@ftp.noodles.com 2>&1 | mail -s "Backup result for $HOSTNAME" cook@noodles.com
EOF


見たことない、$[$RANDOM%60] みたいな書き方があって、これはどういうことになるんだ、と思ったけど、
ちゃんと説明してあって、

Using the previous recipe, your backups will run once per day. To avoid everyone starting their backups at the same time, the recipe uses a little trick: the exact time of the backup will be randomly chosen when you create the crontab. Your backup will always be started at this same time, until you modify the crontab, of course.
If you want to check which time was scheduled for your backups, just do “crontab -l”. The minute and hour of the backups are the two numbers in front of the three asterisks.
If want your backups to occur at a fixed time, or at different frequencies, feel free to adapt the crontab.


ここに設定するタイミングで、ランダムで数字が決定されて、それによって、
cron の設定時間が集中することを避けることが目的のようだ。
feel free to adapt the crontab. とあって、もちろん自分で cron の時間は好きに設定できるんだけど、
提供側として、デフォルトの案内をランダムにしとく、という発想は面白いと思った。
僕もとりあえずランダムで出た数字のままにしといたけど、意外と効果あるのかもしれないなー。


あとはちゃんと送信できていて、S3 側で、保存期間を過ぎると自動削除することができるみたいなので
バックアップは完了。素晴らしいなー。(dotcloud も S3も)

rails3 + dotcloud + Travis CI の設定メモ

dotcloudで遊んでみた - Kentaro Kuribayashi's blog

あらかじめ本番用設定ファイルを$HOME/etcに置く手間がかかるけど、ソースをgithubにおきつつ、秘密のファイルを.gitignoreで守りつつ、dotcloudにもちゃんとdeployできるようになった。手間については、deployment.ymlを更新するtaskを定義してやれば済む話なので、まあどうにかなることではありそう。


上記記事を参考にして、github でソースを管理しつつ、dotcloud にデプロイできるようになった。
https://github.com/banyan/Vimpusher/blob/master/postinstall
(今はもうちょっといい方法あるのかな)


続けて Travis CI を設定しようと思ったけど、
config/database.yml などのファイルが存在しないため、
Travis CI で rails の起動がこけてしまう。


Travis CI の before / after の hook はどうすればいいかなと思って
Travis CI 本体のリポジトリを見たら設定してあった。
https://github.com/travis-ci/travis-ci/blob/master/.travis.yml
そしてちゃんと Document も存在してた。
http://about.travis-ci.org/docs/user/build-configuration/

before_install, after_install

You can also define scripts to be run before and after the dependency installation script:

before_install: some_command
after_install:  another_command


.travis.yml はこんな感じになりました。
https://github.com/banyan/Vimpusher/blob/master/.travis.yml


database.yml は

MySQL on Travis binds to 0.0.0.0 and requires no authentication. Specify an empty username and no password:

ということで、username と password を空にして localhost に接続するようにしてうまく Travis CI で動いた。

Vimpusher という Web サービスをリリースしました

明けましておめでとうございます。これは Vim Advent Calendar 2011 の35日目の記事です。


Vim Advent Calendar 2011 に参加するにあたって、Vimpusher という Web サービスを作ってみました。



これは何か


元々、http://vimpi.net/ という Web サービスがあって、
僕はこのサイトを昔知ったときに心が踊りました。
Vimpi は Vimプラグインwatch するというコンセプトで作られていました。


Vimpusher は基本的には同じなのですが、
自動で自分の使っているプラグインが更新されたらいいな、と思って作ってみました。


@masudaK さんも Vimと親しくなるある「キッカケ」と、それからの付き合い方について - カイワレの大冒険 Third で言われてますが、最近は github で .vimrc (dotfiles) を管理されている方も多いと思います。


また vundle, neobundle, pathogen などのプラグインマネージャーがでてきたことで、
プラグインの管理が以前と比べて格段に楽になりました。

  1. このサービスは、どこか public な場所に .vimrc を公開していて (github とか)
  2. pathogen, vundle, neobundle, pathogen などのプラグインマネージャーを使っている人


を対象にした非常にニッチなサービスなのですが、
Vimpusher で .vimrc を登録しておけば、毎日 (か適当なタイミングで) クロールして、
人気のあるプラグインが分かるようになることを目論んでいます。


ということでもし上記条件にあてはまる方は登録して頂けるとありがたいです。


Vimpusher という名前


pusher とは麻薬の密売人みたいな意味があるということで
vim のヤバいプラグインが分かるような意味でつけてみました


間に合わなかった機能


本当はいろんなことを考えてて、

  • 使い始めたけど、使うのをやめたプラグインの可視化
    • プラグイン自体の利用数が減るのが分かったりする
      • グラフ
  • follow とかできて、気になる人が使い始めた新しいプラグインが分かる
      • github 的なタイムラインとか
  • coderwall 的な何か


はい、全然間に合いませんでした。
あと、基本的なページングとかも実装されてないので、
本当にとりあえずできたっていう感じです。


作りはじめて気づいた仕様


Vim Scripts というサイトが vim.org で公開されているプラグインの mirror を
github に作っているのですが、これがあるおかげで、github

Bundle 'FuzzyFinder' 


とか githubリポジトリがなくてもインストールできるのですが、
逆にこれが理由で、オリジナルの URL が2個存在することになります。


例えば、https://github.com/tpope/vim-rails が開発中の最新のリポジトリで、
https://github.com/vim-scripts/rails.vim はミラーですが、
これが同じものを指すということをプラグラムで自動的にするのは難しく
今のところこれは別のプラグインということになっています。


ただ、グループという概念をいれて、
https://github.com/tpope/vim-railshttp://github.com/vim-scripts/rails.vim に紐づくよ
ということをできるように考えました。(まだ UI は実装してないのでひもづけることはできません)


例えば、https://github.com/Shougo/neocomplcache とミラーでは、最新版を見てるかどうか
という違いはあるので、これは別のものと考えてもいいのかもしれませんが、
とりあえず時間的に間に合わなかったので、あとで考えることにしました。


コード

言い訳


本当に時間がなくて、最後 HTML とかインラインで CSS がりがり書いたりして、
テストも書けてない箇所が多く、そこは残念です。


ただこういう機会がないと一応リリースまでも持っていけなかったと思うので、
末端 vimmer である僕に機会を与えてもらってありがたいです。


粛々ときれい直していきたいなーと思っておりますので、
バグとか、何か要望等ありましたら @banyan か github のほうで連絡頂ければと思います。

tmux で複数のセッションを移動する

この記事は ターミナルマルチプレクサ Advent Calendar 2011 : ATND の9日目です。
8日目は、matsuu さんの tmuxで複数のペインに対して一斉に同じ文字を入力する - Dマイナー志向 でした。


今日は tmux で複数のセッションを移動するための switch-client というコマンドの紹介です。

switch-client [-lnp] [-c target-client] [-t target-session]
(alias: switchc)
Switch the current session for client target-client to target-session. If -l, -n or -p is used, the client is moved to the last, next or previous
session respectively.

:ls
0: 15 windows (created Tue Dec  6 22:49:51 2011) [181x59]
1: 3 windows (created Wed Dec  7 00:54:51 2011) [181x59]
2: 1 windows (created Wed Dec  7 02:03:36 2011) [181x59]
3: 4 windows (created Wed Dec  7 02:03:47 2011) [181x59]


こんな感じのセッションがある時に、switch-client を使うとセッション間での移動が可能になります。

:switch-client -t n # 移動したい session の番号
:switch-client -l   # 最後の (直前に選択されていた) セッションへ移動します。
:switch-client -n   # セッションを次のセッションへ移動します。
:switch-client -p   # セッションを前のセッションへ移動します。


CHANGES を見ると、tmux 0.1 の頃から、switch-client はあったようです。

16 November 2007

略... 
* (nicm) switch-client command to switch client between different sessions. This
  is pretty cool:

    $ tmux bind q switch 0
    $ tmux bind w switch 1

  Then you can switch between sessions 0 and 1 with a key :-).


そして tmux 1.4 から switch-client に -[lnp] オプションが追加されたので
セッションの選択が番号を意識せずに、移動しやすくなりました。

bind-key          ( switch-client -p
bind-key          ) switch-client -n
bind-key          L switch-client -l


デフォルトのキーバインド (tmux 1.5) は↑ですが、
僕は下のような設定にしています。

bind-key N switch-client -n
bind-key P switch-client -p


session がこんなに簡単に切り替えられると、夢が広がります。*1
window 開きすぎ症候群の人や、session を手塩にかけて大切に育てる人には便利になると思います!

*1:screen にはこれと同じようなコマンドはあるのでしょうか?

tmux で main-vertical / main-horizontal で layout を変更と同時にカレント(アクティブ)のペインを main のペインにしたい

これはターミナルマルチプレクサ Advent Calendar の4日目です。
ターミナルマルチプレクサ Advent Calendar 2011 : ATND
今日は tmux の小ネタです。


したいこと

  • tmux で main-vertical / main-horizontal で layout を変更と同時にカレント(アクティブ)のペインを main のペインにしたい*1


例えば以下のような layout の pane2 で作業をしている時に、
横方向で広いレイアウトで作業をしたくなったと仮定します。



通常であれば、

:select-layout main-horizontal

とした後に、:swap-pane や :select-pane を使いながら任意の場所に移動すると思います。
ですが、これを行うのは、脳に負担がかかり健康によくありません。


解決策

bind -r H select-layout main-vertical \; swap-pane -s : -t 0 \; select-pane -t 0 \; resize-pane -R 9
bind -r K select-layout main-horizontal \; swap-pane -s : -t 0 \; select-pane -t 0 \; resize-pane -D 18


これを ~/.tmux.conf に書きます。 *2


この動作自体は tmux では設定ができないため、マルチコマンドを利用します。
tmux ではマルチコマンドがセミコロンでつなげることで、設定できます。

Multiple commands may be specified together as part of a command sequence. Each command should be separated by spaces and a semicolon; commands are executed
sequentially from left to right. A literal semicolon may be included by escaping it with a backslash (for example, when specifying a command sequence to
bind-key).

keybind + H
keybind + K 



これで main-vertical / main-horizontal で layout を変更と同時にカレント(アクティブ)のペインを main のペインにすることが可能となりました。*3
もしもっといい方法や他の方法がある方は教えて頂けると嬉しいです。

*1:vim の window-moving での "CTRL-W H" と "CTRL-W K" と同じようなイメージです

*2:resize-pane の幅はモニタのサイズなどもあるため、適宜好みの幅にします

*3:なぜ J と L がないかというと、main-vertical / main-horizontal で右と下がメインのレイアウト変更がないため、そうしています。