とりあえず日記

VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ(いまここ🍄)

秀丸エディタからclang-interpreterを呼び出してみた

先日作ったclang-interpreter秀丸エディタから呼び出してみた。
http://d.hatena.ne.jp/ohtorii/20110724/p1

clang-interpreterとは?

C/C++インタープリタです。
なんか凄そうですが、LLVM/Clangのサンプルを多少改造しただけのものです。

動作イメージ

標準出力を秀丸エディタのアウトプット枠へ表示しています。

printfとか


数学関数


パフォーマンス

clang-interpreterは内部でJITコンパイルしている(はず)のでそれなりに高速です。(VC2010でビルドしたバイナリと比べてたった7倍遅いだけです!!)

制限事項

  • STLのヘッダファイル(vector/string/deque/map/set...)とwindows.hはコンパイルできません。MSの独自拡張がありclang2.9ではビルドが通りません。(clang3.0に期待するしか・・・)
  • ユーザー定義のincludeパスは指定できません、、、そのうち何とかしたいなっと
  • 標準入出力(printf/fopen/fwrite...)は使用可能です。
  • VisualStudioのインクルードヘッダを参照します、VisualStudioをインストールしておいて下さい。
    • VisualStudio2008/VisualStudio2010で動作を確認しています、ヘッダファイルがあればいいので無料のExpress版でも大夫なはず。

まとめ

自分はC/C++で小さなテストルーチンを書くことが多いです、その試行錯誤を高頻度に行うことができるようになり個人的には満足しています。

アプリケーションをインタプリタで動かすことは目的にしていません、あくまでもコードの断片を動かすことだけが目的です。

コードを書いたその場で結果を確認でき、コードをファイルへ保存しなくても良いのがストレス無くて便利でした。

LLVMのWEBにコンパイルを行うサービスなどありますが、それはそれ、これはこれ、ということで。

Markdownを変換するマクロ書いてみた

最近、github絡みでMarkdown形式のテストをよく書くようになったので、HTMLへ変換してブラウザーで表示する秀丸マクロを書いてみた。
markdownをリアルタイムでプレビューするwebサービスなどありますが、それはそれということで。

