I changed it again.
It now uses a modified-modified-version of View() ( durr

)
It now caches the last formatted hotkey file so it doesn't have to re-read and re-parse it every time.
I added a ViewKeyListFromHK() function to be used from a hotkey to temporairly display the view until the hotkey is released.
I added the StripHKModifiers() function from another topic (link in code) that's used in the ViewKeyListFromHK() function.
Code:
; http://www.autohotkey.com/forum/topic215.html
;*******************************************************************************
; Extract a list of Hotstrings and Hotkeys from this script and display them
;*******************************************************************************
; Modified by Vixay Xavier on Sat October 11, 2008 06:02:29 PM
; Modified by infogulch on Mon September 21, 2009 08:30:00 PM
; Modified by infogulch on Tue September 22, 2009 03:00:00 PM
;#SingleInstance force
ViewKeyListFromHK( scriptfile ) {
View(FormatKeyListFile( scriptfile ), "Title=Key List, Key=" StripHKModifiers() ", KeyDir=" ErrorLevel )
}
ViewKeyList( scriptfile ) {
View(FormatKeyListFile( scriptfile ), "Title=Key List (Esc to exit)" )
}
FormatKeyListFile( scriptfile, force = False ) {
; this function reads scriptfile and returns a formatted string from FormatKeyList
; it automatically caches the most recent formatted result so it doesn't have to reparse it
; pass force = True to force it to reread and reparse the scriptfile
static file, formatted
if (file != scriptfile) && !Force
{
fileread, contents, %scriptfile%
formatted := FormatKeyList( contents )
file := scriptfile
}
return formatted
}
FormatKeyList( lines, srt = False ) {
; this does the actual formatting. Pass the text to be formatted
loop, parse, lines, `n, `r
if SubStr(A_LoopField, 1, 2) = ";;"
KeyList .= SubStr(A_LoopField, 3) "`n"
else if RegExMatch(A_LoopField, "^\s*(?<hk>[^:]+)::(?<cmd>.*?)(?:(?<=\s);;(?<desc>.*))?$", _)
KeyList .= HumanReadableHK( _hk ) " == " (_desc ? _desc : _cmd) "`n"
else if RegExMatch(A_LoopField, "^\s*:(?<opt>[^:]*):(?<hs>[^:]+)::(?<rep>.*?)(?:(?<=\s);;(?<desc>.*))?$", _)
KeyList .= _hs " = " (_desc ? _desc : _rep) "`n"
if sort
sort, KeyList, P16 ; sort the comments
return KeyList
}
HumanReadableHK( key ) {
;a function to take care of replacing symbols in hotkeys with their words
StringReplace, key, key, +, Shift%A_Space%+%A_Space%
StringReplace, key, key, #, Win%A_Space%+%A_Space%
StringReplace, key, key, !, Alt%A_Space%+%A_Space%
StringReplace, key, key, ^, Ctrl%A_Space%+%A_Space%
StringReplace, key, key, &, %A_Space%and%A_Space%
StringReplace, key, key, $, hooked%A_Space%
return key
}
/* Function View( Text="""", Options="""" ) by SKAN. (Slightly modified by infogulch)
returns the milliseconds the view was shown
sets errorlevel to 1 if the timout was reached
sets errorlevel to 0 if the hotkey state was reached first
Text: The text to be displayed
Options: space and comma separated string of options (format: option=default)
Window W=640, H=480, X=[centered], Y=[centered]
Title=A_ScriptFullPath, Wrap=False, ReadOnly=True
Font=Courier New, FHt, FWt
Key=Esc, KeyDir=Down
Timeout=0 (0 means no timeout)
*/
View( Text= "", Options= "" ) {
; http://www.autohotkey.com/forum/viewtopic.php?p=298037#298037
ReadOnly := True, Title := A_ScriptFullPath, Key := "Esc", KeyDir := "Down"
loop, Parse, Options,`,=, %A_Space%%A_Tab%`r`n
A_Index & 1 ? ( Var := A_LoopField ) : ( %Var% := A_LoopField )
W:=W ? W:640
, H:=H ? H:480
, X:=X+0!="" ? X:((A_ScreenWidth/2)-(W/2))
, Y:=Y+0!="" ? Y:((A_ScreenHeight/2)-(H/2))
, WS:=Wrap ? 0x50201044:0x503010C4
, WS|=ReadOnly ? 0x800:0
, Text := RegExReplace(Text, "(?<!\r)\n", "`r$0")
, KeyDir := KeyDir = "down" || KeyDir = "d" ? "D" : ""
, Timeout := Timeout+0 ? "T" Timeout : ""
hWnd := DllCall( "CreateWindowEx",Int,0, Str,"#32770", Str, Title, UInt, 0x10400000
, UInt,X, UInt,Y, UInt,W, UInt,H, Int,0,Int,0,Int,0,Int,0,Int,0 )
VarSetCapacity( CR,16,0 ), DllCall( "GetClientRect", UInt, hWnd, UInt,&CR )
Edit := DllCall( "CreateWindowEx", Int, 0, Str, "Edit", Int, 0, UInt, WS, Int, 0,Int,0, UInt
,NumGet(CR,8), UInt, NumGet(CR,12), UInt,hWnd, Int,0,Int,0,Int,0 )
hFnt := DllCall( "CreateFont", Int,FHT ? FHt:0, Int,0,Int,0,Int,0, Int,( FWt="Bold")? 700
:0, Int,0,Int,0,Int,0,Int,0,Int,0,Int,0,Int,0,Int,0, Str,Font ? Font:"Courier New" )
DllCall( "SendMessageA", UInt, Edit, UInt,0x30, UInt,hFnt, UInt,0 ) ; WM_SETFONT
DllCall( "SendMessageA", UInt, Edit, UInt,0xD3, UInt,1 , UInt,5 ) ; EM_SETMARGINS
DllCall( "SendMessageA", UInt, Edit, UInt,0x0C, UInt,0 , UInt,&Text ) ; WM_SETTEXT
DllCall( "SendMessageA", UInt, Edit, UInt,0xB1, UInt,-1 , UInt,0 ) ; EM_SETSEL
Start := A_TickCount
WinActivate, ahk_id %hwnd%
KeyWait, %Key%, %KeyDir% %Timeout%
err := ErrorLevel, DllCall( "DestroyWindow", UInt, hWnd ), DllCall( "DeleteObject", UInt, hFnt )
return A_TickCount - Start, ErrorLevel := err
}
StripHKModifiers( x = "" ) {
; http://www.autohotkey.com/forum/viewtopic.php?p=298035#298035
RegEx := RegExMatch( x ? x : A_ThisHotkey, "i)(?:[~#!<>\*\+\^\$]*([^ ]+)( UP)?)$", Key)
return Key1, ErrorLevel := (Key2 ? "Down" : "Up")
}
;FOR TESTING AS STANDALONE SCRIPT, if it is included in another script it will be safely ignored
/* (comment these block comment lines out to test with Ctrl+z)
;;===HotKeys===
CapsLock & z::ViewKeyListFromHK( A_ScriptFullPath ) ;; View this list
a::a
a & $`;::
MsgBox test
exitapp
;add comments like these to your own script to make the output of this script easier to read
;;
;;===Hotstrings===
::t1::tester! ;;description. the next one uses the replacement text itself as the description
:c:t2::testmy! ;;
*/