「フォルダツリーをポップアップ表示」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
MSY-07 (トーク | 投稿記録)
ソースコードの整形
MSY-07 (トーク | 投稿記録)
変数にvarの宣言を追加
 
(同じ利用者による、間の2版が非表示)
42行目: 42行目:


== ソースコード ==
== ソースコード ==
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript" copy>
// 同じフォルダにあるファイルを開く.js r2
// 同じフォルダにあるファイルを開く.js r2
// もしくは 簡易フォルダツリー
// もしくは 簡易フォルダツリー


CONFIG = {}
var CONFIG = {};


/** 設定 **/
/** 設定 **/


// 一覧に含めるフォルダ名の正規表現
// 一覧に含めるフォルダ名の正規表現
CONFIG.folder_pattern = /^[^\.]/
CONFIG.folder_pattern = /^[^\.]/;


// 一覧に含めるファイル名の正規表現
// 一覧に含めるファイル名の正規表現
CONFIG.file_pattern = /^[^\.]/
CONFIG.file_pattern = /^[^\.]/;


// 別例: 現在のファイルと同じ拡張子だけ表示
// 別例: 現在のファイルと同じ拡張子だけ表示
// CONFIG.file_pattern = document.Name.indexOf('.') == -1 ? /./ : RegExp(document.Name.substr(document.Name.indexOf('.')), "i")
// CONFIG.file_pattern = document.Name.indexOf('.') == -1 ? /./ : RegExp(document.Name.substr(document.Name.indexOf('.')), "i");


// 一覧から除外するファイル名の正規表現
// 一覧から除外するファイル名の正規表現
CONFIG.file_ignore_pattern = /\.(?:png|jpg|gif|db|exe|dll|obj|tmp)$/i
CONFIG.file_ignore_pattern = /\.(?:png|jpg|gif|db|exe|dll|obj|tmp)$/i;


// 大文字小文字を無視するならtrue、そうでなければfalse
// 大文字小文字を無視するならtrue、そうでなければfalse
CONFIG.ignore_case = true
CONFIG.ignore_case = true;


// 拡張子ごとにまとめるならtrue、そうでなければfalse
// 拡張子ごとにまとめるならtrue、そうでなければfalse
CONFIG.sort_by_extension = true
CONFIG.sort_by_extension = true;


// 時間でソートするならtrue、そうでなければfalse
// 時間でソートするならtrue、そうでなければfalse
CONFIG.sort_by_modified_time = false
CONFIG.sort_by_modified_time = false;


/** 以下本体 **/
/** 以下本体 **/


var FS = new ActiveXObject("Scripting.FileSystemObject")
var FS = new ActiveXObject("Scripting.FileSystemObject");


function main() {
function main() {
var dir = document.Path
var dir = document.Path;
var choosed = choose(ls(dir))
var choosed = choose(ls(dir));


while (choosed && /\/$/.test(choosed)) {
while (choosed && /\/$/.test(choosed)) {
dir = FS.BuildPath(dir, choosed)
dir = FS.BuildPath(dir, choosed);
choosed = choose(ls(dir))
choosed = choose(ls(dir));
}
}


if (choosed) {
if (choosed) {
var path = FS.BuildPath(dir, choosed).replace(/\//g, '\\')
var path = FS.BuildPath(dir, choosed).replace(/\//g, '\\');
editor.OpenFile(path, 0, meOpenAllowNewWindow)
editor.OpenFile(path, 0, meOpenAllowNewWindow);
}
}
}
}


function ls(path) {
function ls(path) {
var folder = FS.GetFolder(path)
var folder = FS.GetFolder(path);


var folders = []
var folders = [];
each_item(folder.SubFolders, function(e) {
each_item(folder.SubFolders, function(e) {
if (CONFIG.folder_pattern.test(e.Name)) {
if (CONFIG.folder_pattern.test(e.Name)) {
folders.push(e.Name + "/")
folders.push(e.Name + "/");
}
}
})
});
folders.sort()
folders.sort();


folders.unshift('../')
folders.unshift('../');


var files = []
var files = [];
each_item(folder.Files, function(e) {
each_item(folder.Files, function(e) {
if (CONFIG.file_pattern.test(e.Name) && !CONFIG.file_ignore_pattern.test(e.Name)) {
if (CONFIG.file_pattern.test(e.Name) && !CONFIG.file_ignore_pattern.test(e.Name)) {
files.push(e.Name)
files.push(e.Name);
}
}
})
});


if (CONFIG.sort_by_time) {
if (CONFIG.sort_by_time) {
files.sort(function(a, b) {
files.sort(function(a, b) {
a = FS.GetFile(a).DateLastModified
a = FS.GetFile(a).DateLastModified;
b = FS.GetFile(b).DateLastModified
b = FS.GetFile(b).DateLastModified;
return a < b ? 1 : a > b ? -1 : 0
return a < b ? 1 : a > b ? -1 : 0;
})
});
} else if (CONFIG.ignore_case) {
} else if (CONFIG.ignore_case) {
files.sort(function(a, b) {
files.sort(function(a, b) {
a = a.toLocaleLowerCase()
a = a.toLocaleLowerCase();
b = b.toLocaleLowerCase()
b = b.toLocaleLowerCase();
return !a ? -1 : !b ? 1 : a < b ? -1 : a > b ? 1 : 0
return !a ? -1 : !b ? 1 : a < b ? -1 : a > b ? 1 : 0;
})
});
} else {
} else {
files.sort()
files.sort();
}
}


129行目: 129行目:
// JScriptは安定ソートなのでこれでも大丈夫なはず
// JScriptは安定ソートなのでこれでも大丈夫なはず
files.sort(function(a, b) {
files.sort(function(a, b) {
var sa = get_extension(a)
var sa = get_extension(a);
var sb = get_extension(b)
var sb = get_extension(b);
return !sa ? 1 : !sb ? -1 : sa < sb ? -1 : sa > sb ? 1 : 0
return !sa ? 1 : !sb ? -1 : sa < sb ? -1 : sa > sb ? 1 : 0;
})
});
}
}


return folders.concat(files)
return folders.concat(files);
}
}


