フォルダツリーをポップアップ表示

提供: MeryWiki
移動先: 案内検索

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

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

インストール[編集]

  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つの設定は無視されます

更新履歴[編集]

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

ソース[編集]

// 同じフォルダにあるファイルを開く.js r2
// もしくは 簡易フォルダツリー
 
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()