GoToTilla - jump to tokens within AHK sourcecode #ahk #script

September 15, 2015 ยท View on GitHub

/* ##################### GoToTilla v0.22 by hoppfrosch - Added parsing of properties (AHK > 1.1.16.*) http://www.autohotkey.com/board/topic/95536-gototilla-a-combination-of-goto-and-tillagoto/ GoToTilla v0.21 by budRich http://www.autohotkey.com/board/topic/95536-gototilla-a-combination-of-goto-and-tillagoto/ A combination of: GoTo by Avi Aryan http://www.autohotkey.com/board/topic/95009-goto-hotkeys-hotstrings-functions-and-labels-in-any-editor/ and TillaGoto by TheGood http://www.autohotkey.com/forum/viewtopic.php?t=41575 TheGood was inspired by Rajats Active GoTo http://www.autohotkey.com/board/topic/10936-active-goto-v4/ #####################

Go To functions, labels, hotkeys and hotstrings in any editor. The only requirement is that the Editor shows file full path in Title Bar and has a Goto (Ctrl+G) option. Examples of such editors - Notepad++, Sublime Text, PSPad, ConTEXT

Ctrl+Space to show a list of all functions,hotkeys,hotstrings and labels. Type to narrow list down, navigate with mouse or arrowkeys, select with doubleclick or Enter.

*/

;------- CONFIGURE ------------------- GoTo_AutoExecute() ;1 = Gui is movable, A_temp = Working Directory +F7::Reload

#if GetActiveFile() ;If ahk window is active ^Space:: Activefileindex := fileiscached( GetActiveFile() ) if ( Activefile_old != Activefileindex ) FreshList("-all", activefileindex)

GuiControl,, txtSearch,% "" WinShow, GoToTilla WinActivate, GoToTilla ControlFocus,, ahk_id %htxtSearch%

Activefile_old := Activefileindex return #if

#IfWinActive, GoToTilla ^Space::WinHide, GoToTilla Up::ControlSend,, {Up}, ahk_id %hlblList% Down::ControlSend,, {Down}, ahk_id %hlblList% Enter::Gosub, SelectItem #IfWinActive