function get_extension(str) {
function get_extension(str) {
var i = str.lastIndexOf('.')
var i = str.lastIndexOf('.');
return i >= 0 && str.substr(i + 1)
return i >= 0 && str.substr(i + 1);
}
}


function each_item(collection, callback) {
function each_item(collection, callback) {
var result
var result;


for (var e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
for (var e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
result = callback(e.item())
result = callback(e.item());
if (result) {
if (result) {
return result
return result;
}
}
}
}
155行目: 155行目:


function choose(words) {
function choose(words) {
var menu = makeMenu()
var menu = makeMenu();
var i = menu.Track(0)
var i = menu.Track(0);


return i && words[i - 1]
return i && words[i - 1];


function makeMenu() {
function makeMenu() {
var menu = window.CreatePopupMenu()
var menu = window.CreatePopupMenu();


if (!words || words.length == 0) {
if (!words || words.length == 0) {
return menu
return menu;
}
}


var n = -1
var n = -1;


function addHotkey(word) {
function addHotkey(word) {
if (n > 34) {
if (n > 34) {
return word
return word;
}
}
n++
n++;
return "&" + n.toString(36) + ". " + word
return "&" + n.toString(36) + ". " + word;
}
}


for (var i = 0; i < words.length; i++) {
for (var i = 0; i < words.length; i++) {
menu.Add(addHotkey(words[i]), i + 1)
menu.Add(addHotkey(words[i]), i + 1);
}
}


return menu
return menu;
}
}
}
}


main()
main();
</syntaxhighlight>
</syntaxhighlight>

2025年11月25日 (火) 06:57時点における最新版

今開いているファイルのフォルダの内容をポップアップで表示して、選択するとそのファイルを開きます。

手石さんのポップアップメニューでファイル選択の下位互換です。手石さんのものはページ切り替えなどのボタンがあり、これよりも使いやすいと思います。

インストール[編集]

  1. 下のスクリプトをコピーして、MeryのMy Macroフォルダなどに保存
  2. マクロを[カスタマイズ]→[新規作成]で登録し、Alt+Pなどお好みで設定する

カスタマイズ[編集]

変数を変えることで、挙動がいくらかカスタマイズできます。

名前 初期設定 効果
CONFIG.folder_pattern /^[^\.]/ この正規表現にマッチするフォルダ名を一覧に含めます。

初期設定では . で始まるフォルダを除外します。

CONFIG.file_pattern /^[^\.]/ この正規表現にマッチするファイル名を一覧に含めます。

初期設定では . で始まるフォルダを除外します。

CONFIG.file_ignore_pattern /\.(?:png|jpg|gif|db|exe|dll|obj|tmp)$/i この正規表現にマッチするファイル名は一覧から除きます。

初期設定では画像ファイルなど適当に思いついたものを除外してあります。

CONFIG.ignore_case true trueにすると一覧のソートで大文字小文字を無視します。
CONFIG.sort_by_extension true trueにすると一覧で拡張子ごとにまとめます。
CONFIG.sort_by_modified_time false trueにするとファイルの最終変更時間で降順にソートします。

これをtrueにすると上2つの設定は無視されます。

変更履歴[編集]

  • r2 (2013-09-21)
    • ディレクトリをまたぐと開けなかったバグの修正
  • r1 (2013-09-10)
    • 初版

ソースコード[編集]

// 同じフォルダにあるファイルを開く.js r2
// もしくは 簡易フォルダツリー

var CONFIG = {};

/** 設定 **/

// 一覧に含めるフォルダ名の正規表現
CONFIG.folder_pattern = /^[^\.]/;

// 一覧に含めるファイル名の正規表現
CONFIG.file_pattern = /^[^\.]/;

// 別例: 現在のファイルと同じ拡張子だけ表示
// CONFIG.file_pattern = document.Name.indexOf('.') == -1 ? /./ : RegExp(document.Name.substr(document.Name.indexOf('.')), "i");

// 一覧から除外するファイル名の正規表現
CONFIG.file_ignore_pattern = /\.(?:png|jpg|gif|db|exe|dll|obj|tmp)$/i;

// 大文字小文字を無視するならtrue、そうでなければfalse
CONFIG.ignore_case = true;

// 拡張子ごとにまとめるならtrue、そうでなければfalse
CONFIG.sort_by_extension = true;

// 時間でソートするならtrue、そうでなければfalse
CONFIG.sort_by_modified_time = false;

/** 以下本体 **/

var FS = new ActiveXObject("Scripting.FileSystemObject");

function main() {
	var dir = document.Path;
	var choosed = choose(ls(dir));

	while (choosed && /\/$/.test(choosed)) {
		dir = FS.BuildPath(dir, choosed);
		choosed = choose(ls(dir));
	}

	if (choosed) {
		var path = FS.BuildPath(dir, choosed).replace(/\//g, '\\');
		editor.OpenFile(path, 0, meOpenAllowNewWindow);
	}
}

function ls(path) {
	var folder = FS.GetFolder(path);

	var folders = [];
	each_item(folder.SubFolders, function(e) {
		if (CONFIG.folder_pattern.test(e.Name)) {
			folders.push(e.Name + "/");
		}
	});
	folders.sort();

	folders.unshift('../');

	var files = [];
	each_item(folder.Files, function(e) {
		if (CONFIG.file_pattern.test(e.Name) && !CONFIG.file_ignore_pattern.test(e.Name)) {
			files.push(e.Name);
		}
	});

	if (CONFIG.sort_by_time) {
		files.sort(function(a, b) {
			a = FS.GetFile(a).DateLastModified;
			b = FS.GetFile(b).DateLastModified;
			return a < b ? 1 : a > b ? -1 : 0;
		});
	} else if (CONFIG.ignore_case) {
		files.sort(function(a, b) {
			a = a.toLocaleLowerCase();
			b = b.toLocaleLowerCase();
			return !a ? -1 : !b ? 1 : a < b ? -1 : a > b ? 1 : 0;
		});
	} else {
		files.sort();
	}

	if (CONFIG.sort_by_extension) {
		// JScriptは安定ソートなのでこれでも大丈夫なはず
		files.sort(function(a, b) {
			var sa = get_extension(a);
			var sb = get_extension(b);
			return !sa ? 1 : !sb ? -1 : sa < sb ? -1 : sa > sb ? 1 : 0;
		});
	}

	return folders.concat(files);
}

function get_extension(str) {
	var i = str.lastIndexOf('.');
	return i >= 0 && str.substr(i + 1);
}

function each_item(collection, callback) {
	var result;

	for (var e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
		result = callback(e.item());
		if (result) {
			return result;
		}
	}
}

function choose(words) {
	var menu = makeMenu();
	var i = menu.Track(0);

	return i && words[i - 1];

	function makeMenu() {
		var menu = window.CreatePopupMenu();

		if (!words || words.length == 0) {
			return menu;
		}

		var n = -1;

		function addHotkey(word) {
			if (n > 34) {
				return word;
			}
			n++;
			return "&" + n.toString(36) + ". " + word;
		}

		for (var i = 0; i < words.length; i++) {
			menu.Add(addHotkey(words[i]), i + 1);
		}

		return menu;
	}
}

main();
スポンサーリンク