「
タグファイルから補完
」を編集中
2023年7月22日 (土) 17:51時点における
MSY-07
(
トーク
|
投稿記録
)
による版
(見出しの修正)
(
差分
)
← 古い版
|
最新版
(
差分
) |
新しい版 →
(
差分
)
ナビゲーションに移動
検索に移動
警告: このページの古い版を編集しています。
公開すると、この版以降になされた変更がすべて失われます。
警告:
ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。
ログイン
または
アカウントを作成
すれば、あなたの編集はその利用者名とともに表示されるほか、さまざまなメリットもあります。
スパム攻撃防止用のチェックです。 決して、ここには、値の入力は
しない
でください!
ctagsの生成したtagsファイルから検索して単語のメニューを出します。 項目を選ぶとその単語が挿入されます。 単語が完全な形の場合、タグジャンプを行います。 kazyさんの[[ctags.exeでtagsファイルを生成、タグジャンプを行うマクロ]]とあわせてお使いください。(単独で使ってもタグジャンプ機能はあります) == インストール == #下のスクリプトをコピーして、MeryのMy Macroフォルダなどに保存 #Mery.exeのあるフォルダに[https://hp.vector.co.jp/authors/VA025040/ctags/ ctags.exe]を置く #マクロを登録し、Ctrl+→やCtrl+Shift+SpaceやCtrl+Qキーなどにお好みで設定する == 使い方 == #補完したい単語にカーソルを置き、マクロを起動する #初回起動の場合、タグファイルの作成を待つ #すでに単語が完全な場合、メニューを選ぶとその定義にジャンプする #メニューの項目を選ぶと、その単語が挿入される #メニューの最後の「タグファイルを更新する」を選ぶと、タグファイルを作り直すことができる == カスタマイズ == 変数を変えることで、挙動がいくらかカスタマイズできます。 {| border="1" style="width: 80%; margin-left: 2em; border-collapse: collapse" ! 名前 !! 初期設定 !! 効果 |- | 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にするとフォルダを尋ねずに無言で作成を始めます |} == 更新履歴 == * r1~r2: 失念 * r3: 単独でctags呼び出し * r4: ホットキー * r5: C言語の関数で引数を表示、今開いてるファイル中の単語からも補完、文字の大小を区別しないオプション * r6: 確認せずにctagsを起動するオプション * r7: 補完候補の単語が1つだけのときうまく補完されないのを修正 == ソースコード == <syntaxhighlight lang="javascript"> // タグファイルから補完.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 で動作確認しています /** 設定 **/ // タグファイルの名前 TAGS = ".merytags" // ctags.exeの名前 // 相対パスの場合はmery本体のあるディレクトリのものを使います // "c:\\bin\\ctags.exe" のように絶対パスも指定できます CTAGS = "ctags.exe" // ctagsに与える引数 (初期設定:位置を行番号で記憶(必須)、フォルダを再帰的に処理、関数の引数を記憶) CTAGS_FLAGS = "--excmd=number --recurse --fields=+S" // 単語の途中で補完する際の挙動 // trueにするとカーソルの置かれた単語全体から補完 // falseにするとカーソルより左から補完します WHOLE_WORD = true // 単語の検索の挙動 // trueにすると検索時大文字と小文字を区別しません // falseにすると区別します CASE_INSENSITIVE = true // タグを作るフォルダ // "." にすると、編集中のファイルのあるフォルダでタグを作ります // ".." などにすると、編集中のファイルの一つ上のフォルダからタグを作ります DEFAULT_TAGS_DIR = "." // タグファイルがない場合の挙動 // trueにするとタグを作成するフォルダを尋ねます // falseにするとフォルダを尋ねずに無言で作成を始めます 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 } } </syntaxhighlight>
編集内容の要約:
MeryWikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は
MeryWiki:著作権
を参照)。
著作権保護されている作品は、許諾なしに投稿しないでください!
このページを編集するには、下記の数式を計算してその答えを欄に入力してください (
ヘルプ
):
いちたすには =
キャンセル
編集ヘルプ
(新しいウィンドウで開きます)
スポンサーリンク
ナビゲーション メニュー
個人用ツール
ログインしていません
トーク
投稿記録
アカウント作成
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
編集
履歴表示
その他
検索
スポンサーリンク
スポンサーリンク
案内
メインページ
ヘルプ
よくある質問
マクロリファレンス
マクロライブラリ
プラグインライブラリ
構文ファイル
テーマ
寄付・開発支援
練習用ページ
開発室
開発者のブログ
ツール
スポンサーリンク