Sign in to follow this  
Followers 0
archrival

Go To Definition

5 posts in this topic

Visual Studio and other IDEs have the nice ability to jump directly to a method declaration, I always wished SciTE had this. I've seen and and realized that thankfully the main work of automating SciTE had been done for me so I made my own. I heavily modified SciTE Jump and created Go To Definition.

This will allow you to jump directly to the function underneath your mouse cursor by pressing F12 (or Alt-F12 for AutoIt Beta). This script looks in the current window and follows all #include directives to build a function list. It then selects the current "word" which when the cursor is over a function will select the function name and jumps directly to that function in the file it exists in.

This can be added to the Tools menu by passing /install to the exe, the beta menu item can also be added by additionally passing /beta to the /install parameter.

This is a first pass, but as most developers say "works for me". Hopefully it works for you as well.

#NoTrayIcon
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=4
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <File.au3>
#include <WinAPIEx.au3>

Global $includepattern = '^#include ["<]([\w\.-]+)[">]'
Global $funcpattern = '^Func ([\w]+)'
Global $pathSeparator = "\"

Global $autoitincludepath = ""

Local $includes = ObjCreate("Scripting.Dictionary")
Local $functions = ObjCreate("Scripting.Dictionary")

Local $useBeta = False
Local $install = False

If ProcessExists("SciTE.exe") = 0 Then
    MsgBox(16, 'An unexpected error occurred.', 'SciTE needs to be running for ' & @AutoItExe & ' to function correctly.')
    Exit
EndIf

Global $hSciTE_Director = WinGetHandle("DirectorExtension"), $hSciTE_Window = WinGetHandle("[CLASS:SciTEWindow]") ; Get SciTE Handles.

If $CmdLine[0] > 0 Then
    For $i = 1 To $CmdLine[0]
        If $CmdLine[$i] = "/beta" Then
            $useBeta = True
        ElseIf $CmdLine[$i] = "/install" Then
            $install = True
        EndIf
    Next
EndIf

If $useBeta Then
    $autoitincludepath = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "betaInstallDir") & "\Include"
Else
    $autoitincludepath = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & "\Include"
EndIf

If $install Then
    _AddSciTECommand(1, $useBeta)
    Exit
EndIf

$currentfile = _SciTE_GetCurrentFile()

_ProcessFile($currentfile, $functions)

WinWait("[CLASS:SciTEWindow; INSTANCE:1]")
$hSciTE = WinGetHandle("[CLASS:SciTEWindow; INSTANCE:1]")
ControlFocus($hSciTE, "", "[CLASS:Scintilla; INSTANCE:1]")
; Hackish way to select the word under the cursor
ControlSend($hSciTE, "", "[CLASS:Scintilla; INSTANCE:1]", "^{LEFT}")
ControlSend($hSciTE, "", "[CLASS:Scintilla; INSTANCE:1]", "^+{RIGHT}")

; Copy the text to the clipboard, unfortunately SciTE's edit window is non-standard
ControlSend($hSciTE, "", "[CLASS:Scintilla; INSTANCE:1]", "^c")

$selected = StringStripWS(ClipGet(), 8)
; Reset clipboard to empty, not
ClipPut("")

If ($functions.Exists($selected)) Then
    $fileandline = StringSplit($functions.Item($selected), "|", 2)
    ; Get file and line number of the function
    $thisfile = $fileandline[0]
    $thisline = $fileandline[1]
    _SciTE_Open($thisfile)
    _SciTE_GoToLine($thisline)
EndIf

Func _ProcessFile($file, ByRef $functions)
    Local $contents
    $filepath = _GetDirectoryName(FileGetLongName($file))

    _FileReadToArray($file, $contents)

    Local $linenum = 0
    For $line In $contents
        $fullincludefilename = ""

        $includematch = StringRegExp($line, $includepattern, 1)
        If Not @error And IsArray($includematch) And UBound($includematch) = 1 Then
            If FileExists(_PathCombine($filepath, $includematch[0])) Then
                $fullincludefilename = _PathCombine($filepath, $includematch[0])
            ElseIf FileExists(_PathCombine($autoitincludepath, $includematch[0])) Then
                $fullincludefilename = _PathCombine($autoitincludepath, $includematch[0])
            Else
                ConsoleWriteError("Unable to find include " & $includematch[0] & @CRLF)
            EndIf
        EndIf

        $functionmatch = StringRegExp($line, $funcpattern, 1)
        If Not @error And IsArray($functionmatch) And UBound($functionmatch) = 1 Then
            $functions.Item($functionmatch[0]) = $file & "|" & $linenum
        EndIf

        If IsArray($includematch) And Not $includes.Exists($fullincludefilename) Then
            $includes.Item($fullincludefilename) = $file
            _ProcessFile($fullincludefilename, $functions)
        EndIf

        $linenum += 1
    Next
