「タグファイルから補完」の版間の差分
ナビゲーションに移動
検索に移動
ソースコードの整形 |
変数にvarの宣言を追加 |
||
| (同じ利用者による、間の3版が非表示) | |||
| 8行目: | 8行目: | ||
== インストール == | == インストール == | ||
# | #下のスクリプトをコピーして、MeryのMacrosフォルダなどに保存 | ||
#Mery.exeのあるフォルダに[https://hp.vector.co.jp/authors/VA025040/ctags/ ctags.exe]を置く | #Mery.exeのあるフォルダに[https://web.archive.org/web/20241217153248/https://hp.vector.co.jp/authors/VA025040/ctags/ ctags.exe]を置く | ||
#マクロを登録し、Ctrl+→やCtrl+Shift+SpaceやCtrl+Qキーなどにお好みで設定する | #マクロを登録し、Ctrl+→やCtrl+Shift+SpaceやCtrl+Qキーなどにお好みで設定する | ||
| 83行目: | 83行目: | ||
== ソースコード == | == ソースコード == | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript" copy> | ||
// タグファイルから補完.js r7 2012-10-24 | // タグファイルから補完.js r7 2012-10-24 | ||
// https://www.haijin-boys.com/wiki/%E3%82%BF%E3%82%B0%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E8%A3%9C%E5%AE%8C | // https://www.haijin-boys.com/wiki/%E3%82%BF%E3%82%B0%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E8%A3%9C%E5%AE%8C | ||
| 92行目: | 92行目: | ||
// タグファイルの名前 | // タグファイルの名前 | ||
TAGS = ".merytags" | var TAGS = ".merytags"; | ||
// ctags.exeの名前 | // ctags.exeの名前 | ||
// 相対パスの場合はmery本体のあるディレクトリのものを使います | // 相対パスの場合はmery本体のあるディレクトリのものを使います | ||
// "c:\\bin\\ctags.exe" のように絶対パスも指定できます | // "c:\\bin\\ctags.exe" のように絶対パスも指定できます | ||
CTAGS = "ctags.exe" | var CTAGS = "ctags.exe"; | ||
// ctagsに与える引数 (初期設定:位置を行番号で記憶(必須)、フォルダを再帰的に処理、関数の引数を記憶) | // ctagsに与える引数 (初期設定:位置を行番号で記憶(必須)、フォルダを再帰的に処理、関数の引数を記憶) | ||
CTAGS_FLAGS = "--excmd=number --recurse --fields=+S" | var CTAGS_FLAGS = "--excmd=number --recurse --fields=+S"; | ||
// 単語の途中で補完する際の挙動 | // 単語の途中で補完する際の挙動 | ||
// trueにするとカーソルの置かれた単語全体から補完 | // trueにするとカーソルの置かれた単語全体から補完 | ||
// falseにするとカーソルより左から補完します | // falseにするとカーソルより左から補完します | ||
WHOLE_WORD = true | var WHOLE_WORD = true; | ||
// 単語の検索の挙動 | // 単語の検索の挙動 | ||
// trueにすると検索時大文字と小文字を区別しません | // trueにすると検索時大文字と小文字を区別しません | ||
// falseにすると区別します | // falseにすると区別します | ||
CASE_INSENSITIVE = true | var CASE_INSENSITIVE = true; | ||
// タグを作るフォルダ | // タグを作るフォルダ | ||
// "." にすると、編集中のファイルのあるフォルダでタグを作ります | // "." にすると、編集中のファイルのあるフォルダでタグを作ります | ||
// ".." などにすると、編集中のファイルの一つ上のフォルダからタグを作ります | // ".." などにすると、編集中のファイルの一つ上のフォルダからタグを作ります | ||
DEFAULT_TAGS_DIR = "." | var DEFAULT_TAGS_DIR = "."; | ||
// タグファイルがない場合の挙動 | // タグファイルがない場合の挙動 | ||
// trueにするとタグを作成するフォルダを尋ねます | // trueにするとタグを作成するフォルダを尋ねます | ||
// falseにするとフォルダを尋ねずに無言で作成を始めます | // falseにするとフォルダを尋ねずに無言で作成を始めます | ||
CONFIRM_CREATE_TAGS = false | var CONFIRM_CREATE_TAGS = false; | ||
/** 本体 **/ | /** 本体 **/ | ||
var FileSystem = new ActiveXObject("Scripting.FileSystemObject") | var FileSystem = new ActiveXObject("Scripting.FileSystemObject"); | ||
var Shell = new ActiveXObject("WScript.Shell") | var Shell = new ActiveXObject("WScript.Shell"); | ||
main() | main(); | ||
function main() { | function main() { | ||
var ctags = makeCtags() | var ctags = makeCtags(); | ||
var tags = makeTags(ctags) | var tags = makeTags(ctags); | ||
var query = getQueryWord() | var query = getQueryWord(); | ||
var result = tags.lookup(query) | var result = tags.lookup(query); | ||
var word = chooseWord(result) | var word = chooseWord(result); | ||
if ("string" === typeof word) { | if ("string" === typeof word) { | ||
writeWord(word) | writeWord(word); | ||
} else if (word === false) { | } else if (word === false) { | ||
tags.update() | tags.update(); | ||
} else { | } else { | ||
jumpToDefinition(word) | jumpToDefinition(word); | ||
} | } | ||
} | } | ||
| 148行目: | 148行目: | ||
return { | return { | ||
run: run | run: run | ||
} | }; | ||
function run(dir) { | function run(dir) { | ||
var ctags = findCtags() | var ctags = findCtags(); | ||
try { | try { | ||
Shell.CurrentDirectory = dir | Shell.CurrentDirectory = dir; | ||
window.Status = 'タグファイルを作成しています お待ちください' | window.Status = 'タグファイルを作成しています お待ちください'; | ||
Shell.Run('"' + ctags + '" -o ' + TAGS + " " + CTAGS_FLAGS, 0, true) | Shell.Run('"' + ctags + '" -o ' + TAGS + " " + CTAGS_FLAGS, 0, true); | ||
} catch (e) {} | } catch (e) {} | ||
window.Status = 'タグファイルを作成しました' | window.Status = 'タグファイルを作成しました'; | ||
return FileSystem.BuildPath(dir, TAGS) | return FileSystem.BuildPath(dir, TAGS); | ||
} | } | ||
function findCtags() { | function findCtags() { | ||
if (FileSystem.FileExists(CTAGS)) { | if (FileSystem.FileExists(CTAGS)) { | ||
return CTAGS | return CTAGS; | ||
} | } | ||
var dir = FileSystem.GetParentFolderName(editor.FullName) | var dir = FileSystem.GetParentFolderName(editor.FullName); | ||
var ctags = FileSystem.BuildPath(dir, CTAGS) | var ctags = FileSystem.BuildPath(dir, CTAGS); | ||
if (FileSystem.FileExists(ctags)) { | if (FileSystem.FileExists(ctags)) { | ||
return ctags | return ctags; | ||
} | } | ||
throw new Error("ctags.exeが見つかりませんでした\nMery本体のディレクトリに置くか、絶対パスを設定してください") | throw new Error("ctags.exeが見つかりませんでした\nMery本体のディレクトリに置くか、絶対パスを設定してください"); | ||
} | } | ||
} | } | ||
function makeTags(ctags) { | function makeTags(ctags) { | ||
var fullname = findTagfile() | var fullname = findTagfile(); | ||
var text = loadTagfile() | var text = loadTagfile(); | ||
return { | return { | ||
lookup: lookup, | lookup: lookup, | ||
update: update | update: update | ||
} | }; | ||
function getPath() { | function getPath() { | ||
return FileSystem.GetParentFolderName(fullname) | return FileSystem.GetParentFolderName(fullname); | ||
} | } | ||
function lookup(word) { | function lookup(word) { | ||
if (/^\s*$/.test(word)) { | if (/^\s*$/.test(word)) { | ||
return | return; | ||
} | } | ||
word = reEscape(word) | word = reEscape(word); | ||
var opts = CASE_INSENSITIVE ? "igm" : "gm" | var opts = CASE_INSENSITIVE ? "igm" : "gm"; | ||
var re = new RegExp("^" + word + ".*$", opts) | var re = new RegExp("^" + word + ".*$", opts); | ||
var lines = text.match(re) | var lines = text.match(re); | ||
if (!lines) { | if (!lines) { | ||
return [] | return []; | ||
} | } | ||
return calcWords().concat(calcDefinitions(word)) | return calcWords().concat(calcDefinitions(word)); | ||
function calcWords() { | function calcWords() { | ||
var words = new Array(lines.length) | var words = new Array(lines.length); | ||
words[0] = lines[0].substring(0, lines[0].indexOf("\t")) | words[0] = lines[0].substring(0, lines[0].indexOf("\t")); | ||
if (words.length === 1) { | if (words.length === 1) { | ||
return words[0] === word ? [] : words | return words[0] === word ? [] : words; | ||
} | } | ||
var n = 0 | var n = 0; | ||
for (var i = 1; i < lines.length; i++) { | for (var i = 1; i < lines.length; i++) { | ||
var w = lines[i].substring(0, lines[i].indexOf("\t")) | var w = lines[i].substring(0, lines[i].indexOf("\t")); | ||
if (words[n] !== w) { | if (words[n] !== w) { | ||
n++ | n++; | ||
words[n] = w | words[n] = w; | ||
} | } | ||
} | } | ||
words.length = n + 1 | words.length = n + 1; | ||
words.sort(function(a, b) { | words.sort(function(a, b) { | ||
return a.localeCompare(b) | return a.localeCompare(b); | ||
}) | }); | ||
return words | return words; | ||
} | } | ||
function calcDefinitions(word) { | function calcDefinitions(word) { | ||
var defs = new Array(lines.length) | var defs = new Array(lines.length); | ||
var n = 0 | var n = 0; | ||
for (var i = 0; i < lines.length; i++) { | for (var i = 0; i < lines.length; i++) { | ||
var line = lines[i] | var line = lines[i]; | ||
var tab1 = line.indexOf("\t") | var tab1 = line.indexOf("\t"); | ||
if (tab1 !== word.length) { | if (tab1 !== word.length) { | ||
continue | continue; | ||
} | } | ||
var tab2 = line.indexOf("\t", tab1 + 1) | var tab2 = line.indexOf("\t", tab1 + 1); | ||
var endnum = line.indexOf(";", tab2 + 1) | var endnum = line.indexOf(";", tab2 + 1); | ||
var sig = line.indexOf("signature:", endnum + 1) | var sig = line.indexOf("signature:", endnum + 1); | ||
var name = line.substring(0, tab1) | var name = line.substring(0, tab1); | ||
var filename = line.substring(tab1 + 1, tab2) | var filename = line.substring(tab1 + 1, tab2); | ||
var linenum = line.substring(tab2 + 1, endnum) | var linenum = line.substring(tab2 + 1, endnum); | ||
var signature = sig < 0 ? "" : line.substring(sig + "signature:".length) | var signature = sig < 0 ? "" : line.substring(sig + "signature:".length); | ||
var fullname = FileSystem.BuildPath(getPath(), filename) | var fullname = FileSystem.BuildPath(getPath(), filename); | ||
defs[n] = [fullname, linenum, filename, name + signature] | defs[n] = [fullname, linenum, filename, name + signature]; | ||
defs[n].toString = joinme | defs[n].toString = joinme; | ||
n++ | n++; | ||
} | } | ||
defs.length = n | defs.length = n; | ||
return defs | return defs; | ||
} | } | ||
function joinme() { | function joinme() { | ||
return this[3] + " (" + this[2] + " : " + this[1] + ")" | return this[3] + " (" + this[2] + " : " + this[1] + ")"; | ||
} | } | ||
} | } | ||
function reEscape(w) { | function reEscape(w) { | ||
return w.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") | return w.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); | ||
} | } | ||
function loadTagfile() { | function loadTagfile() { | ||
if (!fullname) { | if (!fullname) { | ||
fullname = makeTagfile() | fullname = makeTagfile(); | ||
} | } | ||
return slurp(fullname) | return slurp(fullname); | ||
} | } | ||
function findTagfile() { | function findTagfile() { | ||
var dir = document.Path | var dir = document.Path; | ||
while (FileSystem.FolderExists(dir)) { | while (FileSystem.FolderExists(dir)) { | ||
var file = FileSystem.BuildPath(dir, TAGS) | var file = FileSystem.BuildPath(dir, TAGS); | ||
if (FileSystem.FileExists(file)) { | if (FileSystem.FileExists(file)) { | ||
return file | return file; | ||
} | } | ||
dir = FileSystem.GetParentFolderName(dir) | dir = FileSystem.GetParentFolderName(dir); | ||
} | } | ||
} | } | ||
function makeTagfile() { | function makeTagfile() { | ||
var dir = FileSystem.BuildPath(document.Path, DEFAULT_TAGS_DIR) | var dir = FileSystem.BuildPath(document.Path, DEFAULT_TAGS_DIR); | ||
if (CONFIRM_CREATE_TAGS) { | if (CONFIRM_CREATE_TAGS) { | ||
dir = window.Prompt("タグファイル作成フォルダ", dir) | dir = window.Prompt("タグファイル作成フォルダ", dir); | ||
} | } | ||
if (!dir) { | if (!dir) { | ||
window.Quit() | window.Quit(); | ||
} | } | ||
return ctags.run(dir) | return ctags.run(dir); | ||
} | } | ||
function update() { | function update() { | ||
return ctags.run(getPath()) | return ctags.run(getPath()); | ||
} | } | ||
function slurp(filename) { | function slurp(filename) { | ||
var f = FileSystem.OpenTextFile(filename) | var f = FileSystem.OpenTextFile(filename); | ||
var text = f.ReadAll() | var text = f.ReadAll(); | ||
f.Close() | f.Close(); | ||
return text | return text; | ||
} | } | ||
} | } | ||
function getQueryWord() { | function getQueryWord() { | ||
var s = document.selection | var s = document.selection; | ||
if (!s.IsEmpty) { | if (!s.IsEmpty) { | ||
return s.Text | return s.Text; | ||
} | } | ||
if (WHOLE_WORD) { | if (WHOLE_WORD) { | ||
s.SelectWord() | s.SelectWord(); | ||
// hoge|(); → hogeFuga|(); のように補完 | // hoge|(); → hogeFuga|(); のように補完 | ||
if (s.Text.length == 1 && !/\w/.test(s.Text)) { | if (s.Text.length == 1 && !/\w/.test(s.Text)) { | ||
s.Collapse(meCollapseStart) | s.Collapse(meCollapseStart); | ||
s.WordLeft(true) | s.WordLeft(true); | ||
} | } | ||
} else { | } else { | ||
s.WordLeft(true) | s.WordLeft(true); | ||
} | } | ||
if (/\A\s+\z/.test(s.Text)) { | if (/\A\s+\z/.test(s.Text)) { | ||
s.Collapse(meCollapseEnd) | s.Collapse(meCollapseEnd); | ||
} | } | ||
return s.Text | return s.Text; | ||
} | } | ||
function chooseWord(words) { | function chooseWord(words) { | ||
if (words && words.length === 1 && typeof words[0] === "string") { | if (words && words.length === 1 && typeof words[0] === "string") { | ||
return words[0] | return words[0]; | ||
} | } | ||
var menu = makeMenu() | var menu = makeMenu(); | ||
var i = menu.Track(0) | var i = menu.Track(0); | ||
return i === -1 ? false : words && words[i - 1] | return i === -1 ? false : words && words[i - 1]; | ||
function makeMenu() { | function makeMenu() { | ||
var menu = window.CreatePopupMenu() | var menu = window.CreatePopupMenu(); | ||
initMenu(menu) | initMenu(menu); | ||
menu.Add("タグファイルを更新する", -1) | menu.Add("タグファイルを更新する", -1); | ||
return menu | return menu; | ||
} | } | ||
function initMenu(menu) { | function initMenu(menu) { | ||
if (!words || words.length == 0) { | if (!words || words.length == 0) { | ||
return | return; | ||
} | } | ||
var n = 0 | var n = 0; | ||
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); | ||
} | } | ||
menu.Add(undefined, 0, meMenuSeparator) | menu.Add(undefined, 0, meMenuSeparator); | ||
} | } | ||
} | } | ||
| 393行目: | 393行目: | ||
function jumpToDefinition(def) { | function jumpToDefinition(def) { | ||
if (!def) { | if (!def) { | ||
return | return; | ||
} | } | ||
window.Status = def + "にジャンプします" | window.Status = def + "にジャンプします"; | ||
var file = def[0] | var file = def[0]; | ||
var line = def[1] | var line = def[1]; | ||
editor.OpenFile(file, 0, meOpenAllowNewWindow) | editor.OpenFile(file, 0, meOpenAllowNewWindow); | ||
editor.ActiveDocument.selection.SetActivePoint(mePosLogical, 1, line, false) | editor.ActiveDocument.selection.SetActivePoint(mePosLogical, 1, line, false); | ||
editor.ActiveDocument.Activate() | editor.ActiveDocument.Activate(); | ||
} | } | ||
function writeWord(word) { | function writeWord(word) { | ||
if (word) { | if (word) { | ||
document.selection.Text = word | document.selection.Text = word; | ||
} | } | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
2025年11月25日 (火) 10:27時点における最新版
ctagsの生成したtagsファイルから検索して単語のメニューを出します。
項目を選ぶとその単語が挿入されます。
単語が完全な形の場合、タグジャンプを行います。
kazyさんのctags.exeでtagsファイルを生成、タグジャンプを行うマクロとあわせてお使いください(単独で使ってもタグジャンプ機能はあります)。
インストール[編集]
- 下のスクリプトをコピーして、MeryのMacrosフォルダなどに保存
- Mery.exeのあるフォルダにctags.exeを置く
- マクロを登録し、Ctrl+→やCtrl+Shift+SpaceやCtrl+Qキーなどにお好みで設定する
使い方[編集]
- 補完したい単語にカーソルを置き、マクロを起動する
- 初回起動の場合、タグファイルの作成を待つ
- すでに単語が完全な場合、メニューを選ぶとその定義にジャンプする
- メニューの項目を選ぶと、その単語が挿入される
- メニューの最後の「タグファイルを更新する」を選ぶと、タグファイルを作り直すことができる
カスタマイズ[編集]
変数を変えることで、挙動がいくらかカスタマイズできます。
| 名前 | 初期設定 | 効果 |
|---|---|---|
| TAGS | ".merytags" | タグファイルの名前。 |
| CTAGS | "ctags.exe" | ctags.exeの名前。
相対パスの場合はmery本体のあるディレクトリのものを使います。 "c:\\bin\\ctags.exe" のように絶対パスも指定できます。 |
| CTAGS_FLAGS | "--excmd=number --recurse --fields=+S" | ctagsに与える引数。
初期設定の意味は左から
|
| WHOLE_WORD | true | 単語の途中で補完する際の挙動。
trueにするとカーソルの置かれた単語全体から補完。 falseにするとカーソルより左から補完します。 |
| CASE_INSENSITIVE | true | 単語の検索の挙動。
trueにすると検索時大文字と小文字を区別しません。 falseにすると区別します。 |
| DEFAULT_TAGS_DIR | "." | タグを作るフォルダ。
"." にすると、編集中のファイルのあるフォルダでタグを作ります。 ".." などにすると、編集中のファイルの一つ上のフォルダからタグを作ります。 |
| CONFIRM_CREATE_TAGS | true | タグファイルがない場合の挙動。
trueにするとタグを作成するフォルダを尋ねます。 falseにするとフォルダを尋ねずに無言で作成を始めます。 |
変更履歴[編集]
- r7 (2012-10-14)
- 補完候補の単語が1つだけのときうまく補完されないのを修正
- r6 (2012-08-23)
- 確認せずにctagsを起動するオプション
- r5 (2012-08-01)
- C言語の関数で引数を表示、今開いてるファイル中の単語からも補完、文字の大小を区別しないオプション
- r4 (2012-06-22)
- ホットキー
- r3
- 単独でctags呼び出し
- r2
- 失念
- r1
- 失念
ソースコード[編集]
// タグファイルから補完.js r7 2012-10-24
// https://www.haijin-boys.com/wiki/%E3%82%BF%E3%82%B0%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E8%A3%9C%E5%AE%8C
// https://hp.vector.co.jp/authors/VA025040/ctags/ の 日本語版ctags 5.8J2 で動作確認しています
/** 設定 **/
// タグファイルの名前
var TAGS = ".merytags";
// ctags.exeの名前
// 相対パスの場合はmery本体のあるディレクトリのものを使います
// "c:\\bin\\ctags.exe" のように絶対パスも指定できます
var CTAGS = "ctags.exe";
// ctagsに与える引数 (初期設定:位置を行番号で記憶(必須)、フォルダを再帰的に処理、関数の引数を記憶)
var CTAGS_FLAGS = "--excmd=number --recurse --fields=+S";
// 単語の途中で補完する際の挙動
// trueにするとカーソルの置かれた単語全体から補完
// falseにするとカーソルより左から補完します
var WHOLE_WORD = true;
// 単語の検索の挙動
// trueにすると検索時大文字と小文字を区別しません
// falseにすると区別します
var CASE_INSENSITIVE = true;
// タグを作るフォルダ
// "." にすると、編集中のファイルのあるフォルダでタグを作ります
// ".." などにすると、編集中のファイルの一つ上のフォルダからタグを作ります
var DEFAULT_TAGS_DIR = ".";
// タグファイルがない場合の挙動
// trueにするとタグを作成するフォルダを尋ねます
// falseにするとフォルダを尋ねずに無言で作成を始めます
var CONFIRM_CREATE_TAGS = false;
/** 本体 **/
var FileSystem = new ActiveXObject("Scripting.FileSystemObject");
var Shell = new ActiveXObject("WScript.Shell");
main();
function main() {
var ctags = makeCtags();
var tags = makeTags(ctags);
var query = getQueryWord();
var result = tags.lookup(query);
var word = chooseWord(result);
if ("string" === typeof word) {
writeWord(word);
} else if (word === false) {
tags.update();
} else {
jumpToDefinition(word);
}
}
function makeCtags() {
return {
run: run
};
function run(dir) {
var ctags = findCtags();
try {
Shell.CurrentDirectory = dir;
window.Status = 'タグファイルを作成しています お待ちください';
Shell.Run('"' + ctags + '" -o ' + TAGS + " " + CTAGS_FLAGS, 0, true);
} catch (e) {}
window.Status = 'タグファイルを作成しました';
return FileSystem.BuildPath(dir, TAGS);
}
function findCtags() {
if (FileSystem.FileExists(CTAGS)) {
return CTAGS;
}
var dir = FileSystem.GetParentFolderName(editor.FullName);
var ctags = FileSystem.BuildPath(dir, CTAGS);
if (FileSystem.FileExists(ctags)) {
return ctags;
}
throw new Error("ctags.exeが見つかりませんでした\nMery本体のディレクトリに置くか、絶対パスを設定してください");
}
}
function makeTags(ctags) {
var fullname = findTagfile();
var text = loadTagfile();
return {
lookup: lookup,
update: update
};
function getPath() {
return FileSystem.GetParentFolderName(fullname);
}
function lookup(word) {
if (/^\s*$/.test(word)) {
return;
}
word = reEscape(word);
var opts = CASE_INSENSITIVE ? "igm" : "gm";
var re = new RegExp("^" + word + ".*$", opts);
var lines = text.match(re);
if (!lines) {
return [];
}
return calcWords().concat(calcDefinitions(word));
function calcWords() {
var words = new Array(lines.length);
words[0] = lines[0].substring(0, lines[0].indexOf("\t"));
if (words.length === 1) {
return words[0] === word ? [] : words;
}
var n = 0;
for (var i = 1; i < lines.length; i++) {
var w = lines[i].substring(0, lines[i].indexOf("\t"));
if (words[n] !== w) {
n++;
words[n] = w;
}
}
words.length = n + 1;
words.sort(function(a, b) {
return a.localeCompare(b);
});
return words;
}
function calcDefinitions(word) {
var defs = new Array(lines.length);
var n = 0;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
var tab1 = line.indexOf("\t");
if (tab1 !== word.length) {
continue;
}
var tab2 = line.indexOf("\t", tab1 + 1);
var endnum = line.indexOf(";", tab2 + 1);
var sig = line.indexOf("signature:", endnum + 1);
var name = line.substring(0, tab1);
var filename = line.substring(tab1 + 1, tab2);
var linenum = line.substring(tab2 + 1, endnum);
var signature = sig < 0 ? "" : line.substring(sig + "signature:".length);
var fullname = FileSystem.BuildPath(getPath(), filename);
defs[n] = [fullname, linenum, filename, name + signature];
defs[n].toString = joinme;
n++;
}
defs.length = n;
return defs;
}
function joinme() {
return this[3] + " (" + this[2] + " : " + this[1] + ")";
}
}
function reEscape(w) {
return w.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}
function loadTagfile() {
if (!fullname) {
fullname = makeTagfile();
}
return slurp(fullname);
}
function findTagfile() {
var dir = document.Path;
while (FileSystem.FolderExists(dir)) {
var file = FileSystem.BuildPath(dir, TAGS);
if (FileSystem.FileExists(file)) {
return file;
}
dir = FileSystem.GetParentFolderName(dir);
}
}
function makeTagfile() {
var dir = FileSystem.BuildPath(document.Path, DEFAULT_TAGS_DIR);
if (CONFIRM_CREATE_TAGS) {
dir = window.Prompt("タグファイル作成フォルダ", dir);
}
if (!dir) {
window.Quit();
}
return ctags.run(dir);
}
function update() {
return ctags.run(getPath());
}
function slurp(filename) {
var f = FileSystem.OpenTextFile(filename);
var text = f.ReadAll();
f.Close();
return text;
}
}
function getQueryWord() {
var s = document.selection;
if (!s.IsEmpty) {
return s.Text;
}
if (WHOLE_WORD) {
s.SelectWord();
// hoge|(); → hogeFuga|(); のように補完
if (s.Text.length == 1 && !/\w/.test(s.Text)) {
s.Collapse(meCollapseStart);
s.WordLeft(true);
}
} else {
s.WordLeft(true);
}
if (/\A\s+\z/.test(s.Text)) {
s.Collapse(meCollapseEnd);
}
return s.Text;
}
function chooseWord(words) {
if (words && words.length === 1 && typeof words[0] === "string") {
return words[0];
}
var menu = makeMenu();
var i = menu.Track(0);
return i === -1 ? false : words && words[i - 1];
function makeMenu() {
var menu = window.CreatePopupMenu();
initMenu(menu);
menu.Add("タグファイルを更新する", -1);
return menu;
}
function initMenu(menu) {
if (!words || words.length == 0) {
return;
}
var n = 0;
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);
}
menu.Add(undefined, 0, meMenuSeparator);
}
}
function jumpToDefinition(def) {
if (!def) {
return;
}
window.Status = def + "にジャンプします";
var file = def[0];
var line = def[1];
editor.OpenFile(file, 0, meOpenAllowNewWindow);
editor.ActiveDocument.selection.SetActivePoint(mePosLogical, 1, line, false);
editor.ActiveDocument.Activate();
}
function writeWord(word) {
if (word) {
document.selection.Text = word;
}
}
スポンサーリンク