Home > Archives > 2007年01月

2007年01月

リージョンを シェルコマンドの実行結果で置換3

整理してこんな形になった.まだ微妙にあやしいけどそのうちちゃんと elisp を勉強しよう.

(defun filter-command-region (start end command)
  "Filter region by a command. 
The region is passed to the command as input.
The region is overwritten by the result."
  (interactive (perfom-command-region-interactive-func
		"Shell command on region (filtering): "))
  (perform-command-region-general start end command nil nil t))
 
(defun perform-command-region (start end command) 
  "Perform a command on region.
The region is passed to the command as input.
The region remains on top of the result."
  (interactive (perfom-command-region-interactive-func
		"Shell command on region: "))
  (perform-command-region-general start end command nil nil nil))
 
(defun perform-command-region-comment (start end command)
  "Perform a command on comment-region.
The region is uncommented and then passed to the command as input.
The comment-region remains on top of the result."
  (interactive (perfom-command-region-interactive-func
		"Shell command on commented region: "))
  (perform-command-region-general start end command t nil nil))
 
(defun perfom-command-region-interactive-func (msg)
"A general interaction function for perform-command-region-general..."
  (let (string)
    (unless (mark)
      (error "The mark is not set now, so there is no region"))
    ;; Do this before calling region-beginning
    ;; and region-end, in case subprocess output
    ;; relocates them while we are in the minibuffer.
    (setq string (read-from-minibuffer msg
				       nil nil nil
				       'shell-command-history))
    ;; call-interactively recognizes region-beginning and
    ;; region-end specially, leaving them in the history.
    (list (region-beginning) (region-end)  string)))
;;
;; perform a command on region.
;;
(defun perform-command-region-general (start end command uncomment comment overwrite)
  "A general function to perform a command on region.
uncomment: Set t to uncomment the region before passing it to the command. 
comment  : Set t to comment-out the region after the command. 
overwrite: Set t to overwrite the region with the result of the command. 
           Otherwise the original region remains on top of the result.
"
  (let ((swap (< start end)) (exit-status))
    (if (not overwrite)
	(let ()
	  (kill-region start end)
	  (setq sp (point-marker))
	  (yank nil)
	  (setq ep (point-marker)))
      (let ()
	(goto-char start)
	(setq sp (point-marker))
	(goto-char end)	
	(setq ep (point-marker))))
    ;; uncomment the region
    (and uncomment (uncomment-region (marker-position sp) (marker-position ep))
    (goto-char (marker-position sp))	  
    (setq exit-status
	  ;; see describe-function
	  ;; error output is marged into standard output
	  (call-process-region (marker-position sp) (marker-position ep) shell-file-name t
			       (list t t)
			       nil shell-command-switch command))
    ;; swap the point and mark if necessary
    (and swap (goto-char (marker-position sp)))
    ;; yank the original contents
    (if (not overwrite)
	(let ()
	  (setq p1 (point-marker))
	  (yank nil) 	
	  (setq p2 (point-marker))
	  (and comment (comment-region (marker-position p1) (marker-position p2)))
	  (setq p1 nil)
	  (setq p2 nil)
	  )) 
    (setq sp nil)
    (setq ep nil)
    exit-status))
;;
;; Key bindings
;;
(defun filter-command-region-keybindings ()
  "Set up default key bindings for filter-command-region, ..."
  (interactive)
  (define-key global-map [(control ?!)] 'filter-command-region)
  (define-key global-map [(control meta ?#)] 'perform-command-region)
  (define-key global-map [(control meta ?!)] 'perform-command-region-comment))

リージョンを シェルコマンドの実行結果で置換

vi の ! コマンドに対応するコマンドを shell-command-on-region を簡略化して作ってみる.キモは call-process-region という組み込み関数.

;; replace specified region with output of 
;; a shell command against the content of the regon
(defun filter-command-region (start end command)
  (interactive 
   (let (string)
     (unless (mark)
       (error "The mark is not set now, so there is no region"))
     ;; Do this before calling region-beginning
     ;; and region-end, in case subprocess output
     ;; relocates them while we are in the minibuffer.
     (setq string (read-from-minibuffer "Shell command on region: "
					nil nil nil
					'shell-command-history))
     ;; call-interactively recognizes region-beginning and
     ;; region-end specially, leaving them in the history.
     (list (region-beginning) (region-end)  string)))
  (let (exit-status)
    ;; Replace specified region with output from command.
    (let ((swap (< start end)))
      (goto-char start)
      (push-mark (point) 'nomsg)
      (setq exit-status
	    ;; see describe-function
	    ;; error output is marged into standard output
	    (call-process-region start end shell-file-name t
				 (list t t)
				 nil shell-command-switch command))
      ;; swap the point and mark if necessary
      (and swap (exchange-point-and-mark)))
    exit-status))
(define-key global-map [(control ?!)] 'filter-command-region)

shell-command-on-region が M-! なので C-! で使えるようにしてみた.元のリージョンを上書きせずにコメントしてくれるほうが使いやすいかも…

リージョンを シェルコマンドの実行結果で置換2

ついでなので,元のリージョンの内容を出力の上部にコメントとして出力するものも作った.

(defun perform-command-region (start end command)
  (interactive 
   (let (string)
     (unless (mark)
       (error "The mark is not set now, so there is no region"))
     ;; Do this before calling region-beginning
     ;; and region-end, in case subprocess output
     ;; relocates them while we are in the minibuffer.
     (setq string (read-from-minibuffer "Shell command on region: "
					nil nil nil
					'shell-command-history))
     ;; call-interactively recognizes region-beginning and
     ;; region-end specially, leaving them in the history.
     (list (region-beginning) (region-end)  string)))
  (let (exit-status)
    ;; Replace specified region with output from command.
    (let ((swap (< start end)))
      (goto-char start)
      (kill-region start end)
      (yank)
      (push-mark (point) 'nomsg)
      (setq exit-status
	    ;; see describe-function
	    ;; error output is marged into standard output
	    (call-process-region start end shell-file-name t
				 (list t t)
				 nil shell-command-switch command))
      ;; swap the point and mark if necessary
      (and swap (exchange-point-and-mark))
      ;; mark current position
      (setq p1 (point-marker))
      (set-marker-insertion-type p1 nil)
      ;; yank the original contents
      (yank nil) 
      (setq p2 (point-marker)) 
      ;; comment the yanked contents
      (comment-region (marker-position p1) (marker-position p2))
      (setq p1 nil)
      (setq p1 nil))
    exit-status))
(define-key global-map [(control meta ?!)] 'perform-command-region)

そして C-M-! で発動すると.これって comment-region がない場合にどうなるんだろう?

論文が…

二通りの立場が混ぜ合わされていることを指摘される.指摘されるとわかるのだが,執筆中はローカルの最適解へ向かってしまうため気づかない.もう少しグローバルな最適化をちゃんとすべきだなぁ.何はともあれ,さっさと直して10ページに収めましょう.

メインPCがストライキ

へんな負荷をかけたら突然ウィンドウがまったく開かなくなった.どうやらお仕事したくなくなったらしい.しょうがないのでまっさらに記憶喪失になってもらうことにした.とりあえずWebとメールは復旧したがそれ以外のツール群が… すでに半日つぶしたので後はレイジーにインストールしよう.

Emacs Lisp の関数定義を探す

describe-function というコマンドで見つかるらしい.

近くで火事

消防車のサイレンで二度寝できず外に出てみたら煙が… 出火原因は良く分からんけど最近乾燥しとるので火の元には注意しようかと思う.

使えん

どうみてもBINDの設定がGUIでは最低限しか出来ない.view 設定で内向きと外向きを切り替えるとか全く出来なさそう.隠しメニューとかあって出来るのかもしれないが… 見つけられん.よって GUI で DNS の設定をするのはあきらめましょう.

MacOS をいじる

サーバのセッティングが仕事として降ってきたのでラックに載せたりしてみた.旧サーバの電源のファン辺りから異音がしているのでさっさと移行しないとやばそうかも.しかしながら,なるべくGUIの設定ツールで設定してくれといわれたため作業進まず.

いつものように延びる

締め切りが毎度のごとく一週間程度延びたことに気づく.さっさと終わらせたいところだが色々書き換えねば…

つづく

First version 上げる予定だったが思いのほか苦戦.まだ書き続ける.

書く

どう考えてもLNCS10ページは短すぎる.アイデアだけ例示して技術的な詳細はテクレポ行きで.つーわけで手元にある情報を全部書き出す.

Fate/Zero 読み終える

とりあえず,つづきまだー? そして,文庫サイズの方が読みやすいと思うのは気のせいだろうか?

ひとりごと

scan/scanr の後に shift つけるとわけ分からなくなる…と思ったが,計算途中に断面の要素の計算を一部重複するので条件付で簡単であることに気づく.が,定式化すんの面倒かも.なんにせよscanとscanrの同時使用は中間データを作らざるを得ないので気にしないのが良い気がする.

Fortress つづき

fortress スクリプトのクラスパスがおかしい(revision 89).手動で直せということか? ここら辺全部まとめて ant のタスクにしてくれたほうが使いやすいのだが… とりあえず syntax expander を求めてソースをさかのぼる.

今日は雨?

朝起きた.雨が降っていた.寝なおした.また起きた.雨が降っている気がした.考えながら寝る.

scan と scanr の通信を同時に出来るか?

Tree 式の計算だと p = 2^k でなくても 2log(p) ステップで通信の形を同じに出来るので通信を同時にできる.HyperCube 式の計算だと p = 2^k なら log(p) ステップで通信を同時に出来る.でも,HyperCube式で p = 2^k でないと通信の形が同じにならずに結局 2log(p)ステップかかる.特殊ケース以外は結局通信のステップ数がどうにもならんので scan と scanr は同時にやる必要ない気がする.

おもちゃ届く

昨日ふと思い出して注文したジャイロマウス(空間マウス)BOMU-W24A/BLが届いた.早速使ってみたのだがメニューの選択とかで「真横に動かす」とかの動作が難しい.まあ,プレゼンでそんなに細かい作業は要らないので問題ないだろうけど… 要練習.

探し物見つからず

連射王を探しに秋葉へ行ってみたが下巻のみしか見つからず.やはり先週買いに出るべきだったかと少々悔やんでみる.何も買わずに帰るのもあれなのでたくさん積まれてた Fate/Zero を購入して戻る.

Fortress@Windows は要修正

Windows 環境で Fortress 動かそうとしたら二回目の実行でこけることが判明.何が悪いのかとエラーメッセージを見てみたら,ライブラリの AST (FortressLibrary.jst) の読み込みに失敗しているらしい.まだまだ開発途中らしくライブラリのソースをパースした AST を *.jst に吐き出しておいて,次回以降の実行で再利用する仕様らしい.この*.jst には元のソースのファイル名も出力されるのだが,このファイル名が少々問題となっていた.

具体的には, Windows のファイル名には \ が含まれるため,パースに失敗する.解決としては \ をちゃんとエスケープすればいい.ライブラリの読み込みの処理を追っていくと

 com.sun.fortress.interpreter.driver
 com.sun.fortress.interpreter.nodes

あたりのクラスが関係していて

 Libraries#link -> Driver#writeJavaAst -> Printer#dumpSpan -> Span#appendTo -> SourceLoc#getFileName 

となっている.SourceLoc#getFileName の返すファイル名を Span#appendTo が出力しているので,この部分でエスケープをいれてやればいいはず.ということで,

            w.append("\"");
            // Need to add escapes to the file name
            w.append(begin.getFileName());
            w.append("\"");
            w.append(",");

            w.append("\"");
            // Need to add escapes to the file name
            w.append(begin.getFileName().replaceAll("\\\\", "\\\\\\\\"));
            w.append("\"");
            w.append(",");

にしてやってとりあえずの問題解決を図った.

Fortress を落としてくる

http://fortress.sunsource.net/ にてソースが公開された Fortress のソースをダウンロード.初めて Subversion を使用した.ダウンロードするだけなら guest のアカウントで落とせるとのことなので,

svn checkout http://fortress.sunsource.net/svn/fortress/trunk fortress --username guest

でパスワードは空で落とせる.とりあえずライセンスは BSD らしいのでどうとでもいじれる.

んで,何も考えず eclipse でプロジェクト開いたらエラーだらけ.500個超えてた気がする.どうやら一部のソースファイルをプログラムで生成するらしく ant 使って

 ant clean compile 

としてやらないとダメらしい.READMEにこのコマンド書いてあったけどふっ飛ばしてた.とりあえずコンパイル終わったので一休み.

CVS でHEADのバージョンと更新日付を一覧表示なスクリプト(無用?)

cvs でどのファイルが最近更新されてバージョンがいくつなのかを見やすく一覧表示したかった.というより,HEAD のやつと一個前のバージョンとの diff をうまく取る方法を知らんのでこんなことをしてみたくなった.ということで何も考えず次の一行が出来上がった.

cvs log  | awk 'BEGIN{ form = "%-20s %-10s %-20s\n"; printf form,"name","head","date"; } /Working file/{ p = $3} /head:/{ h = $2; cnt=0;} /date:/{ d = $2; if (cnt==0) { cnt = cnt + 1; printf form,p,h,d;}}'

cvs の出力の整形の仕方とか絶対あると思うのだけど… 調べるより書いたほうが速いに違いないと思ってみる.

一日ボケる

徹夜作業と風邪でダメージが蓄積していたため今日は一日ぼけーとして過ごす.なんか久しぶりにゲームした気がする.

ps2pdf でなく ps2pdf14 を使う

dvipsk と ps2pdf を使って dvi -> ps -> pdf と変換してたらいつの間にか”無効なフォント「MS-Mincho-H」が文書から削除されました”みたいなことを Acrobat が文句たれるようになっていた.この文句がでると文章全体がゴシック体になってしまうらしく困ってたのだが,ps2pdf14 を使って作成する PDF のバージョンを変えたら文句を吐かれないと分かった.何が違うんだろう?

クラスタの調子が…

実験用のプログラム書いたのにクラスタの一部のマシンの調子があまりよろしくないみたい.特定の部分のマシンを入れると実行時間が極端に変化する.やっぱりマシンの元気度を測るためのプログラムを一回作るべきなのだろうなぁ…

論文執筆中

先は長いが締め切りは近い.とりあえず主な部分だけ書いて共著者にコメントを求む.

さて本文を

式の整理に時間喰いすぎたので本文がほとんど書けてない… これから根性で書く.

ちと整理を

式の数が多すぎるのでまとめられる部分をまとめて整理する.が,ひじゃうに眠いので打ち込みは寝てから.

一回休み

頭痛くて寝てすごす.明日の準備もしなければ…

検証用コードは書けた.次は

どうにかごまかして検証コードを書けた.ということで,次は本文に式を移して説明と例を入れるべし.だがその前に,くしゃみばかりしているので寝る.風邪というよりアレルギーなきもしてきた…

Haskell ではまる

existential type でバインドされてて外側からは見えない型が二つあって,それらが同じ型である場合しか考えたくないのだがコンパイラにはそんなこと分からず… 動かん.そこの型を明示的に持てばこの部分だけは問題解決するが他の部分で… とりあえず計算のシミュレートさえ出来れば良いのでトリックでごまかす.

初詣へ

例年どおり早朝に三島大社へ初詣.おみくじは小吉.抱きかかえられていたフェレットに反応する人間多数.バッグに入ってた猫に反応する人間皆無.ところで,このおみくじでは小吉と吉のどっちが上なんだ?

Home > Archives > 2007年01月

Search
Feeds

Page Top