- Offizieller Beitrag
Hi,
da die Funktionsliste in SciTE ( aufrufbar mit Alt+L ) nur in einem recht mickrigen Control angezeigt wird, habe ich hier mal eine Variante erstellt, in der die Anzeige in einem AutoIt-Listview erfolgt und somit von jedem nach eigenem Geschmack angepaßt werden kann.
Vorgehensweise ist identisch, wie bei der "Standard-Liste": HotKey (in meinem Bsp. Ctrl+Alt+L) aufrufen, Funktionsliste erscheint, Doppelklick auf Funktion, Cursor springt zur Zeile mit der Funktion und wird in den sichtbaren Bereich des Editors gescrollt.
Da ich zur Zeit mich etwas mehr mit LUA beschäftige, war dies eine schöne Übung zum Datenaustausch zwischen LUA- und AutoIt-Skript. Gelöst über eine temporäre Datei.
Funktionell ist alles prima und tut, was es soll.
ABER, Ein Schönheitsfehler besteht: Ich rufe aus dem LUA-Skript heraus mittels "os.execute(Dateipfad)" das kompilierte AutoIt-Skript zur Anzeige der Funktionen auf. Jedoch wird mir dabei im Hintergrund das Windows-CMD Fenster angezeigt. Bisher habe ich noch keine Möglichkeit gefunden dieses zu unterdrücken.
ShowFuncList.au3
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>
; Anzeige der Funktionsliste
; wird übergeben bei "Strg+Alt+L" im Skript
If Not $CmdLine[0] Then Exit
Global $sPathDataExchange = $CmdLine[1]
Local $aFuncs = StringSplit(FileRead($sPathDataExchange), @CR)
Local $gui = GUICreate('Funktionsliste', 500, 450, -1, -1, $WS_SIZEBOX, $WS_EX_TOPMOST)
Local $ListView = GUICtrlCreateListView('Funktionsliste', 5, 5, 490, 415, BitOR($LVS_NOCOLUMNHEADER,$LVS_SHOWSELALWAYS))
For $i = 1 To $aFuncs[0]
GUICtrlCreateListViewItem($aFuncs[$i], $ListView)
Next
Local $hListView = GUICtrlGetHandle($ListView)
_GUICtrlListView_SetColumnWidth($hListView, 0, $LVSCW_AUTOSIZE_USEHEADER)
GUISetState()
[/autoit] [autoit][/autoit] [autoit]GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
[/autoit] [autoit][/autoit] [autoit]While True
Switch GUIGetMsg()
Case -3
Exit
EndSwitch
WEnd
Func _DblClck($iIndex)
Local $sFunc = _GUICtrlListView_GetItemText($hListView, $iIndex)
If $sFunc = '' Then Return
Local $fh = FileOpen($sPathDataExchange, 2)
FileWrite($fh, '$' & $sFunc)
FileClose($fh)
Exit
EndFunc
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
$hWndListView = $hListView
If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hWndListView
Switch $iCode
Case $NM_DBLCLK
Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
Return _DblClck(DllStructGetData($tInfo, "Index"))
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
MyFunctionsList.lua !geändert!
--------------------------------------------------------------------------------
-- MyFunctionList()
--------------------------------------------------------------------------------
function MyFunctionsList()
local data = { }
local doc = editor:GetText()
local self = { }
self.Pattern = "()[%s][Ff][Uu][Nn][Cc][%s]+([%w%s_]*%(.-%))"
self.Seperator = ";"
self.DataTable = { }
for pos, str in doc:gmatch(self.Pattern) do
-- If we have a multi-line function definition, show it all on one line.
str = str:gsub("[\r\n]*", "")
-- Insert the string into both tables.
table.insert(data, str)
self.DataTable[str] = editor:LineFromPosition(pos)
end
-- Sort the table and build a string out of it.
table.sort(data, function(a, b) return string.lower(a) < string.lower(b) end)
local list = table.concat(data, self.Seperator)
-- DataExchange:
--~ local userDir = os.getenv("USERPROFILE")
local exchgDir = os.getenv("HOMEDRIVE") -- hardcodiert 'C:', sonst Problem bei Execute und mgl. Leerzeichen im Pfad
local tmpFile = exchgDir .. "\\LUA_DataExchange.txt" -- Dateipfad für Datenaustausch im USERDIR festlegen
if string.len(list) > 0 then -- wenn Funktionen im Skript vorhanden
-- Begin - EXPORT
local ret_1, ret_2 = string.gsub(list, "%);", ")\r") -- Trenner zw. Funktionen mit 'CR' ersetzen
local fout = assert(io.open(tmpFile, "wb")) -- Datei zum Schreiben öffnen
fout:write(ret_1) -- Liste in Datei schreiben (2. Returnwert enthält Anzahl Ersetzungen von .gsub)
assert(fout:close()) -- Datei schließen
-- HIER der Knackpunkt: Bei Aufruf externer EXE bleibt ein CMD-Fenster offen
os.execute(exchgDir .."\\ShowFuncList.exe \"".. tmpFile .."\"") -- Anzeigeskript mit Datei Funktions-Liste aufrufen
-- End - EXPORT
-- Begin - Auswertung angeklickte Funktion, wenn 1.Zeichen "$" dann wurde eine Funktion angeklickt
local fin = assert(io.open(tmpFile)) -- Datei zum Lesen öffnen
local sRead = fin:read("*a") -- Datei einlesen
local selected = string.sub(sRead, 1, 1) -- und erstes Zeichen selektieren
assert(fin:close()) -- Datei schließen
if selected == '$' then -- 1.Zeichen = "$", also wurde eine Funktion gewählt (kein Abbruch o. Auswahl)
local sFunc = string.sub(sRead, 2, string.len(sRead)) -- "$" abschneiden = Funktionsname
editor:GotoLine(self.DataTable[sFunc]) -- gehe zu Zeile mit Funktion (aus Array DataTable)
end
-- Ende - Auswertung
os.remove(tmpFile) -- Datenaustausch-Datei löschen
end
end -- FunctionsList
Alles anzeigen
Wer es selbst testen möchte, wie folgt vorgehen:
- ShowFuncList.au3 kompilieren und im Pfad @UserProfileDir als "..\USERNAME\ShowFuncList.exe" abspeichern "C:\ShowFuncList.exe" abspeichern
- "MyFunctionsList.lua" im Pfad "..\SciTE\LUA" abspeichern
- im selben Pfad die Datei "SciTEStartup.lua" öffnen
- im Block: "-- Load all the Lua files" eine neue Zeile anfügen: 'LoadLuaFile("MyFunctionsList.lua")'
- nun noch den Aufruf per HotKey festlegen in "SciTEUser.properties"
# END => DO NOT CHANGE ANYTHING BEFORE THIS LINE #-#-#-#-#-#
#41 Zeige Funktionsliste
command.name.41.$(au3)=MyFunctionsList
command.41.$(au3)=MyFunctionsList
command.subsystem.41.$(au3)=3
command.mode.41.$(au3)=savebefore:no
command.shortcut.41.$(au3)=Ctrl+Alt+L
Nach Neustart von SciTE steht die Funktion zur Verfügung.
Falls jemand eine Idee hat, wie ich das CMD-Window unterdrücken kann (oder eine andere Form des Aufrufs aus LUA kennt) - bitte melden.
Edit:
Ich kann es zwar ausblenden - aber es popt vorher kurz auf, sieht nicht sehr gelungen aus.
Folgender Code am Skriptanfang setzt das Fenster 'HIDE':
If Not WinExists("[Class:ConsoleWindowClass]") Then
WinWait("[Class:ConsoleWindowClass]")
EndIf
Local $hWndCMD = WinGetHandle("[Class:ConsoleWindowClass]")
WinSetState($hWndCMD, '', @SW_HIDE)