LoginSignup
2
4

More than 3 years have passed since last update.

AutoHotkeyのコメントからヘルプを作成する

Last updated at Posted at 2019-06-26

概要

たくさん登録しすぎて忘れられてしまったホットキーの魂を救済するために、AutoHotkeyのスクリプト内に記述したコメントからホットキー/ホットストリングの一覧を作成するスクリプトを作りました。
AutoHotkeyHelp.png

コメント形式

以下の形式で記述したコメントを解析して、GUIウィンドウを生成します。
コメント内に@hotkey, @hotstrのいずれかのドキュメンテーションタグが存在しないとヘルプの対象にはならないので、自作関数などのコメントとも共存可能です。

/**
 * ホットキー/ホットストリングの説明
 *
 * @hotkey [ホットキー]
 * @hotstr [ホットストリング]
 * @target [対象ウィンドウ]
 * @condition [発動条件]
 */

@hotkey@hotstrタグは、一つのコメント内で複数記述が可能なので、同じ操作が複数のホットキーに割り当てられている時でも、コメントブロックは1つでOKです。
@targetはホットキーの発動対象となるウィンドウを#IfWinActive等で限定している場合にその対象を記載します。同じ名前のウィンドウはヘルプ左側のツリーでまとめられるので、間違えると残念なことになります。
@conditionはIMEがオンの場合などの特定の発動条件がある場合に記載します。

なお、上記以外のドキュメンテーションタグ(@hogehoge)は全てヘルプには反映しない安全設計なので、ヘルプには表示したくない@todoとか@authorなんかを書いておいても大丈夫です。

ソース

ヘルプの表示は[Win]+[F1]に割り当てています。

/**
 * AutoHotkey設定一覧を表示する。
 */
