Jump to content

Recommended Posts

Posted

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
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
Posted

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:

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_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: 22/04/2018

Posted

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 ...
 

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...