
#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