数式とソースコードのテスト

はてなブログで MathJax を埋め込んでみて、きちんと数式が出るかのテスト。

積分 $$ I = \int _{-\infty} ^ {\infty} e ^ {-x^2} dx $$ の値を求めよう。 $ xy $ 平面上で円形にそって全範囲を積分することを考えると $$ I^2 = \left( \int _{\infty} ^{\infty} e ^ {-x^2} dx \right) ^2 = \int _{\infty} ^{\infty} \int _{-\infty} ^{\infty} e ^ {-(x^2+y^2)} dx dy $$ である。曲座標変換 $ x = r \cos \theta, y = r \sin \theta $ とすると $$ I^2 = \int _0 ^{2\pi} \int _0 ^{\infty} e ^ {-r^2} r dr d\theta = 2 \pi \int _0 ^{\infty} r e ^ {-r^2} dr = 2 \pi \left[ - \frac{1}{2} e ^ {-r^2} \right] _0 ^{\infty} = \pi $$ となるので、 $ I > 0 $ より $$ I = \sqrt{\pi} $$ となる。

ソースコードがきちんとハイライトされるかのテスト。

import Control.Applicative ((<$>))

main = do
  n <- (read :: String -> Int) <$> getLine
  print $ n * n
#include <iostream>
using namespace std;
int main() {
  cout << "Hello from Hatena Blog" << endl;
  return 0;
}

どちらも問題なさそう。 MathJax はエスケープめんどいけど、普通に使うのと変わらんからいいか。

submodule を含む Git リポジトリからファイルをエクスポート

  1. git-submodule の使いかた
  2. Git リポジトリからファイルをエクスポートする
  3. submodule を含む Git リポジトリからファイルをエクスポートする

この3点のメモ
Git には submodule という機能があり、あるリポジトリの下に別のリポジトリを置くことができる。

$ cd some-repository
$ git submodule add git://example.com/hoge.git hoge

のようにすると、 some-repository/hoge に git://example.com/hoge.git をクローンすることができ、 some-repository は hoge 以下のファイルを直接管理はしない。
hoge リポジトリは some-repository とは別の独立したリポジトリのような感じになるので、そこ以下で編集したり commit/pull/push など通常のリポジトリと同様に扱える。
一度 submodule add してしまえば hoge リポジトリをいじった後 some-repository 側で特に操作の必要はない。嘘っぽい。 hoge リポジトリをいじった後 some-repository 側で add, commit が必要みたい。
ちなみに別のマシンからこのリポジトリを使うときは、

$ git clone git://example.com/some-repository.git
$ cd some-repository
$ git submodule init
$ git submodule update

とすれば全ての submodule を同期できる。
で、今回 submodule 付きの Git リポジトリからファイルをエクスポートする必要が出てきた。
普通の Git リポジトリであれば、ファイルのエクスポートは

$ git checkout-index -a -f --prefix=/path/to/export-dir/

のようにすることでできる。このとき /path/to/export-dir/ の最後の / を忘れると悲惨なことになるので注意。
submodule 付きのリポジトリの場合、こうするだけでは submodule で管理されているリポジトリはエクスポートしてくれなかった。
なので、各 submodule ディレクトリ以下にコマンドを実行できる git-submodule foreach を使ってすべての submodule リポジトリに対して git-checkout-index を実行する。

$ cd some-repository
$ git submodule foreach 'git checkout-index -a -f --prefix=`pwd | sed -e "s:/path/to/some-repository/:/path/to/export-dir/:g"`/'

これでok

zsh の menuselect 中に case-insensitive なインクリメンタルサーチをする

ちょっと zsh をカスタマイズしていたら止まらなくなってしまって、気に入らない挙動が出てきてしまったので自分でパッチを書いたという話。
zsh の機能で menuselect

zstyle ':completion:*:default' menu select=2

を設定している人も多いと多いと思うのだけれど、この場面で C-s または C-r を押すことでインクリメンタルサーチができる。
しかしこのとき case sensitive な検索しかできないのがどうにも我慢がならない。
C-s のときのコマンドが

history-incremental-search-forward

であることまでを突き止め、それで検索しまくったのだけど、

The search is case-insensitive if the search string does not have uppercase letters and no numeric argument was given.

http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html

と書いてあるくせに menuselect の中ではそうでないらしい。
ぐぬぬ・・
で、仕方ないから自分でソースをいじることにした。
できたパッチが https://gist.github.com/1926791/e29ded0cb38ca88845649ef47579a2ce5d0a3fd7
Src/Zle/complist.c 内で strstr で一致を探していたのが悪く、大文字小文字を区別しない strstri を定義してこれを使うことにした。
(ちなみに本当の履歴のインクリメンタルサーチは Src/Zle/zle_hist.c 内の zlinecmp という関数を使っていて、今回もそれを使おうと思ったのだけどなんかうまくいかなかった。誰かいい実装できたら教えてください。)
このパッチを Homebrew なんかから使うときは

$ brew edit zsh

として、

def install

の上の行あたりに

