|
秀まるおさん、こんにちは。
K'zawaです。
下記マクロのようにしてみました。ヘッダー周りの処理をする過程でヘッダー名がわ
かったので、それを読むようにもしてみました。
と、秀まるおさんの言葉に思わず乗ってしまいましたが、忘れてました。
この方法(カーソルを動かさずに文字を取得する)をなぜ放棄していたかというと、
カーソルがその文字に置かれてないので、文字以外の情報が得られないからなのです。
色とか協調とか、実際のX, yとか、移動させようとしたが失敗したこととか。これら
はカスタマイズするときに必要になってくることがあります。
今回のマクロで成立しても、その先がいまいちなのです。
なので、選択を解除して復元するのは無理があると言っても、カーソルの移動は必要
になってくると思います。
Shift+矢印キーに相当することがマクロでできたほうがいいと書いたのは、そういっ
た背景があります。都度、離れたところにある文字の属性を取れるようにして欲しい
と要望するよりも無難な気がしたものですから。
無理なら無理ということで構いませんので、ご検討いただけると幸いです。
// 1文字発音 2009/04/07
// 秀丸エディタ Ver8.71以上/秀丸メール Ver6.72以上(複数選択系のバグ修正が
なされた)
// 2018.4.27 範囲選択時、カーソル位置の左まで選択されるときは左の文字を読む
のがだめになっていたのを復活。複数選択対応など
setcompatiblemode 0x0F; // マクロの互換性の指示
#del = iskeydown( 0x2E ); // Deleteキーがおされているかどうかの値
if ( rectselecting ) { // BOX選択のとき
call GetCharCode_Rect; // BOX選択専用の文字コード取得サブルーチンへ
} else { // BOX選択以外のとき
call GetCharCode; // 文字コード取得サブルーチンへ
}
#code = ##return; // サブルーチンからの戻り値(文字コード)
// 発音処理
ddeinitiate "HidemaruReader", "Read"; // 秀丸リーダーと通信開始
if ( #del && multiselecting ) { // 複数選択で削除のとき
ddeexecute "-!複数範囲削除";
} else if ( #del && rectselecting ) { // 複数選択で削除のとき
ddeexecute "-!ボックス削除";
} else if ( $headername != "" ) { // 変数にヘッダー名が入っているとき
ddeexecute "!" + $headername;
} else if( #code == 13 ) { // 改行文字のとき
ddeexecute "!かいぎょう";
} else if( #code == 9 ) { // タブ文字のとき
ddeexecute "!タブ";
} else if( #code == eof ) { // ファイル末尾のとき
ddeexecute "!ファイルのまつび";
} else if( #code == 0 ) { // 開業や[EOF]より右にカーソルがあるとき
ddeexecute "!ブランク";
} else { // それ以外の普通の文字のとき
ddeexecute "#" + unichar( #code );
}
ddeterminate; // 秀丸リーダーとの通信終了
endmacro; // マクロ終わり
GetCharCode: // 文字コード取得サブルーチン
if ( selecting == 0 && y < -1 && x == 0 ) { // 非選択で秀丸メールのヘッ
ダー名の先頭にカーソルがあるとき
call GetHeaderName gettext( 0, y, linelen, y, 1 ), "^(\\c[\\c\\-]*:).
+"; // カーソル行の文字列と検索文字列を渡してサブルーチンを呼び出す
return unicode; // 一応カーソル位置の文字コードも返して戻る
}
if (
( ! selecting ) // 範囲選択 してないとき
|| ( seltopx == selendx && seltopy == selendy ) // 幅0の選択範囲
|| ( seltoplineno > 0 && seltopcolumn == selendcolumn && seltoplinen
o == selendlineno ) // 折り返し位置で幅0(golineend3からShift+右矢印した状態
含む)
|| ( x == seltopx && y == seltopy ) // カーソル位置がseltop*側のとき、
カーソル移動の必要なし
) {
return unicode; // カーソル位置の文字コードを返して戻る
}
// カーソル位置が選択範囲外で、左が範囲内の一文字以上選択している通常選
択または行選択のとき
if ( #del ) { // 削除のとき
$$s = gettext( seltopx, seltopy, 1, seltopy + 1, 1 ); // 選択範囲
の最初の文字
} else if ( column == 0 ) { // 論理行頭のとき
$$s = "\n"; // 一文字以上選択し、カーソルはselend側なので改行に決ま
っている
} else if ( y < -1 ) { // 秀丸メールのヘッダー(空行よりも上)のとき
$$s = gettext( x - 1, y, x, y, 1 ); // カーソル左の文字
if ( $$s == "" ) { // あるはずなのにない→ヘッダーの折り返しのとき
$$s = wcsrightstr( gettext( 0, y - 1, x, y, 1 ), 1 ); // 前の
行の最後の文字
}
if ( $$s == "\x20" ) { // 半角スペースだったとき(もしかしてヘッ
ダー名?)
call GetHeaderName gettext( 0, y, x, y, 1 ), "^(\\c[\\c\\-]*:) +
$"; // 行頭からカーソル位置までの文字列と検索文字列を渡してサブルーチンを呼
び出す
if ( $$return != "" ) $$s = $$return; // 戻り値が空でなければ$
$sに入れる
}
} else { // それ以外のとき
$$s = gettext2( column - 1, lineno, column, lineno, 1 ); // カー
ソル左の文字
}
##code = unicode( $$s ); // 文字コードに変換
return unicode( $$s ); // 取得した文字コードを返して戻る
GetCharCode_Rect: // BOX選択専用の文字コード取得サブルーチン
if ( #del ) { // (BOX)削除のとき
return unicode; // (使わないけど)カーソル位置の文字コードを返して戻る
}
if ( multiselecting && selectionlock == 0 ) { // 複数選択で選択ロック
ではないとき
return unicode; // カーソル位置の文字コードを返して戻る
}
// 必要な情報を記憶
##selopenx = selopenx; ##selopeny = selopeny; // 選択開始位置
##x = x; ##y = y; // 現在のカーソル位置
##selectionlock = selectionlock; // 選択ロック状態かどうか
##multiselecting = multiselecting; // 複数選択かどうか
// カーソル行の中に限った範囲選択の左側のx値を得る
disabledraw; //描画禁止
tomultiselect; // 複数選択化(カーソルによるせんたくはカーソル行だけに
なる)
##leftx = seltopx; // 選択の左側x値
// BOX選択の復元
escape; // 選択解除
moveto ##selopenx, ##selopeny; // 選択開始位置へ移動
if ( ##multiselecting ) beginrectmulti; // BOX選択開始(複数選択化)
else beginrect; // BOX選択開始
moveto ##x, ##y; // 元のカーソル位置に移動
if ( ##x > ##leftx ) { // ##xが大きいとき(カーソル位置は選択範囲にふく
まれない)
left; // 左へ移動
}
##code = unicode; // カーソル位置の文字コードを取得
moveto ##x, ##y; // 元のカーソル位置に移動
if ( ! ##selectionlock ) endsel; // 元々選択ロック状態ではなかったと
きendselする
enabledraw; // 描画再開
return ##code; // 取得した文字コードを返して戻る
GetHeaderName: // ヘッダー名を取り出すサブルーチン
loaddll "HmJre.dll"; // 正規表現DLLをロードする
$headername = dllfuncstr( "ReplaceRegular", $$2, $$1, 0, "\\1", 0 );
// 余分な文字を削除(失敗時は空文字列)
freedll; // 正規表現DLLを開放する
return wcsleftstr( $headername, 1 ); //置換した文字列の1文字目を返す
|
|