Toralf generously conceded that I add to his work on SyntaxTidy he offered in http://www.autohotke...?t=2528&start=0
I gladly seized this license to add a few features - and thanks to Toralf for his work, and to all others who contributed ideas.
All further suggestions welcome. And of course all bug reports.
; Functionality:
; - Gui: For drag&drop of files, setting of options and feedback
; - Options:
; - custom file extension
; - custom indentation ( one tab or a number of spaces )
; - different indentation styles ( Rajat or Toralf )
; - indentation of continuation lines ( a number of tabs or spaces )
; - indentation preservation of block continuation lines ( round brackets ) On/Off
; - indentation preservation of block comments ( /* ... */ ) On/Off
; - case correction for syntax words with more than 3 characters ( thanks Rajat )
; - statistics for script ( lines of code, comments, total and empty )
; - Dropped Files: Contents will be indented and copied to a new file
; with a user defined extension.
; - ShortCut F2: ( thanks ChrisM ) Highlighted syntax in an editor
; will be indented, if nothing is highlighted all text will be indented.
; - Gui remembers last position and settings between sessions ( thanks Rajat )
; - The spelling of subroutine calls and function calls is adjusted to the spelling
; in their respective definitions
; - Win-Ctrl-d toggles dubug mode
; Recent changes:
; - case adjustment of labels and self defined functions
; - improved detection of one line if commands (avoid false positives)
; - improved indentation of comment lines
; - code restructured
; - only full word replacement, i.e. no longer replacement of _parts_ of a word which correspond to a keyword
; - no replacement in quoted text and commentaries
; - faster (about 4 to 5 times) - making the code rather envolved, though
; - case adjustment of ahk function names
; just in case: ---- !!!!!! Backup your data !!!!!
(the script has been tested on itself.)
OwnHotkey=F9 ScriptName = Auto-Syntax-Tidy v6.1 ; OS=WinXP, AHK=1.0.35.16, Author = Toralf, Co-Author = Hajos ; 2005-06-09, 2005-06-27, 2005-07-10 ; ; What it does: ; It takes an AHK script and changes the indentation and case of keywords according to syntax. ; ; Known limitations: ; - a space is required before the "(" in an if-statement expression ; - case correction only for names longer than 3 characters ; - after doing indentation in an editor the cursor jumps ; to the first position in the last line ; - sparsely commented ; ; Functionality: ; - Gui: For drag&drop of files, setting of options and feedback ; - Options: ; - custom file extension ; - custom indentation ( one tab or a number of spaces ) ; - different indentation styles ( Rajat or Toralf ) ; - indentation of continuation lines ( a number of tabs or spaces ) ; - indentation preservation of block continuation lines ( round brackets ) On/Off ; - indentation preservation of block comments ( /* ... */ ) On/Off ; - case correction for syntax words with more than 3 characters ( thanks Rajat ) ; - statistics for script ( lines of code, comments, total and empty ) ; - Dropped Files: Contents will be indented and copied to a new file ; with a user defined extension. ; - ShortCut F2: ( thanks ChrisM ) Highlighted syntax in an editor ; will be indented, if nothing is highlighted all text will be indented. ; - Gui remembers last position and settings between sessions ( thanks Rajat ) ; - The spelling of subroutine calls and function calls is adjusted to the spelling ; in their respective definitions ; - Win-Ctrl-d toggles dubug mode ; Recent changes: ; - case adjustment of labels and self defined functions ; - improved detection of one line if commands (avoid false positives) ; - improved indentation of comment lines ; - code restructured ; - only full word replacement, i.e. no longer replacement of _parts_ of a word ; which correspond to a keyword ; - no replacement in quoted text and commentaries ; - faster (about 4 to 5 times) - making the code rather envolved, though ; - case adjustment of ahk function names ; just in case: ---- !!!!!! Backup your data !!!!! ; ; Suggestions are appreciated ; #SingleInstance force SetBatchLines, -1 Hotkey, %OwnHotkey%, IndentHighlightedText DebugMode = 0 ;Turn DebugMode on ( =1 ) to show MsgBox with Debug Info Gosub, ahk_specific Gosub, Read_ahkSyntaxFiles Gosub, BuildGUI Return ;############# End of autoexec section #################################### #^d:: DebugMode := DebugMode = 0 MsgBox, DebugMode = %DebugMode% Return ;############# ahk specific stuff ######################################### ahk_specific: CommentChar := ";" BlockBegin := "{" BlockEnd := "}" BlockCommentBegin := "/*" BlockCommentEnd := "*/" ContBlockBegin := "(" ContBlockEnd := ")" Return ;############# Read directives and commands from syntax file ############## Get_ahkdir: ;search for AHK directory, if not found take best guess. RegRead, ahk_dir, HKEY_LOCAL_MACHINE, SOFTWARE\AutoHotkey, InstallDir If ErrorLevel <> 0 ; Use a best guess location instead. ahk_dir = %ProgramFiles%\AutoHotkey ; ahk_dir = C:\Programme\AutoHotkey IfNotExist %ahk_dir% { MsgBox Could not find the AutoHotkey folder.`nPlease Edit script. ExitApp } Return Read_ahkSyntaxFiles: Gosub, Get_ahkdir ;path to syntax files PathSyntaxFiles = %ahk_dir%\Extras\Editors\Syntax ;read each line of syntax file and collect directives and if-keywords Loop, Read, %PathSyntaxFiles%\CommandNames.txt ;read syntax file { Line = %A_LoopReadLine% ;trim spaces ;get first character and first 2 characters of line StringLeft, FirstChar, Line , 1 StringLeft, FirstTwoChars, Line , 2 If ( InStr( Line, ";" ) = 1 ) ;skip comments Continue ;otherwise if keyword is directive or if-keyword add it to list If ( InStr( Line, "#" ) = 1 ) ListOfDirectives=%ListOfDirectives%%Line%, Else If ( InStr( Line, "if" ) = 1 ) { ;get first word, since more words may follow after an If-keyword StringSplit, Word, Line, %A_Space% Line = %Word1% If Line not in %ListOfIfCommands% ListOfIFCommands=%ListOfIFCommands%%Line%, } } Loop, Read, %PathSyntaxFiles%\Functions.txt ; get ahk function names { BracketPos := InStr( A_LoopReadLine, "(" ) If ( BracketPos ) { StringLeft, Tfn, A_LoopReadLine, BracketPos ahk_functions = %ahk_functions%,%Tfn% } } SyntaxFiles = CommandNames|Keywords|Keys|Variables ;process all syntax files Loop, Parse, SyntaxFiles, | %A_LoopField%0 := ListOfNames( PathSyntaxFiles, A_LoopField, ".txt", CommentChar ) Return ListOfNames( Path, NameList, Ext, CommentChar ) { local List, LineLength, GreatestLength Loop, Read, %Path%\%NameList%%Ext% ;read each line of syntax file { Line = %A_LoopReadLine% ;trim spaces ;get first character, length of line, and check for internal spaces StringLeft, FirstChar, Line , 1 If ( InStr( Line, A_Space ) ) ;skip if line contains spaces Continue If Line is Space ;skip empty lines Continue If ( FirstChar = CommentChar ) ;skip comments Continue If ( FirstChar = "#" ) ;skip directives Continue StringLen, LineLength, Line If ( LineLength >= 3 ) ;store words longer than 3 characters { List = %NameList%%LineLength% %List% := %List% . Line . "|" GreatestLength := AtLeast( LineLength, GreatestLength ) } } Return GreatestLength } ;############# Build GUI for Auto-Syntax-Tidy ############################# BuildGUI: LogText = Drop files to be indented`nor mark Text in editor and press %OwnHotkey%.`n`n IniRead, Extension, %ScriptName%.ini, Settings, Extension, _autoindent.ahk IniRead, Indentation, %ScriptName%.ini, Settings, Indentation, 2 IniRead, NumberSpaces, %ScriptName%.ini, Settings, NumberSpaces, 2 IniRead, NumberIndentCont, %ScriptName%.ini, Settings, NumberIndentCont, 8 IniRead, Style, %ScriptName%.ini, Settings, Style, 2 IniRead, CaseCorrectCommandNames, %ScriptName%.ini, Settings, CaseCorrectCommandNames, 1 IniRead, CaseCorrectVariables, %ScriptName%.ini, Settings, CaseCorrectVariables, 1 IniRead, CaseCorrectKeys, %ScriptName%.ini, Settings, CaseCorrectKeys, 1 IniRead, CaseCorrectKeywords, %ScriptName%.ini, Settings, CaseCorrectKeywords, 1 IniRead, CaseCorrectFunctions, %ScriptName%.ini, Settings, CaseCorrectFunctions, 1 IniRead, statistics, %ScriptName%.ini, Settings, statistics, 1 IniRead, KeepContIndent, %ScriptName%.ini, Settings, KeepContIndent, 0 IniRead, KeepBlockCommentIndent, %ScriptName%.ini, Settings, KeepBlockCommentIndent, 0 Gui, +ToolWindow +AlwaysOnTop Gui, Add, Text, xm Section , Extension for files Gui, Add, Edit, ys-3 r1 w117 vExtension, %Extension% Gui, Add, GroupBox, xm w210 r6.3, Indentation Gui, Add, Text, xp+8 yp+15 Section, Type: Gui, Add, Radio, ys vIndentation, 1xTab or Gui, Add, Radio, ys Checked, Spaces Gui, Add, Edit, ys-3 r1 Limit1 Number w15 vNumberSpaces, %NumberSpaces% Gui, Add, Text, xs Section, Style: Gui, Add, Radio, ys vStyle, Rajat or Gui, Add, Radio, ys Checked, Toralf Gui, Add, Text, xs Section, Indentation of continuation lines: Gui, Add, Radio, xs vIndentCont Section, Tabs or Gui, Add, Radio, ys Checked, Spaces Gui, Add, Edit, ys-3 r1 Limit2 Number w20 vNumberIndentCont, %NumberIndentCont% Gui, Add, Text, xs Section, Keep present indentation inside ... Gui, Add, Checkbox, xs Section vKeepBlockCommentIndent Checked%KeepBlockCommentIndent%, Block comments Gui, Add, Checkbox, ys vKeepContIndent Checked%KeepContIndent%, Cont´n blocks Gui, Add, GroupBox, xm w210 r2, Case-Correction for Gui, Add, Checkbox, xp+8 yp+18 Section vCaseCorrectCommandNames Checked%CaseCorrectCommandNames%, Commands Gui, Add, Checkbox, vCaseCorrectVariables Checked%CaseCorrectVariables%, Variables Gui, Add, Checkbox, ys vCaseCorrectKeys Checked%CaseCorrectKeys%, Keys Gui, Add, Checkbox, vCaseCorrectKeywords Checked%CaseCorrectKeywords%, Keywords Gui, Add, Checkbox, xp+50 ys vCaseCorrectFunctions Checked%CaseCorrectFunctions%, Functions Gui, Add, Text, xm Section, Information Gui, Add, Checkbox, ys vstatistics Checked%statistics%, statistics Gui, Add, Edit, xm r10 w210 vlog ReadOnly, %LogText% If ( Indentation = 1 ) GuiControl, , 1xTab or, 1 If ( Style = 1 ) GuiControl, , Rajat, 1 ;get previous position and show Gui IniRead, PosX_Gui, %ScriptName%.ini, General, PosX_Gui, IniRead, PosY_Gui, %ScriptName%.ini, General, PosY_Gui, Gui, Show, %PosX_Gui% %PosY_Gui%, %ScriptName% Return ;############# Shortcut %OwnHotkey% - indent highlighted text ############## IndentHighlightedText: WinGetActiveTitle, CurrTitle ClipSaved := ClipboardAll ; Save and clear clipboard Clipboard = Send, ^c ; Copy highlighted text to clipboard If Clipboard is Space ; If nothing is highlighted, select all Send, ^a^c ClipboardString := Clipboard If ClipboardString is not Space { Gosub, PrepareWork IndentText( ClipboardString ) Clipboard := ClipboardString WriteLogInfo( "marked text" ) WinActivate, %CurrTitle% WinWaitActive, %CurrTitle% ;paste clipboard Send, ^v{Home} } ;restore clipboard and free memory Clipboard := ClipSaved ClipSaved = ClipboardString = Return ;############# Process all dropped files ################################## GuiDropFiles: Gosub, PrepareWork Loop, Parse, A_GuiControlEvent, `n ;process dropped files { OutFile = %A_LoopField%%Extension% FileRead, Text, %A_LoopField% IndentText( Text ) ;paste file into new file ; if Extension is empty, old file will be overwritten FileDelete, %OutFile% FileAppend, %Text%, %OutFile% WriteLogInfo( A_LoopField ) } Text = Return ;############# Write log ################################################## WriteLogInfo( Name ) { global LogText = %LogText%Indentation done for: %Name%`n If statistics Gosub, AddstatisticsToLog Else LogText = %LogText%`n GuiControl, , Log , %LogText% } AddstatisticsToLog: ;calculate lines of code CodeLineCount := TotalLineCount - CommentLineCount - EmptyLineCount Now_msec := A_TickCount - Now_msec ;add information LogText = %LogText%=====statistics:=====`n LogText = %LogText% Code Lines: %A_Tab%%A_Tab%%CodeLineCount%`n LogText = %LogText% Comment Lines: %A_Tab%%A_Tab%%CommentLineCount%`n LogText = %LogText% Empty lines: %A_Tab%%A_Tab%%EmptyLineCount%`n LogText = %LogText%Total Number of lines: %A_Tab%%TotalLineCount%`n ;`n LogText = %LogText%Time elapsed [msec]: %A_Tab%%Now_msec%`n`n Return ;############# PrepareWork ################################################ PrepareWork: Gui, Submit, NoHide ;get Options CaseFlag := SetCaseCorrectNames( CaseFlag ) Gosub, CreateIndentationUnits Return ;############# Set ahk name lists for case correction ###################### SetCaseCorrectNames( CaseFlag ) { local cn, cf, cni, MaxNameLength cf = 0 Loop, Parse, SyntaxFiles, | { cf := ( cf << 1 ) + CaseCorrect%A_LoopField% MaxNameLength := AtLeast( MaxNameLength, %A_LoopField%0 ) } ; rebuild all lists if current selection <> previous selection If ( CaseFlag != cf ) { cf = 0 Loop, %MaxNameLength% ; 22: length of longest ahk names CaseCorrectNames%A_Index% = | Loop, Parse, SyntaxFiles, | { cn := A_LoopField cf := ( cf << 1 ) + Casecorrect%A_LoopField% If ( Casecorrect%A_LoopField% ) { Loop, %MaxNameLength% CaseCorrectNames%A_Index% := CaseCorrectNames%A_Index% . %cn%%A_Index% } } Loop, %MaxNameLength% { Sort CaseCorrectNames%A_Index%, D| ; cni = CaseCorrectNames%A_Index% / cn := %cni% / msgbox,%cn% } } ahk_MaxNameLength := MaxNameLength Return cf } ;############# Create indentation unit depending on options ############### CreateIndentationUnits: AutoTrim, Off ;Create indentation size depending on options If Indentation = 1 IndentUnit = %A_Tab% Else IndentUnit := N_Chars( NumberSpaces, A_Space ) ;Create indentation for line continuation If IndentCont = 1 IndentContLine := N_Chars( NumberIndentCont, A_Tab ) Else IndentContLine := N_Chars( NumberIndentCont, A_Space ) ;set autotrim back to default AutoTrim, On Return ;############# Indent a Text ############################################## IndentText( ByRef Text ) { global Now_msec := A_TickCount string = ;turn off autotrim to handle spaces and tabs AutoTrim, Off Gosub, ResetStartValues Loop, Parse, Text, `n, `r ;Read each line { Line := IndentedLine( A_LoopField ) String = %String%%Line%`n If DebugMode MsgBox, %string%`nIndentLevel: %IndentLevel%`n%indentcommand0%|%indentcommand1%|%indentcommand2%|%indentcommand3%|%indentcommand4%|%indentcommand5%|%indentcommand6%| } AutoTrim, On AdjustFunctionNames( ) StringTrimRight, Text, String, 1 ;remove last `n String = } ;############# Reset all start values ##################################### ResetStartValues: String = ;string to be built up Indent = ;indentation string NextIndent = IndentLevel = 0 ;Index of array IndentIncrement and IndentCommand InsideBlockComment = 0 ;Status flags InsideContinuation = 0 IndentCommand0 = -- EmptyLineCount = 0 ;Counters TotalLineCount = 0 CommentLineCount = 0 CaseCorrectFunctionNames= ;CSV list of function names in current script CaseCorrectSubNames= ;CSV list of subroutine names in current script Tfn = Return ;############# Set next indentation level and indentation prefix ########## SetNextIndentation( Level ) { local n NextIndent = n = 0 AutoTrim, Off Loop, %Level% ;Create indentation depending on IndentLevel { If IndentIncrement%n% NextIndent = %NextIndent%%IndentUnit% n++ } AutoTrim, On IndentLevel := Level Return } SetIndentLevel( Type, Level, Inc ) { local i If Type in Sub,Func IndentLevel = 0 i := AtLeast( IndentLevel, 0 ) + 1 AtLeast( Level, 0 ) ;in case something went wrong If ( IndentLevel = 0 and InStr( Type, "OneLine" ) ) { Type := "-" Level = 0 } If Type IndentCommand%IndentLevel% := Type IndentCommand%i% := "--" ;necessary mark IndentIncrement%IndentLevel% := Inc SetNextIndentation( Level ) } SetPrevLevel( Type, Level, Offset ) { global Loop ;Loop backwards through command list { If Level < 0 Break If IndentCommand%Level% in %Type% Break Level -- } If ( Level < 0 ) SetNextIndentation( 0 ) Else SetNextIndentation( Level + Offset ) Return IndentLevel } SetBlockIndentation( Type ) { local IndentBlock If PrevCommand in If,Elif,Else,Loop ;line is a one command block SetIndentLevel( "OneLine"PrevCommand, IndentLevel + 1, 1 ) Else ;normal comand line SetPrevLevel( "Sub,LeftBr", IndentLevel, 1 ) IndentBlock := NextIndent SetIndentLevel( Type, IndentLevel + 1, Toralf ) Return IndentBlock } SetElseBlockIndentation( Type ) { local IndentBlock SetPrevLevel( "If,Elif", IndentLevel, 0 ) IndentBlock := NextIndent SetIndentLevel( Type, IndentLevel + 1 , Toralf ) Return IndentBlock } ;############# Some testing functions ##################################### IsOneLineIf( Line ) { ;eliminate Escaped commas local pcomma, pbracket, p StringGetPos, p, Line , IfWin If p = 0 ; IfWin... commands are not single line cmds Return 0 StringReplace, Line, Line , ```, , , All StringGetPos, pcomma, Line , `, If ErrorLevel Return 0 StringGetPos, pbracket, Line , ( If ( ErrorLevel = 0 and pbracket < pcomma ) Return 0 ;Search for a third comma StringGetPos, p, Line , `, , L3 If ErrorLevel = 0 ;Line is possibly a one-line If-statement If ( Word3 != "in" and Word3 != "Contains" ) Return 1 Return 0 } ;############# Some low level functions ################################### N_Chars( n, char ) ;Concatenate n copies of Char { ret = Loop, %n% ret = %ret%%char% Return %ret% } AtLeast( ByRef Var, Min ) { If ( Var < Min ) Var := Min Return Var } StringPosNotAlnum( p ) { global String StringMid, a, String, p, 1 If a is Alnum Return 0 If a = _ Return 0 Return 1 } NotAlnum( ByRef String, p ) { StringMid, a, String, p, 1 If a is Alnum Return 0 If a = _ Return 0 Return 1 } ;############# SplitLine ################################################## SplitLine( ByRef Line ) { local p, TempLine Word1 = Word2 = StringReplace, TempLine, Line, %A_Tab%, %A_Space%, All StringGetPos, p, TempLine, `; If ( p >= 0 ) StringLeft, TempLine, TempLine, p + 1 StringReplace, TempLine, TempLine, `, , %A_Space%, All StringReplace, TempLine, TempLine, %A_Space%%A_Space%%A_Space%%A_Space%, %A_Space%, All StringReplace, TempLine, TempLine, %A_Space%%A_Space%%A_Space%, %A_Space%, All StringReplace, TempLine, TempLine, %A_Space%%A_Space%, %A_Space%, All StringSplit, Word, TempLine, %A_Space%%A_Tab%`, } ;############# Construct an indented line ################################# IndentedLine( OriginalLine ) { local Line, PrevIndex Toralf := Style = 2 ;set indentation to the amount determined by previous lines Indent := NextIndent PrevIndex := IndentLevel - 1 AtLeast( PrevIndex, 0 ) AutoTrim, On ;count line TotalLineCount ++ ;trim the line - does not work with Line := OriginalLine Line = %OriginalLine% ;get first character of line StringLeft, FirstChar, Line, 1 StringLeft, FirstTwoChars, Line , 2 If FirstChar = ;line is empty { EmptyLineCount ++ Return } SplitLine( Line ) FirstWord := Word1 SecondWord := Word2 ;function implementation? If ( FirstChar != BlockBegin and FirstChar != CommentChar and IndentLevel = 1 ) ;line is not start of bracket block If tfn { ;if an earlier line begins with a function name, ; then that line is not the beginning of the function implementation tfn = ;dismiss the function name stored SetNextIndentation( 0 ) } StringGetPos, BracketPos, FirstWord, ( FirstWordIsFunctionDef := ( IndentLevel = 0 and BracketPos > 0 ) If FirstWordIsFunctionDef { Tfn := TidyFunctionName( FirstWord, BracketPos ) FirstWordIsFunctionDef := tfn <> "" } ;check: is line a continuation of the previous line? LineIsImplicitCont := ( FirstChar = ", " or FirstTwoChars = "||" or FirstTwoChars = "&&" or FirstWord = "and" or FirstWord = "or" ) ;get last character of First word StringRight, FirstWordLastChar, FirstWord, 1 AutoTrim, Off ;###### after all the preparations, here the work begins ########## If ( FirstChar = "#" ) ;line is a directive Loop, Parse, ListOfDirectives, CSV If ( FirstWord = A_LoopField ) { StringReplace, Line, Line, %A_LoopField%, %A_LoopField% Return %Line% } If ( FirstTwoChars = BlockCommentEnd ) ;line is end of BlockComment { InsideBlockComment := False CommentLineCount ++ Return %Line% } If InsideBlockComment ;line is inside a BlockComment { CommentLineCount ++ If KeepBlockCommentIndent Return %OriginalLine% Else Return %Line% } If ( FirstTwoChars = BlockCommentBegin ) ;line is start of a BlockComment { InsideBlockComment := True CommentLineCount ++ Return %Line% } If ( FirstWord = ContBlockBegin ) ;line is start of a continuation block { InsideContinuation ++ ;allow nested cont´s Return Indent Line } If ( FirstWord = ContBlockEnd and InsideContinuation ) ;end of a continuation block { InsideContinuation -- AtLeast( InsideContinuation, 0 ) Return Indent Line } If ( InsideContinuation ) ; don´t indent If KeepContIndent Return %OriginalLine% Else Return %Line% If ( FirstChar = ":" ) ;line is hotstring { SetIndentLevel( "Sub", 1, Toralf ) Return %Line% } If ( FirstChar = BlockBegin ) ;line is start of bracket block { If ( IndentLevel = 1 and tfn <> "" ) ; start of a function implementation If tfn not in %CaseCorrectFunctionNames% ; build a CSV list CaseCorrectFunctionNames = %CaseCorrectFunctionNames%,%tfn% tfn = SetIndentLevel( "LeftBr", IndentLevel + 1, 1 ) Return Indent Line } If ( FirstChar = BlockEnd ) ;line is end of bracket block { SetPrevLevel( "LeftBr", IndentLevel, -1 ) If Toralf Return NextIndent IndentUnit Line Else Return NextIndent Line } PrevCommand := IndentCommand%PrevIndex% If ( FirstChar = CommentChar ) ;line is comment { CommentLineCount ++ If ( InStr( PrevCommand, "OneLine" ) ) SetPrevLevel( "Sub,LeftBr", IndentLevel, 1 ) Return NextIndent Line } If ( FirstWordLastChar = ":" ) ;line is start of subroutine or Hotkey IfNotInString , FirstWord, `:`: ;line is start of a subroutine { StringLeft, Tsn, Line, StrLen( FirstWord ) - 1 If Tsn not in %CaseCorrectSubNames% ; build a CSV list CaseCorrectSubNames = %CaseCorrectSubNames%,%Tsn% SetIndentLevel( "Sub", 1, Toralf ) SetKeyWordCase( Line ) Return %Line% } SetKeyWordCase( Line ) IfInString , FirstWord, `:`: ;line is a hotkey or hotstring definition { If ( SecondWord <> "" and Asc( SecondWord ) != 59 ) SetIndentLevel( "Sub", 0 , 0 ) ; one line hotkey def´n Else SetIndentLevel( "Sub", 1, Toralf ) ;probably multiline def´n Return %Line% } If FirstWordIsFunctionDef ;line is function { SetIndentLevel( "Func", 1, Toralf ) Return %Line% } If ( FirstWord = "Loop" ) ;line is start of Loop block Return SetBlockIndentation( "Loop" ) line If FirstWord in %ListOfIFCommands% ;line is start of If-Statement { StringReplace, Line, Line, if, If If ( IsOneLineIf( Line ) ) ;Line is a one-line If-statement Return SetBlockIndentation( "1If" ) Line Else Return SetBlockIndentation( "If" ) Line } If ( FirstWord = "Else" ) ;line begins an Else block If SecondWord in %ListOfIfCommands% ;Else If ... Return SetElseBlockIndentation( "Elif" ) Line Else ;just a plain Else Return SetElseBlockIndentation( "Else" ) Line ;If line is a continuation add the appropiate indentation If LineIsImplicitCont Return Indent IndentContLine Line Else ;line is a normal command or Return { If ( FirstWord = "Return" and IndentCommand0 = "Sub" ) { If PrevCommand in If,Elif,Else,Loop SetIndentLevel( "OneLine"PrevCommand, IndentLevel + 1, 1 ) Else If ( SetPrevLevel( "Sub,LeftBr", IndentLevel, 1 ) = 1 ) SetIndentLevel( "0", 0 , 0 ) } Else If PrevCommand in If,Elif,Else,Loop SetIndentLevel( "OneLine"PrevCommand, IndentLevel + 1, 1 ) Else If PrevCommand in Func ;Line follows a function call SetIndentLevel( "0", 0, 0 ) Else ;line is normal command SetPrevLevel( "Sub,LeftBr", IndentLevel, 1 ) Return NextIndent Line } } ;############# Show debug MsgBox ############################################ /* ShowDebugStrings: msgtext = line#: %TotalLineCount%`n msgtext = %msgtext%Style: %Style%`n msgtext = %msgtext%line: %Line%`n msgtext = %msgtext%Indent: |%Indent%|`n msgtext = %msgtext%1stChar: >%FirstChar%<`n msgtext = %msgtext%1st Word: >%FirstWord%<`n msgtext = %msgtext%2nd Word: >%SecondWord%<`n msgtext = %msgtext%1st WordLastChar: >%FirstWordLastChar%<`n`n msgtext = %msgtext%IndentLevel: %IndentLevel%`n msgtext = %msgtext%Indent1: %IndentIncrement1% - %IndentCommand1%`n msgtext = %msgtext%Indent2: %IndentIncrement2% - %IndentCommand2%`n msgtext = %msgtext%Indent3: %IndentIncrement3% - %IndentCommand3%`n msgtext = %msgtext%Indent4: %IndentIncrement4% - %IndentCommand4%`n msgtext = %msgtext%Indent5: %IndentIncrement5% - %IndentCommand5%`n msgtext = %msgtext%Indent6: %IndentIncrement6% - %IndentCommand6%`n msgtext = %msgtext%Indent7: %IndentIncrement7% - %IndentCommand7%`n msgtext = %msgtext%Indent8: %IndentIncrement8% - %IndentCommand8%`n msgtext = %msgtext%Indent9: %IndentIncrement9% - %IndentCommand9%`n msgtext = %msgtext%Indent10: %IndentIncrement10% - %IndentCommand10%`n msgtext = %msgtext%Indent11: %IndentIncrement11% - %IndentCommand11%`n msgtext = %msgtext%`nDirectives: %ListOfDirectives%`n msgtext = %msgtext%`nIf-Commands: %ListOfIFCommands%`n msgtext = %msgtext%`nCommandNames: %CommandNames%`n msgtext = %msgtext%`nKeywords: %Keywords%`n msgtext = %msgtext%`nKeys: %Keys%`n msgtext = %msgtext%`nVariables: %Variables%`n MsgBox %msgtext%`n%String% Return */ ;############# Case correction of line #################################### SetKeyWordCase( ByRef String ) ; identify sequences of alphanumeric characters (i. e. words) ; compare them with list of keywords and if found replace them { local Ls, Ls2, Line, inquote, p1, wl ;p1: pos of 1st char of a word, wl: word length, inquote: flag Ls := StrLen( String ) StringGetPos, Ls2, String, %CommentChar% If ErrorLevel Ls2 := Ls StringLeft, Line, String, %Ls2% p1 = 1 inquote = 0 Loop, Parse, Line, ; find words { If inquote If A_LoopField = " { inquote = 0 p1 = 0 } Else Continue Else If A_LoopField= " ; skip quoted text inquote = 1 If A_LoopField is Alnum If p1 wl ++ Else { p1 := A_Index ; start of a new word wl = 1 } Else if A_LoopField = _ If p1 wl ++ Else { p1 := A_Index ; start of a new word wl = 1 } Else ; no alnum char If ( p1 ) ; end of word found { If ( wl >= 3 and wl <= ahk_MaxNameLength ) TestReplace_ahkName( String, LS, p1, wl ) p1 = 0 } Else Continue } If ( p1 and wl >= 3 and wl <= ahk_MaxNameLength ) ; end of line TestReplace_ahkName( String, Ls, p1, wl ) } TestReplace_ahkName( ByRef String, Ls, p1, wl ) { ; wl: word length local cn, w, p2, Name StringMid, w, String, p1 , wl cn = CaseCorrectNames%wl% StringGetPos, p2, %cn%, |%w% If ErrorLevel Return StringMid, Name, %cn%, p2 + 2 , wl ReplaceName( String, Name, p1 - 1, Ls - p1 - wl +1 ) } ;############# Tidy up Function and Subroutine Names ###################### TidyFunctionName( Word, Bpos ) { local a, n, tfn n := Bpos Loop { StringMid, a, word, n, 1 If ( a <> "_" ) If a is not Alnum Break n-- If n = 0 Break } If n = 0 StringMid, tfn, Word, 1, Bpos+1 Return tfn } AdjustFunctionNames( ) { local n, a, p, ls, ln, tn ; tn: tidy name, ln: name length ls := StrLen( String ) If ( CaseCorrectFunctions ) CaseCorrectFunctionNames = %CaseCorrectFunctionNames%%ahk_functions% ; MsgBox,%CaseCorrectFunctionNames% Loop, Parse, CaseCorrectFunctionNames, CSV { If A_Index = 1 Continue tn := A_LoopField ln := StrLen( tn ) p = 0 Loop { n := p + 1 StringGetPos, p, String, %tn%, , n IfLess, p, 0, Break If StringPosNotAlnum( p ) ReplaceName( string, tn, p, ls - p - ln ) } } Loop, Parse, CaseCorrectSubNames, CSV { If A_Index = 1 Continue tn := A_LoopField ln := StrLen( tn ) p = 0 Loop { n := p + 1 StringGetPos, p, String, %tn%, , n IfLess, p, 1, Break StringMid, a, String, p, 1 If a is Alnum If ( a = "g" ) { TestAndReplaceSubName( string, tn, "Gui, ", ls, ln, p ) TestAndReplaceSubName( string, tn, "Gui ", ls, ln, p ) } Else Continue TestAndReplaceSubName( string, tn, "Gosub", ls, ln, p ) TestAndReplaceSubName( string, tn, "Menu", ls, ln, p ) TestAndReplaceSubName( string, tn, "`:`:", ls, ln, p ) TestAndReplaceSubName( string, tn, "Hotkey", ls, ln, p ) } } } TestAndReplaceSubName( ByRef string, ByRef name, test, ls, ln, p ) { local pn, pt StringGetPos, pt, String, %test%, R , ls - p StringGetPos, pn, String, `n, R , ls - p If ( pn < pt ) ;string %test% in the same line ReplaceName( string, name, p, ls - p - ln ) } ReplaceName( ByRef string, ByRef name, pl, pr ) { ; pl: left part, pr: right part to remain local StrL, StrR StringLeft, StrL, String, pl StringRight, StrR, String, pr String = %StrL%%name%%StrR% } ;############# On Gui close exit all ###################################### GuiClose: ;store current position and settings and exit app WinGetPos, PosX, PosY, SizeW, SizeH, %ScriptName% Gui, Submit IniWrite, x%PosX%, %ScriptName%.ini, General, PosX_Gui IniWrite, y%PosY%, %ScriptName%.ini, General, PosY_Gui IniWrite, %Extension%, %ScriptName%.ini, Settings, Extension IniWrite, %Indentation%, %ScriptName%.ini, Settings, Indentation IniWrite, %NumberSpaces%, %ScriptName%.ini, Settings, NumberSpaces IniWrite, %NumberIndentCont%, %ScriptName%.ini, Settings, NumberIndentCont IniWrite, %Style%, %ScriptName%.ini, Settings, Style IniWrite, %CaseCorrectCommandNames%, %ScriptName%.ini, Settings, CaseCorrectCommandNames IniWrite, %CaseCorrectVariables%, %ScriptName%.ini, Settings, CaseCorrectVariables IniWrite, %CaseCorrectKeys%, %ScriptName%.ini, Settings, CaseCorrectKeys IniWrite, %CaseCorrectKeywords%, %ScriptName%.ini, Settings, CaseCorrectKeywords IniWrite, %CaseCorrectFunctions%, %ScriptName%.ini, Settings, CaseCorrectFunctions IniWrite, %statistics%, %ScriptName%.ini, Settings, statistics IniWrite, %KeepContIndent%, %ScriptName%.ini, Settings, KeepContIndent IniWrite, %KeepBlockCommentIndent%, %ScriptName%.ini, Settings, KeepBlockCommentIndent ExitApp Return ;############# End of File #################################################Hajos