2003.10.1
■前口上
permalink:"200310.html#d01_t1"
このサイトは、だめなプログラマー見習いが、怠惰な生活から抜け出し、切磋琢磨のすえ、歴史に残るソフトウェアを作り上げるまでの軌跡…をえがきます。
もしかしたら一割くらいは本気かもしれません。怠惰な自分に対して、少しでも課題を課すことで、自分の『そこ上げ』をしたい気持ち、なにかを創り上げたいと思っているもやもやした焦燥感などからこのページはできています……できる予定です。
■ちゅういがき
permalink:"200310.html#d01_t2"
このページはネタとかでなくマジでわかってない人間が作っているので、解説していることのほとんどは的外れな可能性があります。 正しい知識を得たい場合はリンク先などの情報を確認していただくようにお願いします。
また無断でリンクを張っております。すみませんです。
■コンセプト
permalink:"200310.html#d01_t3"
色々サイトを見て回って気づいたのですが、世の中には
『だめだめなプログラマの日常生活ページ』
と
『論理的なプログラムページ』
はいっぱいあるんだけど、その中間があまりないような気がします。
つまり、じだらくでオタな生活を送るプログラマーが、いったい脳細胞をどうやってこねくりまわして、どんなんなったらプログラムなんて論理的なもんができてくるんだろう? という疑問に答えてくれるところはない。自分ですら、どうやってるのかよくわからない。
そのメカニズムを解析したりはできませんが、プログラムを作る時のダラダラした思考の流れなんかが書ければいいなあと思ってます。
■キャラ設定(キャラ設定?)
permalink:"200310.html#d01_t4"
頭の中でうだうだと葛藤してる様子を描写するために、ここはあえて! 『架空キャラとの会話』形式にしてみよう。
ダメかな? どうだろ。まあいいや。
- ロロ
- 脳内師匠。ピュアバーチャル(純粋仮想)ネットアイドル。検索エンジンの化身。
- いつも冷静なツッコミ役。だけどしゃべることはどこかの受け売りだ(検索エンジンだし)。
- なんか天使みたいな適当に萌えるカッコしててください。
ついでに自分もキャラ付けしておこう。
- あお
- 語り手。バカ。飽きっぽい。基本的に行動力がない。
- 土日につねに『休む』をスケジューリングするような生活を何年も続けている。
- 『猫でもわかるプログラミング Windows SDK編』の最初のほうと、
- ペゾルド本の最初の20ページくらいを読んでSDK萌えになる。
とりあえず二人合わせて『あおとろろ』つーことで。なんか調子悪かったらやめる。
2003.10.2
■[xyzzy]xyzzyとは?
permalink:"200310.html#d02_t1"
とりあえず一発目なんだけど、今ハマってる xyzzy を題材にしようと思う。
xyzzy ってのはいまさら説明するのはおこがましいんだけど、亀井さんって日本の方が作った、Windows上でうごく『emacsふうエディタ』ね。あの超高性能で超とっつきにくいことで有名な『Emacs』ってエディタにこう、Emacsが忘れかけていた野生の息吹をふきこんだような、そんなエディタだ。
- ロロ「
- わかりにくい比喩で申し訳ありません。xyzzy は Common lisp の処理系を持った、非常に優れたフリーのテキストエディタです。今回はこれをカスタマイズするプログラムを書いてみようと思います」
■[xyzzy]前の行と同じだけインデント
permalink:"200310.html#d02_t2"
あ〜xyzzyってさ、すごいいいエディタだと思うんだけど『なんでこんなことができんのじゃ』って時々思うんですよ。
- ロロ「
- 例えばどういうことが?」
普通のエディタでいう『オートインデント』とか〜。単純に何も考えずに前の行と同じだけインデントしてくれたらいいのに、そういうモードとか変数とか用意されてないみたいだし。lispとかhtmlとかは階層構造まで考えてインデントしてくれるのですっごい便利だけれど、普通のテキストはそこまでいかなくていいから単純なオートインデントしてくれればいいのに。
- ロロ「
- よい課題ができましたね。早速とりかかりましょう」
…いや、やめましょ。mode とか、どう考えても、そこまでいじる技量がないし。
- ロロ「
- 問題を縮小して、『前の行と同じだけインデント』させるコマンドなら作れるのでは?」
まあそれならできるかなあ。ちょっと便利そうだし考えてみるか。
■[xyzzy]前の行と同じだけインデント2
permalink:"200310.html#d02_t3"
作る前に割り当てられるキーを探す。インデントだし、シフト+タブ(S-Tab) あたりがいいんじゃないか。コントロール+タブはすでに割り当ててあった。
S-Tabは、本来はxyzzyにキー割り当てができない組み合わせなんだけど、なんとかいう関数をつかってニセのキーに振り分けて定義できるはずだ。確か。
割り当てられるキーが決まったので、次に割り当てる関数の名前を考えよう。
indent-to …え〜と、前行へとぶのは、previous-line ? だから、indent-to-previous-line …これじゃ前の行がインデントするみたいだ。『前の行と同じだけ』だから、indent-as-same-previous-line かな?
長いし合ってるかどうかわからないけど、とりあえずこれで。
- ロロ「
- 正確には『indent-to-column-as-much-as-previous-line』ですね。excite翻訳ですけど」
頼りないなあ…
ええと、n桁までインデントする命令って何だっけ。indent-to か。あとは前の行の桁数を数えればいいわけだ。
まず前の行に行くでしょ。
(previous-line)
それで、空白とタブの数を数えればいい?
(looking-at "^\\([ \t]+\\)")
- ロロ「
- だめ。looking-atは前方参照ですから。前の行に移動した時にカーソルが行頭にあるとは限りません」
ああ、ではこうですね。
(previous-line)
(goto-bol)
(looking-at "^\\([ \t]+\\)")
- ロロ「
- looking-at の正規表現の中でカッコを使っていますが、ヒットした空白の数を数える気でいるのですか?」
え? なんかまずい? 文字列の数を数えるのは length でしょ。それをindent-toに
- ロロ「
- だめ。タブが入ってる」
あ。そうかタブが入ってると、文字数と桁数は一致しないんだった…じゃあ桁数を求める式が必要だな…
- ロロ「
- current-column という現在位置の桁数を返す関数があります」
うーん、そうするとこんな感じ?
(and
(previous-line)
(goto-bol)
(looking-at "^[ \t]+")
(progn
(goto-char (match-end))
(setq col (current-column))))
なんかいけそうなので完成させてみよう。
(defun indent-as-same-previous-line ()
(interactive)
(let col
(save-excursion
(and
(previous-line)
(goto-bol)
(looking-at "^[ \t]+")
(progn
(goto-char (match-end))
(setq col (current-column)))))
(if col (indent-to col))))
これで…あれ、エラーが出る。
- ロロ「
- だめ。let の col はリストでなければいけません。そして match-end の引数が少ない。あと、これではカーソルが行の途中にあったときにインデントできません」
う…はい。
★[xyzzy]前の行と同じだけインデント3
permalink:"200310.html#d02_t4"
これでいいかな。なんか長くなってしまった。
(defun indent-as-previous-line ()
"前の行と同じだけインデント"
(interactive)
(let (col)
(save-excursion
(and
(previous-line) (goto-bol)
(looking-at "^[ \t]+")
(goto-char (match-end 0))
(setq col (current-column))))
(if col
(progn
(goto-bol)
(indent-to col)))))
(set-extended-key-translate-table exkey-S-tab #\S-C-F23)
(global-set-key #\S-C-F23 'indent-as-previous-line)
関数名もついでに変えた。
苦労はしたけれど、ちょっと自分の xyzzy が便利になった。
★[xyzzy]一度にたくさんの行頭にスペースを入れたい
permalink:"200310.html#d02_t5"
- ロロ「
- ちなみに、一度にたくさんの行に同じだけスペースを入れたい場合は、HIEさん の xyzzyの音 -編集- の『セレクション各行の先頭に指定した文字を挿入』が便利ですね」
ああっ! これあったら indent-as-previous-line あんまりいらねえ!
2003.10.3
■[xyzzy] indent-rigidly を思い出す
permalink:"200310.html#d03_t1"
- ロロ「
- 思い出しました…GNU Emacsには、C-x TAB に indent-rigidly というコマンドが登録されているのです。これは、リージョンにふくまれた行すべてを指定コラム数だけ字下げするというものでした」
はあ。
- ロロ「
- これがxyzzy上で動くようになるともっと素敵ですね。よい機会です。defunを探してきて、それを参考にxyzzy上で動くものを作りましょう。ぜひそうしましょう」
えー。もう一応の目的は達したんスけど。
- ロロ「
- だめ。もう探してきました」
■[xyzzy] indent-rigidly を調べる
permalink:"200310.html#d03_t2"
いじってるうち、マイナスの引数でも与えられる事に気づいた。けっこう、便利かも。
リファレンスには、『マーカー』(バッファ内を書き換えてもずれないポインターみたいなの)の説明がなかったので、xyzzyでは使えないのかと思った。xyzzy Lisp Programming に使用例が書いてあったので助かったけど。
下の行から上の行に向かってリージョンを指定した時の、逆転の仕方がわかんなかった。リファレンスでは mule は自動的にやってくれるようなことを書いてあったけど xyzzy はだめみたい。上下を逆転する方法を探してしょぼしょぼすくりぷとで見つける。
リファレンスを探しているうち、(back-to-indentation)という関数を見つけた。インデントでない文字まで飛んでくれるらしいので、こちらを使うことにする。
★[xyzzy]で動く indent-rigidly
permalink:"200310.html#d03_t3"
(defun indent-rigidly (from to &optional (arg 1))
"リージョンを引数桁だけインデントする"
(interactive "*r\np")
(or (< from to)
(rotatef from to))
(save-excursion
(goto-char to)
(setq to (point-marker))
(goto-char from)
(or (bolp) (forward-line 1))
(while (< (point) (marker-point to))
(let ((bol (point))
(indent (progn (back-to-indentation) (current-column))))
(delete-region bol (point))
(or (eolp)
(indent-to (max 0 (+ indent arg)))))
(forward-line 1))))
(global-set-key '(#\C-x #\TAB) 'indent-rigidly)
2003.10.4
■[xyzzy]前の行と同じだけインデント4
permalink:"200310.html#d04_t1"
- ロロ「
- [xyzzy]前の行と同じだけインデント3で作った indent-as-previous-line ですけど、せっかく (back-to-indentation) というのを見つけたのですから、これを使って短くしてみませんか」
んー、ネタ切れっぽい企画ですが、やりますか。
(defun indent-as-previous-line ()
"前の行と同じだけインデント"
(interactive)
(let (col)
(save-excursion
(and
(forward-line -1)
(back-to-indentation)
(setq col (current-column))))
(if col
(progn
(goto-bol)
(indent-to col)))))
(set-extended-key-translate-table exkey-S-tab #\S-C-F23)
(global-set-key #\S-C-F23 'indent-as-previous-line)
どう? どう? さすがにこなれて来た感じ! (forward-line -1) で前の行の先頭へ移動、これも一命令にまとめたよ。
- ロロ「
- 残念ながら…『前の行がインデントしていなかった時は、何もしない』という前の仕様が破られています」
え? あ、本当だ。前は何も起こらなかったのに、今回は変更こそしないけどカーソルが行の先頭に移動してしまいますね…
- ロロ「
- (back-to-indentation)は失敗しても常にtを返しますから、それが仇になっていますね」
★[xyzzy]前の行と同じだけインデント5
permalink:"200310.html#d04_t2"
- ロロ「
- さっきの現象を修正するついでに、『今の行のインデントを消してから新しくつけ直す』という新しい仕様を付け加えてみましょう」
うーん、indent-rigidly を参考にすれば大丈夫かなあ。
まずいらんインデントを削除して、削除された時もカーソル移動してほしいからこれも特別扱いするには…変数を増やしてこれをsave-excursionの外側まで持ってきて…and意味なくなって来たし取るかぁ。あといい動きになるよう条件式を調整して…
こうかっ? って、前より増えてるし。
(defun indent-as-previous-line ()
"前の行と同じだけインデント"
(interactive)
(let (col bol eol)
(save-excursion
(forward-line -1)
(back-to-indentation)
(setq col (current-column))
(setq bol (progn (forward-line 1) (point)))
(setq eol (progn (back-to-indentation) (point))))
(when (or (< bol eol)
(< 0 col ))
(goto-bol)
(delete-region bol eol)
(indent-to col))))
- ロロ「
- もうここまで来ると好き好きかもしれませんね。前の動きの方が良かったという方もおられるでしょうし…」
ガーン! ここまでやらせといてそれかい!
■[xyzzy]X68000っぽい行移動
permalink:"200310.html#d04_t3"
『カーソル行を上下に移動』は便利だな〜
- ロロ「
- そうですね。でも、X68000に付属してたエディタの動作を思い出そうとしていたのですが、一行だけではなくてセレクションごと移動することもできたと思います」
また課題っスか! だが確かに、そっちの方が便利そうだ。
まずセレクションの扱い方がわからない。HIEさんのページを穴が開くほどみる。
ふむ、これによると、セレクションの扱い方はリージョンとそれほど変わるところはないらしい。
- selection-mark
- セレクションの開始ポイントを返す
- selection-point
- セレクションの終端ポイントを返す
- get-selection-start-end
- セレクションの開始位置と終了位置を多値で返す
- stop-selection
- セレクションを解除する
- start-selection
- セレクションを開始する
- get-selection-type
- セレクションの選択状態(1:行 2:文字 3:矩形)を取得
- ロロ「
- まず transpose-lines-down の動きを解析させてもらいましょう」
Ok。わからない式は出てこなかったよ。
- C-uによる前置き引数ゲット。ゲットできない場合、n=1.
- n行先に移動できるかどうかチェック。移動できないなら、なにも処理しない。
- カーソル行の、カラム位置、頭と次行のポイントを取得。
(もし次行まで進めないようなら、改行を入れる) - 頭と次行のポイントで削除して、n行移動して、削除した行を挿入。
- 一行戻って保存したカラム位置に移動すれば、さっきのカーソル位置と同じ。
- ロロ「
- さあ、これを複数行移動できるように拡張しようと思ったら、何が必要?」
え、えと…最初の行数、かなあ。
色々いじってるうちに、セレクションの状態を保存しないバージョンなら、できた。
(defun transpose-lines-down-each (&optional (n 1))
(interactive "*p")
(let ((beg (selection-mark))
(end (selection-point)))
(if (> beg end) (rotatef beg end))
(when (save-excursion
(and (goto-char end) (bolp)
(goto-char beg) (bolp)))
(insert (prog1
(buffer-substring beg end)
(delete-region beg end)
(forward-line n))))))
一回実行するたびセレクションが解除されるので、連続で実行したりできない。
- ロロ「
- それは、もちろんだめ。自分でセレクションをしなおすように変更しましょう」
ソウデスネ、というところで時間切れ。
2003.10.6
♪メモ
permalink:"200310.html#d06_t1"
今日はせっかく書いた原稿を忘れてきてしまったので更新できず。本当なら10/04に途中までで止まってた、『セレクションを上下に移動するコマンド』の続きをやろうと思ったんだけれど…
自分向けメモ。このサイトの趣旨ですが、別にxyzzyとlispしかやらないってわけじゃないです。たまたま今現在の興味がそっちに向いてるってだけで。気が向いたらなんでもやる。どっちにでも転ぶ。現在の目標は、とにかく更新を続けることです。
■[Windows]英語キーボード 導入メモ
permalink:"200310.html#d06_t2"
英語キーボードを導入する確実な方法がいまいちわからん。
わからんが、結果的にレジストリを書き換えることにより一応成功したのでやり方を書いておく。
- レジストリエディタを起動する。[スタート][ファイル名を指定して実行] regedit [Enter]
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
- 次のように値を変更する
名前 データ
LayerDriver JPN KBD101.DLL
OverrideKeyboardIdentifier PCAT_101KEY
- 再起動する
もっとまっとうな方法があるような気がするのだが。もしかしたら途中でつなぎ変えたのが悪いのであって、ハードウェアウィザードなどで書き換えできるのかもしれない。
2003.10.7
■[xyzzy]どうやってセレクションを戻す?
permalink:"200310.html#d07_t1"
こないだの続きから。
; 行セレクションを上下に移動
(defun transpose-lines-down-each (&optional (n 1))
(interactive "*p")
(let ((beg (selection-mark))
(end (selection-point)))
(if (> beg end) (rotatef beg end))
(when (save-excursion
(and (goto-char end) (bolp)
(goto-char beg) (bolp)))
(insert (prog1
(buffer-substring beg end)
(delete-region beg end)
(forward-line n))))))
セレクションごと下移動させるところまでは、できた。まだ実現してないのは、最後にセレクションを復元するところ。
復元しないこのままでは、一回コマンドを実行するごとにセレクションが解除されるので激しく使えない。
とりあえず色々リファレンスやxyzzyのlispソースを見ながらいじってみる。
selection-start-end は、select.l で定義されてる。セレクションの処理に使うと便利?
これを使うと少し短くなるかな。
(selection-start-end (beg end)
(if (> beg end) (rotatef beg end))
beg と end の大小が逆転してるとき、beg < end となるように正規化を入れてたけど、これ、なくても動くなあ。取ってしまおう。
セレクションのサイズをどのタイミングで入手すればいいのか、ずっと考えていた。一番最初にサイズを取っておき、マーカーを置いて削除後の位置を計算する、という考えにずっととらわれていたんだけど…
今ハッと気がついた。
最後の insert のカッコの中でやってる処理は、こんなのだ。
- beg から end までの文字列を取得する
- beg から end まで削除する
- n 行移動する
- 最初に取得した文字列を貼りつける
このとき『n 行移動する』処理の直後に、新しいセレクションを開いたらいいんじゃないのか?
その考えにしたがってコーディング。なんか、今までの苦労がうそのように簡単にできてしまった。
★[xyzzy]行セレクションを上下に移動(評価版)
permalink:"200310.html#d07_t2"
;; 行セレクションを上下に移動
(defun transpose-selection-down (&optional (n 1))
"行セレクションを n 行下に移動"
(interactive "*p")
(if (not (pre-selection-p))
(transpose-lines-down n)
(let ((pre-selection-type (get-selection-type)))
(selection-start-end (beg end)
(when (save-excursion
(and (goto-char end) (bolp)
(goto-char beg) (bolp)))
(insert (prog1
(buffer-substring beg end)
(delete-region beg end)
(forward-line n)
(start-selection pre-selection-type t))))))))
(defun transpose-selection-up (&optional (n 1))
"行セレクションを n 行上に移動"
(interactive "*p")
(transpose-selection-down (- n)))
(global-set-key #\S-M-Down 'transpose-selection-down)
(global-set-key #\S-M-Up 'transpose-selection-up)
- ロロ「
- transpose-lines-down を呼び出しているので、『カーソル行を上下に移動』も定義する必要があります」
2003.10.8
■[xyzzy]上下移動完璧版を追求しろ
permalink:"200310.html#d08_t1"
- ロロ「
- 昨日のコマンドにいくつか残っていた不満点を解消したいですね」
いや、特になんの不満も感じずに使えてるんですが。
- ロロ「
- まず transpose-lines-down を呼び出している点です。もともと関数を改造して作ったということもあり、非常に似通った処理になっています。統合することができればもっと効率がよくなるでしょう」
無視された。
さんざん参考にしておいて、transpose-lines-down を .xyzzy から追い出すんですか? なんか気ィ悪いですが。
- ロロ「
- 追い出すんじゃなくって、取りこむんです、動作ごと」
詭弁みたいだけど、まあいっか。…不満点ってそれだけ?
- ロロ「
- 次に、ウィンドウの端から出るほど動かそうとすると、微妙におかしな挙動になってしまいます。これも自然に見えるよう修正すべきでしょう」
あー、下方向にずらしていくときの挙動は何もおかしくないけど、上方向にずらしていって、セレクションが画面端からはみ出したとたん、いきなりセレクション全体が画面外に飛び出して戻ってこないな。
動きの見た目はおかしいけど、セレクションの移動じたいは成功してるみたいだから、表示だけを直せばいいんですかね?
- ロロ「
- そうですね。画面にバッファのどの部分を表示するか、指示を追加してやればいいでしょう」
■[xyzzy]似た処理をまとめて統合しろ
permalink:"200310.html#d08_t2"
まずは統合か! 統合っていわれてもどうやればいいのか… 色々がんばってみたけど変数とカッコがいりくんでごちゃごちゃしてきた。結局カッコの中に関数を入れこんだだけになりそうだ。
- ロロ「
- だめですね。せっかくセレクション対応版を作ったのだから、一行だけの時も同じ条件に置いてやればいいでしょう?」
???? 同じ条件?
- ロロ「
- 一行だけの時は、一行だけセレクションにしてやればいいんですよ」
…なるほど! こういうことですかね?
(when (セレクションなしの場合)
(カーソル位置の行を一行、セレクションにする))
(セレクション対応の処理...)
- ロロ「
- 最後に戻してやる必要がありますけどね。その考え方で統合してみましょう」
ものっそ疲れた。こうなりまった。
色を変えてあるのが、一行だけの時に評価される式な。
統合のほかにも関数名が変えたり、細部変えたりしてる。
(defun transpose-selection-down (&optional (n 1))
"行セレクションを 改造中"
(interactive "*p")
(let ((pre-selection-type (get-selection-type))
(column (current-column)))
(unless pre-selection-type
(goto-bol)
(start-selection 1 t)
(or (forward-line 1)
(progn (goto-eol) (insert #\LFD))))
(selection-start-end (beg end)
(when (save-excursion
(and (goto-char end) (bolp)
(goto-char beg) (bolp)))
(insert (prog1
(buffer-substring beg end)
(delete-region beg end)
(forward-line n)
(when pre-selection-type
(start-selection pre-selection-type t))))
(unless pre-selection-type
(forward-line -1)
(goto-column column))))))
■[xyzzy]ウィンドウからはみ出たのを知るには
permalink:"200310.html#d08_t3"
次は、ウィンドウの端からはみ出た時の処理なんだけど、どういう関数があるのか全然知らないんだよな。ということで師匠、よろしく。
- ロロ「
- この辺りでしょうか」
- scroll-window
- Function: (scroll-window ARG)
- ウィンドウを指定行数分スクロールします。負の数値は前方向にスクロールします。
- カーソルも釣られて移動してしまうので注意!
- pos-not-visible-in-window-p
- Function: (pos-not-visible-in-window-p POINT &optional WINDOW)
- 指定されたPOINTがWINDOWの表示範囲内にないかを返します。
- pos-visible-in-window-pの逆です。
- get-window-line
- Built-in function: (get-window-line &optional WINDOW)
- カーソルのWINDOW上での位置を返します。一番上が0です。
- window-height
- Function: (window-height)
- 現在のウィンドウの高さを行単位で得ます。
- recenter
- Function: (recenter &optional ARG)
- スクロールして現在行の画面上の表示位置を調整します。
- (recenter 0)で現在行がウィンドウの一番上に来ます。
- 引数を省略すると現在行が画面の中央に位置します。
- ロロ「
- ほとんどの情報は xyzzy Reference に拠っています」
今回なんとかしないといけないのは、上方向に移動した時だけみたいだ。下方向に移動した時は画面がカーソルを追っかけてくれるのでなんの問題もないからだ。
上方向なのか下方向なのか区別がつかないので、pos-not-visible-in-window-p はこの場合にはあんまり役にたたない。上方向だけなら
(minusp (get-window-line))
これだけで判断できるみたい。
insert してしまうとカーソルが移動してしまうので、その前に判断したほうがいいのかな?
さらに画面スクロールには、面倒な計算やカーソル保存がいらない recenter を使うといいみたいだ。どうやら完成が近づいてきたみたい。
★[xyzzy]行セレクションを上下に移動(完成版)
permalink:"200310.html#d08_t4"
;; 行セレクションを上下に移動
(defun transpose-selection-down (&optional (n 1))
"行セレクションを n 行下に移動"
(interactive "*p")
(let ((pre-selection-type (get-selection-type))
(column (current-column)))
(unless pre-selection-type
(goto-bol)
(start-selection 1 t)
(or (forward-line 1)
(progn (goto-eol) (insert #\LFD))))
(selection-start-end (beg end)
(when (and (goto-char end) (bolp)
(goto-char beg) (bolp))
(insert (prog1
(buffer-substring beg end)
(delete-region beg end)
(forward-line n)
(and (minusp (1- (get-window-line)))
(recenter 1))
(when pre-selection-type
(start-selection pre-selection-type t))))
(unless pre-selection-type
(forward-line -1)
(goto-column column))))))
(defun transpose-selection-up (&optional (n 1))
"行セレクションを n 行上に移動"
(interactive "*p")
(transpose-selection-down (- n)))
(global-set-key #\S-M-Down 'transpose-selection-down)
(global-set-key #\S-M-Up 'transpose-selection-up)
変更点
- transpose-lines-down の処理を取りこんだ
- 画面上での挙動を調整した
- 動作に違いのない(save-excursion)を取り去った
2003.10.9
♪memo
permalink:"200310.html#d09_t1"
今のところここは誰も見てないと思うけど、せめて一ヶ月はつづけたいなあ。もし更新が一ヶ月つづいたらそーっと宣伝してみようかなあ。
液晶ディスプレイとブラウン管とでは、色のコントラストの見え方が全然ちがうなあ。
コントラストは心持ちキツめにしておかないと見づらい。
回りこみの設定を修正した。IEで見てる分には思い通りの結果が得られているが…他のUAでもチェックしないとなあ。文法チェックもしないとなあ。気の迷いでXHTMLになんかするんじゃなかったなあ。
ロロ師匠のセリフだけ色変えてみた。さらに字下げになるようcssをいじってみた。
■[xyzzy|nDiary]cut-diary.l
permalink:"200310.html#d09_t2"
- ロロ「
- cut-diary.l とは nDiary と連携して動作する、日記まとめ書き支援ツール(おおげさ)です」
- 自分の今までの日記を見直したりメンテするのが好き。
- それに、技術的なことは見返さないと思い出せない
- 日記になる前のメモとか草案みたいなのも保存しておきたい
なので、日記をある程度テキストファイルにためこんで書きたいな、と思った。
- ロロ「
- しかし日記生成ツール nDiary には、『一日一ファイル』というきまりがあるのです」
ふつーは昔書いた日記をいじくったりしないよなあ。そもそもあんまり日記じゃないしなコレ。
そんなわけで、必要にせまられて作った。実体はまとめ書きしたテキストファイルから、日記ファイル(*.diary)を切り出して保存してるだけの単純な関数(*1)だ。
- ロロ「
- 大まかな仕様は以下の通りです」
- xyzzy lispで組む。
- 横線(変更可)を見つけたらファイル境界の印
- 横線の下の行に日付が入っていたら、その日付でファイルを新規作成して内容をペースト
■[xyzzy|nDiary]cut-diary 次の区切り線
permalink:"200310.html#d09_t3"
一日分をジャンプするため、『次の区切り線まで移動』処理を作った。マクロを使ってみる。
;;
;; 次の区切り線まで移動
(defun cut-diary-next-rule (&optional reverse)
(interactive)
(let (func (if reverse #'re-search-backward
#'re-search-forward))
(and (funcall func *cut-diary-rule-regexp* t)
(forward-line 1))))
(defmacro cut-diary-previous-rule (&optional reverse)
(interactive)
`(cut-diary-next-rule ,(not reverse)))
マクロ動かないし cut-diary-next-rule も動かない。根本的に間違えてる?
let のとこにカッコ足りなかった。追加する。
インタラクティブな関数をマクロにすることはできないみたい。置きかえる。
;;
;; 次の区切り線まで移動
(defun cut-diary-next-rule (&optional reverse)
(interactive)
(let ((func (if reverse #'re-search-backward
#'re-search-forward)))
(and (funcall func *cut-diary-rule-regexp* t)
(forward-line 1))))
(defun cut-diary-previous-rule (&optional reverse)
(interactive)
(cut-diary-next-rule (not reverse)))
動いたけど動作がおかしいというか、これではこうしか動きようがない。
previous-rule ですぐ手前の区切り行にヒットする。変えないと。
これがやっとのことで動いたバージョン。
;;
;; 次の区切り線まで移動
(defun cut-diary-next-rule (&optional reverse)
(interactive)
(let ((func (if reverse #'re-search-backward
#'re-search-forward)))
(when reverse (forward-line -2))
(and (funcall func *cut-diary-rule-regexp* t)
(forward-line 1))))
(defun cut-diary-previous-rule (&optional reverse)
(interactive)
(cut-diary-next-rule (not reverse)))
■[xyzzy|nDiary]cut-diary.l の設定例
permalink:"200310.html#d09_t4"
こいつを、こんな感じに設定して使ってる。
(require "cut-diary")
(setq *cut-diary-directory* "/_work/memo/www/txt")
(defun my-ndiary-compile ()
"日記を html に変換するの"
(interactive)
(if *ndiary-offer-save*
(save-some-buffers))
(setq cmd (read-string "Script: " :default (concat "ruby " *ndiary-filename*)))
(save-window-excursion
(pop-to-buffer (get-buffer-create "nDiary output") 8)
(execute-shell-command cmd nil "nDiary output")
(unless *executing-macro* (sit-for 0.5))))
(defun my-ndiary-mode-hook ()
(define-key *ndiary-mode-map* '(#\C-c #\C-c) 'my-ndiary-compile)
(define-key *ndiary-mode-map* '(#\C-c #\C-v)
#'(lambda () (interactive)
(cut-diary-cut) (my-ndiary-compile)))
(define-key *ndiary-mode-map* '(#\C-c #\-) 'cut-diary-draw-rule)
(define-key *ndiary-mode-map* #\M-n 'cut-diary-next-rule)
(define-key *ndiary-mode-map* #\M-p 'cut-diary-previous-rule))
(add-hook '*ndiary-mode-hook* 'my-ndiary-mode-hook)
- ロロ「
- 上の方にある関数 (my-ndiary-compile) は、 ndiary-mode の (ndiary-compile) を改悪させていただいたものです。nDiary の実行結果を出すウィンドウを、0.5秒で消すように改造してあります」
2003.10.10
■[nDiary]おこられて修正
permalink:"200310.html#d10_t1"
- ロロ「
- 昨日までの書式で、XHTML1.0の文法チェックをしようとしたところ、Another HTML lint に、<p>の中に<dl>要素入れちゃだめって怒られてしまいました」
…がんばって直しましたよ、ええそりゃもう。
正規表現の手直しはまかせな! 加州知事だってぶんなぐってやるぜ。
でも ruby いじくるのだけはカンベンな!
■[xyzzy]save-excursion はマークは保存しない?
permalink:"200310.html#d10_t2"
- ロロ「
- 今 cut-diary を動かした時に気づいたのですが、実行するとマークが勝手に移動してしまいます」
ん、ちゃんと(save-excursion)で囲ってますが…
- ロロ「
- xyzzy の save-excursion ってマークは保存しないのかもしれません。検証してみましょう」
では *scratch* に移動して簡易調査。こんな感じで書いて、最後で Ctrl+J をお酢。
その前に *scratch* バッファの終わりあたりで Ctrl+スペース を押してマークしとく。
(save-excursion
(goto-char (point-min))
(set-mark))
結果は…マークが最上段に移動してしまった。カーソルは戻ってきてるけど。
- ロロ「
- (save-excursion)は実行前の状態を保存します。そして引数の処理がすべて終わったのち、元の状態に戻してくれるフォームなのですが…、この場合復元されたのはカーソル位置だけだったようです。emacs の同名のフォームのように、マークを復元してくれたりはしないようですね…」
ちなみに、(save-restriction)で同じ事を試しても結果は同じだった。(save-window-excursion)を使ったところ、やっとマーク位置が復元された。
■[web]『過去日記リンク』の名前(英名)をさがす
permalink:"200310.html#d10_t3"
いや、この表題の左にある四角(■)に nDiary がリンク貼ってくれてるんだけど、 htmllint が『お前おんなじテキストで違うリンク先に張りやがってこれじゃ何がどこにリンクしてるかわからんやないけアクセシビリティをなんや思てるんじゃボケー』と因縁つけてくるし、確かに何のリンクなのかわかりにくいので少し説明をつけようと思ったんだが、このリンクの正式名称がわからん。
日本語でいうと、『月別ファイルの該当トピックへのリンク』いやいや… そんな日本語じゃダメだろ…
しょうがないので英語できっぱりしたのがないか探す。
- ロロ「
- どうやって」
とりあえずgoogle さんに reference とか anchor とか link とか思い当たる単語を食べさせてみる。
…
ネットは広大だわ…
- ロロ「
- 検索単語があいまいすぎです」
どうにもならない。
あきらめかけた刹那、脳裡に『blog permanent link』というキーワードが送信されてきた! 検索して確認。確かにある。これだ。間違いない。
このリンクは『permalink』という名前だ! 日本語では『永続リンク』 だれだか知らないが電波をありがとう!
2003.10.11
■[xyzzy]ファイル同士の比較(Windows で動く diff)
permalink:"200310.html#d11_t1"
- ロロ「
- ファイルの比較をします。今日は」
だんだん師匠の言葉遣いがラフに変わってきてるな。
- ロロ「
- xyzzy で、Ctrl-F5 を押すとテキストファイルの比較ができます。
まず、二つのバッファのカーソル(キャレット)位置を合わせ、Ctrl-F5 を押します。違いがあればその位置までキャレットが移動します。これが基本的な使い方です」
この基本的な動作でずっと満足してたんだけど、欲が出てきてしまった。たとえば違う行はここですとか、ここが入れ替わってるよとか、色で教えてくれたりしたらいいよなあ。
- ロロ「
- diff をインストールすればまさにそのような動作をしてくれます。diff は元々 unix のコマンドなので、Windows 上で動くものを探さないといけませんね。xyzzy の関連ページをいくつか見て、導入事例を探してみましょう」
- xyzzy研究室のおすすめ http://www.fsci.fuk.kindai.ac.jp/kakuto/soft.html の
『GNU patch and GNU diff for Win32 』 - xyzzyの音 − 外部アプリの導入 − も同じとこおすすめ
- chez sugi でも同じところおすすめ。
- Han's roomの diff-buffer.l
- OHKUBOさんとこもみておこう。
んあ、みんな同じの使ってらっしゃるじゃねーの。これ頂いていこ。
展開したら、 PATHの通ったとこにいれる。どうすっぺか。D:\ruby\bin とかすでにPATHを通した場所に入れてももちろんOKなんだが、今回はD:\bin にパス通してこの直下に入れよう。
diff.exe と、ついでに patch.exe をコピーして準備完了?
実際につかってみよう。Han's room さんの diff-buffer.l もインストールして、 .xyzzy に以下の行を加えた。
(require 'diff-buffer)
おう! 見事! ウィンドウが分かれるし、色分けされてるし、だけど何この色?
ロロ「色設定が微妙だったみたいです。背景9と背景11、それとマージ用に背景15を使うようですね」
背景9と背景11を、『共通設定』で普通のシアンとライムにしておこう。背景15も明るい色に変更しておく。これでいい感じ。
2003.10.13
■[nDiary]関連というか、単なるメモ
permalink:"200310.html#d13_t1"
10/11のメンテ。本来画像のあるべきところに画像を貼る。
nDiary を通じてはじめて画像を貼った。html方式ではないのでちょっと戸惑ったけど、慣れたら楽だろうと思う。もちろん普通の <img href="..."> 形式でも書くことはできる。
2003.10.14
♪メモ
permalink:"200310.html#d14_t1"
- 攻殻機動隊 STAND ALONE COMPLEX 01
- Amazon でDVDを買った。
- なんでいまさら? というかこっちが聞きたい。なんでまだ観てなかったんだろ。
- なんで? こんなん好きやん自分?
- あれか。攻殻2に落胆して…いや、落胆したんだっけ? 確かに豪華な割に味のない料理だと思ったがそれなりに愉しんだような…
- ここ数年アニメ観るの面倒くさくなってるのが原因? そうかも。
- 押井氏の映画とPSゲーム版攻殻をあわせたような印象。いい意味でスタンダードで、スピード感があって映像もいい感じ。タチコマ。
- ビギナー
- 第二話からなんとなく。ドラマを最初から終わりまで観たのひさしぶりだなあ。
- リアリティのない司法モノ(逆転裁判?)。『供述:その人が話した内容』なんてテロップがひんぱんに出て、なんか視聴者をバカにしてる感じもないではないが(でも実際バカなんだろうなあ)割と面白い。ビデオ録って見るかも。
2003.10.15
■[xyzzy]『マウスでコピペ』を改造
permalink:"200310.html#d15_t1"
これが元の、マウスでコピペ(引用)。超便利。
;;
;; マウスでコピペ
;;
(defun mouse-right-press ()
(interactive)
(mouse-left-press)
(paste-from-clipboard))
(global-set-key #\LBtnUp 'copy-selection-to-clipboard)
(global-set-key #\RBtnUp 'mouse-right-press)
(global-set-key #\MBtnUp 'mouse-menu-popup)
- ロロ「
- コピーする時には非常に便利なのですが、選択した範囲が消えるようになってしまいます。セレクションを対象にしたコマンド等にマウスを使えなくなって微妙に不便です」
環境設定によっては、なんてこたない話なんだろうけどね。
- ロロ「
- 【共通設定】『さまざま』の『クリップボードへのコピーで範囲をクリアしない』をチェックしておくと範囲が消えたりはしないのですが、普通にコピーした時にもセレクションが消えなくなってしまいます」
『セレクション時には C-x と C-c を カット コピーとして扱う』も使ってるので、セレクションが残ってると普通のコマンドを入れたときコピーやカットになってしまってストレスがたまるんだよな。まあどれかひとつ使うのをあきらめれば済む話なんだが…
で、マウスで選択した時だけ、コピーすると同時に範囲も保持してくれるようにしようと思った。
これが、修正試作1号(動きません。実行しないほうがいいです)
(defun mouse-left-press ()
(interactive)
(let ((pre-selection-type (get-selection-type)))
(selection-start-end (beg end)
(copy-selection-to-clipboard)
(start-selection pre-selection-type t beg))))
(global-set-key #\LBtnUp 'mouse-left-press)
なんか間違えてるみたい。マウスクリックでカーソルが移動しなくなった。
今、元に戻そうと思って元の定義をC-x C-eしたんだけど…戻らない。(global-set-key)の行をコメントアウトして、xyzzyを立ち上げ直しても…戻らない。相変わらずマウスでカーソルが移動できない。これは怪奇現象? マウス関連はいじっちゃダメなん?
- ロロ「
- mouse-left-press とは、マウス左ボタン押下(#\LBtnDown)にセットされている関数の名前です。つまり、すでに定義されています。mouse.l に。要は、標準を思いっきり上書きしています」
…最初に確認しとけばよかった。mouse-right-press は無いけど mouse-left-press はあるのね!
関数名を変えた。あと copy-selection-to-clibboard の中身を見た結果、変数をいじくった方が早いことがわかった。ので変更する。
(defun mouse-left-up () ;セレクションを外さないようにする
(interactive)
(let ((*shodat-copy-mode* t))
(copy-selection-to-clipboard)))
(global-set-key #\LBtnUp 'mouse-left-up)
★[xyzzy]マウス選択と同じにコピー(セレクションを外さない)
permalink:"200310.html#d15_t2"
完成したのがこれ。
(defun mouse-right-press ()
(interactive)
(mouse-left-press)
(paste-from-clipboard))
(defun mouse-left-up () ;セレクションを外さないようにする
(interactive)
(let ((*shodat-copy-mode* t))
(copy-selection-to-clipboard)))
(global-set-key #\LBtnUp 'mouse-left-up)
(global-set-key #\RBtnUp 'mouse-right-press)
(global-set-key #\MBtnUp 'mouse-menu-popup)
■[nDiary]スクリプトイロイロ
permalink:"200310.html#d15_t3"
rubyはわからないけど、正規表現ならなんとかわかるので、いろいろ置換スクリプトを書いてみてる。
ところでなんで『正規表現』なんて名前がついてるんだろう? 何が正規? ワイルドカードとか、そういう名前の方が合うと思うんだけど。
- ロロ「
- 正規表現とは、パターンの表現方法のことです。パターンを『正規化』したものなのでこの名前がついています。パターンというのは、あるテキストの集合のことです」
ボクおなか痛くなったんでお休みしていいでしょうか。
- ロロ「
- だめ」
- ロロ「
- 難しいことを抜きにして説明するとしたら、色々なテキストにマッチするということは、色々なテキストの『代表』になっているということです。レギュラー選手です。レギュラーを日本語に訳すと正規。だから正規表現と呼ばれているんです」
まあ…その説明でなんとなくわかったしいいか。あまり突っ込むと師匠も多分頼りないし。
気を取り直して、実際の置換の話な。まずロロ師匠のセリフを変換してるところはこうなっている。
# $Id$
=begin
usage:
=end
class Filter
def mezanade(str, type)
# 発言を定義文に書き換え
# <p>○○「…」</p> →
# <dl class= [Class]{literal}"voice"><dt>○○「</dt><dd>…」</dd></dl>[/Class]
case type
when :AFTER_P
str.gsub!(/<p([^>]*)>([^「]+)「/m,
'<dl\1 class="voice"><dt>\2「</dt><dd>')
str.gsub!(/」<\/p>/m, '」</dd></dl>')
end
end
end
注釈にある通り、nDiaryが<p>...</p>で囲んだ領域を分捕って<dl>...</dl>にムリヤリ変換してる。
こんな内容のファイルを作成して、diary.conf にフィルターとして指定しておけばOK
その他に<a>に name と id の二つの属性を付けたり
when :AFTER_ONEDAY
# name 属性と id 属性両方を指定する
str.gsub!(/(<a [^>]*)id=("[^"]+[^\\]")/m, '\1id=\2 name=\2')
<tt> タグを <kbd> タグにするフィルターも入れておこう。
when :AFTER_CODE
# <tt> タグを <kbd> タグにする
str.gsub!(/<(\/)tt>/m, '<\1kbd>')
で、こっからが大変。あの■ボタンに張ってあるリンクをはずし、別の文字列のリンクと差し替えたいのだ。
デザインの上ではやりたいことはもう頭にあって、アサノさんのジャンル別設定の仕方とか のジャンル別欄のデザインをですねえ、まんまパクらせてもらおうかな、と。さらに置換の考え方の面でも非常に参考にしております。
■[nDiary]permalink切り離し
permalink:"200310.html#d15_t4"
まず、あらかじめ ndiary.conf の『トピックを全文リンクにする(ver. 0.8.0 以前の動作)』を true に設定しておく。
# permalink 項目を抜き出す
str.gsub!(/<h3([^>]*)><a([^>]*)href=("[^"]*")([^>]*)>([^<]*)<\/a><\/h3>/m,
'<p class="topicnavi"><span class="topicnavi">permalink:<a\2href=\3\4>\3</a></span></p><h3\1>\5</h3>')
カッコが多いが…やってることは属性 href のなかみを取ってきて、それをリンクにして見出しの外に作り直しているだけ。
最初カッコを入れ子にしていたのがうまくいかなかった。スラッシュのエスケープもよく忘れるしね。
■[nDiary]Todo
permalink:"200310.html#d15_t5"
このへん読んでおく
- 有里さんのtopic_sortの使い方
- なんちゃってRSS の話(nDiaryWikiあたり?)
- blogとは
- I can't blog
- C-Tools
- 大森望さん僕がblogしない理由
- ZDNN:ウェブログに見る日米個人サイトコミュニティ事情
2003.10.16
■[nDiary] nDiaryを使おうと思った5つの特徴
permalink:"200310.html#d16_t1"
- 静的生成。htmlファイルを作成してからアップロード。手元にテキストデータが置けるので、安心感がある。プロバイダがcgi置けないところでも大丈夫。それに、俺が動的生成より好き。
- 直感的に書けるテキスト。てきとうに頭にマークつけたら見出し。一行空けたら段落。『・』つけたら箇条書き、など、html以外に何か書式を覚える必要がない。
- コードが書きやすい。Code:に続けて生のコードをペーストするだけ。技術系のサイトが作りたかった俺にとってコレは大きい。
- プラグインで拡張可能。ゴテゴテと機能を追加することもできる。機能を追加してしまうと結局変なコマンドを覚えなきゃいけなかったりするんだけどね。強制されるのと自分で追加するのとでは印象も違うのだ。
- トピック自動生成。しょうらい的にTipsをまとめたページができるといいな。全然使いこなせないけど。
■[nDiary] nDiaryをあきらめようと思った3つの特徴
permalink:"200310.html#d16_t2"
- ruby で書いてある。rubyってなー。ちょっとなー。食わずぎらいってわけでもないんだけど、rubyってWindowsのことがきらいみたいだし。一見さんお断り感ありありだし。公式サイトにWindowsバイナリが置いてないとこなんて今時ないぜ。覚えるのもインストールもめんどくせー。
- yyyymmdd.diary というファイルを一日ごとに作らなければならない。拡張子 .diary なが! それより何より一日ごとにファイルを分けなきゃいけないのはすごく面倒です…
- 他に似た機能のソフトがたくさんあって目移りする。
いろいろ不満もあったnDiaryだが、今はxyzzyの分割マクロも組んだし、ほぼ理想的な書き殴り体制が確立したので大変助かっている。rubyさえ書ければ自由度も高い。
しかし自由度が高い分とっつきが悪い。試す分には簡単なんだけれど、テンプレートがあんまり公開されてないので、なかなか自分が思ったようなレイアウトにできないのよね。この辺を改善していくといいんじゃないでしょうか。
- ロロ「
- 何様ですか」
■[近況]1024x768に戻す
permalink:"200310.html#d16_t3"
家でhtmlとかソースファイルを読もうとすると、文字を追ってるうちにイライラして放り出すことが多かった。これは掲示板とか二次元絵とかの誘惑が多いからだろう、あるいはアホになってきてるからだろうと勝手に納得してたんだけど
思うところあって、1280x1024にしてたディスプレイ解像度を1024x768にまで下げた。
やはり、今までだましだまし使いつづけてきたものの、この Logitec の17インチモニタでは、1280x1024ではひとつひとつのドットを表示しきれていない。
画像はソフトフォーカスになりキレイに見えるし日本語を読むだけなら支障はなかったのだが、横文字やプログラムを見るとイライラしていたのもオレがアホウになったのもおそらくこの解像度が原因だろう。
デスクトップの広さと引き換えにくっきりしたエッジを手に入れたので、脳の方もくっきりしてくれるといいなあ。
■メモ
permalink:"200310.html#d16_t5"
URLメモ
- いしなお氏
- http://ishinao.net/
- URLメモとToDoを公開。まねしよう。
- http://mylog.ishinao.net/memo.html
- Weblogツールリスト(HTMLアップロード)
- http://artifact-jp.com/weblog/htmlup.html
- 日記ツール総合スレッド
- http://pc.2ch.net/test/read.cgi/linux/1003248633/
- IPPO's Diary
- http://member.nifty.ne.jp/ippo/s_d200212.html
つーかnDiary系全部目通せ、一回。
Googleさまじゃなくてアンテナで拾え。自分でうんうん唸るよりマシでしょう。
2003.10.17
■本をよむ
permalink:"200310.html#d17_t1"
- 誰も教えてくれなかったWebデザインの基本 Basic of Web Design
- とにかく、Webデザインの外見面でのテクニックの集大成のような本。フォントのバランス、カメラ使用時の基本的なテクニック、配色など説明もレイアウトもわかりやすい。
- とかく初心者向けの本は、ある特定アプリケーションの一挙一動の説明になりがちだけれど、この本はなぜ見た目がよくないのかについてわかりやすく説明しているので説明に流されることもなく応用しやすいと思う。
- 前半の章は絶賛。後半は俺の知ってることが大半ってこともあるかもしれないが、微妙。
- 後半はHTMLの話、おもにテーブルレイアウトやフレームレイアウトの話が大半になってくるんだけど、テーブルの話はともかく、『コンテンツの横幅を固定しよう』ってのには閉口だし、『CSSはフォントをポイント指定してサイズを固定するために使う』にいたっては開いた口がふさがらない。
- 何やってもレイアウトの変わらないページってのは、たとえるならA3版のハードカバーの本みたいなもので、クライアントにとってもいいことばかりじゃないと思うんだけどなあ。横スクロールバーは出るわ印刷はできないわで。もうちょっと柔軟な表記にページを割いてほしかったぞ。
- SF作家の近未来科学読本 人間と科学はどこに行きつくか
- 昭和57年刊の本 著者は石原藤夫さん。モノレール文庫においてあった古本。つまんなかったとしても20年前の未来予想として笑ってやろうか、などと不純な動機で読む。が全然しっかりしてて今読んでも何のおかしさも感じなかった。さすがSF作家。
- 特に二章『技術はどこまで進歩するか』はでは第五の情報革新として『コンピュータと電気通信の融合』をあげていてさすがだと思った。まだワープロ全盛の時代、通信は音響カプラのじだいなのに。ここで期待されてる電電公社のINS構想は結果的にアメリカにしてやられたんだっけ。
- 『腕時計がコンピュータでありテレビ電話でもあるという極限的未来』ほぼ狙いを外してない未来予想をされてるなー。まさに携帯だよね。腕時計は片手で操作できないので、今のところ懐中時計に近いカタチだけれど。
- これ以外著書を一冊も読んだことないので恐れ多くて自分からは逝けないけど、何かの縁なのでリンクしとこう。
2003.10.21
■[xyzzy]ジャンプの続きを見せろ
permalink:"200310.html#d21_t1"
下向きにジャンプしたときカーソルがウィンドウの下のほうにあると見づらいので、cut-diary.l のジャンプ命令を少しいじって、そういうときは recenter するようにした。まだもう少し改善の余地はあるかも。
;;
;; 次の区切り線まで移動
(defun cut-diary-next-rule (&optional reverse)
(interactive "p")
(let ((func (if reverse #'re-search-backward
#'re-search-forward)))
(forward-line (if reverse -1 1))
(and (funcall func *cut-diary-rule-regexp* t)
(if (> (get-window-line) (/ (window-lines) 2))
(recenter)))))
(defun cut-diary-previous-rule (&optional reverse)
(interactive "p")
(cut-diary-next-rule (not reverse)))
■[Win32]送る→ファイル名に日付つけてコピー
permalink:"200310.html#d21_t2"
ファイルを、これから編集したい、けれどもバックアップを残しておきたい! なんて思ったときに、
同じディレクトリに、Ctrl-C Ctrl-Vでファイルのコピーを作成。
ファイル名の『コピー 〜 』の部分を削除して、タイムスタンプの日付を付加してリネーム。
この作業って異様によく行なう気がしたので自動化するツールを作ってみようと思った。
- ロロ「
- コンテキストメニューの『送る』から呼べるようにすると便利ですね」
作り始める前にまず実験。引数で渡されるファイル名をそのまま表示してみるだけのプログラムを作る。
それのファイルをSendToフォルダに入れ、 長いファイル名を渡してみる。やっぱり短いファイル名しか渡っていない。NT系でやるとどうなるかはわからないが…
- ロロ「
- まず短いファイル名から長いファイル名を得る方法を探す必要がありますね」
…その前に面倒くさくなってきたので同じ機能のがないか探そう… Rnmcopy というのが非常に近いが現在日付でリネームすることはできてもタイムスタンプを自動で付けてはくれない… FlexibleRenamer は別名コピーをやってくれない… 問題が微妙すぎて検索ワードが思いつかない… 捜すのが面倒…
■[xyzzy]やっぱりxyzzyのファイラーにする
permalink:"200310.html#d21_t3"
やっぱりやめよう。
- ロロ「
- …やめるのは勝手ですが、もはやコンテンツとして成り立っていませんよ…」
そうですねー。
- ロロ「
- …まあ、今Win32の資料が手元にないということもありますから、その代わりに xyzzy のファイラーを改造して同じ機能のものをつくるというのはどうでしょうか」
は〜い。
『名前つけてコピー』同等品はすでに filer.l のなかに filer-copy-as という名前の関数として定義されてるんだよ〜。あとは、filer-copy-as が呼び出してるダイアログ表示関数、filer-get-copy-file-name の…
{filer.l より引用}
(defun filer-get-copy-file-name (name)
(multiple-value-bind (result data)
(dialog-box '(dialog 0 0 209 67
(:caption "別名でコピー")
(:font 9 "MS Pゴシック")
(:control
(:static nil "新しいファイル名(&N):" #x50020000 7 35 52 8)
(:edit new nil #x50810080 7 45 140 14)
(:button IDOK "OK" #x50010001 152 7 50 14)
(:button IDCANCEL "キャンセル" #x50010000 152 24 50 14)
(:static nil "元のファイル名(&O):" #x50020000 7 7 48 8)
(:edit old nil #x50810880 7 17 140 14)))
(list (cons 'new (concat name "~"))
(cons 'old name))
'((new :non-null "新しいファイル名を入力して" :enable (IDOK))))
(when result
(cdr (assoc 'new data)))))
こいつの、新ファイル名をこしらえてる部分、
(cons 'new (concat name "~"))
ここを、"~"のかわりにファイル名から取得した更新日付をくっつけてやればいいだけだ。
■[xyzzy]ファイル名から日付を取得しよう
permalink:"200310.html#d21_t4"
更新日付を取得する関数自体は、filer.l を真似してすぐできた。細部はわからんけれども、こんな感じだ。
(defun my-filer-rename-with-timestamp (name)
(concat (pathname-name name) "_"
(multiple-value-bind (sec min hour day mon year)
(decode-universal-time (file-write-time name))
(format nil "~4,'0d~2,'0d~2,'0d" year mon day))
(if (pathname-type name)
(concat "." (pathname-type name)))))
だけどもここで問題が。元の filer-get-copy-file-name が name に渡してるのは 『パス無しのファイル名』なんだよなあ。これだけじゃもちろんタイムスタンプを取得するにはパスが足りない。どうしようか。考えても浮かばないので、 filer-copy-as から元から全部とっかえることにした。
★[xyzzy]送る→ファイル名に日付つけてコピー
permalink:"200310.html#d21_t5"
んなわけで長くなった。
(in-package "editor")
(defun my-filer-rename-with-timestamp (name)
(concat (pathname-name name) "_"
(multiple-value-bind (sec min hour day mon year)
(decode-universal-time (file-write-time name))
(format nil "~4,'0d~2,'0d~2,'0d" year mon day))
(if (pathname-type name)
(concat "." (pathname-type name)))))
(defun my-filer-get-copy-file-name (name)
(multiple-value-bind (result data)
(dialog-box '(dialog 0 0 209 67
(:caption "別名でコピー")
(:font 9 "MS Pゴシック")
(:control
(:static nil "新しいファイル名(&N):" #x50020000 7 35 52 8)
(:edit new nil #x50810080 7 45 140 14)
(:button IDOK "OK" #x50010001 152 7 50 14)
(:button IDCANCEL "キャンセル" #x50010000 152 24 50 14)
(:static nil "元のファイル名(&O):" #x50020000 7 7 48 8)
(:edit old nil #x50810880 7 17 140 14)))
(list (cons 'new (my-filer-rename-with-timestamp name))
(cons 'old (file-namestring name)))
'((new :non-null "新しいファイル名を入力して" :enable (IDOK))))
(when result
(cdr (assoc 'new data)))))
(defun my-filer-copy-as ()
(let ((old-file (filer-fetch-file))
new-file)
(when old-file
(when (file-directory-p old-file)
(error "ディレクトリはまだできてない"))
(setq new-file (my-filer-get-copy-file-name old-file))
(when new-file
(let ((if-exists :error)
(if-access-denied :error))
(declare (special if-exists if-access-denied))
(setq new-file (merge-pathnames new-file (filer-get-directory)))
(filer-subscribe-to-reload (directory-namestring new-file))
(filer-copy-file old-file new-file)
(message "done."))))))
(define-key filer-keymap #\@ 'my-filer-copy-as)
(in-package "user")
こいつを .xyzzy に書いておく。そんで、ファイラー上で@を押すと、デフォルトがいままでの『(ファイル名)~』ではなくて、『(ファイル名)_YYYYMMDD.(拡張子)』になるので、@押してそのままEnterでコピーできてオレ的には便利。
- ロロ「
- ファイルを管理するのには、もっと良い方法を――たとえば、CVSなどのバージョン管理システムを導入するなど――探すべきだと思いますけれどね」
■RSSとは
permalink:"200310.html#d21_t6"
なんかバージョン管理システムのことかと思ってた。それはRCS。
- ここ見ればほとんど解決
- RSS -- サイト情報の要約と公開(神崎正英さん)
ただこれだけではいま現在自分にあるいは客にどんなメリットがあるのかわからない。
エージェント達(検索サイトとかのロボットのことね)が色々便利に使うだろうことはわかったけれども、例えばどんなエージェントなのか、それはある特定のコミュニティに参加しなければ意味のないものなのか…etc.
- 興味深い記述
- semblog-dev: RSSとHTML
アレか! 要するに昔からある、WWWCよませ用メタデータみたいなもんか!規格だけあって流行ってなかったけど、自動生成ツール&自動収集ツールのおかげでどばっと(ファイル数が)増えたと。っていうかWWWCメタデータから半歩も進んでないような気がする。XML、RDF、お墨付きを得てカッキテキなふりしてしゃしゃり出てきただけってことはないだろうか。
どうもオレXML陣営が好きになれん。それは、なんか宣伝の方法がおかしいからなんだよ! みんなでフォーマットを合わせて幸せになろうよ! ってのでいいじゃねえか。なのになんだか話がおおげさにおおげさになっていくのはナゼ? XMLのパブリックな文章からは、ぶっちゃけこういう話です、というのを全員が避けて話しているような緊迫感をうける。
- 解決篇
- HotWired Japan: RSSでサイトの情報を公開しよう(Jason Cookさん)
あーあやっぱバージョンで揉めてるのね。0.91の次は2.0で、関係なく0.9xの次は1.0で、RSSはReally Simple Syndicateの略で、RSSはRDF Site Summeryの略らしい。もうなんかわやくちゃですやん。
プログラマ的勘だと、こういうのは政治的判断をしようとしちゃダメだな。後でいくらでも直してやるぜってことで、今ツールが動く一番枯れたバージョンにすべきだ。ということで HotWired のお薦めは 0.91 なのかな?
HotWiredの記事はわかりやすいな。みんなが避けて話していたぶっちゃけ話が全部書いてあるよ…
- 結局使ってみないとわからん?
- アンフェタデスク
RSSビューアー。向こうの企業ページとか、blogとか見たらだいたいわかるらしい。
WWWCは更新チェックだけだよね? 伺かの『ヘッドラインセンサ』は実際にhtmlを取りに行ってるんだっけ? この辺もなんか似たようなもん感が激しくするね…
■RSS リンクメモ
permalink:"200310.html#d21_t7"
- CNET Japan - Blog戦争:RSSはどこへ行く?
- ZDNN:ブロッグの世界でも、ついに“業界標準戦争” CNETと原文同じと思われ。
- NDO::Weblog: RSS を巡る業界標準戦争について、ZDNNにて。
- エンタープライズ:Opinion:Webサービス標準の対立は時間のムダ はげどう。
- dW:Web services:Python Web servicesデベロッパー:Python用のRSS
- [N]:RSSとは?
- 創語: ついにRSSに火がついた
- RSS(RDF Site Summary)[HTML・XML]All About Japan
- @ parallel minds:「リンク」から見るweb日記とblog
これについては風野さんの - 読冊日記2003年5月下旬 で語られてるので
2003.10.22
■うそつき四択
permalink:"200310.html#d22_t1"
『がしゃがしゃがしゃ、ちーん』という音を聞いて『あーレジスターね』とわかる世代はどこからどこまでなんだろうか。けっこう、機械式レジスターなんか見たこともないって人も、テレビのSEの影響で音としては聞いたことがあったり、計算とか金額と結びついて覚えてる人は多そうなんだけど。
■おれの名は IP パケット
permalink:"200310.html#d22_t2"
おれの名は IP パケット。
生まれは東京都内のあるビルの中。
これから太平洋を越えて、某米国企業のメールサーバまで、
長い航海のはじまりだ。
昔感動したスレがまだ細々と続いていたので、時間を忘れて読んでしまった。
■[xyzzy]Han さんのサイトでスクリプト拾う
permalink:"200310.html#d22_t3"
日記を読んでイロイロ導入する。Hanさんの日記は会社で読むにはちとエチーのですがなるべくxyzzyネタにしぼって読む。すばらしいスクリプトがいっぱいあるよ。
- ロロ「
- ここで『セッション』という機能をはじめて知りました」
『セッションを開くときに最初に表示されるディレクトリを変更』『リージョンと選択範囲をトグルで変換』『タイプしたキーバインドをglobal-set-keyの構文としてバッファに挿入する』『入力した機能が、割り当てられているキーを調べる(即席) 』などなど、たくさん頂きました。
■アレだな
permalink:"200310.html#d22_t4"
10月の最初のほうに、もうしわけ程度に見たテレビについて言及したりしてるくせに、その後ぜんぜん書いてねえや。あー。攻殻も続き見てるし、ビギナーも続き見てますよ。あとマンガ買ったり、文庫本読んだりもしてるんですけど、感想書くタイミング逸しちゃってダメです。
2003.10.23
■ES細胞
permalink:"200310.html#d23_t1"
- ロロ「
- 余りにも馬鹿みたいですが、包み隠さないファーストインプレッションということで晒しておきます」
京都大学が分離に成功? したみたいなんだけど、ヒトの受精卵の細胞? どんな臓器にも成長? ブタに移植したりするんだろうなあ。攻殻に出てたアレだわ。何がインパクトあったかって、恥ずかしながら ES細胞って名前を知らなかったけど、そのネーミングが未来っぽくてすげぇ。21世紀っぽい!
2003.10.24
■大塚さんの笑顔だけ見てまた眠る
permalink:"200310.html#d24_t1"
すっかり二度寝の習慣がついてしまい。
最初に鳴るのは目覚し時計。その次に携帯のアラーム、さらにその次に携帯のメッセージ機能でベルを鳴らす三段構えにしているのだが、そろそろ効き目がなくなってきた。
今朝は三段構えを全消しにした後にもまた惰眠。電車20分前に習慣と気力だけで起きた。
■アラハタはジャム屋さんのアヲハタの字面から来た語か
permalink:"200310.html#d24_t2"
読冊日記より。夢の中に出てきた奇妙な単語達がすごく面白いんですけど。奇妙ぐあいが脳に心地よく、卓越した言語センスによっぱらいました。
- ありがとうと言おう7ヶ条 その7
上記以外でありがとうと言ってもいいなと思ったときはありがとうと言おう。
- 夢の中で竹本泉の漫画を読んでいたら出てきた文。
(2000年10月30日)
ワラタ。出てきそう。
2003.10.25
■内部演繹
permalink:"200310.html#d25_t1"
そろそろ1ヶ月なのでみんなに来てもらえる方法を模索する。
俺の日記に誰もリンク張ってくれません
http://pc.2ch.net/test/read.cgi/unix/1010930714/
- ロロ「
- そんなことを模索するより、内容の充実に力を入れた方がいいのではないでしょうか」
これでもオレにしたらがんばって書いてるほうなんですが。
- ロロ「
- ここ数日プログラミングの話をしていませんよ」
結構こまかい修正なんかやっちゃいるんだけど、後で書こうと思うとめんどくさくってねー。
- ロロ「
- Windows プログラミングも題材に取り上げるはずだったのですが」
『猫でも』にもリンクさせてもらっときながら、ふがいないな〜。まあいずれやりますよー。
- ロロ「
- あと、私は、こんなキャラクターでいいのですか? スタンスとしても特に定まってはいませんし、言葉遣いも慇懃なだけですけれども」
あんまりきゃぴりん☆ってキャラだと難しいし疲れるし気持ち悪がられるし。
- ロロ「
- 萌えますか?」
俺は、わりと。
2003.10.26
■レガシーデバイス
permalink:"200310.html#d26_t1"
古いニュースだが、日本テレビのプロデューサーが視聴率リサーチ対象家庭を興信所で探し出し、不正を働いたという話。視聴率って数百世帯だけで測ってるんだよな、確か。
思うんだけど、今時視聴率なんててきとーなもんで測ってる場合なのか? それはサンプル数が少ないとかもあるけれど、『TV付けてる奴がどのチャンネルに合わせてるか』なんて今や娯楽はTVだけじゃあるまいに、民放だけでだんだん小さくなるパイを食い合って満足してていいのかって話。
日本シリーズを各社奪い合って掛け持ちでやったり(当然通常番組は割食うし)、番組改変期とか銘打ってつまらないバラエティを同時にやったり、そういうたかが裏同士の戦いってバカバカしいとか思わないのかなあ。HDDレコーダが出てきてこういうのは無くなっていくだろうと思ってたんだが。
デジタル放送になったらどうなるのかな。どう考えても技術的に『何を観てるか』ぐらい把握可能だろうし、もしデジタルになってもリサーチ会社が同じことしてるとしたら完璧な欺瞞、癒着だろうと思うよ。
■あなたの精神年齢チェック
permalink:"200310.html#d26_t2"
あなたの精神年齢は【5歳】ぐらいで【幼児・小学生】レベルです。
どうもあなたは実年齢に比べて、まったく精神的に自立できていないようです。
まあそれはいい。いいけど、試しに『現在恋人がいる』の質問をかえて再度判定してみた。
あなたの精神年齢は【25歳】ぐらいで【華の青年】レベルです。
あなたは普通の社会人として通用する程度の精神年齢の持ち主です。
ムカつく。さらに試しに年齢と『現在恋人がいる』以外の項目を全部子供っぽい(であろう)モノに変えてみた。
あなたの精神年齢は【25歳】ぐらいで【華の青年】レベルです。
あなたは普通の社会人として通用する程度の精神年齢の持ち主です。
ムカつく(笑
2003.10.27
■[xyzzy]テキストの比較 と カッコの強調表示
permalink:"200310.html#d27_t1"
xyzzy でテキストを比較したいときに、よく M-x diff を使うのだが、diff に .xyzzy のような lisp で書かれたファイルを読ませてやると、たまにカッコの扱いで不具合が出る気がする。
調べてみると、どうやら
- きたさんの paren.l
- xyzzy 標準の(亀井さんの) diff.l
この二つが競合? しておこる不具合のようだ。
paren.l とは lisp プログラムや C プログラムで、開きカッコと閉じカッコの対応付けをやってくれる超いい感じのライブラリだ。
lisp プログラミングなんかをやっていると、とにかくカッコだらけになってどこがどこに対応してるのかわからなくなってくる。もちろん xyzzy の lisp-mode は、コマンドひとつでどこが対応してるのか教えてくれたりするんだけど、これを随時ビジュアル的に示してくれるのが、paren.l 。ちょっと表示を控えめにして使ってる。こんな感じ。
;; site-lisp/paren
(require "paren")
(setq-default editor:*paren-highlight-only-paren* t)
(turn-on-global-paren)
diff.l は前にもやったテキストを比較してくれるやつね。比較だけじゃなくて、一部分の同期を取ったりすることもできる。
どちらも便利で手放せないライブラリなので、なんとかしたいなあ。
- ロロ「
- ここで、いつもの様にgooglingします。
xyzzy の 音 にばっちり対処方法が書いてありました。さらにリンク元のOHKUBO Hiroshi さんの xyzzy 関連の覚え書きによると、M-x diff 中はやはり paren.l の強調表示はないほうがいいようですね」
ふむ。こんな感じで siteinit.l に登録してみたよ。
(add-hook 'ed::*diff-mode-hook* 'turn-off-paren)
autoload とパッケージまわりでうまくいくかどうか不安だったけど、問題ないみたい。
今回は一発解決だったなあ。次もうまくいくといいんだけど。
■[nDiary]ソース色付け
permalink:"200310.html#d27_t2"
テスト。
ruby, lisp, C, C++ ちゃんぽんでソースコメント文字列の色を変換する nDiary 用フィルターの。
;;
;; じぶんが特殊バッファだったら削除&ウィンドウを戻す(qキーに割り当て 過激?)
;;
(defun quit-temp-buffer-or-self-insert () ;; コメント
(interactive)
(let ((name (buffer-name (selected-buffer))))
(or
(if (member name
'("*grep*" "*Help*" "*Completion*" "*Shell output*"
"nDiary output" "*Command Output*")
:test #'string=)
(progn
(delete-buffer name)
(if (> (count-windows nil) 1) /* コメント C用だから変だけど */
(delete-window))
t))
(self-insert-command))))
(global-set-key #\q 'quit-temp-buffer-or-self-insert)
// lispじゃ使えないけど コメントのテストだから
// 気にしない。
こんな感じでちかんかましとります。
class Filter
COLORIZ_BEGIN = ' [Class]'
COLORIZ_END = '[/Class]'
def colorize(str, type)
case type
when :CODE
#こめんと
str.gsub!(%r{(/\*.*\*/)}m, COLORIZ_BEGIN + '{comment}\1' + COLORIZ_END);
str.gsub!(%r{(//[^]]*)$}m, COLORIZ_BEGIN + '{comment}\1' + COLORIZ_END);
str.gsub!(/(;;[^]]*)$/m, COLORIZ_BEGIN + '{comment}\1' + COLORIZ_END);
str.gsub!(/(#[^])]*)$/m, COLORIZ_BEGIN + '{comment}\1' + COLORIZ_END);
#リテラル
str.gsub!(/([^\\])(\".*[^\\]\")/m,
'\1' + COLORIZ_BEGIN + '{literal}\2' + COLORIZ_END + '\3');
str.gsub!(/([^\\])('[^\\]')/m,
'\1' + COLORIZ_BEGIN + '{literal}\2' + COLORIZ_END + '\3'); # 1文字のみ
when :AFTER_CODE
str.gsub!(%r{ \[Class\]\{([\w]+)\}(.*)\[/Class\]}m,
'<span class="\1">\2</span>')
end
end
end
まだ、色分けの判断ミスが起こるんだよなあ。
- ロロ「
- これ以上に複雑なことがやりたいのであれば、Code: のオプション設定で言語を指定するなどの方法に切り替えたほうが良さそうですね」
2003.10.29
■Ruby嫌いでGoogle
permalink:"200310.html#d29_t1"
ちょっとネタのつもりでぐぐってみる。本当にRuby嫌いな人のサイトはほとんど引っかからない…のだが…。
検索結果を読んでるとだんだん Ruby が嫌いになってきた。
なんつうか、人に勧めるカンドコロを間違えてる奴が多すぎ。
もうオレとしては Ruby 萎え。
- ロロ「
- 私は、そうでもないですよ。たくさんの言語を知っているということは、それだけたくさんの道具を持っているのと同じことだと思いますから。それに、nDiary のプラグインを作ってみたいですし」
…そうなんだ。オレのテンションは下がるいっぽうなのに、勉強したい気持ち(ロロの人格)のほうは全然下がらない。癪にさわらない入門ページを探すか…
■ムカつかない入門ページを探す
permalink:"200310.html#d29_t2"
■[Ruby]入門中メモ
permalink:"200310.html#d29_t3"
- ブロック、イテレータがこんな文法だとは知らなかった。なるほど… Ruby はこういうやり方で if や while といった条件構文もメソッドとして取りこんでいるわけか…
- Rubyにとってのメソッドは Lispにとってのリストと同じ? ていうか if とかこういうの何て呼んだらいいんだ? ブロックメソッド?
- カンマ使った代入文(i,j = j,i+j こんなの?)は見慣れないなあ。慣れるまでは左辺はカッコでくくっておくか。
- 「気軽なオブジェクト指向プログラミングを支援するスクリプト言語」というキャッチフレーズはいいな。
- 微妙に難しいな。(2..5) === i を別の形式で書きたいときは?
- for i in obj と obj.each do |i| は同じ処理を行なう
- ifもちゃんと値を返すよ。
- 文の最後に“;”をつけなくてもよい、文を何行に分けて書いてもよい、ということは… オーバーロード(引数の型や数によって違うメソッドを実行)は無い?
- 『オブジェクトです』『メソッドです』で説明した気になってはいけないなと自戒。なんかこの辺を何も知らない人に説明するには、実装の例をかんたんにして1コ見せたほうがわかりやすいのかも。
- 知りもしないモノを貶す人は、知りもしないモノを人に薦める。
2003.10.30
腿の側面の筋肉がすげぇ痛いYO。スクワット200回やったせいだ。
- ロロ「
- 弱」
脚だけはチャリで鍛えてると思ってたんだが。
- ロロ「
- 自転車とは使う筋肉の部位が違うのでしょうね」
さきおととい始めたときは、400回ぐらい軽くできると思ってたんだけどなあ。
- ロロ「
- …一昨昨日? 三日前からずっと筋肉痛を持ち越したままなんですか?」
へえ。さきおとといって『一昨昨日』と書くんだ。なぜ『二昨日』じゃないんだろう。