def patches
  p = []
  p << "https://raw.github.com/gist/1926791"
  return p
end

と書いて

$ brew install zsh

すればよい。
ちなみに menuselect のとき、コマンド実行までに2回エンターを押さなければいけないことが我慢できない人も多いと思うのだけど、

bindkey -M menuselect '^M' .accept-line
# (^M は quoted-insert)

のようにすることで1回でコマンドを実行できるようになる。これもっと早く知りたかったなあ。 (http://www.zsh.org/mla/users/2009/msg01018.html)

Samba で Windows とディレクトリ共有

VMware 内で Arch Linux を飼っているのだけれど、 Linux カーネルのバージョンが上がるたびに open-vm-toolsディレクトリ共有機能がうまく動かなくなるのにいつも悩んでいた。
のでいっそのこと Samba を使ってディレクトリ共有することにした、メモ。
まず必要なものをインストール

$ sudo pacman -S samba

これだけだっけ? もう覚えてない・・
次にマウントポイントを作る

$ sudo mkdir -p /mnt/windows

で、 /etc/fstab 編集

//Windows/Users/Name /mnt/windows cifs credentials=/etc/fstab.windows,codepage=cp932,iocharset=utf8,uid=Name,gid=wheel,defaults 0 0

こんな感じにするとうまくいった。WindowsWindows 側のマシン名、 Name は Windows 側のユーザー名。詳しいオプションなんかは http://ikdlab.k.hosei.ac.jp/~todoroki/todowiki/index.php?samba#lbb88b7d とか見た。
マウントオプションにユーザー名とパスワードを書かなきゃいけないんだけど、ここに書くのは嫌なので credentials というオプションで外部ファイルを指定できるらしい。
/etc/fstab.windows の内容は以下。

username=Name
password=Pass

さらに

$ sudo chown root:root /etc/fstab.windows
$ sudo chmod 400 /etc/fstab.windows

で root 以外から読めないようにします。
ここまでできたら再起動してきちんとマウントできていることを確認
で、あとはホームあたりにアクセスしやすいようにシンボリックリンクを張っておきます

$ ln -s /mnt/windows $HOME/windows

これで完了。

[Emacs]linum-modeを軽くする

最近妙に Cocoa Emacs が重いなあと思っていたのだけれど、 linum-mode が原因のようで、こいつを切ると見違えたように軽くなった。
でもさすがに行番号がないのは寂しい。同じようなインターフェイスの wb-line-number はちょっと使ってみたけどいろいろダメだし。
どうするか・・
しょうがないのでソースを見ることに。

(define-minor-mode linum-mode
  "Toggle display of line numbers in the left marginal area."
  :lighter ""                           ; for desktop.el
  (if linum-mode
      (progn
        (if linum-eager
            (add-hook 'post-command-hook (if linum-delay
                                             'linum-schedule
                                           'linum-update-current) nil t)
          (add-hook 'after-change-functions 'linum-after-change nil t))
        (add-hook 'window-scroll-functions 'linum-after-scroll nil t)
        ;; mistake in Emacs: window-size-change-functions cannot be local
        (add-hook 'window-size-change-functions 'linum-after-size)
        (add-hook 'change-major-mode-hook 'linum-delete-overlays nil t)
        (add-hook 'window-configuration-change-hook
                  'linum-after-config nil t)
        (linum-update-current))
    (remove-hook 'post-command-hook 'linum-update-current t)
    (remove-hook 'post-command-hook 'linum-schedule t)
    (remove-hook 'window-size-change-functions 'linum-after-size)
    (remove-hook 'window-scroll-functions 'linum-after-scroll t)
    (remove-hook 'after-change-functions 'linum-after-change t)
    (remove-hook 'window-configuration-change-hook 'linum-after-config t)
    (remove-hook 'change-major-mode-hook 'linum-delete-overlays t)
    (linum-delete-overlays)))

すると、 add-hook の嵐。これじゃ重くて当然。
うーん。どれか削れるものはないか。

post-command-hook

前のコマンドを逐一見ているこいつが明らかに一番重い。作者もそれをわかっているのか

(if linum-delay
    'linum-schedule
  'linum-update-current)

のようにして、遅延を入れられるようにしているっぽい。で、 linum-delay という変数を見てみたがこれは単なる真理値。
問題は linum-schedule のほうで、こいつを見てみると

(defun linum-schedule ()
  ;; schedule an update; the delay gives Emacs a chance for display changes
  (run-with-idle-timer 0 nil #'linum-update-current))

このようになっているが、これって意味あるのか? 0 秒アイドル後に実行って、タイマー設定しないのと同じでは。
なのでここを適当な 0 でない値に変更することで遅延を入れられるはず。
ただ私の主義としてこういう場合は advice を定義したいので、結局

(setq linum-delay t)
(defadvice linum-schedule (around my-linum-schedule () activate)
  (run-with-idle-timer 0.2 nil #'linum-update-current))

この3行を .emacs に追記することで linum-mode が軽くなった。
ファイル編集中最後の行に追記したりすると表示がちょっと遅れるけど、これは大した問題ではないはず。