// Update 13.08.2016 erzwungene Kommentarposition
// Wenn im Script irgendwo "aligncomment=POSITION" enthalten ist, werden die Kommentare an dieser Position/Spalte ausgerichtet, wenn diese Position eine andere ist, als von
// AlignComment() berechnet!
// bsp. aligncomment=45, es werden die Kommentare an Spalte 45 ausgerichtet.
Hi,
damit ein Script "schön" aussieht, benutzen einige von euch bereits Tidy (Link zur neuesten Beta) (Scite Ctrl+T). Leider werden damit alle Kommentare, die man per Semikolon abgetrennt hinter eine Zeile schreibt, direkt hinter dieser Zeile ausgerichtet.
Manchmal ist es aber gewünscht, dass die Kommentare unabhängig von der Zeilenlänge der Codezeilen an einer bestimmten Spaltenposition ausgerichtet werden.
Dies wird mit AlignComment erreicht.
Dabei wird das auszurichtende Script per Kommandozeile an AlignComment übergeben, welches zunächst eine Sicherungskopie des Scriptes erstellt. Dann wird Tidy aufgerufen (falls installiert), eine Positionsspalte für die Kommentare errechnet und alle Kommentare an dieser Spalte ausgerichtet.
Per Ctrl+Q (;~) auskommentierte Zeilen werden NICHT ausgerichtet bzw bleiben so erhalten, wie Tidy sie anlegt!
Zeilen, die ausschliesslich einen Kommentar enthalten (also mit ; anfangen), werden in die Spalte geschrieben, in der auch die aktuellen Codezeilen stehen. Damit werden z.B. in 4 ineinandergeschachtelten For/To-Schleifen der Anfang der Kommentarzeilen zum Anfang der Codezeilen ausgerichtet.
Zur Zeit ist es so, dass AlignComment so ausrichtet, dass 80% aller Codezeilen kürzer als die Kommentarposition ist. Das heisst, bei "langen" Zeilen wird der Kommentar einfach an die Zeile angehängt.
Wer das ändern möchte, kann gern die Variable $faktor_align entsprechend anpassen.
#include <Array.au3>
#include <WindowsConstants.au3>
;AlignComment by Andy @ www.autoit.de
;Aligns Comments where are introduced by a Semicolon ; (;~ won´t be aligned!)
;
;The Script should be placed in the Scite-Directory\AlignComment\AlignComment.au3
;
;add following lines in the SciteUser.propreties-file (Scite\Options\open User-properties)
;if the #38 is occupied, please choose an other number, and replace all 38 !
;# 38 AlignComment
;command.38.*.au3="$(autoit3dir)\autoit3.exe" "$(SciteDefaultHome)\AlignComment\AlignComment.au3" "$(FilePath)"
;command.name.38.*.au3=AlignComment
;command.save.before.38.*.au3=1
;command.is.filter.38.*.au3=1
;command.shortcut.38.*.au3=F4 ;replace F4 with any other non-used keyboard shortcut to start AlignComment
;
;After that, restart Scite, load a script with comments and press F4...thats all
$faktor_align = 0.30 ;80% der Zeilen sind kürzer als die Kommentarposition...
;sendscite-commands
;http://www.autoitscript.com/forum/index.php?showtopic=25029&view=findpost&p=175714
If $cmdline[0] = 0 Then ;kein Dateiname angegeben
MsgBox(0, "Error AlignComment.au3", "No File selected!")
Exit
Else
$Tidy_path = RegRead("HKEY_CLASSES_ROOT\AutoIt3Script\Shell\Tidy\Command", "")
$Tidy_path = StringTrimRight(StringReplace($Tidy_path, '"', ""), 3)
SendSciTE_Command('menucommand:106') ;"Datei speichern" der aktuell in Scite geöffneten Datei
FileCopy($cmdline[1], $cmdline[1] & ".BAK") ;Sicherungskopie erstellen
If @error Then ;falls keine Sicherungskopie herzustellen ist, abbrechen
MsgBox(0, "Error AlignComment.au3", "No Backup Copy possible! Check " & $cmdline[1])
Exit
EndIf
$workdir = StringLeft($cmdline[1], StringInStr($cmdline[1], "\", 1, -1) - 1)
ShellExecuteWait($Tidy_path, '"' & $cmdline[1] & '"', $workdir, Default, @SW_HIDE)
$file = FileRead($cmdline[1]) ;Dateiinhalt zeilenweise lesen
EndIf
SendSciTE_Command('menucommand:104') ;reload
SendSciTE_Command('menucommand:420') ;clear Output in Scite Console window
ConsoleWrite("+ AlignComment by Andy @ www.autoit.de" & @CRLF)
ConsoleWrite("+ Orginal file copied to: " & $cmdline[1] & ".BAK" & @CRLF)
$zeilen = StringSplit($file, @CRLF, 3)
$alignvorgabe = StringRegExp($file, "(?i)aligncomment\s*=\s*(\d+)", 3) ; findet aligncomment=44 im text
$alignvorgabepos = 0
If IsArray($alignvorgabe) Then
$alignvorgabepos = $alignvorgabe[0]
EndIf
;~ _ArrayDisplay($zeilen)
$anz = 0
;position des kommentarzeichens ermitteln
Dim $len[UBound($zeilen)] ;
For $i = 0 To UBound($zeilen) - 1 ;jede einzelne zeile
$string = StringRegExp($zeilen[$i], '((?:[^''";]*([''"]).*?\2)*[^;]*)(;.*$)', 3) ; falls kommentar in zeile, ist dieser in $string[2], ansonsten string[0}=""
If $string = 1 Then ;kein Kommentar in der Zeile
$l = StringLen($zeilen[$i]) ;länge ohne Kommentar
If $l > 10 Then ;keine leerzeile
$len[$i] = $l ;anzahl zeichen
Else ;leerzeilen zählen (werden nicht mitberechnet)
$anz += 1
EndIf
Else ;kommentar in der Zeile enthalten
$l = StringLen($string[0]) ; länge ohne Kommentar
If $l > 10 Then ;nur wenn keine Kommentarzeile
$len[$i] = $l ;zeilenlänge ohne kommentar
Else ;kommentarzeilen werden auch nicht mitgezählt
$anz += 1
EndIf
EndIf
Next
_ArraySort($len, 1) ;array absteigend sortieren
;_ArrayDisplay($len)
$c_pos = $len[Int($faktor_align * (UBound($len) - 1 - $anz))] ;position des kommentars, so dass 80% aller zeilen kleiner als die Kommentarposition ist
If $c_pos < $alignvorgabepos Then $c_pos = $alignvorgabepos
;If $c_pos < 30 Then $c_pos = 30
ConsoleWrite(" Comments at the end of a line are aligned at Position " & $c_pos & @CRLF)
ConsoleWrite(" Whole line Comments are indented" & @CRLF)
$a = 'test ;'
$Kom = "" ;Das ist ein Kommentar
$leerstring = _stringrep(" ", $c_pos) ;maximale anzahl leerzeichen
$c_zeile = ""
For $i = 0 To UBound($zeilen) - 1 ;anzahl zeilen
$z = $zeilen[$i] ;einzelne Zeile
$z = StringReplace($z, Chr(9), " ") ;tabs ersetzen durch 4 leerzeichen (scite)
$string = StringRegExp($z, '((?:[^''";]*([''"]).*?\2)*[^;]*)(?:(;.*$)|.$)', 3) ; falls kommentar in zeile, ist dieser in $string[2], ansonsten string[0}="" ohne kommentar ist $string=1
If UBound($string) <> 3 Then ;kein kommentar in dieser Zeile
$c_zeile = $c_zeile & $z & @CRLF
Else ;kommentar in der zeile enthalten
$string[0] = StringStripWS($string[0], 2) ;leerzeichen entfernen
$l = StringLen($string[0]) ;stringlänge ohne Kommentar
If $l > $c_pos Or $string[0] = "" Or StringRegExp($string[0], '\A(?m)(\s+$)') = True Then ; kommentarzeile oder Zeile zu lang, kommentarzeilen werden eingerückt
$c_zeile = $c_zeile & $z & @CRLF ;Zeile bleibt unverändert
Else
$l = StringLen($string[0])
$anz_lz = $c_pos - $l + 1 ;länge Code ohne Kommentar
$c_zeile = $c_zeile & $string[0] & StringLeft($leerstring, $anz_lz) & $string[2] & @CRLF ;Kommentar wird ausgerichtet
EndIf
EndIf
Next
FileDelete($cmdline[1])
FileWrite($cmdline[1], $c_zeile)
Sleep(100)
SendSciTE_Command('menucommand:104') ;Script laden
Exit (0)
;copied from Xenobiologists OrganizeIncludes
;===============================================================================
; Description: Sending commands to SciTE interface
;===============================================================================
Func SendSciTE_Command($sCmd, $Wait_For_Return_Info = 0)
Local $WM_COPYDATA = 74
Local $WM_GETTEXT = 0x000D
Local $WM_GETTEXTLENGTH = 0x000E224
Local Const $SCI_GETLINE = 2153
Local $Scite_hwnd = WinGetHandle('DirectorExtension') ; 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
;~ ConsoleWrite('SciTE Command --> ' & $sCmd & @LF)
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))
DllCall('User32.dll', 'None', 'SendMessage', 'HWnd', $Scite_hwnd, _
'Int', $WM_COPYDATA, 'HWnd', $My_Hwnd, _
'Ptr', DllStructGetPtr($COPYDATA))
GUIDelete($My_Hwnd)
EndFunc ;==>SendSciTE_Command
Func _stringrep($s, $k) ;zeichen, anzahl, schneller Ersatz für _stringrepeat()
While StringLen($s) * 2 <= $k ;schneller ersatz für stringrepeat
$s &= $s
WEnd
$s &= StringLeft($s, $k - StringLen($s))
Return $s
EndFunc ;==>_stringrep
Alles anzeigen
Damit man AlignComment aus Scite mit einem Tastendruck aufrufen kann, sollte man folgendermassen vorgehen:
AlignComment im Verzeichnis "euerSciteVerzeichnis\AlignComment\AlignComment.au3" abspeichern.
Dann in Scite die Datei SciteUser.properties (Optionen\Benutzer-Einstellungen öffnen) öffnen und folgende Zeilen eintragen:
# 38 AlignComment
command.38.*.au3="$(autoit3dir)\autoit3.exe" "$(SciteDefaultHome)\AlignComment\AlignComment.au3" "$(FilePath)"
command.name.38.*.au3=AlignComment
command.save.before.38.*.au3=1
command.is.filter.38.*.au3=1
command.shortcut.38.*.au3=F4
F4 kann durch eine andere freie Tastenkombination ersetzt werden! Falls die #38 bereits in eurer SciteUser.properties enthalten ist, sucht die nächste freie Nummer und ersetzt alle 38er durch diese freie Nummer.
Nun Scite einmal neustarten (sicher ist sicher^^) und ein Script mit vielen Kommentaren laden, F4 drücken und sich über die ausgerichteten Kommentare freuen^^! Viel Spass!
Bitte Rückmeldung, ob AlignComment auch mit 64Bit-Systemen zurechtkommt. Ich habe es nur auf 32bit getestet, aber bis auf den Registry-Aufruf um das Tidy-Verzeichnis zu bekommen sollte es keine Probleme geben!
Falls jemand AlignComment auch mit anderen Programmiersprachen bzw Kommentartrennern verwenden möchte, bitte Info!
/EDIT/ die Schleifen von For $i = 0 To UBound($zeilen) - 2 nach For $i = 0 To UBound($zeilen) - 1 geändert.(s.Oscars Post). Das führt allerdings dazu, dass im 32-Bitmodus eine Leerzeile ans Script angehängt wird.