// // Warp v1.11 (2013/04/21) // by mobitan http://mobitan.org/ // // 背景色 (0xBBGGRR) #BackColor[1] = 0x66FF99; // 移動 #BackColor[2] = 0xFF9966; // 複写 #BackColor[3] = 0x6699FF; // 交換 // 文字色 (0xBBGGRR) #TextColor[1] = 0x000000; // 移動 #TextColor[2] = 0x000000; // 複写 #TextColor[3] = 0x000000; // 交換 #mode = val(getarg(0)); setcompatiblemode 0x2020F; loaddll "hmjre.dll"; begingroupundo; call Initialize; call Main; call Finalize ##return; endgroupundo; freedll; endmacro; /* クリップボードもマウスも使わずコピペしたい! v1.1 (2013/04/20) BOX対応 v1.0 (2013/04/16) 初版 */ // [グローバル変数] // #mode = 動作モード 1:移動 2:複写 3:交換 // #shape0 = 起動時の範囲形状 0:点 1:文字列 2:矩形 // $ap0 = 起動時の範囲始点座標 // $cp0 = 起動時の範囲終点座標/カーソル座標 // 以下、[1]:ワープ元 [2]:ワープ先 // #shape[] = 範囲形状 0:点 1:単語 2:行 3:矩形 // $ap[] = 範囲始点座標 // $cp[] = 範囲終点座標/カーソル座標 // #rows[] = 矩形範囲の行数 // $text[][] = テキスト (矩形範囲は行ごとに [0] から) // $indent[] = インデント文字列 Main: call Step1; if (!##return) return false; call MoveToCoord $cp0; while (true) { inputpos "ワープ先を指定してください"; if (!result) return false; call Step2 (!iskeydown(0x0D)); if (!##return) return false; if (##return < 2) break; } call Step3; if (!##return) return false; return true; Initialize: #shape0 = selecting + rectselecting; call Coord x, y; $cp0 = $$return; if (selecting) { call Coord selopenx, selopeny; $ap0 = $$return; } return; Finalize: // ##1 = false:起動時の状態に戻す if (##1) return; disabledraw; selectall; call Unpaint 1; call Unpaint 2; if (#shape0 == 0) { escape; call MoveToCoord $cp0; } else { call SelectCoord $ap0, $cp0, (#shape0 == 2); } enabledraw; return; //.--------------------------------------------------------------------- Step1: // ワープ元を取得 call GetShape; #shape[1] = ##return; if (#shape[1] == 0 || #shape[1] == 2) { call SelectLine; call GetIndent; $indent[1] = $$return; } call Coord seltopx, seltopy; $cp[1] = $$return; call Coord selendx, selendy; $ap[1] = $$return; if (#mode < 1 || #mode > 3) { menu "移動(&S)", "複写(&D)", "交換(&F)"; if (!result) return false; #mode = result; } call GetText 1; return true; Step2: // ワープ先を取得 // ##1 = true:マウスで位置指定された call GetShape; #shape[2] = ##return; if (#shape[2] != 3) { if (#shape[1] == 1) { if (##1) { call SelectWord; } } else if (#shape[1] == 0 || #shape[1] == 2) { ##bc = seltopcolumn; call SelectLine; call GetIndent; $indent[2] = $$return; if (#shape[2] != 2 && #mode != 3) { // 行頭なら上に挿入、行末なら下に挿入 // if (#shape[2] == 0) { // if (##bc == linelen2) ##u = 3; // else if (##bc == 0) ##u = 2; // } call AdjustPos ##1, ##u; if (!##return) return false; } } else if (#shape[1] == 3) { message "BOX 範囲のワープ先は BOX 範囲で指定してください"; return 2; } } call Coord seltopx, seltopy; $cp[2] = $$return; call Coord selendx, selendy; $ap[2] = $$return; if (#shape[1] != 3 && #shape[2] != 3) { // 矩形は座標チェックできないお if ($cp[1] < $ap[2] && $cp[2] < $ap[1]) { message "ワープ元とワープ先が重なってます。再指定してください"; return 2; } if ($cp[2] == $ap[2] && ($cp[1] == $cp[2] || $ap[1] == $cp[2]) && #mode != 2) { // 隣接するゼロ幅の場所 return false; } } call GetText 2; return 1; Step3: // ワープ元とワープ先を編集 disabledraw; call MoveToCoord $cp[1]; call PutText 1, 2, #mode; call MoveToCoord $cp[2 - ($cp[1] <= $cp[2])]; call PutText 2, 1, 3; enabledraw; return true; GetShape: // 範囲形状を取得 // ##return = 範囲形状 0:点 1:行内 2:行全体/複数行 3:矩形 if (!selecting) { beginsel; endsel; ##r = 0; } else if (rectselecting) { ##r = 3; } else if (seltoplineno == selendlineno) { ##r = 1; } else { ##r = 2; } return ##r; AdjustPos: // ワープ先の位置を決める // ##1 = true:マウス使用 // ##2 = 選択肢番号 $$m[0] = "置換(&D)"; $$m[1] = "上に挿入(&E)"; $$m[2] = "下に挿入(&C)"; ##nm = 3; ##bx = seltopx; ##by = seltopy; ##dx = selendx; ##dy = selendy; if (##2) { ##pos = ##2; } else { moveto ##bx, ##by; beginsel; moveto ##dx, ##dy; endsel; if (!##1) menuarray $$m, ##nm; else mousemenuarray $$m, ##nm; ##pos = result; } if (##pos == 1) { beginsel; moveto ##bx, ##by; endsel; } else if (##pos == 2) { moveto ##bx, ##by; beginsel; endsel; } else if (##pos == 3) { moveto ##dx, ##dy; beginsel; endsel; } else { return false; } return true; GetText: // テキストを取得 // ##1 = 添字 call Paint ##1, 0, #mode; moveto seltopx, seltopy; ##i = 0; call NextPainted ##1, 0, 0x09; // 始端へ while (##return) { beginsel; call NextPainted ##1, 0, 0x0A; // 終端へ endsel; call Subst gettext(seltopx, seltopy, selendx, selendy, false), "\x0D", ""; $text[##1][##i] = $$return; ##i = ##i + 1; call NextPainted ##1, 0, 0x01; // 次の始端へ } #rows[##1] = ##i; return; PutText: // テキストを編集 // ##1 = 自位置の添字 = インデントの添字 // ##2 = 対位置の添字 = テキストの添字 // ##3 = 1:削除 2:色を消す 3:上書き if (#shape[##1] == 3) { if (#shape[##2] != 3) call SplitText ##2; } else { if (#shape[##2] == 3) call JoinText ##2; } ##i = 0; call NextPainted ##1, 0, 0x09; // 始端へ ##bx = x; ##by = y; while (##return) { beginsel; call NextPainted ##1, 0, 0x0A; // 終端へ endsel; if (##3 == 1) { delete; } else if (##3 == 2) { call Unpaint ##1; } else if (##3 == 3) { call InsertText ##1, ##2, ##i % #rows[##2]; } ##i = ##i + 1; call NextPainted ##1, 0, 0x01; // 次の始端へ } if (##i == 0) return false; if (#shape[##1] == 3) beginrect; else beginsel; moveto ##bx, ##by; endsel; return true; InsertText: // テキストをインデント調整しつつ挿入 // ##1 = インデントの添字 // ##2 = テキストの添字1 // ##3 = テキストの添字2 if ($indent[##2] == "" || $indent[##1] == "") { insert $text[##2][##3]; } else { call Subst $text[##2][##3], "(^|\\n)" + $indent[##2], "\\1" + $indent[##1]; insert $$return; } return; JoinText: // 配列 → 改行区切り // ##1 = 添字 ##i = 0; while (##i < #rows[##1]) { $$s = $$s + $text[##1][##i] + "\n"; $text[##1][##i] = ""; ##i = ##i + 1; } #rows[##1] = 1; $text[##1][0] = $$s; return; SplitText: // 改行区切り → 配列 // ##1 = 添字 $$s = $text[##1][0]; ##i = 0; while (##p < wcslen($$s)) { ##q = wcsstrstr($$s, "\n", ##p); if (##q < 0) ##q = wcslen($$s); $text[##1][##i] = wcsmidstr($$s, ##p, ##q - ##p); ##p = ##q + 1; ##i = ##i + 1; } #rows[##1] = ##i; return; SelectLine: // 行選択 if (!selecting) { selectline; } else { ##bl = seltoplineno; ##dl = selendlineno + (seltoplineno == selendlineno || selendcolumn != 0); if (linecount2 < ##dl) gofileend; else moveto2 0, ##dl; beginsel; moveto2 0, ##bl; endsel; } return; SelectWord: // 単語選択 if (strstr("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", char(code)) >= 0 || unicode > 0xA0) { selectword; } else { beginsel; endsel; } return; GetIndent: // インデント文字列を取得 // $$return = インデント文字列 call Match gettext2(0, lineno, 100, lineno, true), "^[ \\t ]+"; return $$return; //.--------------------------------------------------------------------- Paint: // 選択範囲に色を塗る // ##1 = レイヤ番号 // ##2 = ユーザーデータ // ##3 = 色番号 $$layer = currentmacrobasename + "#" + str(##1); colormarker #TextColor[##3], #BackColor[##3], 11, 1, ##2, $$layer; return; Unpaint: // 選択範囲の色を消す // ##1 = レイヤ番号 $$layer = currentmacrobasename + "#" + str(##1); colormarker -1, -1, 11, 0, 0, $$layer; return; PrevPainted: // prevcolormarker // ##1 = レイヤ番号 // ##2 = ユーザーデータ // ##3 = prevcolormarker 文のフラグ // ##return = result $$layer = currentmacrobasename + "#" + str(##1); prevcolormarker ##3, ##2, $$layer; return result; NextPainted: // nextcolormarker // ##1 = レイヤ番号 // ##2 = ユーザーデータ // ##3 = nextcolormarker 文のフラグ // ##return = result $$layer = currentmacrobasename + "#" + str(##1); nextcolormarker ##3, ##2, $$layer; return result; Coord: // 座標 // ##1 = x // ##2 = y // $$return = 座標 return rightstr("00000000" + str(ytolineno(##1, ##2)), 8) + rightstr("00000000" + str(xtocolumn(##1, ##2)), 8); MoveToCoord: // 座標へ移動 // $$1 = 座標 moveto2 val(midstr($$1, 8, 8)), val(midstr($$1, 0, 8)); return; SelectCoord: // 座標範囲を選択 // $$1 = 範囲始点座標 // $$2 = 範囲終点座標 // ##3 = true:矩形 call MoveToCoord $$1; if (##3) beginrect; else beginsel; call MoveToCoord $$2; endsel; return; Match: // 正規表現検索 // $$1 = 対象文字列 // $$2 = 検索パターン // ##3 = 大文字小文字の区別 $$f = leftstr("FindRegularNoCaseSense", 11 + (##3 == 0) * 11); ##p = dllfunc($$f, $$2, $$1, 0); if (##p == -2) message currentmacrobasename + ": " + "Match:\n正規表現のエラーです\n" + $$2; if (##p < 0) return ""; return midstr($$1, ##p, dllfunc("GetLastMatchLength")); Subst: // 正規表現置換 // $$1 = 対象文字列 // $$2 = 検索パターン // $$3 = 置換パターン // ##4 = 大文字小文字の区別 $$f = leftstr("ReplaceRegularNoCaseSense", 14 + (##4 == 0) * 11); return dllfuncstr($$f, $$2, $$1, 0, $$3, 2); /* 111111 222222 333333 444444 555555 666666 */ // (C) mobitan 2013