EndFunc   ;==>_ProcessFile

Func _SciTE_Open($sFile)
    _SciTE_Send_Command(0, $hSciTE_Director, "open:" & StringReplace($sFile, "\", "\\"))
EndFunc   ;==>_SciTE_Open

Func _SciTE_Send_Command($hWnd, $hSciTE, $sCmd)
    Local $tCmdStruct, $tCOPYDATA
    $sCmd = ":" & Dec(StringRight($hWnd, 8)) & ":" & $sCmd
    $tCmdStruct = DllStructCreate("Char[" & StringLen($sCmd) + 1 & "]")
    If @error Then
        Return SetError(1, 0, 0)
    EndIf
    DllStructSetData($tCmdStruct, 1, $sCmd)
    $tCOPYDATA = DllStructCreate("Ptr;DWord;Ptr")
    DllStructSetData($tCOPYDATA, 1, 1)
    DllStructSetData($tCOPYDATA, 2, StringLen($sCmd) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tCmdStruct))
    _SendMessage($hSciTE, $WM_COPYDATA, $hWnd, DllStructGetPtr($tCOPYDATA))
EndFunc   ;==>_SciTE_Send_Command

Func _EnumArray(ByRef $aArray, $iBefore = 3, $iStart = 1)
    $iStart = $iBefore + $iStart
    For $A = 0 To UBound($aArray, 1) - 1
        $aArray[$A] = $iStart
        $iStart += 1
    Next
EndFunc   ;==>_EnumArray

Func _SciTE_GetCurrentFile()
    Local $sFile, $sTitle

    $sTitle = WinGetTitle($hSciTE_Window)
    If @error Then ; No Window
        Return SetError(1, 0, 0)
    EndIf
    If _IsEmpty($sTitle) Then ; New File.
        Return SetError(3, 0, 0)
    EndIf
    $sFile = StringRegExpReplace($sTitle, "(.*)\x20[-|*]\x20.*\z", "$1") ; Extract File Name, by Melba23
    If FileExists($sFile) Then
        Return $sFile
    EndIf
    Return SetError(2, 0, 0) ; File Does Not Exist.
EndFunc   ;==>_SciTE_GetCurrentFile

Func _GetDirectory($sFilePath)
    Return StringRegExpReplace($sFilePath, "(^.*\\)(.*)", "\1")
EndFunc   ;==>_GetDirectory

Func _IsEmpty($sFile)
    If $sFile = "" Then
        Return 0
    EndIf
    Return StringRegExp($sFile, '(?i)\(Untitled\)|\(NoFile\)|\(NoWindow\)') = 1
EndFunc   ;==>_IsEmpty

Func _SciTE_GoToLine($iLineNumber)
    _SciTE_Send_Command(0, $hSciTE_Director, "goto:" & $iLineNumber)
EndFunc   ;==>_SciTE_GoToLine

Func _AddSciTECommand($iWrite = 1, $addBeta = False)
    Local $sScriptDir = StringRegExpReplace(_WinAPI_GetProcessFileName(ProcessExists("SciTE.exe")), "(^.*\\)(.*)", "\1")
    Local $aArray[3] = [2, @UserProfileDir & "\SciTEUser.properties", $sScriptDir & "properties\au3.properties"], $iNumber, $sWrite = -1

    For $A = 1 To $aArray[0]
        $iNumber = _CommandNumber($aArray[$A])
        If $iNumber = -1 Then
            ExitLoop
        EndIf
        $sWrite = _CommandWrite($iNumber, $addBeta)
        If @error = 0 Then
            ExitLoop
        EndIf
    Next

    If $sWrite = -1 Then
        Return SetError(1, 0, 0)
    EndIf

    If $iWrite Then
        FileCopy(@ScriptFullPath, $sScriptDir & "GoToDefinition\" & @ScriptName, 9)
        Return _SetFile($sWrite, $aArray[1])
    EndIf

    Return 1
EndFunc   ;==>_AddSciTECommand

Func _CommandNumber($sFile)
    Local $aReturn, $sData
    $sData = _GetFile($sFile)
    If StringInStr($sData, @AutoItExe) Then
        Return SetError(2, 0, -1)
    EndIf
    $aReturn = StringRegExp(_GetFile($sFile), '(?s)(?i)command\.name\.(.*?)\.', 3)
    If @error Then
        Return SetError(1, 0, "")
    EndIf
    Return StringRegExpReplace($aReturn[UBound($aReturn) - 1], "[^0-9]", "") + 1
EndFunc   ;==>_CommandNumber

Func _CommandWrite($iNumber, $useBeta = False)
    Local $command, $commandname, $commandshortcut
    If $iNumber = "" Then
        Return SetError(1, 0, -1)
    EndIf

    If $useBeta Then
        $command = '.$(au3)="$(SciteDefaultHome)\GoToDefinition\GoToDefinition.exe" /beta'
        $commandname = '.$(au3)=Go To Definition (Beta)'
        $commandshortcut = '.$(au3)=Alt+F12'
    Else
        $command = '.$(au3)="$(SciteDefaultHome)\GoToDefinition\GoToDefinition.exe"'
        $commandname = '.$(au3)=Go To Definition'
        $commandshortcut = '.$(au3)=F12'
    EndIf

    Return '# ' & $iNumber & ' Go To Definition' & @CRLF & _
            'command.' & $iNumber & $command & @CRLF & _
            'command.name.' & $iNumber & $commandname & @CRLF & _
            'command.shortcut.' & $iNumber & $commandshortcut & @CRLF & _
            'command.subsystem.' & $iNumber & '.$(au3)=2' & @CRLF & _
            'command.save.before.' & $iNumber & '.$(au3)=2' & @CRLF & _
            'command.quiet.' & $iNumber & '.$(au3)=1' & @CRLF
EndFunc   ;==>_CommandWrite

Func _SetFile($sString, $sFile, $iOverwrite = 0)
    Local $hFileOpen
    $hFileOpen = FileOpen($sFile, 1 + $iOverwrite)
    FileWrite($hFileOpen, $sString)
    FileClose($hFileOpen)
    If @error Then
        Return SetError(1, 0, $sString)
    EndIf
    Return $sString
EndFunc   ;==>_SetFile

Func _GetFile($sFile)
    Local $hFileOpen, $sData
    $hFileOpen = FileOpen($sFile, 0)
    If $hFileOpen = -1 Then
        Return SetError(1, 0, "")
    EndIf
    $sData = FileRead($hFileOpen)
    FileClose($hFileOpen)
    Return $sData
EndFunc   ;==>_GetFile

Func _PathCombine($path1, $path2)
    Local $path
    Local $uncpath = False

    ; Remove repeating slashes
    If StringLeft($path1, 2) = $pathSeparator & $pathSeparator Then
        $uncpath = True
    EndIf

    $path1 = StringRegExpReplace($path1, $pathSeparator & $pathSeparator & "+", $pathSeparator & $pathSeparator)
    $path2 = StringRegExpReplace($path2, $pathSeparator & $pathSeparator & "+", $pathSeparator & $pathSeparator)

    If $uncpath Then
        $path1 = $pathSeparator & $path1
    EndIf

    ; Remove all trailing slashes
    While StringRight($path1, 1) = $pathSeparator
        $path1 = StringTrimRight($path1, 1)
    WEnd

    ; Remove all trailing slashes
    While StringLeft($path2, 1) = $pathSeparator
        $path2 = StringTrimLeft($path2, 1)
    WEnd

    If _StringIsNullOrEmpty($path1) And _StringIsNullOrEmpty($path2) Then
        $path = ""
    ElseIf Not _StringIsNullOrEmpty($path1) And Not _StringIsNullOrEmpty($path2) Then
        $path = $path1 & $pathSeparator & $path2
    ElseIf _StringIsNullOrEmpty($path1) And Not _StringIsNullOrEmpty($path2) Then
        $path = $path2
    Else
        $path = $path1
    EndIf

    Return $path
EndFunc   ;==>_PathCombine

Func _GetDirectoryName($path)
    Local $error = 0
    Local $directory, $directorymatch

    $directorymatch = StringRegExp($path, "^(.*)\\", 1)

    If @error Then
        $error = @error
    Else
        If IsArray($directorymatch) Then
            $directory = $directorymatch[0]
        Else
            $error = -1
        EndIf
    EndIf

    Return SetError($error, 0, $directory)
EndFunc   ;==>_GetDirectoryName

Func _StringIsNullOrEmpty($string)
    Local $result = False

    If StringLen(StringStripWS($string, 8)) = 0 Then
        $result = True
    EndIf

    Return $result
EndFunc   ;==>_StringIsNullOrEmpty

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

Haha, nope. I guess not. It appears to function the exact same way... :mellow:

However, it still works! :)

Obviously I never knew the existing function existed, good thing I didn't spend too much time on it.

Edited by archrival

Share this post


Link to post
Share on other sites

I heavily modified SciTE Jump and created Go To Definition.

I can see you liked I'm very flattered indeed, I honestly thought no one had seen this post of mine. :mellow:

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

I honestly thought no one had seen this post of mine. :)

Oww. I didn't. :mellow:

... Although CTRL+J is a tough competitor to compete with. ...


"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0