2012-04-01
zaw.zshでtmuxのウインドウを選択したい
こちらに tmux + irssi + canything で Anything 風チャンネル切り替えする - unknownplace.org http://unknownplace.org/memo/2012/03/26/1/ に触発されました!いつも参考にさしていただいております、有難や〜 <(__)>
これまで普段GNU Screenを使わしてもらってきたのだけれども、
一念発起してtmuxも使うようにします!
どちらもあんまり使いこなせわしませんけれども、どうぞよろしくおねがいいたします。
さて表題のtmuxのウインドウの絞り込みについて。
gistはコチラ
git://gist.github.com/2266172.git
https://gist.github.com/2266172
外部コマンドにしておきたかったのと、絞り込みはzawでやりたいなと思っていたので、zaw付属のzaw-launcher.zshでやってみました。こんな感じです。
使い方です。
- $fpath に zaw をクローンしたディレクトリを追加します;
- $fpath に zaw の設定ファイルを置いたディレクトリを追加します;
- $fpath においた zaw というファイルで zaw の設定をします。
$fpath への追加は ~/.zshenv でやっています。こんな感じ。
fpath+=/c/zaw # zaw をクローンしたディレクトリ fpath+=~/.zsh.d/zfunc # zaw の設定ファイルを置いたディレクトリ
上の zaw の設定ファイルのサンプルは、
% zsh my-tmux-zaw show-zaw-config-sample
と打つと出力されます。シェルの起動が少しでも速くなるようにzawは必要になったら読み込む設定にするようにしているためこんなことになっちゃっています、ごめんなさい。
~/.zshrcには
autoload -Uz zaw; zle -N zaw
と書いてます。
実行例です。
% zsh ~/.tmux.d/my-tmux-zaw.zsh ... とやると、選択できるようになります。
コマンドラインから分割したい場合にはこうなります。
% command tmux split-window "zsh ~/.tmux.d/my-tmux-zaw.zsh"
bind b if-shell \ "zsh ~/.tmux.d/my-tmux-zaw.zsh dispatch new-window" \ refresh-client bind B split-window "zsh ~/.tmux.d/my-tmux-zaw.zsh"
上の場合、プレフィックスキーに続けて'b'で、新しいウインドウで選択できるようにしていて、'B'で分割するようにしています。
if-shell〜refresh-clientの所が苦しい所なのだけれども我慢…windowを新しく作る前の値を取っておきたくってこんなことをしています。
さて、
どうしてzawでやりたかったのかしらん、ということのメモ。
ウインドウを切り換えようとして一覧を表示したものの、候補を選択している間に気が変わって、やっぱり分割にしたい、等という時もあるかもしれない気がしていました。
そうすると、アクションの選択もanything.elっぽくするのに楽ちんかもしれないような気がしたためです。
もう一つ、zawは縦方向へコンパクトに表示することができる所が好きです。
最後の一つ、zawでtmuxというのは見つけられなかった…
と…完全に趣味の世界です(^^;;
screenもそうだけれど、tmux、これから長い付き合いになりそうだ、どうぞよろしく!
2011-11-07
zargsの補完を自分好みに
zargsの補完は関数_zargsで行われているのだけれども、コマンドの位置でそのコマンドの補完関数が呼ばれないので、ちょっと悲しい。例えば、
% zargs * -- ls -
ここで、ls用の補完がなされません。
そこでわーっと書いてみてできあがったのがこちら。なんだか予想外に長くなっちゃった(^^;
https://gist.github.com/1345186
git://gist.github.com/1345186.git
注意点です。
値をオプショナルで取る引数の扱いをサボッています。常に指定されるものとして動作します、ごめんなさいm(__)m
例えば、'zargs --replace'ときたらば、本来'--replace'は値がオプショナルなのですけれども、入力をうながすように動作します。
今のところのmy-zargsおよびtコマンドが以下です。
#autoload local replace='{}' (( ${@[$@[(I)--],-1][(I)$replace]} )) && \ set -- -I$replace $@ ; set -- zargs $@ $@
ここでコマンドが指定されていなかったらばパラメータへ足す、というようにした方が良かったんじゃないのかな〜とも思っています。
2011-10-31
写経(その9)
『Lisp in Small Pieces』より
This nightmare won't keep us awake, however, since there is no comuter in the world that actually works with no side effects.
冒頭のmin-max、練習問題の写経、およびそのバリエーション。
;; minmax (define (firstnumber? tree) (if (pair? tree) (firstnumber? (car tree)) tree)) (define (minmax tree) (let* ((mi (firstnumber? tree)) (ma mi)) (define (scan! tree) (cond ((pair? tree) (scan! (car tree)) (scan! (cdr tree))) (else (if (> tree ma) (set! ma tree) (if (< tree mi) (set! mi tree)))))) (scan! tree) (list mi ma))) (minmax '((2 . 3) (1 . (-1 . 10)) . (8 . 6))) (define (minmax tree) (define (rec tree) (if (pair? tree) (let ((a (rec (car tree))) (d (rec (cdr tree)))) (list (min (car a) (car d)) (max (cadr a) (cadr d)))) (list tree tree))) (rec tree)) (minmax '((2 . 3) (1 . (-1 . 10)) . (8 . 6))) (define (minmax tree) (define (rec tree k) (if (pair? tree) (rec (car tree) (^[mina maxa] (rec (cdr tree) (^[mind maxd] (k (min mina mind) (max maxa maxd)))))) (k tree tree))) (rec tree list)) (minmax '((2 . 3) (1 . (-1 . 10)) . (8 . 6))) (define (minmax tree) (define (iter mi ma left right) (if (pair? left) (iter mi ma (car left) (cons (cdr left) right)) (let ((min1 (min left mi)) (max1 (max left ma))) (if (pair? right) (iter min1 max1 (car right) (cdr right)) (list (min right min1) (max right max1)))))) (let1 n (firstnumber? tree) (iter n n (car tree) (cdr tree)))) (minmax '((2 . 3) (1 . (-1 . 10)) . (8 . 6)))
この後出てくるインタプリタは継続渡しスタイルで書かれるので、それの予習というわけでさらにシンプルな3つを練習。
(define (fact n) (if (zero? n) 1 (* n (fact (- n 1))))) (fact 4) (define (fact n k) (if (zero? n) (k 1) (fact (- n 1) (^x (k (* n x)))))) (fact 4 values) (define (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) (fib 8) (define (fib n k) (if (< n 2) (k n) (fib (- n 1) (^x (fib (- n 2) (^y (k (+ x y)))))))) (fib 8 values) (define (count-leaf tree) (if (pair? tree) (+ (count-leaf (car tree)) (count-leaf (cdr tree))) 1)) (count-leaf '((a . b) ((c . d) (e . f)) (g . h) . ())) (define (count-leaf tree k) (if (pair? tree) (count-leaf (car tree) (^l (count-leaf (cdr tree) (^r (k (+ l r)))))) (k 1))) (count-leaf '((a . b) ((c . d) (e . f)) (g . h) . ()) values)
継続渡しスタイルで書かれているコードは、それが十分に小さくっても脳みそひっくり返るんだけれども、何回も書いたり凝視たりしているうちにふとある時腑に落ちて、自分でも新たに書くことができるはずと思うに至りました。
関連する記事はコチラ。
2011-10-28
debianで私家版窓使いの憂鬱Linux&Mac(Darwin)対応版とDvorak配列
窓使いの憂鬱いつも使わしてもらっております。大変感謝〜。
debianでmayuを使ってDvorak配列にして使っています。debian上の設定ではQWERTY配列にしていて、その上にmayuの設定でDvorak配列へとカスタマイズしているという状態です。mayuを停止させちゃうとQWERTY配列になっちゃう。このことです。
さて、mayuが動いていない時でDvorak配列にしたいのが、
GRUB、起動直後のdm_cryptのパスフレーズの入力、シングルユーザーモード時、そして、当然ですけれどもmayuを止めた時。このあたりの局面で陽にDvorak配列にするような記録です。
まず最初に/etc/default/keyboardの内容を変更します。
mayuはdebian上の設定ではQWERTY配列にした上で設定しているので、おそらくインストール時に選択されたであろうDvorak配列から変更します。
Xなりudevなりでこのファイルを見ないようにすれば良いのかな…とも思うのだけれどもよくわかんない…
/etc/default/keyboardを編集する前に、それに必要になるファイルを作成します。
まず、コンソールで使う用(/etc/default/keyboard.us.dvorak)
XKBMODEL="pc101" XKBLAYOUT="dvorak" XKBVARIANT="" XKBOPTIONS="ctrl:nocaps,compose:rctrl" BACKSPACE="guess"
これは多分インストール直後の/etc/default/keybordと同じになることと思う。
mayu実行中に使う用(/etc/default/keyboard.mayu)
XKBMODEL="pc101" XKBLAYOUT="us" XKBVARIANT="" XKBOPTIONS="ctrl:nocaps,compose:rctrl" BACKSPACE="guess"
これ自体はQWERTY配列なんだけれども、mayuの設定はこの上でmayuでDvorak配列へとカスタマイズしたいのです。なんか何度も書いちゃっている…
/etc/default/keyboard.{mayu,us.dvorak}を作ったらば、それぞれ/etc/console-setup/cached_*.kmap.gzファイルを作成します。LANGは環境に合わせる必要があると思います。
% zargs -I{} {mayu,us.dvorak} -- print echo -n '''saving kmap {}...''' \; sudo sh -c '''LANG=C setupcon -k --save-only {}''' \&\& echo done.|sh
saving kmap mayu...done.
saving kmap us.dvorak...done.
これで/etc/default/keyboardファイルを編集できます。
/etc/default/keyboardは以下のように、KMAPに今作ったus.dvorakを指定してあげます。
ここでKMAPで指定されたのはmayuが止まっている時に有効になるキーマップ
/etc/default/keyboardを以下のようにしました。
XKBMODEL="pc101" XKBLAYOUT="us" XKBVARIANT="" XKBOPTIONS="ctrl:nocaps,compose:rctrl" KMAP=/etc/console-setup/cached_ISO-8859-1_del.us.dvorak.kmap.gz BACKSPACE="guess"
これもkmap.gzを作成します。
% sudo setupcon -k --save-only
mayuの起動、終了。
runitを使っている場合、mayuのrunスクリプトでキーボードをmayu用にQWERTY配列にした後にmayuを実行するようにして、finishスクリプトで元に戻す。
例えばこんな具合です。
run
#!/bin/sh # echo $HOST > env/HOST # echo $HOME > env/HOME exec 2>&1 (setupcon --force -k mayu 3>&2 2>&1 1>&3) | read dummyerrorout && return -1 exec env - \ PATH="/opt/mayu/bin:$PATH" \ envdir ./env sh -c ' exec mayu -D$HOST -v '
- D$HOSTとしているのはマシン毎(…つながっているキーボード毎のが正確です)にちょっと変更したい部分があるため分岐できるようにしています。
finish
#!/bin/sh exec 2>&1 setupcon --force -k us.dvorak
これがやりたいがためだけに長い間使わしてもらってきたdaemontoolsを止めた(^^;
今までありがとうありがとう。こんにちわrunit、こんにちわこんにちわ。
さて、次に起動時のパスフレーズの入力について
initrdが必要なようにしてdm_cryptを使っています。
起動直後は、initrd.imgの中に入っている/etc/boottime.kmap.gzをlaodkeysするようなスクリプトになっている(/usr/share/initramfs-tools/scripts/init-top/keymap)。
そこで、/etc/console/boottime.kmap.gzを用意して(/usr/share/initramfs-tools/hooks/keymap)、initrd.imgの中に放り込んでもらいます。
% sudo sh -c '(cd /etc/console && ln -s ../console-setup/cached_UTF-8_del.us.dvorak.kmap.gz boottime.kmap.gz)' % print -z sudo update-initramfs -v -u -k $(uname -r) % sudo update-initramfs -v -u -k 3.0.6-ck1
/etc/console/boottime.kmap.gzは
/etc/console-setup/cached.kmap.gzでも良いみたい。
最後、GRUB2
とってもありがたいことにキーボード配列は自由にカスタマクズできるようになっていて、更に幸いにも、こちらなんかぁゃιぃ日記(2011-08-02)でその手順を公開されておられます。参考にさせていただきます。ありがとうございますm(__)m
GRUB用にレイアウトファイルを用意して、それを使うようにすればよい、ということです、以下のようにしました。
% sudo mkdir /boot/grub/layouts % (cd /tmp && grub-kbdcomp dvorak && sudo mv dvorak.gkb /boot/grub/layouts/) % (cat << EOF terminal_input at_keyboard keymap dvorak EOF ) | sudo sh -c 'cat -> /boot/grub/custom.cfg'
debianのgrubのデフォルトのままだとterminal_inputがconsoleだったので、$prefx/custom.cfgでterminal_inputが設定されるようにしました。また、GRUBの$prefix/layoutsの下に.gkbファイルを置いた場合には'keymap キーマップ名'とできるみたいです。
さて。
色々いぢっちゃっていて込み入った感じです。ごちゃごちゃわかりにくくってごめんなさいm(__)m
2011-10-14
git stash pop等の後にそのアレをもう一度stashへ戻すコマンド
ごく稀にgit stash pop等した後に少し経ってから、もう一度さっきのstashでやり直したくなった、ということがります。例えば--indexを付け忘れていた、という場合。
そこで、引数にコミットを取って、表題のようなことをするマンドを作ってみました。
#!/bin/zsh _0="$0" () { local 0=${_0} emulate -L sh OPTIONS_SPEC= USAGE="[-f--force] <commit>..." SUBDIRECTORY_OK=t . git-sh-setup require_work_tree cd_to_toplevel } git-stash~ () { local stashishp="$1" shift local refstash=refs/stash local c=; for c in "$@"; do git-stash~~ $stashishp "$c" done } git-stash~-stashish-p () { # XXX: This may not be accurate though [[ -n "${1-}" ]] && [[ "${1}" == (#s)WIP\ on* ]] && [[ -n "${2-}" ]] && [[ "${2}" == (#s)index\ on* ]] && [[ -n "${3-}" ]] } git-stash~~ () { local stashp="$1" local commit="$2" git rev-parse "$commit" 2>&1 >/dev/null || die "$commit doesn't exist" local abbrevcommit="$(git rev-parse --short $commit)" local stashmsg= () { setopt localoptions no_ksharrays no_kshzerosubscript extendedglob local -a cs; : ${(A)cs::=${(@f)"$(git log -3 -s --format=%s $commit)"}} "$stashp" "$cs[@]" && { stashmsg="$cs[1]"; return 0 } return -1 } || die "$abbrevcommit doesn't seem like stash" : >>"$GIT_DIR/logs/$refstash" git update-ref -m "$stashmsg" $refstash $commit || die "Cannot save the commit status" say Saved stashish commit $abbrevcommit "$stashmsg" } zparseopts -E -D f=force -force=force (($#==0)) && usage if [[ -z "${force}" ]]; then set -- git-stash~-stashish-p "$@" else set -- : "$@" fi git-stash~ "$@"
気付いた点など。
メッセージのチェックは使いようによっては必要ないのかしらん…入れました…
レポジトリの外でgit stash~ -hとやるとエラーになっちゃいます。ごめんなさいm(__)m
動作の様子はこちら。git-stash~という実行可能ファイルでPATHの中に保存しています。
% git stash~ ; git stash~ -h
Usage: git stash~ [-f--force] <commit>...
Usage: git stash~ [-f--force] <commit>...
% git stash list
stash@{0}: WIP on master: bbb2454 hello git stash
stash@{1}: WIP on master: bbb2454 hello git stash
% git stash clear
% git stash list
% man git stash | grep git\ fsck -A2
git fsck --unreachable |
grep commit | cut -d\ -f3 |
xargs git log --merges --no-walk --grep=WIP
% !!| tr -d '\n' | sed -e 's/$/ --pretty=format:%H/' | sh
a094688f209b86ab47b798aafe0383f1b8952ae1
401fefc4ad0f970599dbdc5d68244da5ec40327d
% !!| xargs git stash~
Saved stashish commit a094688 WIP on master: bbb2454 hello git stash
Saved stashish commit 401fefc WIP on master: bbb2454 hello git stash
% git stash list
stash@{0}: WIP on master: bbb2454 hello git stash
stash@{1}: WIP on master: bbb2454 hello git stash
TODO: 任意のコミットを取って、可能ならばstashへ突っ込むようなコマンド。
gistがこちらです。
