Last active
May 12, 2023 06:08
-
-
Save densya203/886a908406c9dfc853592f5e8fd59531 to your computer and use it in GitHub Desktop.
秀丸マクロ。WSL2のext4ファイルシステム(すなわち /mnt/ 以外)に配置してある大量のファイル群へのグレップを、純正の4倍(当社比)早く実行します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 最新バージョンは | |
// https://gist.github.com/densya203/886a908406c9dfc853592f5e8fd59531 で入手ください。 | |
// gist から解凍した後、このファイルを秀丸で開いて Shift-JIS CR+LF にしてください。 | |
// | |
//----------------------------------------------------------------------------- | |
// 初期設定 各自の環境に合わせて設定してください。 | |
//----------------------------------------------------------------------------- | |
// 検索対象ファイルの拡張子 | |
// 最後はカンマで終わってOK | |
// html と js → "html,js," | |
$DEFAULT_FILE = "rb,erb"; | |
// WindowsからデフォルトのWSLへアクセスするときのパス | |
// 「//wsl.localhost/」にパワーシェルで wsl -l -q を実行したときに最初にヒット | |
// する文字列を足してもらえばOKだと思います。 | |
// / 区切りで設定 | |
$DEFAULT_LINUX_PATH_PREFIX = "//wsl.localhost/Ubuntu"; | |
// グレップ結果からタグジャンプや おーなーしぇふさんの z_grep.mac の | |
// 「Grep検索結果から置換(行単位で置換)」を使いたい人用の設定 | |
// http://hidemacro.gtx.jp/doc/kensaku.htm | |
$DEFAULT_REPLACE_PATH_FROM = "/home/"; | |
$DEFAULT_REPLACE_PATH_TO = "\\\\wsl.localhost\\Ubuntu\\home\\"; | |
// ↑にはネットワークドライブを当てて、↓のようにするとパスが短くなり、かつトリ | |
// プルクリックでのタグジャンプが効いてなにかといいです。 | |
// $DEFAULT_REPLACE_PATH_TO = "U:\\home\\"; | |
//----------------------------------------------------------------------------- | |
// 定数定義 | |
//----------------------------------------------------------------------------- | |
// 履歴保存位置 | |
$REGISTRY_PATH = "Software\\Hidemaruo\\Hidemaru\\" + currentmacrobasename; | |
// 履歴保存数 | |
#HISTORY_SIZE_KEYWORD = 30; | |
#HISTORY_SIZE_FILE = 5; | |
#HISTORY_SIZE_DIRECTORY = 30; | |
//----------------------------------------------------------------------------- | |
// メイン処理 | |
//----------------------------------------------------------------------------- | |
Main: | |
debuginfo 2; // 2 → アプトプット枠にも出力 | |
disabledraw; | |
call InitDengakuDLL; | |
call ReadDataFromRegistry; | |
call CreateDialog; | |
call LoadHistoryToCtrls; | |
call MainLoop; | |
goto EndProcess; | |
return; | |
//----------------------------------------------------------------------------- | |
// 田楽DLLの利用準備 | |
//----------------------------------------------------------------------------- | |
InitDengakuDLL: | |
if (version < 311) { | |
message "このマクロには秀丸の Ver.3.11 以降が必要です。"; | |
endmacro; | |
} | |
$$dllFileName = hidemarudir + "\\dengakudll.dll"; | |
// 田楽DLLのロード | |
loaddll($$dllFileName); | |
if (!result) { | |
message "田楽DLL をロードできませんでした。\nネットで検索してゲットした「dengakudll.dll」を\n" + hidemarudir + " に配置してください。"; | |
endmacro; | |
} | |
return; | |
//----------------------------------------------------------------------------- | |
// レジストリから履歴を読み取り、グローバル変数の配列にセットします。 | |
//----------------------------------------------------------------------------- | |
ReadDataFromRegistry: | |
openreg "CURRENTUSER", $REGISTRY_PATH; | |
// 存在しない場合、レジストリキーを生成して初期化する | |
if (result == 0) { | |
createreg "CURRENTUSER", $REGISTRY_PATH; | |
##i = 0; | |
while (##i < #HISTORY_SIZE_FILE){ | |
$$reg_key = "file" + str(##i); | |
if (##i == 0) { | |
writeregstr $$reg_key, $DEFAULT_FILE; | |
} else { | |
writeregstr $$reg_key, ""; | |
} | |
##i = ##i + 1; | |
} | |
##i = 0; | |
while (##i < #HISTORY_SIZE_DIRECTORY){ | |
$$reg_key = "directory" + str(##i); | |
writeregstr $$reg_key, ""; | |
##i = ##i + 1; | |
} | |
writeregstr "from", $DEFAULT_REPLACE_PATH_FROM; | |
writeregstr "to" , $DEFAULT_REPLACE_PATH_TO; | |
writeregstr "reg_on", "0"; | |
} | |
// レジストリに保持されている内容を読み込む | |
##i = 0; | |
while (##i < #HISTORY_SIZE_FILE){ | |
$$reg_key = "file" + str(##i); | |
$file_history[##i] = getregstr($$reg_key); | |
##i = ##i + 1; | |
} | |
##i = 0; | |
while (##i < #HISTORY_SIZE_DIRECTORY){ | |
$$reg_key = "directory" + str(##i); | |
$directory_history[##i] = getregstr($$reg_key); | |
##i = ##i + 1; | |
} | |
$path_replace_from = getregstr("from"); | |
$path_replace_to = getregstr("to"); | |
$reg_on = getregstr("reg_on"); | |
closereg; | |
return; | |
//----------------------------------------------------------------------------- | |
// ダイアログを作成して表示します。 | |
//----------------------------------------------------------------------------- | |
CreateDialog: | |
// 既に開いていればダイアログを閉じる | |
if (#isOpen){ | |
#n = dllfunc("ENDDIALOG"); | |
} | |
// ダイアログの作成 | |
#n = dllfunc("NEWDIALOG", "grepの実行(WSL2ネイティブ)", 100, "0 0 window MeiryoKe_UIGothic 11 px"); | |
#n = dllfunc("NEWPAGE", 99); | |
// 検索する文字列 | |
#n = dllfunc("NEWCONTROL", "text", "", "検索する文字列(&S)"); | |
#n = dllfunc("SETCTRLWIDTH", "", 26); | |
#n = dllfunc("NEWCONTROL", "combo", "target_keyword", ""); | |
#n = dllfunc("SETCTRLWIDTH", "", 63); | |
#n = dllfunc("NEWCONTROL", "check", "reg_on", "正規表現"); | |
#n = dllfunc("SETCTRLSTATE", "reg_on", $reg_on); | |
#n = dllfunc("NEWPAGE", 99); | |
// 検索するファイル | |
#n = dllfunc("NEWCONTROL", "text", "", "検索するファイル(&N)"); | |
#n = dllfunc("SETCTRLWIDTH", "", 26); | |
#n = dllfunc("NEWCONTROL", "combo", "target_file", ""); | |
#n = dllfunc("SETCTRLWIDTH", "", 73); | |
#n = dllfunc("NEWPAGE", 99); | |
// 検索するディレクトリ | |
#n = dllfunc("NEWCONTROL", "text", "", "WSL上の検索するディレクトリ(&D)"); | |
#n = dllfunc("SETCTRLWIDTH", "", 26); | |
#n = dllfunc("NEWCONTROL", "combo", "target_directory", ""); | |
#n = dllfunc("SETCTRLWIDTH", "", 63); | |
// カレント | |
#n = dllfunc("NEWCONTROL", "button", "choose_current_button", "カレント"); | |
#n = dllfunc("SETCTRLWIDTH", "", 10); | |
#n = dllfunc("SETCTRLNOTIFY", "", "10"); | |
#n = dllfunc("NEWPAGE", 99); | |
// 結果のパス変更 | |
#n = dllfunc("NEWCONTROL", "text", "", "結果一覧におけるパスの変更(&C)"); | |
#n = dllfunc("SETCTRLWIDTH", "", 26); | |
#n = dllfunc("NEWCONTROL", "edit", "path_replace_from", $path_replace_from); | |
#n = dllfunc("SETCTRLWIDTH", "", 33); | |
#n = dllfunc("NEWCONTROL", "text", "", "→"); | |
#n = dllfunc("SETCTRLWIDTH", "", 3); | |
#n = dllfunc("NEWCONTROL", "edit", "path_replace_to", $path_replace_to); | |
#n = dllfunc("SETCTRLWIDTH", "", 37); | |
#n = dllfunc("NEWPAGE", 99); | |
// OK キャンセルボタン | |
#n = dllfunc("NEWCONTROL", "okcancel"); | |
#n = dllfunc("SETCTRLWIDTH", "", 50); | |
#n = dllfunc("SETCTRLHEIGHT", "", 1); | |
// ダイアログオープン | |
#n = dllfunc("SHOWDIALOG", hidemaruhandle(0), 0); | |
#isOpen = true; | |
return; | |
//----------------------------------------------------------------------------- | |
// 各コントロールオブジェクトに履歴をロードします。 | |
//----------------------------------------------------------------------------- | |
LoadHistoryToCtrls: | |
// 「検索する文字列」 | |
##i = 0; | |
while(##i < #HISTORY_SIZE_KEYWORD){ | |
if (##i == 0) { | |
// 範囲選択している場合 | |
if (selecting == 1) { | |
#n = dllfunc("SETCTRLSTRING", "target_keyword", gettext(seltopx, seltopy, selendx, selendy, 1)); | |
} else { | |
#n = dllfunc("SETCTRLSTRING", "target_keyword", getsearchhist(##i)); | |
} | |
} | |
#n = dllfunc("SETCTRLITEM", "target_keyword", getsearchhist(##i)); | |
##i = ##i + 1; | |
} | |
// 「検索するファイル」 | |
##i = 0; | |
while (##i < #HISTORY_SIZE_FILE){ | |
if ($file_history[##i] != "") { | |
if (##i == 0) { | |
#n = dllfunc("SETCTRLSTRING", "target_file", $file_history[##i]); | |
} | |
#n = dllfunc("SETCTRLITEM", "target_file", $file_history[##i]); | |
} | |
##i = ##i + 1; | |
} | |
// 「検索するディレクトリ」 | |
##i = 0; | |
while (##i < #HISTORY_SIZE_DIRECTORY){ | |
if ($directory_history[##i] != "") { | |
if (##i == 0) { | |
#n = dllfunc("SETCTRLSTRING", "target_directory", $directory_history[##i]); | |
} | |
#n = dllfunc("SETCTRLITEM", "target_directory", $directory_history[##i]); | |
} | |
##i = ##i + 1; | |
} | |
return; | |
//----------------------------------------------------------------------------- | |
// メインループ。コントロールからの入力を受け付けます。 | |
//----------------------------------------------------------------------------- | |
MainLoop: | |
while (true) { | |
$$mode = ""; | |
while (strlen($$mode) == 0) { | |
$$mode = dllfuncstr("WAITCTRLNOTIFY", 10); | |
} | |
// キャンセルボタン押下 | |
if ($$mode == "0") { | |
// ダイアログを閉じて終了 | |
#n = dllfunc("ENDDIALOG"); | |
$target_keyword = ""; | |
$target_file = ""; | |
$target_directory = ""; | |
break; | |
// OKボタン押下 | |
} else if ($$mode == "1") { | |
$target_keyword = dllfuncstr("GETCTRLSTRING", "target_keyword"); | |
$target_file = dllfuncstr("GETCTRLSTRING", "target_file"); | |
$target_directory = dllfuncstr("GETCTRLSTRING", "target_directory"); | |
$path_replace_from = dllfuncstr("GETCTRLSTRING", "path_replace_from"); | |
$path_replace_to = dllfuncstr("GETCTRLSTRING", "path_replace_to"); | |
$reg_on = dllfuncstr("GETCTRLSTATE" , "reg_on"); | |
$$error_message = ""; | |
if ($target_keyword == "") { | |
$$error_message = $$error_message + "検索する文字列を入力してください。\n"; | |
} | |
if ($target_file == "") { | |
$$error_message = $$error_message + "検索するファイルを入力してください。\n"; | |
} | |
if ($target_directory == "") { | |
$$error_message = $$error_message + "検索するディレクトリを入力してください。\n"; | |
} | |
if ($$error_message != "") { | |
message $$error_message; | |
} else { | |
// ダイアログを閉じて戻る | |
#n = dllfunc("ENDDIALOG"); | |
// グレップを実行 | |
call ExecuteGrepInWsl; | |
break; | |
} | |
// 「カレント」ボタン押下 | |
} else if ($$mode == "10") { | |
$$current_dir = directory; | |
$$current_dir = dllfuncstr("GSUB", $$current_dir, "\\", "/", -1); | |
if (leftstr($$current_dir, 1) != "/") { | |
$$current_dir = midstr($$current_dir, 2); | |
} | |
$$current_dir = dllfuncstr("GSUB", $$current_dir, tolower($DEFAULT_LINUX_PATH_PREFIX), "", 1); | |
#n = dllfunc("SETCTRLSTRING", "target_directory", $$current_dir); | |
} | |
} | |
return; | |
//----------------------------------------------------------------------------- | |
// WSL でのグレップを実行します。 | |
//----------------------------------------------------------------------------- | |
ExecuteGrepInWsl: | |
$$command = ""; | |
// 正規表現を使う場合、E オプション | |
if (val($reg_on)) { | |
$$command = $$command + "wsl grep -rnE '" + $target_keyword + "'"; | |
} else { | |
$$command = $$command + "wsl grep -rnF '" + $target_keyword + "'"; | |
} | |
// 検索するファイルの末尾がカンマでない場合 | |
if (strlen($target_file) && rightstr($target_file, 1) != ",") { | |
$target_file = $target_file + ","; | |
} | |
$$command = $$command + " --include=*.{" + $target_file + "}"; | |
$$command = $$command + " " + dllfuncstr("GSUB", $target_directory, "\\", "/", -1); | |
if ($path_replace_from != "") { | |
$$command = $$command + " | sed 's/" + dllfuncstr("GSUB", $path_replace_from, "/", "\\/", -1) + "/" + dllfuncstr("GSUB", $path_replace_to, "\\", "\\\\", -1) + "/'"; | |
} | |
// :N で表示される行番号を秀丸のグレップ結果と同じ (N) に | |
$$command = $$command + " | sed 's/\\:\\([0-9]\\+\\)\\:/\\(\\1\\)\\: /g'"; | |
// スラッシュを¥に | |
$$command = $$command + " | sed 's/\\//\\\\/g;s/\\(.*:\\)/\\1/'"; | |
if ($target_keyword != "" && $target_file != "" && $target_directory != "") { | |
runex $$command, 1, 0, "", 4, "", 4, "", 0, "", 0, 1, 6; | |
if (result == 0) { | |
message "コマンド実行に失敗しました。"; | |
debuginfo $$command; | |
} else { | |
// 履歴を保存 | |
call SaveDataToRegistry; | |
}; | |
} | |
return; | |
//----------------------------------------------------------------------------- | |
// 履歴をレジストリに保存します。 | |
//----------------------------------------------------------------------------- | |
SaveDataToRegistry: | |
setsearchhist 0, $target_keyword; | |
setpathhist 0, $target_directory; | |
openreg "CURRENTUSER", $REGISTRY_PATH; | |
// --------------------------------------------- | |
// 「検索するファイル」 | |
// --------------------------------------------- | |
$$new_history[0] = $target_file; | |
##new_history_count = 1; | |
##i = 0; | |
while (##i < #HISTORY_SIZE_FILE) { | |
##unq = yes; | |
##j = ##i + 1; | |
while (##j < #HISTORY_SIZE_FILE) { | |
if ($file_history[##i] == $file_history[##j] || $file_history[##i] == $target_file) { | |
##unq = no; | |
break; | |
} | |
##j = ##j + 1; | |
} | |
if (##unq) { | |
$$new_history[##new_history_count] = $file_history[##i]; | |
##new_history_count = ##new_history_count + 1; | |
} | |
##i = ##i + 1; | |
} | |
##i = 0; | |
while (##i < ##new_history_count) { | |
$$reg_key = "file" + str(##i); | |
writeregstr $$reg_key, $$new_history[##i]; | |
##i = ##i + 1; | |
} | |
// --------------------------------------------- | |
// 「検索するディレクトリ」 | |
// --------------------------------------------- | |
$$new_history[0] = $target_directory; | |
##new_history_count = 1; | |
##i = 0; | |
while (##i < #HISTORY_SIZE_DIRECTORY) { | |
##unq = yes; | |
##j = ##i + 1; | |
while (##j < #HISTORY_SIZE_DIRECTORY) { | |
if ($directory_history[##i] == $directory_history[##j] || $directory_history[##i] == $target_directory) { | |
##unq = no; | |
break; | |
} | |
##j = ##j + 1; | |
} | |
if (##unq) { | |
$$new_history[##new_history_count] = $directory_history[##i]; | |
##new_history_count = ##new_history_count + 1; | |
} | |
##i = ##i + 1; | |
} | |
##i = 0; | |
while (##i < ##new_history_count) { | |
$$reg_key = "directory" + str(##i); | |
writeregstr $$reg_key, $$new_history[##i]; | |
##i = ##i + 1; | |
} | |
// --------------------------------------------- | |
// 結果のパス変更 | |
// --------------------------------------------- | |
writeregstr "from" , $path_replace_from; | |
writeregstr "to" , $path_replace_to; | |
// 正規表現 | |
writeregstr "reg_on", $reg_on; | |
closereg; | |
return; | |
//----------------------------------------------------------------------------- | |
// マクロ終了処理 | |
//----------------------------------------------------------------------------- | |
EndProcess: | |
freedll; | |
enabledraw; | |
endmacro; | |
//----------------------------------------------------------------------------- | |
// メイン処理実行 | |
//----------------------------------------------------------------------------- | |
call Main; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
おすすめの人
Ruby on Railsの開発をWSL2上のLinuxで行い、かつ秀丸エディタから離れれず、そしてグレップをよく使う中年のおっさん(=私)。
実装の経緯
WSL2上のUbuntuで、ネイティブに配置されたディレクトリ(/mnt/c などではなく、\\wsl.localhost\Ubuntu 配下のext4ファイルシステム)が大きい(60GB程度)場合、そこでのグレップの実行速度が遅くなることがあります。私の環境では、800件のヒットで体感4倍ほど遅くなりました。
サポートフォーラムで聞いてみたものの、実装するよ、というお返事は残念ながらいただけませんでした。
そこで、秀まるおさんの「自分で使うものは、なければ作れ」精神を胸に、このマクロを作ってみました。寿命は短そうですが・・・。
このマクロは、WSL2上でLinuxのgrepコマンドを実行し、その結果を秀丸で(秀丸純正のgrep結果風に)受け取ることができます。
快適にするために
\\\\wsl.localhost\\Ubuntu\\
にU:
などネットワークドライブを当てておくとパスが短くなって何かと捗ります。実行方法
まず、田楽DLL をダウンロードし、秀丸のexeがあるフォルダに配置してください。
次に、当gistからダウンロードしたzipの中にある GrepInWSL2.mac を、あなたの秀丸マクロフォルダに配置してください。
配置した GrepInWSL2.mac を秀丸で開いて Shift-JIS CR+LF にしてください。
あとは秀丸からマクロの実行をするだけです。
アンインストール方法
設定内容をレジストリに書き込んでいますので、
コンピューター\HKEY_CURRENT_USER\SOFTWARE\Hidemaruo\Hidemaru\densya203-grepinwsl2.mac
を削除してください。
問題点
たまに、WSL (4374) ERROR: CreateProcessParseCommon:789: Failed to translateというエラーが出ることがありますが、未調査です。
検索結果は正しいようです。
謝辞
秀まるおさん
秀丸サポート担当の方
すぎうら まさき さん(田楽DLL開発者の方)
Yusuke Komoriさん(LF-Numberer.mac を勝手に参考にさせていただきました)。
おーなーしぇふさん(z_grep.mac の「Grep検索結果から置換(行単位で置換)」20年ぐらい使ってます。)