GoTo_AutoExecute(resizable=true, WorkingDir=""){ global #SingleInstance force SetTitleMatchMode, 3 SetWorkingDir,% ( WorkingDir == "" ) ? A_scriptdir : WorkingDir SetBatchLines, -1 FileCreateDir, gotoCache FileDelete, gotoCache*.gotolist SetTimer, filecheck, 200 goto_cache := {} if resizable OnMessage(0x201, "DragGotoGui") ; WM_LBUTTONDOWN Gosub, NewGui }

NewGui: Gui, +AlwaysOnTop -Caption +ToolWindow Gui, Margin, 3, 3 Gui, Font, s11, Consolas Gui, Add, Edit, h20 w200 vtxtSearch hwndhtxtsearch gtxtSearch_Event Gui, Add, ListBox, sort w200 h275 vlblList glblList_Event hwndhlblList -HScroll +256 ;LBS_NOINTEGRALHEIGHT Gui, Show, Hide AutoSize, GoToTilla return

GoTo_Readfile(File) { Critical, On

static filecount , commentneedle := A_space ";|" A_tab	";"
if ( filecount_N := fileiscached(File) )
	Filename := filecount_N
else {
	Filename := filecount := filecount ? filecount+1 : 1
	FileAppend,% file "`n",gotoCache\filelist.gotolist
}
FileDelete, gotoCache\%Filename%-*

loop, read, %file%
{
	readline := Trim( A_LoopReadLine )
	if block_comments
		if Instr(readline, "*/") = 1
		{
			block_comments := 0
			continue
		}
		else continue

	if Instr(readline, ";") = 1
		continue

	if Instr(readline, "/*") = 1
	{
		block_comments := 1
		continue
	}
	readline := Trim( Substr(readline, 1, SuperInstr(readline, commentneedle, 1) ? SuperInstr(readline, commentneedle, 1)-1 : Strlen(readline)) )

	if ( readline_temp := Check4Hotkey(readline) )
		CreateCache(filename, "hotkey", readline_temp, A_index)
	else if ( Instr(readline, ":") = 1 ) and ( Instr(readline, "::", 0, 0) > 1 )
		CreateCache(filename, "hotstr", Substr(readline, 1, Instr(readline, "::", 0, 0)-1), A_index )
	else if !SuperInstr(readline, "``|`t| |,", 0) and Substr(readline,0) == ":"
		CreateCache(filename, "label", readline, A_index)
	else if Check4func(readline, A_index, file)
		CreateCache(filename, "func", Substr(readline, 1, Instr(readline, "(")) ")", A_index)
	else if Check4prop(readline, A_index, file)
		CreateCache(filename, "prop", Substr(readline, 1, Instr(readline, "[")) "]", A_index)
}

}

CreateCache(hostfile, type, data, linenum){ if type = func if ( Substr( data, 1, SuperInstr(data, " |`t|,|(", 1)-1 ) == "while" ) return ;Exceptions are listed above

FileAppend,% data ">" linenum "`n",% "Gotocache\" hostfile "-all.gotolist"

}

Check4Hotkey(line) { ;The function assumes line is trimmed using Trim() and then checked for ; comment if ( Instr(line, "::") = 1 ) and ( Instr(line, ":", false, 0) = 3 ) ;hotstring return "" hK := Substr( line, 1, ( Instr(line, ":::") ? Instr(line, ":::")+2 : ( Instr(line, "::") ? Instr(line, "::")+1 : Strlen(line)+2 ) ) - Strlen(line) - 2) if hK = return

if !SuperInstr(hK, " | ", 0)
	if !SuperInstr(hK, "^|!|+|#", 0) And RegExMatch(hK, "[a-z]+[,(]")
		return
	else
		return hK
else
	if Instr(hK, " & ") or ( Substr(hK, -1) == "UP" )
		return hK

}

Check4func(readline, linenum, file){ if RegExmatch(readline, "i)[A-Z0-9#_@$?[]]+(.*)") != 1 return if ( Substr(readline, 0) == "{" ) return 1

loop, {
	FileReadLine, cl, %file%,% linenum+A_index
	if Errorlevel = 1
		return
	cl := Trim( Substr(cl, 1, Instr(cl, ";") ? Instr(cl, ";")-1 : Strlen(cl)) )
	if cl =
		continue

	if block_comments
		if Instr(readline, "*/") = 1 {
			block_comments := 0
			continue
		}
	else continue
	if Instr(readline, "/*") = 1 {
		block_comments := 1
		continue
	}

	return Instr(cl, "{") = 1 ? 1 : 0
}

}

Check4prop(readline, linenum, file){ if A_AhkVersion < "1.1.16.0" return if RegExmatch(readline, "i)[A-Z0-9#_@$?]+[.*]") != 1 return if ( Substr(readline, 0) == "{" ) return 1

loop, {
	FileReadLine, cl, %file%,% linenum+A_index
	if Errorlevel = 1
		return
	cl := Trim( Substr(cl, 1, Instr(cl, ";") ? Instr(cl, ";")-1 : Strlen(cl)) )
	if cl =
		continue

	if block_comments
		if Instr(readline, "*/") = 1 {
			block_comments := 0
			continue
		}
	else continue
	if Instr(readline, "/*") = 1 {
		block_comments := 1
		continue
	}

	return Instr(cl, "{") = 1 ? 1 : 0
}

}

filecheck: FileGetTime, Timeforfile,% goto_tempfile := GetActiveFile(), M if ( goto_cache[goto_tempfile] != Timeforfile ) goto_cache[goto_tempfile] := Timeforfile , Goto_Readfile(goto_tempfile) return

fileiscached(file){ loop, read, gotoCache\filelist.gotolist if ( file == A_LoopReadLine ) return A_index }

GUIEscape: WinHide, GoToTilla return

FreshList(mode, fileindex){ global aLst,lblList aLst := Object() lblList := "" GuiControl,, lblList,| if !fileindex return

loop, read, gotoCache\%fileIndex%%Mode%.gotolist
{
	StringSplit, toadd, A_LoopReadLine, >
	aLst.Insert(toadd1, toadd2)
	lblList .= "|" toadd1
}
GuiControl, -Redraw, lblList
Guicontrol, ,lblList,% !lblList ? "|" : lblList
GuiControl, +Redraw, lblList

}

GetActiveFile(){ WinGetActiveTitle, Title if !( Instr(title, ".ahk") and Instr(title, ":") ) return "" return Trim( Substr( Title, temp := Instr(Title, ":")-1, Instr(Title, ".ahk", 0, 0)-temp+4 ) ) }

DragGotoGui(){ ;Thanks Pulover PostMessage, 0xA1, 2,,, A }

/* SuperInstr() Returns min/max position for a | separated values of Needle(s) return_min = true ; return minimum position return_min = false ; return maximum position

/ SuperInstr(Hay, Needles, return_min=true, Case=false, Startpoint=1, Occurrence=1){ pos := return_minStrlen(Hay) if return_min { loop, parse, Needles,| if ( pos > (var := Instr(Hay, A_LoopField, Case, startpoint, Occurrence)) ) pos := var ? var : pos if ( pos == Strlen(Hay) ) return 0 } else { loop, parse, Needles,| if ( (var := Instr(Hay, A_LoopField, Case, startpoint, Occurrence)) > pos ) pos := var } return pos }

lblList_Event: If (A_GuiEvent <> "DoubleClick") Return SelectItem: ;Get selected item index. LB_GETCURSEL SendMessage, 0x188, 0, 0,, ahk_id %hlblList%

;Check for error. LB_ERR If (ErrorLevel = 0xFFFFFFFF) Return

;Get the associated item data i := GetListBoxItem(hlblList, ErrorLevel)

BlockInput, On WinHide, GoToTilla SendInput, ^g sleep, 100 SendInput,% aLst[i] "{Enter}" BlockInput, Off Return

GetListBoxItem(hLB, i) { ;Get length of item. LB_GETTEXTLEN SendMessage 394, %i%, 0,, ahk_id %hLB% ;Check for error If (ErrorLevel = 0xFFFFFFFF) Return "" ;Prepare variable VarSetCapacity(sText, ErrorLevel * (1 + !!A_IsUnicode), 0) ;Retrieve item. LB_GETTEXT SendMessage 393, %i%, &sText,, ahk_id %hLB% ;Check for error If (ErrorLevel = 0xFFFFFFFF) Return ""

Return sText

}

;Incremental searching txtSearch_Event: GuiControlGet, s,, txtSearch CreateList(s) Return

CreateList(filter = "") { Global hlblList, bShowing, aLst, activefileindex Static sLastfilter := "`n" ;Initialize on an impossible filter

;Trim the right side
While (SubStr(filter, 0) = A_Space)
	StringTrimRight, filter, filter, 1
 
;Trim right side if it ends in " !" since it changes nothing
If (StrLen(filter) > 2) And (SubStr(filter, -1) = " !") And (SubStr(filter, -2, 1) <> A_Space)
	StringTrimRight, filter, filter, 2
 
;Check if the filter is different
If (filter = sLastfilter) ;And bShowing
	Return
 
sLastfilter := filter
 
GuiControl, -Redraw, lblList
GuiControl,, lblList,|
lblList := ""
 
If (filter = "")
	FreshList("-all", activefileindex)
Else {
	For k, v in aLst
		If (InStr(k, filter) = 1)
			lblList .= "|" k
 
	Guicontrol, ,lblList,% !lblList ? "|" : lblList
}
;Select the first item. LB_SETCURSEL
SendMessage 390, 0, 0,, ahk_id %hlblList%
 
;Redraw
GuiControl, +Redraw, lblList

}