Wir hatten ja gerade das Thema Debugging. Ich habe dazu eine Funktion, die ich in der OwnHotkeys UDF habe nach AutoIt übertragen. So funktioniert es:
Code
Markierung im Skript wird kopiert und zusammen mit allen Includes aus dem Skript in eine temporäre
Datei im Skriptordner geschrieben (__TMP__RunSelected.au3).
Zusätzlich werden Consolenausgabebefehle eingefügt für:
- In Funktionsdeklaration alle Parameter
- ansonsten alle auftauchenden Variablen
- Ignoriert werden Variablen in Deklarationszeilen (Global/Local/Dim) und im 'Switch'-Kopf
- Integrierte Variablenerkennung für:
$a[$i][$j] , $m["k"]["j"]
($abc)[$i][$j]
($abc)[$i]
$a[$i] , $m["k"]
$abc.Bla
$abc
Consolenausgabe, Variablen anspringbar mit DblClick auf Ausgabezeile:
@LINE ZeileNR ( Variablenname, bei Array: mit aktuellen Indexwerten ) < Variablentyp > Wert
z.B.: @LINE 32 ( $a[0][0] ) < String > value: c
Standardmäßig wird die erstellte Datei automatisch gestartet. Wenn die Variable "$gbCopyOnly = True"
gesetzt wird, erfolgt kein automatisches Ausführen (EXE-Aufruf mit Parameter).
• Skript kompilieren
• In "SciTEUser.properties" eintragen:
command.name.9.$(au3)=Run Selected Code
command.mode.9.$(au3)=subsystem:0
command.9.$(au3)="C:\Programming\au3\scripts\RunSelectedCode.exe"
command.shortcut.9.$(au3)=Ctrl+Alt+R
Um nur das Skript zu erstellen mit Parameter "True" od. "1" aufrufen:
command.name.10.$(au3)=Create Script From Selection
command.mode.10.$(au3)=subsystem:0
command.10.$(au3)="C:\Programming\au3\scripts\RunSelectedCode.exe" "True"
command.shortcut.10.$(au3)=Ctrl+Alt+C
• Pfad der EXE anpassen
• command-Nr. nach freier Nummer bei euch auswählen (ohne Eintrag ist die erste freie: 36)
• ggf. Shortcut anpassen
Alles anzeigen
Die Variablenerkennung deckt alle häufigen Schreibweisen ab. Natürlich nicht alles. Wenn ihr da noch erweitern möchtet, kann in der Funktion _GetVars die Patternliste erweitert werden. Aber beachten, dass in der richtigen Reihenfolge abgefragt wird, erkannte Variablen werden sofort aus der Zeile entfernt, bevor mit dem nächsten Pattern geprüft wird.
Ich verwende meine "SciTE_GetInfo.au3" in dem Skript, ist mit angehängt.
AutoIt: RunSelectedCode
#cs
Markierung im Skript wird kopiert und zusammen mit allen Includes aus dem Skript in eine temporäre
Datei im Skriptordner geschrieben (__TMP__RunSelected.au3).
Zusätzlich werden Consolenausgabebefehle eingefügt für:
- In Funktionsdeklaration alle Parameter
- ansonsten alle auftauchenden Variablen
- Ignoriert werden Variablen in Deklarationszeilen (Global/Local/Dim) und im 'Switch'-Kopf
- Integrierte Variablenerkennung für:
$a[$i][$j] , $m["k"]["j"]
($abc)[$i][$j]
($abc)[$i]
$a[$i] , $m["k"]
$abc.Bla
$abc
Consolenausgabe, Variablen anspringbar mit DblClick auf Ausgabezeile:
@LINE ZeileNR ( Variablenname, bei Array: mit aktuellen Indexwerten ) < Variablentyp > Wert
z.B.: @LINE 32 ( $a[0][0] ) < String > value: c
Standardmäßig wird die erstellte Datei automatisch gestartet. Wenn die Variable "$gbCopyOnly = True"
gesetzt wird, erfolgt kein automatisches Ausführen (EXE-Aufruf mit Parameter).
• Skript kompilieren
• In "SciTEUser.properties" eintragen:
command.name.9.$(au3)=Run Selected Code
command.mode.9.$(au3)=subsystem:0
command.9.$(au3)="C:\Programming\au3\scripts\RunSelectedCode.exe"
command.shortcut.9.$(au3)=Ctrl+Alt+R
Um nur das Skript zu erstellen mit Parameter "True" od. "1" aufrufen:
command.name.10.$(au3)=Create Script From Selection
command.mode.10.$(au3)=subsystem:0
command.10.$(au3)="C:\Programming\au3\scripts\RunSelectedCode.exe" "True"
command.shortcut.10.$(au3)=Ctrl+Alt+C
• Pfad der EXE anpassen
• command-Nr. nach freier Nummer bei euch auswählen (ohne Eintrag ist die erste freie: 36)
• ggf. Shortcut anpassen
#ce
#include <FileConstants.au3>
#include <String.au3>
#include "SciTE_GetInfo.au3" ; <<<< PFAD ANPASSEN !!!
Global $gbCopyOnly = False ; mit True wird die Datei '\__TMP__RunSelected.au3' in SciTE erstellt, aber nicht automatisch ausgeführt
If $CMDLINE[0] Then $gbCopyOnly = ($CMDLINE[1] = 1 Or $CMDLINE[1] = 'True') ? True : False
Global $gSciTECmd
GUIRegisterMsg(74, "MY_WM_COPYDATA") ; $WM_COPYDATA = 74
_SGI_SetPollTime(-1) ; automatisches Aktualisieren deaktivieren
Global $gmSciTE = _SGI_GetAllHwnd(True)
; MapSciTE Keys: .PID = SciTE Process ID
; .hWnd = hwndSciTE
; .Title = SciTE Window Title
; .Director = hWnd DirectorExtension
; .Editor = hWnd Editor pane
; .Output = hWnd Output pane
; .Toolbar = hWnd Toolbar Ctrl
; .TabCtrl = hWnd Tab Ctrl
; .iTabItem = Index of the current active Tab-Item
; .sTabItem = Text of the current active Tab-Item
; .Statusbar = hWnd Statusbar Ctrl
Global $ghActive = _SGI_GetActiveSciTEHwnd()
If $ghActive = Null Then Exit MsgBox(16, "Fehler", "Das aktive Fenster ist kein SciTE-Fenster!")
_RunSelectedCode()
Func _RunSelectedCode()
_ScI_Dostring('output:ClearAll()')
Local $sErr = '!>> [Error RunSelectedCode] >> '
If _ScI_GetProperty('FileExt') <> 'AU3' Then Return _ScI_OutputToConsole($sErr & 'Attempting to run code from a non-au3 file!')
Local $sFileDir = _ScI_GetProperty('FileDir')
Local $sSel = _ReadSelection()
If $sSel = '' Then Return
$sSel = _SelectionAddOutput($sSel)
Local $sText = _GetEditorText()
Local $sIncl = _GetIncludes($sText) & @CRLF
Local $newPath = StringRegExpReplace($sFileDir & '\__TMP__RunSelected.au3', '\\+', '/')
Local $sFuncAdd = @CRLF & @CRLF & _
";------------------------------ ONLY FOR DEBUG ----------------------------------------------------" & @CRLF & _
"Func _GetTypeAndValue($_v)" & @CRLF & _
" Local $type = VarGetType($_v), $value" & @CRLF & _
" Switch $type" & @CRLF & _
" Case 'Array', 'Map', 'Object', 'DLLStruct', 'Function', 'UserFunction'" & @CRLF & _
" $value = ''" & @CRLF & _
" Case 'Keyword'" & @CRLF & _
" $value = (IsKeyword($_v) = 1 ? 'Default' : 'Null')" & @CRLF & _
" Case 'Ptr'" & @CRLF & _
" $type = IsHWnd($_v) ? 'Handle' : 'Ptr'" & @CRLF & _
" $value = $_v" & @CRLF & _
" Case Else" & @CRLF & _
" $value = String($_v)" & @CRLF & _
" EndSwitch" & @CRLF & _
" Return StringFormat('< %s >%s %s', $type, ($value = '' ? '' : @TAB & @TAB & 'value:'), $value)" & @CRLF & _
"EndFunc" & @CRLF
Local $fh = FileOpen($newPath, BitOR($FO_UTF8,$FO_OVERWRITE))
FileWrite($fh, $sIncl & $sSel & $sFuncAdd)
FileClose($fh)
_ScI_Dostring('scite.Open("' & $newPath & '")')
If $gbCopyOnly Then Return
_ScI_Dostring('scite.MenuCommand(IDM_GO)')
EndFunc
Func _ReadSelection()
Local $sFunc = "function ReadSelection() read = editor:GetSelText() return read end"
Return StringReplace(_ScI_DostringGet($sFunc), '\r\n', @CRLF)
EndFunc
Func _SelectionAddOutput($_sSel)
$_sSel = StringReplace($_sSel, ' _' & @CRLF, ' ') ; Zeilenfortschreibungen entfernen
Local $aLines = StringSplit($_sSel, @CRLF, 1), $sRet = '', $nCmtBlock = 0, $bIsCmnt = False
For $i = 1 To $aLines[0]
Switch StringLeft(StringStripWS($aLines[$i], 1), 3)
Case '#cs'
$bIsCmnt = True
$nCmtBlock += 1
Case '#ce'
$nCmtBlock -= 1
EndSwitch
If $bIsCmnt And $nCmtBlock > 0 Then ; Kommentarblock Start / innen
$sRet &= $aLines[$i] & @CRLF
ElseIf $bIsCmnt And $nCmtBlock = 0 Then ; Kommentarblock Ende
$bIsCmnt = False
$sRet &= $aLines[$i] & @CRLF
ElseIf StringLeft(StringStripWS($aLines[$i], 1), 1) = ';' Then ; Kommentarzeile
$sRet &= $aLines[$i] & @CRLF
Else ; kein Kommentar
$sRet &= _ScanLine(StringStripWS($aLines[$i], 2))
EndIf
Next
Return $sRet
EndFunc
Func _ScanLine($_line)
If $_line = '' Then Return @CRLF
If StringRegExp($_line, '^(?i)Func') Then ; Function Declaration
Local $sFuncName = StringRegExp($_line, '^(?i)Func\s+([_a-z0-9]+)', 1)[0]
$_line = _GetParam($_line, $sFuncName)
ElseIf StringRegExp($_line, '^(?i)\s*(Local|Global|Dim|Switch)') Then ; Declaration
; ignore
ElseIf StringRegExp($_line, '\$[_\w]+') Then ; Variable in line
$_line &= _GetVars($_line)
EndIf
Return $_line & @CRLF
EndFunc
Func _GetParam($_line, $_sFunc)
$_line = StringRegExpReplace($_line, '\)\s*;.*$', ')') ; evtl. Kommentare entfernen
Local $sParam = StringTrimRight(StringMid($_line, StringInStr($_line, '(') +1, -1), 1)
If StringStripWS($sParam, 8) = '' Then Return $_line
; Zuweisungen von Zeichenketten entfernen
$sParam = StringRegExpReplace($sParam, '\s*=\s*"[^"]+"', '')
$sParam = StringRegExpReplace($sParam, "\s*=\s*'[^']+'", '')
; sonstige Zuweisungen entfernen
$sParam = StringRegExpReplace($sParam, '\s*=\s*[^,]+', '')
Local $aParam = StringSplit($sParam, ',')
Local $sRet = $_line & @CRLF & @TAB & 'ConsoleWrite("-- Func: [ ' & $_sFunc & ' ] Passed values:" & @CRLF)' & @CRLF
Local $sValOut = ''
For $i = 1 To $aParam[0]
$aParam[$i] = StringStripWS($aParam[$i], 3)
$sValOut &= @TAB & 'ConsoleWrite("@LINE" & @TAB & @TAB & @ScriptLineNumber -' & $i +1 & ' & ( ' & $aParam[$i] & ' ) " & _GetTypeAndValue(' & $aParam[$i] & ') & @CRLF)' & @CRLF
Next
Return $sRet & $sValOut
EndFunc
Func _GetVars($_line)
Local $sSpace = '', $aSpace = StringRegExp($_line, '^\s+', 1)
If Not @error Then $sSpace = $aSpace[0]
Local $sVars = '', $aVars, $iMatch = 0, $iVar = 0
Local $aPatt[] = [ _
'\$[_\w]+\[[^\]]+\]\[[^]]+\]', _ ; $a[$i][$j] , $m["k"]["j"]
'\(\$[_\w]+\)\[[^\]]+\]\[[^\]]+\]', _ ; ($abc)[$i][$j]
'\(\$[_\w]+\)\[[^\]]+\]', _ ; ($abc)[$i]
'\$[_\w]+\[[^\]]+\]', _ ; $a[$i] , $m["k"]
'\$[_\w]+\.\w+', _ ; $abc.Bla
'\$[_\w]+'] ; $abc
For $i = 0 To UBound($aPatt) -1
If StringRegExp($_line, $aPatt[$i]) Then
$aVars = StringRegExp($_line, $aPatt[$i], 3)
For $j = 0 To UBound($aVars) -1
$iVar += 1
$sVars &= $sSpace & 'ConsoleWrite("@LINE" & @TAB & @TAB & @ScriptLineNumber -' & $iVar & _
' & " ( ' & StringRegExpReplace($aVars[$j], '\[\s*(\$[^\]]+)\]', '[" & \1 & "]') & _
' )" & @TAB & @TAB & _GetTypeAndValue(' & $aVars[$j] & ') & @CRLF)' & @CRLF
$_line = StringReplace($_line, $aVars[$j], '') ; remove match from line
Next
$iMatch += 1
EndIf
Next
If $iMatch = 0 Then Return ''
Return @CRLF & $sVars
EndFunc
Func _GetEditorText()
Local $sFunc = "function GetEditorText() read = editor:GetText() return read end"
Return _ScI_DostringGet($sFunc)
EndFunc
Func _GetIncludes($_sText)
Local $sReturn = ''
Local $aMatch = StringRegExp($_sText, '[\r\n]?(?im)(#include\s+(<|''|")[^>''"]+(>|''|"))', 3)
If Not @error Then
For $i = 0 To UBound($aMatch) -1 Step 3
$sReturn &= $aMatch[$i] & @CRLF
Next
EndIf
Return $sReturn
EndFunc
Func SendSciTE_Command($_sCmd, $Wait_For_Return_Info=0)
Local $WM_COPYDATA = 74
Local $Scite_hwnd = $gmSciTE[$ghActive]['Director'] ; Get SciTE DIrector Handle
Local $My_Hwnd = GUICreate("AutoIt3-SciTE interface") ; Create GUI to receive SciTE info
Local $My_Dec_Hwnd = Dec(StringTrimLeft($My_Hwnd, 2)) ; Convert my Gui Handle to decimal
$_sCmd = ":" & $My_Dec_Hwnd & ":" & $_sCmd ; Add dec my gui handle to commandline to tell SciTE where to send the return info
Local $CmdStruct = DllStructCreate('Char[' & StringLen($_sCmd) + 1 & ']')
DllStructSetData($CmdStruct, 1, $_sCmd)
Local $COPYDATA = DllStructCreate('Ptr;DWord;Ptr')
DllStructSetData($COPYDATA, 1, 1)
DllStructSetData($COPYDATA, 2, StringLen($_sCmd) + 1)
DllStructSetData($COPYDATA, 3, DllStructGetPtr($CmdStruct))
$gSciTECmd = ''
DllCall('User32.dll', 'None', 'SendMessage', 'HWnd', $Scite_hwnd, _
'Int', $WM_COPYDATA, 'HWnd', $My_Hwnd, _
'Ptr', DllStructGetPtr($COPYDATA))
GUIDelete($My_Hwnd)
If $Wait_For_Return_Info Then
Local $n = 0
While $gSciTECmd = '' Or $n < 10
Sleep(20)
$n += 1
WEnd
EndIf
Return $gSciTECmd
EndFunc ;==>SendSciTE_Command
Func MY_WM_COPYDATA($hWnd, $msg, $wParam, $lParam)
Local $COPYDATA = DllStructCreate('Ptr;DWord;Ptr', $lParam)
Local $gSciTECmdLen = DllStructGetData($COPYDATA, 2)
Local $CmdStruct = DllStructCreate('Char[' & $gSciTECmdLen+1 & ']',DllStructGetData($COPYDATA, 3))
$gSciTECmd = StringLeft(DllStructGetData($CmdStruct, 1), $gSciTECmdLen)
EndFunc ;==>MY_WM_COPYDATA
;===============================================================================
; Function Name....: _ScI_GetProperty
; Description......: Gibt den Wert für eine Property zurück
; Parameter(s).....: Property
; Return Value(s)..: Wert der Property
; Docu.............: http://www.scintilla.org/SciTEDoc.html od. "SciTE-Hilfe" --> "SciTE Documentation"
; Author(s)........: BugFix
;===============================================================================
Func _ScI_GetProperty($_sProperty)
SendSciTE_Command("askproperty:" & $_sProperty)
Return StringTrimLeft($gSciTECmd,StringInStr($gSciTECmd, ':', 1, 4))
EndFunc
;===============================================================================
; Function Name....: _ScI_OutputToConsole
; Description......: Gibt einen Wert in die Konsole aus
; Parameter(s).....: auszugebender Wert, Zeilenumbruch mit "\n", Tab mit "\t"
; Return Value(s)..: keine
; Author(s)........: BugFix
;===============================================================================
Func _ScI_OutputToConsole($_vValue)
SendSciTE_Command("output:" & $_vValue)
EndFunc
;===============================================================================
; Function Name....: _ScI_Dostring
; Description......: Einen Luastring mit/ohne Parameter aufrufen OHNE ein Ergebnis zu erhalten
; : Parameter im Lua-String (max. 10) sind in der Form "_1", "_2", .., "_n" zu benennen.
; Parameter(s).....: $_sLua - der Lua-String
; : $p1 - [optional] Parameter1 für den Lua-String ("_1")
; : ... bis
; : $p10 - [optional] Parameter10 für den Lua-String ("_10")
; Return Value(s)..: keine
; Author(s)........: BugFix
;-------------------------------------------------------------------------------
; Bsp.:
; ohne Parameter:
; _ScI_Dostring("print('Hallo Welt!')")
;
; mit Parameter:
; _ScI_Dostring("editor:SetSelection(_1,_2)", 4, 14)
;===============================================================================
Func _ScI_Dostring($_sLuastring, $p1=Null, $p2=Null, $p3=Null, $p4=Null, $p5=Null, $p6=Null, $p7=Null, $p8=Null, $p9=Null, $p10=Null)
Local $aParamCall[] = [$p1,$p2,$p3,$p4,$p5,$p6,$p7,$p8,$p9,$p10], $index = 0
While $aParamCall[$index] <> Null
$_sLuastring = StringRegExpReplace($_sLuastring, '_\d+', $aParamCall[$index], 1)
$index += 1
WEnd
SendSciTE_Command("extender:dostring do " & $_sLuastring & " end")
EndFunc
;===============================================================================
; Function Name....: _ScI_DostringGet
; Description......: Eine Luafunktion mit/ohne Parameter aufrufen UND ein Ergebnis erhalten
; : Maximal 10 Parameter können übergeben werden.
; Parameter(s).....: $_sLuaFunc - String mit der Lua-Funktion
; : $p1 - [optional] Parameter1 für die Funktion
; : ... bis
; : $p10 - [optional] Parameter10 für die Funktion
; Return Value(s)..: Rückgabewert der Lua-Funktion
; Author(s)........: BugFix
;-------------------------------------------------------------------------------
; Bsp.:
; ohne Parameter:
; Local $sFunc = "function LineFromCursor() return editor:LineFromPosition(editor.CurrentPos)+1 end"
; ConsoleWrite(_ScI_DostringGet($sFunc) & @CRLF)
;
; mit Parameter:
; Local $sFunc = "function LineEnd(iLine) return editor.LineEndPosition[iLine] end"
; ConsoleWrite(_ScI_DostringGet($sFunc, 130) & @CRLF)
;===============================================================================
Func _ScI_DostringGet($_sLuaFunc, $p1=Null, $p2=Null, $p3=Null, $p4=Null, $p5=Null, $p6=Null, $p7=Null, $p8=Null, $p9=Null, $p10=Null)
Local $aParamCall[] = [$p1,$p2,$p3,$p4,$p5,$p6,$p7,$p8,$p9,$p10]
; extract function name
Local $sFunc = (StringRegExp($_sLuaFunc, 'function (\w+)\(', 1))[0], $sParam = '()'
If $p1 <> Null Then
; extract parameters
$sParam = (StringRegExp($_sLuaFunc, 'function \w+\(([^)]+)\)', 1))[0]
Local $aParam = StringSplit($sParam, ',')
; rebuild sParam with given values
$sParam = ''
For $i = 1 To $aParam[0]
$sParam &= $aParamCall[$i-1] & ','
Next
$sParam = '(' & StringTrimRight($sParam,1) & ')'
EndIf
SendSciTE_Command("extender:dostring do " & $_sLuaFunc & " props['extender.result']=" & $sFunc & $sParam & " end")
SendSciTE_Command("askproperty:extender.result")
Return StringTrimLeft($gSciTECmd,StringInStr($gSciTECmd, ':', 1, 4))
EndFunc
Alles anzeigen