変換前(秀丸エディタ

変換後(ブラウザー


注意


生成するHTMLのファイル名は固定です、変換するたびに上書きされます。
ブラウザでリロードして下さい。

必要な外部モジュール

perl界では有名(?)な、Markdown.pl を使ってコンバートしています、下記webからダウンロードしておいて下さい。http://daringfireball.net/projects/markdown/

ダウンロード

https://github.com/ohtorii/hidemaru_markdown
(右上のダウンロードからzipを選択して下さい。)

デマングル(demangle)する秀丸マクロを書いてみた。

LLVM/Clangを試しているとC++のマングル(mangle)されたシンボル名を、デマングル(demangle)したいことが、よくあるので秀丸マクロを書いてみた。
マングルされた名前はGCCとVisualStudioに両対応してます。

動作イメージ1

動作イメージ2(複数行選択)

動作イメージ3(矩形選択)

demangleする一般的なやり方

demangleするには、GNU Binary Utilities に含まれる c++filt を使うのが常套手段のようです。
しかしながら自分の環境ではうまくdemangleしてくれなかったので下記ソースコードをVisualStudioへ移植しました。

  • cp-demangle.cpp
  • cp-demangle.h
  • demangle.h

ついでと言っては何ですが、GCCだけでなくVisualStudioのシンボル名もdemangle出来るようにしました。
VCのほうはWindows-APIのUnDecorateSymbolName関数を呼んでいるだけです。

マクロの内部動作

秀丸マクロ側でデマングルするシンボル名を適当な正規表現でかき集めて、デマングルする実行ファイル(demangle.exe)を呼び出しています。
デマングルされた名前は標準出力に出力するので、それを秀丸エディタのアウトプット枠に取り込んでいます。

demangle.exe

>demangle.exe _ZN9wikipedia7article6formatEv ?Fv_Ul@@YAKXZ ?Fxx_i@@YAHP6AHH@Z0@Z
wikipedia::article::format()
unsigned long __cdecl Fv_Ul(void)
int __cdecl Fxx_i(int (__cdecl*)(int),int (__cdecl*)(int))

引数に与えるマングルされた名前はGCCとVCが混在しても良いです。具体的な内容はソースコードのコメントを参照して下さい。

ソースコード(Github)

https://github.com/ohtorii/demangle

導入方法は下記2ファイルを秀丸エディタスクリプトフォルダへコピーするだけです。

  • demangle.exe
  • demangle.mac

demangle.mac を適当なキーボードショートカットに割り当てて下さい。

License

GNU General Public License

「秀丸エディタから VisualStudio を制御するマクロ」を更新しました。

更新履歴

  • ファイル名に日本語が含まれていると正しく動作しない問題を修正。(バグ修正)
  • 秀丸エディタで編集しているファイルを VisualStudio で開くマクロを追加。(機能追加)

ダウンロードはこちらから

https://github.com/ohtorii/visual_studio_hidemaru

マクロの概要

秀丸エディタから VisualStudio を制御するマクロ」って何?ってな方はコチラを。
id:ohtorii:20110402:1301719953

補足

秀丸エディタで編集しているファイルを VisualStudio で開くマクロ」はVisualStudioと秀丸で同じファイルを編集しているときに便利かと思います。

monday.vimを秀丸エディタへ移植してみた。

2012年9月22日(土) 追記

窓の杜で紹介されました。
http://www.forest.impress.co.jp/docs/review/20120920_559434.html

始めに

vimエディタに面白いマクロがあったので秀丸エディタへ移植してみました。

キーを押すだけで単語をインクリメント・デクリメントできます。

  • January → February → March → April
  • class → struct
  • private → public → protected
  • iterator → const_iterator
  • true → false

動作イメージ(プログラマー向け)

動作イメージ(一般)

元ネタ

名無しのvim使い
http://nanasi.jp/articles/vim/monday_vim.html

monday : Lets you use ctrl-a and ctrl-x on names of months and weekdays
http://www.vim.org/scripts/script.php?script_id=1046

オリジナル版と比べて劣化している機能

大文字小文字の構成は無視しています。以下の変換を行いたいならマクロ本体のデータを修正するというベタな方法しかないです。

  • january → february
  • January → February
  • JANUARY → FEBRUARY

詳しくはマクロ内のコメントを参照して下さい。

マクロ(1つ次へ進める。switch_word_next.mac

/*単語を切り替える(一つ次へ)

秀丸エディタ ver8以降で動作。
キーアサインして下さい。
http://d.hatena.ne.jp/ohtorii/
*/
execmacro currentmacrodirectory+"\\switch_word.mac","1";

マクロ(1つ前へ戻る。switch_word_prev.mac

/*単語を切り替える(一つ前へ)

秀丸エディタ ver8以降で動作。
キーアサインして下さい。
http://d.hatena.ne.jp/ohtorii/
*/
execmacro currentmacrodirectory+"\\switch_word.mac","0";

マクロ(本体。switch_word.mac

/*単語を切り替える(内部処理マクロ)

(例)
	true -> false -> true ...
	class -> struct -> class ...
	private -> protected -> public -> private ...
	■ -> □ -> ■ ...
	● -> ○ -> ● ...

下記マクロから呼び出される。
	switch_word_next.mac
	switch_word_prev.mac


http://d.hatena.ne.jp/ohtorii/
*/


////////////////////////////////////////////////////////////////////////////
//		データ定義(必要に応じて編集して下さい)
//		データの追加削除はパターン化しているので分かるかと思います。
////////////////////////////////////////////////////////////////////////////
$eos		= "";
#num_tbl	= 0;

//注意:大文字小文字は区別します

//true -> false
$word_tbl[#num_tbl][0] = "true";
$word_tbl[#num_tbl][1] = "false";
$word_tbl[#num_tbl][4] = $eos;
#num_tbl = #num_tbl + 1;

//True -> False
$word_tbl[#num_tbl][0] = "True";
$word_tbl[#num_tbl][1] = "False";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//TRUE -> FALSE
$word_tbl[#num_tbl][0] = "TRUE";
$word_tbl[#num_tbl][1] = "FALSE";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//private -> protected -> public
$word_tbl[#num_tbl][0] = "private";
$word_tbl[#num_tbl][1] = "protected";
$word_tbl[#num_tbl][2] = "public";
$word_tbl[#num_tbl][3] = $eos;
#num_tbl = #num_tbl + 1;

//class -> struct
$word_tbl[#num_tbl][0] = "class";
$word_tbl[#num_tbl][1] = "struct";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//■ -> □
$word_tbl[#num_tbl][0] = "■";
$word_tbl[#num_tbl][1] = "□";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//● -> ○
$word_tbl[#num_tbl][0] = "●";
$word_tbl[#num_tbl][1] = "○";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//▲ -> △
$word_tbl[#num_tbl][0] = "▲";
$word_tbl[#num_tbl][1] = "△";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//▼ -> ▽
$word_tbl[#num_tbl][0] = "▼";
$word_tbl[#num_tbl][1] = "▽";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//★ -> ☆
$word_tbl[#num_tbl][0] = "★";
$word_tbl[#num_tbl][1] = "☆";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//◆ -> ◇
$word_tbl[#num_tbl][0] = "◆";
$word_tbl[#num_tbl][1] = "◇";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//on -> off
$word_tbl[#num_tbl][0] = "on";
$word_tbl[#num_tbl][1] = "off";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//On -> Off
$word_tbl[#num_tbl][0] = "On";
$word_tbl[#num_tbl][1] = "Off";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//ON -> OFF
$word_tbl[#num_tbl][0] = "ON";
$word_tbl[#num_tbl][1] = "OFF";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//あり -> なし
$word_tbl[#num_tbl][0] = "あり";
$word_tbl[#num_tbl][1] = "なし";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//はい -> いいえ
$word_tbl[#num_tbl][0] = "はい";
$word_tbl[#num_tbl][1] = "いいえ";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//in -> out
$word_tbl[#num_tbl][0] = "in";
$word_tbl[#num_tbl][1] = "out";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//In -> Out
$word_tbl[#num_tbl][0] = "In";
$word_tbl[#num_tbl][1] = "Out";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//IN -> OUT
$word_tbl[#num_tbl][0] = "IN";
$word_tbl[#num_tbl][1] = "OUT";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//begin -> end
$word_tbl[#num_tbl][0] = "begin";
$word_tbl[#num_tbl][1] = "end";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//first -> last
$word_tbl[#num_tbl][0] = "first";
$word_tbl[#num_tbl][1] = "last";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//. -> ->
$word_tbl[#num_tbl][0] = ".";
$word_tbl[#num_tbl][1] = "->";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//* -> &
$word_tbl[#num_tbl][0] = "*";
$word_tbl[#num_tbl][1] = "&";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//
$word_tbl[#num_tbl][0] = "iterator";
$word_tbl[#num_tbl][1] = "const_iterator";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//
$word_tbl[#num_tbl][0] = "reverse_iterator";
$word_tbl[#num_tbl][1] = "const_reverse_iterator";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//
$word_tbl[#num_tbl][0] = "unsigned";
$word_tbl[#num_tbl][1] = "signed";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//
$word_tbl[#num_tbl][0] = "min";
$word_tbl[#num_tbl][1] = "max";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//
$word_tbl[#num_tbl][0] = "yes";
$word_tbl[#num_tbl][1] = "no";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//
$word_tbl[#num_tbl][0] = "Yes";
$word_tbl[#num_tbl][1] = "No";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//
$word_tbl[#num_tbl][0] = "YES";
$word_tbl[#num_tbl][1] = "NO";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

//0...9
$word_tbl[#num_tbl][0]	= "0";
$word_tbl[#num_tbl][1]	= "1";
$word_tbl[#num_tbl][2]	= "2";
$word_tbl[#num_tbl][3]	= "3";
$word_tbl[#num_tbl][4]	= "4";
$word_tbl[#num_tbl][5]	= "5";
$word_tbl[#num_tbl][6]	= "6";
$word_tbl[#num_tbl][7]	= "7";
$word_tbl[#num_tbl][8]	= "8";
$word_tbl[#num_tbl][9]	= "9";
$word_tbl[#num_tbl][10] = $eos;
#num_tbl = #num_tbl + 1;

$word_tbl[#num_tbl][0]	= "0";
$word_tbl[#num_tbl][1]	= "1";
$word_tbl[#num_tbl][2]	= "2";
$word_tbl[#num_tbl][3]	= "3";
$word_tbl[#num_tbl][4]	= "4";
$word_tbl[#num_tbl][5]	= "5";
$word_tbl[#num_tbl][6]	= "6";
$word_tbl[#num_tbl][7]	= "7";
$word_tbl[#num_tbl][8]	= "8";
$word_tbl[#num_tbl][9]	= "9";
$word_tbl[#num_tbl][10] = $eos;
#num_tbl = #num_tbl + 1;

$word_tbl[#num_tbl][0]	= "0";
$word_tbl[#num_tbl][1]	= "1";
$word_tbl[#num_tbl][2]	= "2";
$word_tbl[#num_tbl][3]	= "3";
$word_tbl[#num_tbl][4]	= "4";
$word_tbl[#num_tbl][5]	= "5";
$word_tbl[#num_tbl][6]	= "6";
$word_tbl[#num_tbl][7]	= "7";
$word_tbl[#num_tbl][8]	= "8";
$word_tbl[#num_tbl][9]	= "9";
$word_tbl[#num_tbl][10] = $eos;
#num_tbl = #num_tbl + 1;

//月(先頭大文字バージョン)
$word_tbl[#num_tbl][0]	= "January";
$word_tbl[#num_tbl][1]	= "February";
$word_tbl[#num_tbl][2]	= "March";
$word_tbl[#num_tbl][3]	= "April";
$word_tbl[#num_tbl][4]	= "May";
$word_tbl[#num_tbl][5]	= "June";
$word_tbl[#num_tbl][6]	= "July";
$word_tbl[#num_tbl][7]	= "August";
$word_tbl[#num_tbl][8]	= "September";
$word_tbl[#num_tbl][9]	= "October";
$word_tbl[#num_tbl][10] = "November";
$word_tbl[#num_tbl][11] = "December";
$word_tbl[#num_tbl][12] = $eos;
#num_tbl = #num_tbl + 1;

//月(小文字バージョン)
$word_tbl[#num_tbl][0]	= "january";
$word_tbl[#num_tbl][1]	= "february";
$word_tbl[#num_tbl][2]	= "march";
$word_tbl[#num_tbl][3]	= "april";
$word_tbl[#num_tbl][4]	= "may";
$word_tbl[#num_tbl][5]	= "june";
$word_tbl[#num_tbl][6]	= "july";
$word_tbl[#num_tbl][7]	= "august";
$word_tbl[#num_tbl][8]	= "september";
$word_tbl[#num_tbl][9]	= "october";
$word_tbl[#num_tbl][10] = "november";
$word_tbl[#num_tbl][11] = "december";
$word_tbl[#num_tbl][12] = $eos;
#num_tbl = #num_tbl + 1;

// #if 0
$word_tbl[#num_tbl][0] = "#if 0";
$word_tbl[#num_tbl][1] = "#if 1";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;

$word_tbl[#num_tbl][0] = "#if\t0";
$word_tbl[#num_tbl][1] = "#if\t1";
$word_tbl[#num_tbl][2] = $eos;
#num_tbl = #num_tbl + 1;






////////////////////////////////////////////////////////////////////////////
//			処理本体(以下は編集しないようお願いします。)
////////////////////////////////////////////////////////////////////////////
#g_index_row = -1;
#g_index_col = -1;
call Main;
endmacro;


Main:
	if(rectselecting){
		message("矩形選択は対応していません");
		return false;
	}

	//動作環境を固定化する。
	//折りたたみを維持,部分編集を維持,範囲選択,最後に移動
	//マクロ終了時に元に戻る。
	setcompatiblemode 0x0003|0x000c|0x0200|0x2000;
	disabledraw;
	if(selecting){
		//選択あり、そのまま使う。
		call Proc ##is_next;
		##ret = ##return;
	}else{
		//選択なし
		//1文字選択して試す。
		//一文字のデータ(1 -> 2 -> 3...)を考慮。
		if((0x0d == code)||(-1==code)){
			call SelectRange column, lineno, column-1,lineno;
		}else{
			call SelectRange column, lineno, column+1,lineno;
		}
		call Proc ##is_next;
		##ret = ##return;
		if(! ##ret){
			//次は単語選択して試す。
			escape;
			selectword;
			call Proc ##is_next;
			##ret = ##return;
		}
	}
	return ##ret;


/*
	返値	変換無し	0
			変換あり	1
*/
Proc:
	##is_next	= true;
	if(argcount){
		##is_next	= val(getarg(0));
	}

	//選択された単語を取得する
	$$sel_word		= gettext(seltopx, seltopy, selendx, selendy, 1);
	if($$sel_word == $eos){
		return false;
	}
	call FindNextWord $$sel_word, ##is_next;
	$$next_word = $$return;
	if($eos == $$next_word){
		return false;
	}

	begingroupundo;
	delete;
	##old_column=column;
	##old_lineno=lineno;
	insert $$next_word;
	//選択しておいて何度も呼ばれたときに備える。(使い勝手の向上なのでコメントアウトしても構わない)
	call SelectRange ##old_column, ##old_lineno, ##old_column+strlen($$next_word), lineno;
	endgroupundo;
	return true;


FindTableIndex:
	$$sel_word = $$1;

	##i = 0;
	while(##i < #num_tbl){
		##j = 0;
		while(1){
			$$word = $word_tbl[##i][##j];
			if($$word == $eos){
				break;
			}
			if($$sel_word == $$word){
				#g_index_row = ##i;
				#g_index_col = ##j;
				return true;
			}
			##j=##j+1;
		}
		##i=##i+1;
	}
	return false;


/*	テーブルから次の文字列を取得する
	返値	成功:次の文字列
			失敗:$eos
*/
FindNextWord:
	$$sel_word	= $$1;
	##is_next	= ##2;
	call FindTableIndex $$sel_word;
	if(! return){
		return $eos;
	}

	//変換先の単語を取り出す
	if(##is_next){
		//次の単語へ
		$$next = $word_tbl[#g_index_row][#g_index_col + 1];
		if($$next == $eos){
			//一周したので先頭へもどる
			$$next = $word_tbl[#g_index_row][0];
		}
	}else{
		//前の単語へ
		if(#g_index_col==0){
			//最後の単語を返す(秀丸マクロは配列長を求めることが出来ないのでループで回す)
			##i 	= 0;
			$$next	= $eos;
			while(1){
				if($eos == $word_tbl[#g_index_row][##i]){
					$$next = $word_tbl[#g_index_row][##i - 1];
					break;
				}
				##i = ##i + 1;
			}
		}else{
			$$next = $word_tbl[#g_index_row][#g_index_col - 1];
		}
	}
	return $$next;

SelectRange:
	escape;
	movetolineno 1+##1, ##2;
	beginsel;
	movetolineno 1+##3, ##4;
	endsel;
	return ;

psearchを高速化した。

以前に書いたマクロを高速化しました。
id:ohtorii:20110312:1300105563

ファイルサイズが大きい時に、メニューが表示されるまで延々と待たされていたのを、一瞬で表示出来るようにしました。
どんだけ、無駄な処理をしていたんだと・・・>自分。

GitHub

右上のダウンロードボタンを押してzipを選択)
https://github.com/ohtorii/psearch

ソース

/* psearch.mac
検索結果をポップアップ表示する秀丸マクロ。
(xyzzyのpsearchに相当するマクロです。)


【動作】
選択文字列を検索してポップアップ表示します。
選択文字列がなければ単語選択してから検索します。


【オリジナルの作者】
秀丸エディタスレ Part30
178 :名無しさん@お腹いっぱい。 :2010/10/14(木) 02:08:50 ID:7v+i/hHB0 (2 回発言)


【改変 by ohtorii】
ポップアップ表示の改良
    ・結果に行番号を追加しました。
    ・検索結果から重複する行を取り除きました。
    ・検索開始した位置に矢印を表示するようにしました。

【注意】
    田楽DLLが必要です。
    http://www.ceres.dti.ne.jp/~sugiura/
    田楽DLL Ver.3.20で動作することを確認していますが、多分ver2.xx以降なら動くと思います。

【連絡先】
    ohtorii
    http://d.hatena.ne.jp/ohtorii/
    https://github.com/ohtorii

【履歴】
    2011/06/19 高速化(10秒の処理時間が一瞬に。10MBのXMLでテスト)
    2011/03/12 公開
*/

//検索結果を幾つ表示するか。(好みで変更して下さい)
#g_max_num = 100;




////////////////////////////////////////////////////////////////////////////
//	マクロ本体
////////////////////////////////////////////////////////////////////////////
$g_searchbuffer = searchbuffer;
#g_searchoption = searchoption;
call Main;
setsearch $g_searchbuffer, #g_searchoption;
endmacro;



Main:
	call LoadDengaku;
	if(! ##return){
		return false;
	}

	#old_lineno = lineno;
	#lineno[-1] = lineno;
	#column[-1] = column;
	#search_word = false;
	if(! selecting){
		selectword;
		#search_word=true;
	}

	$word = gettext(seltopx, seltopy, selendx, selendy);
	if(0==strlen($word)){
		return ;
	}

	disabledraw;
	gofiletop;
	if(#search_word){
		searchdown2 $word, word,nocasesense,noregular,nohilight;
	}else{
		searchdown2 $word,nocasesense,noregular,nohilight;
	}
	hilightfound 1;

	#cur_pos_index = -1;
	#prev_line_no = -1;
	while (result && (#i < #g_max_num)) {
		if(lineno != #prev_line_no){
			if(lineno == #old_lineno){
				#cur_pos_index = #i;
				$mark = "→";
			}else{
				$mark = "  ";
			}

			call GetLineStr;
			$line_str = $$return;
			$m[#i] = $mark + str(lineno) + ": " + $line_str;
			#lineno[#i] = lineno;
			#column[#i] = column;
		}
		#i = #i + 1;
		#prev_line_no = lineno;
		finddown;
	}
	movetolineno #column[-1] + 1, #lineno[-1];
	enabledraw;
	menuarray $m, #i;

	if (result){
		if(#cur_pos_index != (result-1)){
			#r = result-1;
			disabledraw;
			movetolineno #column[#r] + 1, #lineno[#r];

			//カーソルを画面中心にする
			//enabledraw y - (windowheight/2);
		}
	}
	return ;

GetLineStr:
	escape;
	golinetop2;
	beginsel;
	golineend2;
	endsel;
	$$text	= gettext2(seltopcolumn, seltoplineno, selendcolumn, selendlineno);
	//タブ文字を空白文字へ変換する。
	$$text = dllfuncstr("GSUB", $$text, "\t", "  ", -1);
	return $$text;
	

LoadDengaku:
	//田楽DLLをロード
	loaddll ( hidemarudir + "\\DengakuDLL.dll" );
	if ( !result ){
		message "田楽DLLをロードできませんでした。";
		return false;
	}
	//
	//田楽DLLのバージョンチェック
	$dllver = leftstr ( dllfuncstr("GETVERSION") ,1 ) + rightstr ( dllfuncstr("GETVERSION") ,2 );
	if ( val ( $dllver ) <= 204 ) {
		message "このマクロの実行には Ver2.04 以降の田楽DLLが必要です。";
		freedll;
		return false;
	}
	return true;

DACPでiTunesをリモートコントロールしてみた(1回目)

DACPでiTunesをリモートコントロールしてみた(1回目) - とりあえず日記
DACPでiTunesをリモートコントロールしてみた(2回目) - とりあえず日記
DACPでiTunesをリモートコントロールしてみた(3回目) - とりあえず日記
DACPでiTunesをリモートコントロールしてみた(4回目) - とりあえず日記

去年のことですが、秀丸エディタからiTruneを操作するマクロを公開しました、今回の日記はその続きです。

MAC購入したんですよ、ところが・・・

MAC購入したのを機に、iTunesWindowsからMACへ移行したんですよ。そしたら、秀丸エディタからiTunesが操作できなくなり不便になりました。

ググったところ、DACP(Digital Audio Control Protocol)経由でWindowsからMACにインストールされたiTunesを操作出来るらしいので、調べた結果とか試したことの覚え書きです。

結果は、localhostならDACPでiTunesを操作できましたが、ネットワーク越しだとペアリングがうまくいかず手詰まり状態です。


間違い勘違いあります、ご注意を。






iTuneを操作する普通のやり方

iTunesを操作するにはCOM経由で行う方法があります。(COMの方が単純で確実です。)
COMの正式な資料(iTunes COM for Windows SDK)はアップルからダウンロードできます。
https://connect.apple.com/

DACPでiTunesを操作する情報源

プロトコルなど必要な情報が揃っています。(JAVAソースコードあり。)

iTunesとペアリングする方法

固有名詞

  • DACP (Digital Audio Control Protocol)

iTunesAndroidから遠隔操作するアプリ

Androidで出来るくらいなのでPCで出来ないはずがない。
Remote for iTunes

DACPでiTunesへ接続する手順

  • まず、自作プログラムとiTunesをペアリングしてGUIDを取得する。(始めに一回だけ)
  • ペアリング時に取得したGUIDを以降のセッションで使用
  • コマンドはHTTPのGET/POSTを使用する。

DACPを操作するライブラリ

自作するにはやることが多く大変そうなので、Githubでググったところ、下記ライブラリが見つかりました。

A web interface to a DACP iTune remote control designed to run on the OpenFrame or Joggler platform(Python)

https://github.com/elsmorian/RemoteFrame

Iphone Remote App plugin for Rhythmbox(Python)

https://github.com/Harper04/dacp-rapp

Playing around with DACP(Python)

https://github.com/hatstand/dacp

.NET library implementiong DMAP, DAAP, and DACP(C#)

https://github.com/gburt/dmap-sharp



幾つもありますが、今回はソースコード行数が少ないという理由で下記ライブラリを試しました。

環境

  • Windows7 64bit SP1
  • Python 2.7.1 (r271:86832, Nov 27 2010, 17:19:03) [MSC v.1500 64 bit (AMD64)] on win32
  • iTunes 10.2.2.14
  • Google Chrome 11.0.696.65
  • pybonjour-1.1.1.zip
  • webpy-webpy-webpy-0.34-51-g12e5bb1.zip

PyBonjour/Webモジュールのインストール

下記モジュールを導入しないとサンプルが動作しません、ご注意を。
(多分、import error になるはず。)

pybonjour

http://code.google.com/p/pybonjour/
今回は、PyBonjour 1.1.1 をダウンロードしました。
iTunes附属のdnssd.dllが必要です。iTunesをインストールしておいて下さい、インストール済みなら何もしなくて良いです。

webpy

http://webpy.org/
今回は、webpy-webpy-webpy-0.34-51-g12e5bb1.zip をダウンロードしました。