HotkeyHelp()
{
    ;GUIの値格納変数
    Static sTab
    Static sHotkeyTree
    Static sHotkeyList
    Static sHotstrTree
    Static sHotstrList

    ;GUIのウィンドウハンドル
    Static sHwndTab
    Static sHwndHotkeyTree
    Static sHwndHotkeyList
    Static sHwndHotstrTree
    Static sHwndHotstrList

    ;ホットキーヘルプのGUIを作成
    Gui, HotkeyHelp:New, , AutoHotkey設定一覧

    ;タブを追加
    Gui, HotkeyHelp:Add, Tab2, HwndsHwndTab VsTab W700 H400, ホットキー|ホットストリング

    ;1つ目のタブを選択
    Gui, Tab, 1

    ;1つ目のタブにツリービューを追加
    Gui, HotkeyHelp:Add, TreeView, HwndsHwndHotkeyTree VsHotkeyTree GSelectTree W120 H360,
    TV_Add("全てのホットキー", 0, "Expand")

    ;1つ目のタブにリストビューを追加
    Gui, HotkeyHelp:Add, ListView, HwndsHwndHotkeyList VsHotkeyList X+5 W550 H360 Grid ReadOnly, 対象|ホットキー|条件|説明|

    ;リストビューの項目幅を設定
    LV_ModifyCol(1, 100)
    LV_ModifyCol(2, 145)
    LV_ModifyCol(3, 90)
    LV_ModifyCol(4, 350)

    ;2つ目のタブを選択
    Gui, Tab, 2

    ;2つ目のタブにツリービューを追加
    Gui, HotkeyHelp:Add, TreeView, HwndsHwndHotstrTree VsHotstrTree GSelectTree W120 H360,
    TV_Add("全てのホットストリング", 0, "Expand")

    ;2つ目のタブにリストビューを追加
    Gui, HotkeyHelp:Add, ListView, HwndsHwndHotstrList VsHotstrList X+5 W550 H360 Grid ReadOnly, 対象|ホットストリング|条件|説明

    ;リストビューの項目幅を設定
    LV_ModifyCol(1, 100)
    LV_ModifyCol(2, 145)
    LV_ModifyCol(3, 90)
    LV_ModifyCol(4, 350)

    ;GUIの表示
    Gui, HotkeyHelp:Show

    /**
    * ツリーアイテム選択時の動作。
    */
    SelectTree:
        ;シングルクリックの場合のみリストビューを更新
        If (A_GuiEvent == "S")
        {
            ;選択中のタブを取得
            GuiControlGet, vCurrentTab, , %sHwndTab%,

            If (vCurrentTab == "ホットキー")
            {
                ;ホットキータブの場合、ホットキーのツリービューとリストビューを選択
                Gui, TreeView, %sHwndHotkeyTree%
                Gui, ListView, %sHwndHotkeyList%

                ;リスト項目を全削除
                Gui, ListView, %sHwndHotkeyList%
                LV_Delete()
            }

            If (vCurrentTab == "ホットストリング")
            {
                ;ホットストリングタブの場合、ホットストリングのツリービューとリストビューを選択
                Gui, TreeView, %sHwndHotstrTree%
                Gui, ListView, %sHwndHotstrList%

                ;リスト項目を全削除
                Gui, ListView, %sHwndHotstrList%
                LV_Delete()
            }

            ;先頭のツリーアイテムを取得
            vTreeTop := TV_GetNext()

            ;選択中のツリーアイテムを取得
            vCurrentTree := TV_GetSelection()

            ;ドキュメンテーションブロック判定フラグ
            vIsDoc := False

            ;スクリプトファイル読み込み
            Loop, Read, %A_ScriptFullPath%
            {
                If (ErrorLevel)
                {
                    ;エラーの場合はバルーンメッセージを表示して終了
                    TrayTip, AutoHotkey, スクリプトファイル読み込みでエラーが発生しました。`r`n%A_Index%行目 %ErrorLevel%, 1, 18
                    Break
                }

                If (A_LoopReadLine == "/**") {
                    ;ドキュメンテーション開始(/**)
                    vIsDoc := True

                    ;変数を初期化
                    vCommand := ""
                    vHotkey := ""
                    vHotstr := ""
                    vTarget := ""
                    vCondition := ""
                    vDesc := ""

                    Continue
                }

                If (vIsDoc) {
                    ;ドキュメンテーションブロックの場合のみ読み込み
                    If (RegExMatch(A_LoopReadLine, "^\s\*[\s|\t]*@hotkey[\s|\t]*"))
                    {
                        ;ホットキーコメント( * @hotkey)
                        RegExMatch(A_LoopReadLine, "(?<=@hotkey[\s|\t]).*$", vCommand)
                        vCommand := Trim(vCommand)

                        ;ホットキーコメントが複数あった場合、改行で区切って格納
                        vHotkey := vHotkey == "" ? vCommand : vHotkey . "`r`n" . vCommand
                    }
                    Else If (RegExMatch(A_LoopReadLine, "\s\*[\s|\t]*@hotstr[\s|\t]*"))
                    {
                        ;ホットストリングコメント( * @hotstr)
                        RegExMatch(A_LoopReadLine, "(?<=@hotstr[\s|\t]).*$", vCommand)
                        vCommand := Trim(vCommand)

                        ;ホットストリングコメントが複数あった場合、改行で区切って格納
                        vHotstr := vHotstr == "" ? vCommand : vHotstr . "`r`n" . vCommand
                    }
                    Else If (RegExMatch(A_LoopReadLine, "\s\*[\s|\t]*@target[\s|\t]*"))
                    {
                        ;対象コメント( * @target)
                        RegExMatch(A_LoopReadLine, "(?<=@target[\s|\t]).*$", vTarget)
                        vTarget := Trim(vTarget)
                    }
                    Else If (RegExMatch(A_LoopReadLine, "\s\*[\s|\t]*@condition[\s|\t]*"))
                    {
                        ;条件コメント( * @condition)
                        RegExMatch(A_LoopReadLine, "(?<=@condition[\s|\t]).*$", vCondition)
                        vCondition := Trim(vCondition)
                    }
                    Else If (RegExMatch(A_LoopReadLine, "\s\*[\s|\t]*@.+[\s|\t]*"))
                    {
                        ;上記以外のドキュメンテーションタグは読み飛ばす( * @hogehoge)
                        Continue
                    }
                    Else
                    {
                        ;それ以外はディスクリプションコメント( * )
                        RegExMatch(A_LoopReadLine, "(?<=\*[\s|\t]).*$", vText)
                        If (vText != "")
                        {
                            vDesc := vDesc . vText
                        }
                    }

                    If (A_LoopReadLine == " */") {
                        ;ドキュメンテーション終了( */)
                        vIsDoc := False

                        ;ツリーアイテムを追加
                        If (vHotkey != "")
                        {
                            ;@hotkey行が存在していた場合、ツリービューとリストビューを選択
                            Gui, TreeView, %sHwndHotkeyTree%
                            Gui, ListView, %sHwndHotkeyList%

                            ;ツリーの先頭項目を取得
                            vTreeItemId := TV_GetNext()

                            ;読み込み行のツリーアイテムID
                            vTargetTreeId := ""

                            ;ツリーの項目数分ループ
                            Loop, % TV_GetCount()
                            {
                                ;ツリーの項目名称を取得
                                TV_GetText(vTreeText, vTreeItemId)
                                If (vTreeText == vTarget)
                                {
                                    ;ツリーの項目名称に存在した場合、ループ処理を終了
                                    vTargetTreeId := vTreeItemId
                                    Break
                                }

                                ;ツリーの項目名称に存在しない場合、次のツリー項目を取得しループを継続
                                vTreeItemId := TV_GetNext(vTreeItemId, "Full")
                            }

                            If (!vTargetTreeId)
                            {
                                ;ツリーの項目名称に存在しない場合、ツリーに項目を追加
                                vTargetTreeId := TV_Add(vTarget, TV_GetNext())
                            }

                            ;ホットキーをリストビューに追加
                            Loop, Parse, vHotkey, `r, `n
                            {
                                ;ホットキーのツリービューとリストビューを選択
                                Gui, TreeView, %sHwndHotkeyTree%
                                Gui, ListView, %sHwndHotkeyList%

                                If (vCurrentTree == vTreeTop || vCurrentTree == vTargetTreeId)
                                {
                                    ;ツリートップ選択中または読み込み行が選択中のツリーアイテムIDと一致する場合、リストビューに追加
                                    vListItemId := LV_Add("Col1", vTarget, A_LoopField, vCondition, vDesc)
                                }
                            }
                        }

                        If (vHotstr != "")
                        {
                            ;@hotstr行が存在していた場合、ツリービューとリストビューを選択
                            Gui, TreeView, %sHwndHotstrTree%
                            Gui, ListView, %sHwndHotstrList%

                            ;ツリーの先頭項目を取得
                            vTreeItemId := TV_GetNext()

                            ;読み込み行のツリーアイテムID
                            vTargetTreeId := ""

                            ;ツリーの項目数分ループ
                            Loop, % TV_GetCount()
                            {
                                ;ツリーの項目名称を取得
                                TV_GetText(vTreeText, vTreeItemId)
                                If (vTreeText == vTarget)
                                {
                                    ;ツリーの項目名称に存在した場合、ループ処理を終了
                                    vTargetTreeId := vTreeItemId
                                    Break
                                }

                                ;ツリーの項目名称に存在しない場合、次のツリー項目を取得しループを継続
                                vTreeItemId := TV_GetNext(vTreeItemId, "Full")
                            }

                            If (!vTargetTreeId)
                            {
                                ;ツリーの項目名称に存在しない場合、ツリーに項目を追加
                                vTargetTreeId := TV_Add(vTarget, TV_GetNext())
                            }

                            ;ホットストリングをリストビューに追加
                            Loop, Parse, vHotstr, `r, `n
                            {
                                ;ホットストリングのツリービューとリストビューを選択
                                Gui, TreeView, %sHwndHotstrTree%
                                Gui, ListView, %sHwndHotstrList%

                                If (vCurrentTree == vTreeTop || vCurrentTree == vTargetTreeId)
                                {
                                    ;ツリートップ選択中・読み込み行が選択中のツリーアイテムIDと一致する場合、リストビューに追加
                                    vListItemId := LV_Add("Col1", vTarget, A_LoopField, vCondition, vDesc)
                                }
                            }
                        }
                    }
                }
            }
        }
    Return

    /**
    * [Esc][閉じる]ボタンクリック時の動作。
    */
    HotkeyHelpGuiEscape:
    HotkeyHelpGuiClose:
        ;GUIウィンドウを破棄
        Gui, HotkeyHelp:Destroy
    Return
}

/**
 * 設定されたホットキー/ホットストリングを一覧表示
 *
 * @hotkey [Win]+[F1]
 * @target デフォルト
 */
#F1::
    IfWinNotExist, AutoHotkey設定一覧
    {
        HotkeyHelp()
    }
    Else
    {
        WinActivate
    }
Return
2
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4