TextWrangler上でmakeしたい

TextWranglerをひとしきり褒めた?ところで、本題。TextWrangler上で統合開発環境のような勝手でmakeしたいという話。
"Run current line as shell command"みたいなのを作ってEmacsのターミナルモードもどきも考えたのですけれど、前にも書いた気がしますがWindows出身の私としてはTerminal.appに充分に満足してまして、正直これでいいじゃんと思ってます。なのでこの話は置いておいて。
やりたいこと
TextWrangler上で特定キーを押す→Terminal.app上でmakeが走る→TextWrangler上でエラー位置にキャレットを移動
この流れを1アクションでやりたい。
何をどう組み合わせるか
TextWrangler上で特定キーを押す→OSXの機能でTextWranglerのメニューに出てるAppleScriptを起動AppleScriptからTerminal.appにコマンドを投げる→Terminal.app上でmakeが走る→エラー位置を切りだしてeditコマンドを実行→TextWrangler上でエラー位置にキャレットを移動
この赤字の部分を作ればOK。
AppleScriptからTerminal.appにコマンドを投げる部分(make.scpt)

tell application "TextWrangler"
	set saved to false
	set n to count text document
	if n > 0 then
		set saved to on disk of front text document
		if saved then
			set the_file to file of front text document
		end if
	end if
	
	if saved then
		set makefile_exists to false
		set cmd to "make"
		tell application "Finder"
			set the_parent to parent of the_file
			repeat
				if POSIX path of (the_parent as alias) = "/" then
					exit repeat
				end if
				-- .#makefile (Finder can not take hidden file)
				set makefile_path to (POSIX path of (the_parent as alias)) & ".#makefile"
				if ((do shell script "test -f " & quoted form of makefile_path & " ; echo $?") as integer) = 0 then
					set makefile_exists to true
					set cmd to "make -f .#makefile"
					exit repeat
				end if
				-- makefile
				set makefile_path to (the_parent as string) & "makefile" -- ":" format
				if file makefile_path exists then
					set makefile_exists to true
					exit repeat
				end if
				-- next
				set the_parent to parent of the_parent
			end repeat
		end tell
		if makefile_exists then
			try
				-- treat makefile_path as alias, raise an error when the normal file
				set link to do shell script "readlink " & quoted form of makefile_path
				-- extract dir
				set make_body to (POSIX path of (the_parent as alias)) & link
				set rev_make_body to (reverse of characters of make_body) as text
				set delimiter to offset of "/" in rev_make_body
				set rev_parent to text delimiter thru (length of rev_make_body) of rev_make_body
				set dirname to (reverse of characters of rev_parent) as text
				-- removing "." or ".." (slash of "$PWD/" is necessary)
				set dirname to do shell script "cd " & quoted form of dirname & " && echo $PWD/"
			on error
				set dirname to POSIX path of (the_parent as alias) -- with last slash
			end try
			set cd_cmd to "cd " & (quoted form of dirname) & " # compiling"
			
			tell application "System Events"
				set terminal_launched to exists (application processes whose bundle identifier is "com.apple.Terminal")
			end tell
			
			tell application "Terminal"
				if terminal_launched then
					set existed to false
					repeat with the_window in windows
						set the_tab to tab 1 of the_window
						if (history of the_tab) contains cd_cmd then
							set existed to true
							do script "clear" in the_window
							do script cmd in the_window
							-- activate
							exit repeat
						end if
					end repeat
					if not existed then
						do script cd_cmd
						set new_window to front window
						do script cmd in new_window
						activate
					end if
				else
					repeat
						set n to count window
						if n > 0 then
							exit repeat
						end if
						delay 0.1
					end repeat
					set new_window to window 1
					do script cd_cmd in new_window
					do script cmd in new_window
					activate
				end if
			end tell
		else
			display dialog "makefileが見つかりません"
		end if
	else
		display dialog "TextWrangler上でファイルが保存されていません"
	end if
	activate
end tell

エラー位置を切りだしてeditコマンドを実行する部分(autojump)

#!/usr/bin/env ocaml

if Sys.command "which edit" > 0 then (
	print_string "command-line tools of TextWrangler were not intalled.\n";
	exit 1
);;

if Array.length Sys.argv <= 1 then (
	print_string "usage: autojump make -w\n";
	exit 1
);;

let cmd =
	let b = Buffer.create 256 in
	let last = Array.length Sys.argv - 1 in
	for i = 1 to last do
		Buffer.add_string b Sys.argv.(i);
		if i < last then Buffer.add_char b ' '
	done;
	let s = Buffer.contents b in
	if s = "make" then "make -w" else s;;

let log = Filename.concat (Sys.getenv "TMPDIR") "autojump.log";;
let (_: int) = Sys.command (cmd ^ " 2>&1 | tee \"" ^ log ^ "\"");;

#load "str.cma";;

let re_cd = Str.regexp "^make\\(\\[[0-9]+\\]\\)?: Entering directory `\\(.*\\)'$";;
let re1 = Str.regexp "^\\([^:]+\\):\\([0-9]+\\): ";; (* gcc *)
let re2 = Str.regexp "^File \"\\([^\"]+\\)\", line \\([0-9]+\\)";; (* ocaml *)

let f = open_in log in
try
	let edit dir file line = (
		Sys.chdir dir;
		let command = "edit " ^ file ^ ":" ^ line in
		print_string command;
		print_newline ();
		ignore (Sys.command command)
	) in
	let rec loop ~dir = (
		let line = input_line f in
		if Str.string_match re_cd line 0 then (
			let entering_dir = Str.matched_group 2 line in
			loop ~dir:entering_dir
		) else if Str.string_match re1 line 0 then (
			let file = Str.matched_group 1 line in
			let line = Str.matched_group 2 line in
			edit dir file line
		) else if Str.string_match re2 line 0 then (
			let file = Str.matched_group 1 line in
			let line = Str.matched_group 2 line in
			edit dir file line
		) else (
			loop ~dir
		)
	) in
	loop ~dir:"."
with End_of_file -> close_in f;;

シェルスクリプトで書けなかった私にはUNIX使いを名乗る資格は無い。
使い方
make.scptをTextWranglerのScripts Folderに入れます。(キーボードショートカットを振る)
make.scptを動かすと、ターミナルをアクティブにして、現在開いているファイルと同じかそれより上の位置にあるmakefile(または.#makefile)を使ってmakeして、再びTextWranglerをアクティブにするところまでやってくれます。同じディレクトリで繰り返す場合はウィンドウは使いまわします。これだけではエラー位置には飛びません。
エラー位置に飛ぶにはmakefileの方でautojump経由でコンパイルする必要があります。.#makefile(.#で始まる名前はsubversionのグローバル無視ファイルですのでこの名前)があればmakefileより優先して使いますので、autojump make -wとでもしておけばOKです。めんどい場合はAppleScript側のset cmd to〜を弄ってください。あれ、なんで今やってないんだっけ……。
ソース位置とmakefileのある位置が違う場合は、makefileへのシンボリックリンクを.#makefileの名前でソース位置に置けば辿ります。AppleScriptからのファイル操作はtell application "Finder"で行ないますので、隠しファイル扱えないんですよ……ひそひそ……。do shell scriptでtest -fやreadlinkを呼んでます、もっと賢い回避策無いかな……。