;Change indentation and case of commands according to syntax ;by toralf & hajos ;requires AHK 1.0.44.09 ;www.autohotkey.com/forum/topic7810.html Version = v12 ScriptName = Auto-Syntax-Tidy %Version% ; Known limitations: ; - a space is required after the last ":" for hotkeys, hotstrings and subroutine ; - comments might not have the right indentation in certain strongly ; encapsulated block-structures, due to not knowing what the next line will bring. ; - case correction only works for words longer than 4 characters, ; (except: (in all cases) If, Loop, Else ; (optional) Goto, Gui, Run, Exit, Send, Sort, Menu ; Parse, Read, Mouse, SendAndMouse, Default, Permit, Screen, Relative ; Pixel, Toggle, UseErrorLevel, AlwaysOn, AlwaysOff ; !!! caution !!! case correction is dangerous, since WinTitles in commands are case sensitive ; ; - after doing indentation in an editor the cursor jumps ; to the first position in the last line ; - Indentation might fail, if a "{" is the last character of a Loop or If statement that ; doesn't support OTB. E.g. "If x = {" or "Loop, Parse, Var, {" ; ; Functionality: ; - Gui: For drag&drop of files, setting of options and feedback ; - command line option "/in" for file and "/log" for log file ; - command line option "/hidden" to start script with hidden GUI ; - command line option "/watch hwnd" to start script with hidden GUI, closes itself when hwnd closes ; - command line option "/toggle" checks if another instance is running and closes both scripts ; - command line option "/hidden" to start script without GUI ; - Options: ; - custom hotkey for indenation ; - custom file extension (overwrites old file if nothing is specified) ; - custom indentation (one tab or a number of spaces) ; - different indentation styles (Rajat, Toralf or BoBo) ; - 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 4 characters (thanks Rajat) ; - statistics for script (lines of code, comments, total and empty an time needed) ; - Dropped Files: Contents will be indented and copied to a new file with a user ; defined extension (overwrites old file if nothing is specified). ; - Hotkey (F2): Highlighted syntax in an editor will be indented, if nothing is ; highlighted all text will be indented. (thanks ChrisM) ; - Gui remembers last position and settings between sessions (thanks Rajat) ; - The case of subroutine calls and function calls is adjusted to the case ; of their respective definitions ; - Ctrl-d toggles debug mode ; - 12% faster then version 7 (due to shortened loop cycles) but 90 lines longer ; ; !!! Not heavily tested !!!! ---- !!!!!! Backup your data !!!!! ; ; Suggestions are appreciated ; ; Wish: ; - Option to strip code: Remove empty lines, all comments, and join split expressions (&&/AND/OR/||) /* changes since version 11: - tray icon allows to toggle show/hide of GUI and to exit script - added progressbar if identation is done inside an editor and blockinput is used to limit interference - shortend code with functions, with new features the line numbers stay equal - log text is scrolled to the end - on /hidden, gui is created but hidden, tray icon is visible in both cases. - on "/watch hwnd" , gui is hidden and closes itself when hwnd closes - on /toggle, script checks if another instance is running and closes both scripts - improved possibilty to find path of AHK - added warning message if syntax files do not exist - OwnHotkey is stored in INI file and has a control in the GUI */ #SingleInstance off SetBatchLines, -1 ;set working dir, in case this script is called from some other script in a different dir SetWorkingDir, %A_ScriptDir% ;process command line parameters ;by Ace_NoOne - www.autohotkey.com/forum/viewtopic.php?t=7556 If %0%{ Loop, %0% { ; for each command line parameter next := A_Index + 1 ;get next parameters number ; check if known command line parameter exists If (%A_Index% = "/in") param_in := %next% ;assign next command line parameter as value Else If (%A_Index% = "/log") param_log := %next% Else If (%A_Index% = "/hidden") param_hidden = Hide Else If (%A_Index% = "/watch"){ param_hidden = Hide param_watch := %next% }Else If (%A_Index% = "/toggle") GoSub, CheckAndToggleRunState } } ;Turn DebugMode on (=1) to show MsgBox with Debug Info DebugMode = 0 ;location of icon file If ( A_OSType = "WIN32_WINDOWS" ) ; Windows 9x IconFile = %A_WinDir%\system\shell32.dll Else IconFile = %A_WinDir%\system32\shell32.dll ;tray menu Menu, Tray, Icon, %IconFile%, 56 ;icon for taskbar and for Process in task manager Menu, Tray, Tip, %ScriptName% Menu, Tray, NoStandard Menu, Tray, Add, Show/Hide, ShowHideGui Menu, Tray, Add, Exit, ExitApp Menu, Tray, Default, Show/Hide Menu, Tray, Click, 1 SplitPath, A_ScriptName, , , , OutNameNoExt IniFile = %OutNameNoExt%.ini Gosub, ReadDataFromIni ;find path to AHK If !FileExist(AHKPath){ SplitPath, A_AHKPath,, AHKPath If !FileExist(AHKPath){ RegRead, AHKPath, HKLM, Software\AutoHotkey, InstallDir If !FileExist(AHKPath){ RegRead, AHKPath, HKCR, Applications\AutoHotkey.exe\shell\Open\Command StringTrimLeft, AHKPath, EdtAHKPath, 1 StringTrimRight, AHKPath, EdtAHKPath, 24 If !FileExist(AHKPath){ AHKPath = %A_ProgramFiles%\AutoHotkey If !FileExist(AHKPath){ AHKPath = C:\Programme\AutoHotkey If !FileExist(AHKPath){ AHKPath = } } } } } } IfNotExist %AHKPath% { MsgBox,,, Could not find the AutoHotkey folder.`nPlease edit the script:`n%A_ScriptFullPath%`nin Linenumber: %A_LineNumber% ExitApp } Gosub, ReadSyntaxFiles If FileExist(param_in){ Gosub, IndentFile ExitApp } Gosub, BuildGui If param_watch SetTimer, WatchWindow, On ;disable hotkey in its own gui Hotkey, IfWinNotActive, %GuiUniqueID% ;set hotkey and remember it Hotkey, %OwnHotkey%, IndentHighlightedText OldHtk = %OwnHotkey% Hotkey, IfWinNotActive, Return ;############# End of autoexec section #################################### ;############# Toogle debug modus ######################################### ^d:: DebugMode := not DebugMode ToolTip, DebugMode = %DebugMode% Sleep, 1000 ToolTip Return ;############# Close script when watch window doesn't exist ############### WatchWindow: DetectHiddenWindows, On If !WinExist("ahk_id " param_watch) ;check if watch window exists GoSub, GuiClose ;if not close this script DetectHiddenWindows, Off Return ;############# Toogle run status - close on second run #################### CheckAndToggleRunState: ;get own PID Process, Exist OwnPID := ErrorLevel ;get own title If A_IsCompiled OwnTitle := A_ScriptFullPath Else OwnTitle := A_ScriptFullPath " - AutoHotkey v" A_AhkVersion ;get list of all windows DetectHiddenWindows, On WinGet, WinIDs, List ;go through list and get their titles Loop, %WinIDs% { UniqueID := "ahk_id " WinIDs%A_Index% WinGetTitle, winTitle, %UniqueID% ;check if there is a window with the same title as this script but not itself If (winTitle = OwnTitle ) { WinGet, winPID, PID, %UniqueID% If (winPID <> OwnPID) { ;close it and itself Process, Close, %winPID% ExitApp } } } DetectHiddenWindows, off Return ;############# Read directives and commands from syntax file ############## ReadSyntaxFiles: ;path to syntax files PathSyntaxFiles = %AHKPath%\Extras\Editors\Syntax ;clear lists ListOfDirectives = ListOfIFCommands = ;read each line of syntax file and search for directives and if-keywords CommandNamesFile = %PathSyntaxFiles%\CommandNames.txt IfNotExist %CommandNamesFile% { MsgBox,,, Could not find the "CommandNames.txt" file.`nPlease edit the script:`n%A_ScriptFullPath%`nin Linenumber: %A_LineNumber% ExitApp } Loop, Read , %CommandNamesFile% ;Read syntax file { ;remove spaces from read line Line = %A_LoopReadLine% ;get first character and first 2 characters of line StringLeft,FirstChar, Line ,1 StringLeft,FirstTwoChars, Line ,2 ;if line is comment, continue with next line If (FirstChar = ";") Continue ;otherwise if keyword is directive or if-keyword add it to list Else If (FirstChar = "#") ListOfDirectives=%ListOfDirectives%,%Line% Else If (FirstTwoChars = "if") { ;get first word, since If-keywords in the syntax file have more words StringSplit, Array, Line, %A_Space% Line = %Array1% If (StrLen(Line) > 4) ListOfIFCommands=%ListOfIFCommands%,%Line% } } ;remove first comma and change to lower char StringTrimLeft,ListOfIFCommands,ListOfIFCommands,1 StringTrimLeft,ListOfDirectives,ListOfDirectives,1 ;remove multiple If Sort, ListOfIFCommands, U D, ;read in all variable names FileRead, Variables, *t %PathSyntaxFiles%\Variables.txt StringReplace , Variables , Variables , `n , | , All FilesSyntax = CommandNames|Keywords|Keys ;Loop over all syntax files Loop, Parse, FilesSyntax,| { String = SyntaxFile = %PathSyntaxFiles%\%A_LoopField%.txt IfNotExist %SyntaxFile% { MsgBox,,, Could not find the syntax file "%A_LoopField%.txt".`nPlease edit the script:`n%A_ScriptFullPath%`nin Linenumber: %A_LineNumber% ExitApp } ;read each line of syntax file Loop, Read , %SyntaxFile% { ;remove spaces from read line Line = %A_LoopReadLine% ;get first character, length of line and look for spaces StringLeft,FirstChar, Line ,1 ;if line contains spaces, continue with next line If InStr(Line," ") Continue ;if line is empty, continue with next line Else If Line is Space Continue ;if line is comment, continue with next line Else If (FirstChar = ";") Continue ;otherwise if word is longer than 4 character, remember it Else If (StrLen(Line) > 4 ) String = %String%,%Line% } ;remove first pipe StringTrimLeft,String,String,1 ;store remembered string in var which has same name as syntaxfile %A_LoopField% := String } CommandNames = %CommandNames%,Goto,Gui,Run,Exit,Send,Sort,Menu ,Parse,Read,Mouse,SendAndMouse,Default,Permit,Screen,Relative ,Pixel,Toggle,UseErrorLevel,AlwaysOn,AlwaysOff ;read in all function names BuildInFunctions = ;read each line of syntax file FunctionsFile = %PathSyntaxFiles%\Functions.txt IfNotExist %SyntaxFile% { MsgBox,,, Could not find the "Functions.txt" file.`nPlease edit the script:`n%A_ScriptFullPath%`nin Linenumber: %A_LineNumber% ExitApp } Loop, Read , %FunctionsFile% { ;remove spaces from read line Line = %A_LoopReadLine% ;get first character, and name of function plus its braket, e.g. "ATan(" StringLeft,FirstChar, Line ,1 StringSplit, Line, Line, ( ;if line is empty, continue with next line If Line is Space Continue ;if line is comment, continue with next line Else If (FirstChar = ";") Continue ;otherwise remember it with braket Else BuildInFunctions = %BuildInFunctions%,%Line1%( } ;don't remove first comma, it will be done just before correction Return ;############# Read Data from Ini file #################################### ReadDataFromIni: IniRead, Extension, %IniFile%, Settings, Extension, _autoindent_%Version%.ahk IniRead, Indentation, %IniFile%, Settings, Indentation, 2 IniRead, NumberSpaces, %IniFile%, Settings, NumberSpaces, 2 IniRead, NumberIndentCont, %IniFile%, Settings, NumberIndentCont, 8 IniRead, IndentCont, %IniFile%, Settings, IndentCont, 2 IniRead, Style, %IniFile%, Settings, Style, 2 IniRead, CaseCorrectCommands, %IniFile%, Settings, CaseCorrectCommands, 1 IniRead, CaseCorrectVariables, %IniFile%, Settings, CaseCorrectVariables, 1 IniRead, CaseCorrectBuildInFunctions, %IniFile%, Settings, CaseCorrectBuildInFunctions, 1 IniRead, CaseCorrectKeys, %IniFile%, Settings, CaseCorrectKeys, 1 IniRead, CaseCorrectKeywords, %IniFile%, Settings, CaseCorrectKeywords, 1 IniRead, CaseCorrectDirectives, %IniFile%, Settings, CaseCorrectDirectives, 1 IniRead, Statistic, %IniFile%, Settings, Statistic, 1 IniRead, ChkSpecialTabIndent, %IniFile%, Settings, ChkSpecialTabIndent, 1 IniRead, KeepBlockCommentIndent, %IniFile%, Settings, KeepBlockCommentIndent, 0 IniRead, AHKPath, %IniFile%, Settings, AHKPath, %A_Space% IniRead, OwnHotkey, %IniFile%, Settings, OwnHotkey, F2 Return OwnHotKey: ;deacticate old hotkey Hotkey, IfWinNotActive, %GuiUniqueID% Hotkey, %OldHtk%, IndentHighlightedText, Off ;Don't allow no hotkey If OwnHotkey is space { Hotkey, %OldHtk%, IndentHighlightedText GuiControl, , OwnHotKey, %OldHtk% }Else{ Hotkey, %OwnHotkey%, IndentHighlightedText OldHtk = %OwnHotkey% } Hotkey, IfWinNotActive, Return ;############# Build GUI for Auto-Syntax-Tidy ############################# BuildGui: LogText = Drop your files for indentation on this Gui.`nOr highlight AHK syntax in script and press %OwnHotkey%.`n`n Gui, +ToolWindow +AlwaysOnTop Gui, Add, Text, xm Section ,Hotkey Gui, Add, Hotkey, ys-3 r1 w165 vOwnHotKey gOwnHotKey, %OwnHotKey% 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, x+8 ys vStyle,Rajat Gui, Add, Radio, x+8 ys Checked,Toralf Gui, Add, Radio, x+8 ys ,BoBo Gui, Add, Text, xs Section,Indentation of Method1 continuation Lines: Gui, Add, Edit, xs ys+15 Section r1 Limit2 Number w20 vNumberIndentCont, %NumberIndentCont% Gui, Add, Radio, ys+4 vIndentCont ,Tabs or Gui, Add, Radio, ys+4 Checked,Spaces Gui, Add, Checkbox, xs vKeepBlockCommentIndent Checked%KeepBlockCommentIndent%, Preserve indent. in Block comments Gui, Add, Checkbox, xs vChkSpecialTabIndent Checked%ChkSpecialTabIndent%, Special "Gui,Tab" indent Gui, Add, GroupBox, xm w210 r3,Case-Correction for Gui, Add, Checkbox, xp+8 yp+18 Section vCaseCorrectCommands Checked%CaseCorrectCommands%,Commands Gui, Add, Checkbox, vCaseCorrectVariables Checked%CaseCorrectVariables%,Variables Gui, Add, Checkbox, vCaseCorrectBuildInFunctions Checked%CaseCorrectBuildInFunctions%,Build in functions Gui, Add, Checkbox, ys vCaseCorrectKeys Checked%CaseCorrectKeys%,Keys Gui, Add, Checkbox, vCaseCorrectKeywords Checked%CaseCorrectKeywords%,Keywords Gui, Add, Checkbox, vCaseCorrectDirectives Checked%CaseCorrectDirectives%,Directives Gui, Add, Text, xm Section, Information Gui, Add, Checkbox, ys vStatistic Checked%Statistic%, Statistic Gui, Add, Edit, xm r10 w210 vlog ReadOnly, %LogText% If (Indentation = 1) GuiControl,,1xTab or,1 If (Style = 1) GuiControl,,Rajat,1 Else If (Style = 3) GuiControl,,BoBo,1 If (IndentCont = 1) GuiControl,, IndentCont, 1 ;get previous position and show Gui IniRead, Pos_Gui, %IniFile%, General, Pos_Gui, Gui, Show, %Pos_Gui% %param_Hidden% ,%ScriptName% Gui, +LastFound GuiUniqueID := "ahk_id " WinExist() ;get classNN of log control GuiControl, Focus, Log ControlGetFocus, ClassLog, %GuiUniqueID% GuiControl, Focus, Extension Return ;############# Toggle show / hide of Gui from tray icon ################### ShowHideGui: If param_Hidden { Gui, Show param_Hidden = }Else{ param_Hidden = Hide Gui, Show, %param_Hidden% } Return ;############# Function iif: returns a or b depending on expression ####### iif(exp,a,b=""){ If exp Return a Return b } ;############# Shortcut F? - indent highlighted text ###################### IndentHighlightedText: ;store time for speed measurement StartTime = %A_TickCount% ;Save and clear clipboard ClipSaved := ClipboardAll Clipboard = ;Cut highlight to clipboard Send, ^c ;get window UID of current window WinUniqueID := WinExist("A") ;If nothing is highlighted, select all and copy If Clipboard is Space { ;Select all and copy to clipboard Send, ^a^c } ;get rid of all carriage returns (`r). StringReplace, ClipboardString, Clipboard, `r`n, `n, All ;restore the original clipboard and free memory Clipboard := ClipSaved ClipSaved = ;If something is selected, do the indentation and put it back in again If ClipboardString is Space MsgBox, 0 , %ScriptName%, (LTrim Couldn't get anything to indent. Please try again. ), 1 Else { ;get Options Gui, Submit, NoHide ;create progress bar and block input StringReplace, x, ClipboardString, `n, `n, All UseErrorLevel NumberOfLines = %ErrorLevel% Progress, R0-%NumberOfLines% FM10 WM8000 FS8 WS400, `n, Please wait`, auto-syntax-tidy is Running, %ScriptName% BlockInput, On ;set words for case correction Gosub, SetCaseCorrectionSyntax ;create indentation Gosub, CreateIndentSize ;reset all values Gosub, SetStartValues ;Read each line form clipboard Loop, Parse, ClipboardString, `n { ;remember original line with its identation AutoTrim, Off Original_Line = %A_LoopField% AutoTrim, On ;do the indentation Gosub, DoSyntaxIndentation ;update progress bar every 10th line If (Mod(A_Index, 10)=0) Progress, %A_Index%, Line: %A_Index% of %NumberOfLines% } CaseCorrectSubsAndFuncNames() ;remove last `n StringTrimRight,String,String,1 ;Save and clear clipboard ClipSaved := ClipboardAll Clipboard = ;put String into clipboard ;StringReplace, String, String, `n, `r`n, All Clipboard = %String% ;close progress bar and activate old window again Progress, Off WinActivate, ahk_id %WinUniqueID% ;paste clipboard Send, ^v{HOME} ;restore the original clipboard and free memory Clipboard := ClipSaved ClipSaved = ;turn off block input BlockInput, Off ;write information LogText = %LogText%Indentation done for text in editor.`n If Statistic Gosub, AddStatisticToLog Else LogText = %LogText%`n GuiControl, ,Log , %LogText% ControlSend, %ClassLog%, ^{End}, %GuiUniqueID% } Return ;############# Set words for case correction ############################## SetCaseCorrectionSyntax: CaseCorrectionSyntax = If CaseCorrectCommands CaseCorrectionSyntax = ,%CommandNames% If CaseCorrectVariables CaseCorrectionSyntax = %CaseCorrectionSyntax%,%Variables% If CaseCorrectKeys CaseCorrectionSyntax = %CaseCorrectionSyntax%,%Keys% If CaseCorrectKeywords CaseCorrectionSyntax = %CaseCorrectionSyntax%,%Keywords% If CaseCorrectDirectives CaseCorrectionSyntax = %CaseCorrectionSyntax%,%ListOfDirectives% ;remove first pipe StringTrimLeft, CaseCorrectionSyntax, CaseCorrectionSyntax, 1 Return ;############# Create indentation size depending on options ############### CreateIndentSize: ;clear IndentSize = IndentContLine = ;turn of autotrim to be able to assign Spaces and tabs AutoTrim, Off ;Create indentation size depending on option If Indentation = 1 IndentSize = %A_Tab% Else Loop, %NumberSpaces% IndentSize = %IndentSize%%A_Space% ;Create indentation for line continuation If IndentCont = 1 Loop, %NumberIndentCont% IndentContLine = %IndentContLine%%A_Tab% Else Loop, %NumberIndentCont% IndentContLine = %IndentContLine%%A_Space% ;set autotrim to default AutoTrim, On Return ;############# Reset all start values ##################################### SetStartValues: String = ;string that holds temporarely the file content (with auto-indentation) Indent = ;indentation string IndentIndex = 0 ;Index of array IndentIncrement and IndentCommand InBlockComment := False ;Status if loop is in a Blockcomment InsideContinuation := False InsideTab = 0 EmptyLineCount = 0 ;Counts the Number of empty Lines for statistics TotalLineCount = 0 ;Counts the Number of total Lines for statistics CommentLineCount = 0 ;Counts the Number of comments Lines for statistics If CaseCorrectBuildInFunctions CaseCorrectFuncList = %BuildInFunctions% ;CSV list of function names in current script including build in functions Else CaseCorrectFuncList = ;CSV list of function names in current script CaseCorrectSubsList= ;CSV list of subroutine names in current script Loop, 11{ IndentIncrement%A_Index% = IndentCommand%A_Index% = } Return ;############# Indent all dropped files ################################### GuiDropFiles: ;store time for speed measurement OverAllStartTime = %A_TickCount% ;get options Gui, Submit,NoHide ;set words for case correction Gosub, SetCaseCorrectionSyntax ;create indentation Gosub, CreateIndentSize OverAllCodeLineCount = 0 OverAllTotalLineCount = 0 OverAllCommentLineCount = 0 OverAllCommentLineCount = 0 ;for each dropped file, read file line by line and indent each line Loop, Parse, A_GuiControlEvent, `n { ;store time for speed measurement StartTime = %A_TickCount% ;file FileToautoIndent = %A_LoopField% ;reset start values Gosub, SetStartValues ;Read each line in the file and do indentation Loop, Read, %FileToautoIndent% { ;remember original line with its identation AutoTrim, Off Original_Line = %A_LoopReadLine% AutoTrim, On ;do indentation Gosub, DoSyntaxIndentation } CaseCorrectSubsAndFuncNames() ;paste file with auto-indentation into new file ; if Extension is empty, old file will be overwritten FileDelete, %FileToautoIndent%%Extension% FileAppend, %String%,%FileToautoIndent%%Extension% ;write information LogText = %LogText%Indentation done for: %FileToautoIndent%`n If Statistic Gosub, AddStatisticToLog Else LogText = %LogText%`n GuiControl, ,Log , %LogText% ControlSend, %ClassLog%, ^{End}, %GuiUniqueID% } If Statistic { LogText = %LogText%=====Statistics:=======`n LogText = %LogText%=====over all files====`n LogText = %LogText%Lines with code: %A_Tab%%A_Tab%%OverAllCodeLineCount%`n LogText = %LogText%Lines with comments: %A_Tab%%OverAllCommentLineCount%`n LogText = %LogText%Empty Lines: %A_Tab%%A_Tab%%OverAllEmptyLineCount%`n LogText = %LogText%Total Number of Lines: %A_Tab%%OverAllTotalLineCount%`n ;time for speed measurement OverAllTimeNeeded := (A_TickCount - OverAllStartTime) / 1000 LogText = %LogText%Total Process time: %A_Tab%%OverAllTimeNeeded%[s]`n`n GuiControl, ,Log , %LogText% ControlSend, %ClassLog%, ^{End}, %GuiUniqueID% } Return ;############# Add statistics to log ###################################### AddStatisticToLog: ;calculate lines of code CodeLineCount := TotalLineCount - CommentLineCount - EmptyLineCount OverAllCodeLineCount += CodeLineCount OverAllTotalLineCount += TotalLineCount OverAllCommentLineCount += CommentLineCount OverAllEmptyLineCount += EmptyLineCount ;add information LogText = %LogText%=====Statistics:=====`n LogText = %LogText%Lines with code: %A_Tab%%A_Tab%%CodeLineCount%`n LogText = %LogText%Lines with comments: %A_Tab%%CommentLineCount%`n LogText = %LogText%Empty Lines: %A_Tab%%A_Tab%%EmptyLineCount%`n LogText = %LogText%Total Number of Lines: %A_Tab%%TotalLineCount%`n ;time for speed measurement TimeNeeded := (A_TickCount - StartTime) / 1000 LogText = %LogText%Process time: %A_Tab%%TimeNeeded%[s]`n`n Return ;############# Indent file from command line ############################## IndentFile: ;set words for case correction Gosub, SetCaseCorrectionSyntax ;create indentation Gosub, CreateIndentSize ;file FileToautoIndent = %param_in% ;reset start values Gosub, SetStartValues ;Read each line in the file and do indentation Loop, Read, %FileToautoIndent% { ;remember original line with its identation AutoTrim, Off Original_Line = %A_LoopReadLine% AutoTrim, On ;do indentation Gosub, DoSyntaxIndentation } CaseCorrectSubsAndFuncNames() ;remove old file and paste with auto-indentation into same file FileDelete, %FileToautoIndent% FileAppend, %String%, %FileToautoIndent% ;write information to log file LogText = Indentation done for: %FileToautoIndent%`n If Statistic Gosub, AddStatisticToLog FileAppend , %LogText%, %param_log% Return ;############# Create indentation for next loop depending on IndentIndex ## SetIndentForNextLoop: ;clear Indent = If IndentIndex < 0 ;in case something went wrong IndentIndex = 0 ;turn AutoTrim off, to be able to process tabs and spaces AutoTrim, Off ;Create indentation depending on IndentIndex Loop, %IndentIndex% { Increments := IndentIncrement%A_Index% Loop, %Increments% Indent = %Indent%%IndentSize% } ;turn AutoTrim on, to remove leading and trailing tabs and spaces AutoTrim, On Return ;############# Strip comments from Line ################################### StripCommentsFromLine(Line) { StartPos = 1 Loop { ;go from semicolon to semicolon, start at 2nd position, First doesn't make sence, since it would be a comment StartPos := InStr(Line,";","",StartPos + 1) If (StartPos > 1) { ;the following is not very robust but it will serve for most cases that a ";" is inside an := or () expression ; limitations: ; - comments that include a " on an := expression line ; - comments that include a ") on an ()expression line StringMid,CharBeforeSemiColon, Line, StartPos - 1 , 1 If (CharBeforeSemiColon = "``") ;semicolon is Escaped Continue Else If ( 0 < InStr(Line,":=") AND InStr(Line,":=") < StartPos AND 0 < InStr(Line,"""") AND InStr(Line,"""") < StartPos AND 0 < InStr(Line,"""","",StartPos) ) ;It on the right side of an := expression and surounded with "..." Continue Else If ( 0 < InStr(Line,"(") AND InStr(Line,"(") < StartPos AND InStr(Line,")","",StartPos) > StartPos AND 0 < InStr(Line,"""") AND InStr(Line,"""") < StartPos AND 0 < InStr(Line,"""","",StartPos) ) ;It is inside and () expression and surounded with "..." Continue Else { ;it is a semicolon StringLeft, Line, Line, StartPos - 1 ;get CommandLine up to semicolon Line = %Line% ;remove Spaces Return Line } } Else ;no more semicolon found, hence no comments on this line Return Line } } ;############# Function MemorizeIndent: Store list of indentations ######## MemorizeIndent(Command,Increment,Index=0){ global If (Index > 0) IndentIndex += %Index% Else If (Index < 0) IndentIndex := Abs(Index) IndentCommand%IndentIndex% = %Command% IndentIncrement%IndentIndex% = %Increment% } ;############# Perform the syntax indentation for each given line ######### DoSyntaxIndentation: ;count line TotalLineCount ++ ;################################## ;########### judge on line ###### ;################################## ;remove space and tabs from beginning and end of original line Line = %Original_Line% If Line is Space ;nothing in line { String = %String%`n ;count line EmptyLineCount ++ Gosub, FinishThisLine Return ;Continue with next line } ;################################## ;########### judge on first chars ;################################## ;get first and last characters of line StringLeft, FirstChar , Line, 1 StringLeft, FirstTwoChars, Line, 2 FinishThisLine := False ;turn AutoTrim off, to be able to process tabs and spaces AutoTrim, Off If (FirstTwoChars = "*/") { ;line is end of BlockComment String = %String%%Line%`n InBlockComment := False CommentLineCount ++ FinishThisLine := True } Else If InBlockComment { ;line is inside the BlockComment If KeepBlockCommentIndent String = %String%%Original_Line%`n Else String = %String%%Line%`n CommentLineCount ++ FinishThisLine := True } Else If (FirstTwoChars = "/*") { ;line is beginning of a BlockComment, end will be */ String = %String%%Line%`n InBlockComment := True CommentLineCount ++ FinishThisLine := True } Else If (FirstChar = ":") { ;line is hotstring String = %String%%Line%`n MemorizeIndent("Sub",1,-1) FinishThisLine := True } Else If (FirstChar = ";") { ;line is comment String = %String%%Indent%%Line%`n CommentLineCount ++ FinishThisLine := True } If FinishThisLine { Gosub, FinishThisLine Return ;Continue with next line } ;turn AutoTrim back on AutoTrim, On ;################################## ;########### judge on commands/words ;################################## ;get pure command line StripedLine := StripCommentsFromLine(Line) ;get last character of CommandLine StringRight, LastChar , StripedLine, 1 ;get shortest first, second and third word of CommandLine Loop, 3 CommandLine%A_Index% = StringReplace, CommandLine, StripedLine, %A_Tab%, %A_Space%,All StringReplace, CommandLine, CommandLine, `, , %A_Space%,All StringReplace, CommandLine, CommandLine, {, %A_Space%,All StringReplace, CommandLine, CommandLine, }, %A_Space%,All StringReplace, CommandLine, CommandLine, %A_Space%if(, %A_Space%if%A_Space%,All StringReplace, CommandLine, CommandLine, ), %A_Space%,All StringReplace, CommandLine, CommandLine, %A_Space%%A_Space%%A_Space%%A_Space%, %A_Space%,All StringReplace, CommandLine, CommandLine, %A_Space%%A_Space%%A_Space%, %A_Space%,All StringReplace, CommandLine, CommandLine, %A_Space%%A_Space%, %A_Space%,All CommandLine = %CommandLine% ;remove Spaces from begining and end StringSplit, CommandLine, CommandLine, %A_Space% FirstWord = %CommandLine1% SecondWord = %CommandLine2% ThirdWord = %CommandLine3% ;get last character of First word StringRight, FirstWordLastChar, FirstWord, 1 ;check if previoulsly found function name is really a function definition ;if line is not start of bracket block but a funtion name exists If ( FirstChar <> "{" AND IndentIndex = 1 AND FunctionName <> "") { FunctionName = ; then that previous line is not a function definition. IndentIndex = 0 ; set back the indentation, which was previously set. Gosub, SetIndentForNextLoop } ;Assume line is not a function FirstWordIsFunction := False ;If no indentation and bracket not as first character it might be a function If ( IndentIndex = 0 And InStr(FirstWord,"(") > 0 ) FirstWordIsFunction := ExtractFunctionName(FirstWord,InStr(FirstWord,"("),FunctionName) LineIsTabSpecialIndentStart := False LineIsTabSpecialIndent := False LineIsTabSpecialIndentEnd := False If (ChkSpecialTabIndent AND FirstWord = "Gui") { If (InStr(SecondWord,"add") And ThirdWord = "tab") LineIsTabSpecialIndentStart := True Else If (InStr(SecondWord,"tab")) { If ThirdWord is Space LineIsTabSpecialIndentEnd := True Else LineIsTabSpecialIndent := True } } ;turn AutoTrim off, to be able to process tabs and spaces AutoTrim, Off ;###### Start to adjust indentation ########## If FirstWord in %ListOfDirectives% ;line is directive { Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All String = %String%%Line%`n } Else If FirstChar in #,!,^,+,<,>,*,~,$ ;line is Hotkey (has be be after directives due to the #) { If InStr(FirstWord,"::"){ String = %String%%Line%`n MemorizeIndent("Sub",1,-1) } } Else If (FirstChar = "," OR FirstTwoChars = "||" OR FirstTwoChars = "&&" OR FirstWord = "and" OR FirstWord = "or" ) ;line is a implicit continuation String = %String%%Indent%%IndentContLine%%Line%`n Else If (FirstChar = ")" and InsideContinuation) { ;line is end of a continuation block Gosub, SetIndentOfLastBracket String := String . Indent . iif(Style=1,"",IndentSize) . Line . "`n" ;IndentIndex doesn't need to be reduced, this is done inside SetIndentOfLastBracket InsideContinuation := False } Else If InsideContinuation { ; line is inside a continuation block If AdjustContinuation String = %String%%Indent%%Line%`n Else String = %String%%Original_Line%`n } Else If (FirstChar = "(") { ;line is beginning of a continuation block String := String . Indent . iif(Style>1,IndentSize) . Line . "`n" MemorizeIndent("(",iif(Style=2,2,1),+1) AdjustContinuation := False If ( InStr(StripedLine, "LTrim") > 0 AND InStr(StripedLine, "RTrim0") = 0) AdjustContinuation := True InsideContinuation := True ;allow nested contīs } Else If LineIsTabSpecialIndentStart { ;line is a "Gui, Add, Tab" line String = %String%%Indent%%Line%`n MemorizeIndent("AddTab",1,+1) } Else If LineIsTabSpecialIndent { ;line is a "Gui, Tab, TabName" line Gosub, SetIndentOfLastAddTaborBracket String = %String%%Indent%%IndentSize%%Line%`n MemorizeIndent("Tab",1,+2) } Else If LineIsTabSpecialIndentEnd { ;line is a "Gui, Tab" line Gosub, SetIndentOfLastAddTaborBracket String = %String%%Indent%%Line%`n } Else If (FirstWordLastChar = ":") { ;line is start of subroutine or Hotkey If (InStr(FirstWord,"::") = 0) { ;line is start of a subroutine StringTrimRight, SubroutineName, Line, 1 If SubroutineName not in %CaseCorrectSubsList% CaseCorrectSubsList = %CaseCorrectSubsList%,%SubroutineName% } String = %String%%Line%`n MemorizeIndent("Sub",1,-1) } Else If (FirstChar = "}") { ;line is end bracket block If (FirstWord = "else"){ ;it uses OTB and must be a "}[ ]else [xxx] [{]" ;do the case correction StringReplace, Line, Line, else, Else Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All Gosub, SetIndentOfLastCurledBracket IndentIndex -- Gosub, SetIndentOfLastIfOrOneLineIf ;else line is also start of If-Statement If SecondWord in %ListOfIFCommands% ;Line is an old If-statement { StringReplace, Line, Line, if, If StringReplace, ParsedCommand, StripedLine, ```, ,,All ;Search if a third comma exists StringGetPos, ParsedCommand, ParsedCommand , `, ,L3 If ErrorLevel ;Line is an old If-statement MemorizeIndent("If",iif(Style=1,0,1),+1) }Else If (SecondWord = "if") { ;Line is a Normal if-statement StringReplace, Line, Line, if, If MemorizeIndent("If",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) }Else If (SecondWord = "loop"){ ;Line is the begining of a loop StringReplace, Line, Line, loop, Loop MemorizeIndent("Loop",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) }Else If SecondWord is Space ;just a plain Else { MemorizeIndent("Else",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) } ;if all the previous if didn't satisfy, ; the Line is an else with any command following, ; then nothing has to be done String = %String%%Indent%%Line%`n }Else { ;line is end bracket block without OTB Gosub, SetIndentOfLastCurledBracket String = %String%%Indent%%Line%`n IndentIndex -- } } Else If (FirstChar = "{") { ;line is start of bracket block ;check if line is start of a function implementation If ( IndentIndex = 1 AND FunctionName <> "" ) ;then add function name to list if not in it already If FunctionName not in %CaseCorrectFuncList% CaseCorrectFuncList = %CaseCorrectFuncList%,%FunctionName%( ;clear function name FunctionName = IndentIndex ++ IndentCommand%IndentIndex% = { IndentIncrement%IndentIndex% := iif(Style=3,0,1) ;check if command after { is if or loop If (FirstWord = "loop"){ ;line is start of Loop block after the { ;do the case correction StringReplace, Line, Line, loop, Loop Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All MemorizeIndent("Loop",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) ;assuming that there are no old one-line if-statements following a { }Else If FirstWord in %ListOfIFCommands% ;line is start of old If-Statement after the { { ;do the case correction StringReplace, Line, Line, if, If, 1 Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All MemorizeIndent("If",iif(Style=1,0,1),+1) }Else If (FirstWord = "if"){ ;line is start of If-Statement after the { ;do the case correction StringReplace, Line, Line, if, If, 1 Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All MemorizeIndent("If",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) } String = %String%%Indent%%Line%`n } Else If FirstWordIsFunction { ;line is function String = %String%%Line%`n MemorizeIndent("Func",1,-1) If (LastChar = "{") { ;it uses OTB If FunctionName not in %CaseCorrectFuncList% CaseCorrectFuncList = %CaseCorrectFuncList%,%FunctionName%( ;clear function name FunctionName = MemorizeIndent("{",iif(Style=3,0,1),+1) } } Else If (FirstWord = "loop") { ;line is start of Loop block ;do the case correction StringReplace, Line, Line, loop, Loop Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All PrevCommand := IndentCommand%IndentIndex% If (PrevCommand = "If"){ ;line is First line of a one-line If-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineIf",iif(Style=2,2,1)) }Else If (PrevCommand = "Else"){ ;Line is First line of a one-line Else-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineElse",iif(Style=2,2,1)) }Else If (PrevCommand = "Loop"){ ;Line is First line of a one-line loop-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineLoop",iif(Style=2,2,1)) }Else { ;it follows a Sub , { , OneLineCommand or nothing Gosub, SetIndentToLastSubBracketOrTab String = %String%%Indent%%Line%`n } MemorizeIndent("Loop",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) } Else If FirstWord in %ListOfIFCommands% ;line is start of old If-Statement { ;do the case correction StringReplace, Line, Line, if, If Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All PrevCommand := IndentCommand%IndentIndex% ;eliminate comments and escaped commas ParsedCommand := StripCommentsFromLine(Line) StringReplace, ParsedCommand, ParsedCommand, ```, ,,All ;Search if a third comma exists StringGetPos, ParsedCommand, ParsedCommand , `, ,L3 If ( ErrorLevel = 0 ){ ;Line is a old one-line If-statement If (PrevCommand = "If"){ ;Line is a one-line command of an If-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineIf",0) MemorizeIndent("OneLineCommand",0,+1) }Else If (PrevCommand = "Else"){ ;Line is a one-line command of an Else-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineElse",0) MemorizeIndent("OneLineCommand",0,+1) }Else If (PrevCommand = "Loop"){ ;Line is a one-line command of a loop-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineLoop",0) MemorizeIndent("OneLineCommand",0,+1) }Else { ;line is Normal one-line if-statement Gosub, SetIndentToLastSubBracketOrTab String = %String%%Indent%%Line%`n } }Else { ;Line is not an one-line if-statement If (PrevCommand = "If"){ ;Line is First line of an one-line If-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineIf",iif(Style=2,2,1)) } Else If (PrevCommand = "Else"){ ;Line is First line of a one-line Else-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineElse",iif(Style=2,2,1)) } Else If (PrevCommand = "Loop"){ ;Line is First line of a one-line loop-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineLoop",iif(Style=2,2,1)) } Else { ;it follows a Sub , { , OneLineCommand or nothing Gosub, SetIndentToLastSubBracketOrTab String = %String%%Indent%%Line%`n } MemorizeIndent("If",iif(Style=1,0,1),+1) } } Else If (FirstWord = "if"){ ;line is start of a Normal If-Statement ;do the case correction StringReplace, Line, Line, if, If Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All PrevCommand := IndentCommand%IndentIndex% If (PrevCommand = "If"){ ;Line is First line of a one-line If-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineIf",iif(Style=2,2,1)) } Else If (PrevCommand = "Else"){ ;Line is First line of a one-line Else-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineElse",iif(Style=2,2,1)) } Else If (PrevCommand = "Loop"){ ;Line is First line of a one-line loop-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineLoop",iif(Style=2,2,1)) } Else { ;it follows a Sub , { , OneLineCommand or nothing Gosub, SetIndentToLastSubBracketOrTab String = %String%%Indent%%Line%`n } MemorizeIndent("If",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) } Else If (FirstWord = "Else") { ;line is a Else block ;do the case correction StringReplace, Line, Line, else, Else Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All PrevCommand := IndentCommand%IndentIndex% If PrevCommand in OneLineCommand,Else Gosub, SetIndentOfLastIfOrOneLineIf ;else line is also start of If-Statement If SecondWord in %ListOfIFCommands% ;Line is an old If-statement { StringReplace, Line, Line, if, If StringReplace, ParsedCommand, StripedLine, ```, ,,All ;Search if a third comma exists StringGetPos, ParsedCommand, ParsedCommand , `, ,L3 If ErrorLevel { ;Line is an old one-line If-statement MemorizeIndent("If",1,+1) } }Else If (SecondWord = "if"){ ;Line is a Normal if-statement StringReplace, Line, Line, if, If MemorizeIndent("If",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) }Else If (Secondword = "loop"){ ;else is followed by a loop command ;do the case correction StringReplace, Line, Line, loop, Loop MemorizeIndent("Loop",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) }Else If SecondWord is Space ;just a plain Else { MemorizeIndent("Else",iif(Style=1,0,1),+1) If (LastChar = "{") ;it uses OTB MemorizeIndent("{",iif(Style=3,0,1),+1) } ;if all the previous if didn't satisfy, ; the Line is an else with any command following, ; then nothing has to be done String = %String%%Indent%%Line%`n } Else { ;line is a Normal command or Return ;do the case correction Loop, Parse, CaseCorrectionSyntax, `, StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All PrevCommand := IndentCommand%IndentIndex% If (PrevCommand = "If"){ ;Line is a one-line command of an If-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineIf",0) MemorizeIndent("OneLineCommand",0,+1) }Else If (PrevCommand = "Else"){ ;Line is a one-line command of an Else-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineElse",0) MemorizeIndent("OneLineCommand",0,+1) }Else If (PrevCommand = "Loop"){ ;Line is a one-line command of a loop-block String := String . Indent . iif(Style<>3,IndentSize) . Line . "`n" MemorizeIndent("OneLineLoop",0) MemorizeIndent("OneLineCommand",0,+1) }Else If (PrevCommand = "Func"){ ;Line follows a function call ??? is this ever True? String = %String%%Line%`n IndentIndex = 0 }Else { ;line is Normal command or Return Gosub, SetIndentToLastSubBracketOrTab PrevCommand := IndentCommand%IndentIndex% ;if command is end of subroutine (return) no indentation, otherwise keep indentation If (FirstWord = "Return" AND PrevCommand = "Sub") { String = %String%%Line%`n IndentIndex = 0 }Else ;String := String . Indent . iif(Style=2,IndentSize) . Line . "`n" String = %String%%Indent%%Line%`n } } Gosub, FinishThisLine Return FinishThisLine: ;###### End of change in indentation ########## ;turn AutoTrim on, to get back to default behaviour AutoTrim, On ;Show MsgBox for debug If DebugMode Gosub, ShowDebugStrings ;get Indentation for next loop Gosub, SetIndentForNextLoop Return ;############# Show MsgBox for debug ###################################### ShowDebugStrings: msgtext = line#: %TotalLineCount%`n msgtext = %msgtext%Style: %Style%`n msgtext = %msgtext%line: %Line%`n msgtext = %msgtext%stripped line: %CommandLine%`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%3rd Word: >%ThirdWord%<`n msgtext = %msgtext%1st WordLastChar: >%FirstWordLastChar%<`n msgtext = %msgtext%FunctionName: >%FunctionName%<`n`n msgtext = %msgtext%IndentIndex: %IndentIndex%`n ;msgtext = %msgtext%LineIsTabSpecialIndentStart: %LineIsTabSpecialIndentStart%`n ;msgtext = %msgtext%LineIsTabSpecialIndent: %LineIsTabSpecialIndent%`n ;msgtext = %msgtext%LineIsTabSpecialIndentEnd: %LineIsTabSpecialIndentEnd%`n`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 ;msgtext = %msgtext%`nBuildInFunctions: %BuildInFunctions%`n ;msgtext = %msgtext%`nCaseCorrectFuncList: %CaseCorrectFuncList%`n MsgBox %msgtext%`n%String% Return ;############# Set the IndentIndex to to last if or onelineif ############## SetIndentOfLastIfOrOneLineIf: ;loop inverse through command array Loop, %IndentIndex% { InverseIndex := IndentIndex - A_Index + 2 ;if command is if or onelineif, exit loop and remember the previous Index If IndentCommand%InverseIndex% in If,OneLineIf { IndentIndex := InverseIndex - 1 Break } } ;set indentation for that index Gosub, SetIndentForNextLoop Return ;############# Set the IndentIndex to to last curled bracket ############## SetIndentOfLastCurledBracket: ;loop inverse through command array Loop, %IndentIndex% { InverseIndex := IndentIndex - A_Index + 1 ;if command is bracket, exit loop and remember the previous Index If (IndentCommand%InverseIndex% = "{") { IndentIndex := InverseIndex - 1 Break } } ;set indentation for that index Gosub, SetIndentForNextLoop Return ;############# Set the IndentIndex to to last bracket ##################### SetIndentOfLastBracket: ;loop inverse through command array Loop, %IndentIndex% { InverseIndex := IndentIndex - A_Index + 1 ;if command is bracket, exit loop and remember the previous Index If (IndentCommand%InverseIndex% = "(") { IndentIndex := InverseIndex - 1 Break } } ;set indentation for that index Gosub, SetIndentForNextLoop Return ;############# Set the IndentIndex to the last addtab ###################### SetIndentOfLastAddTaborBracket: ;loop inverse through command array Loop, %IndentIndex% { InverseIndex := IndentIndex - A_Index + 1 ;if command is AddTab, exit loop and remember the previous Index If IndentCommand%InverseIndex% in {,AddTab { IndentIndex := InverseIndex - 1 Break } } ;set indentation for that index Gosub, SetIndentForNextLoop Return ;############# Set the IndenIndex to to last Sub or bracket ############### SetIndentToLastSubBracketOrTab: FoundItem:=False ;loop inverse through command array Loop, %IndentIndex% { InverseIndex := IndentIndex - A_Index + 1 ;if command is sub or bracket, exit loop and remember the Index If IndentCommand%InverseIndex% in {,Sub { IndentIndex := InverseIndex FoundItem:=True Break }Else If ChkSpecialTabIndent If IndentCommand%InverseIndex% in AddTab,Tab { IndentIndex := InverseIndex FoundItem:=True Break } } ;if not found set index to zero If ! FoundItem IndentIndex = 0 ;set indentation for that index Gosub, SetIndentForNextLoop Return ;############# Extract Function Names ##################################### ExtractFunctionName(FirstWord,BracketPosition, ByRef FunctionName) { ;get function name without braket StringLeft, FunctionName, FirstWord, % BracketPosition - 1 If (FunctionName = "If") ;it is a If statement "If(", empty FunctionName and function will Return 0 FunctionName = ;check each char in name if it is allowed Loop, Parse, FunctionName If ( A_LoopField <> "_" ) If A_LoopField is not Alnum { FunctionName = Break } Return StrLen(FunctionName) } ;############# Do CaseCorrection for Functions and Subroutines ############ CaseCorrectSubsAndFuncNames() { global LenString := StrLen(String) ;remove first comma StringTrimLeft, CaseCorrectFuncList, CaseCorrectFuncList, 1 StringTrimLeft, CaseCorrectSubsList, CaseCorrectSubsList, 1 ;loop over all remembered function names Loop, Parse, CaseCorrectFuncList, CSV { FuncName := A_LoopField LenFuncName := StrLen(FuncName) ;Loop through string to find all occurances of function names StartPos = 0 Loop { StartPos := InStr(String,FuncName,0,StartPos + 1) If (StartPos > 0) { StringMid,PrevChar, String, StartPos - 1 , 1 If PrevChar is not Alnum ReplaceName( String, FuncName, StartPos-1, LenString - StartPos + 1 - LenFuncName ) } Else Break } } ;loop over all remembered subroutine names Loop, Parse, CaseCorrectSubsList, CSV { SubName := A_LoopField LenSubName := StrLen(SubName) ;Loop through string to find all occurances of function names StartPos = 0 Loop { StartPos := InStr(String,SubName,"",StartPos + 1) If (StartPos > 0) { StringMid,PrevChar, String, StartPos - 1 , 1 StringMid,NextChar, String, StartPos + LenSubName, 1 ;if it is an exact match the char after the subroutine names has not to be a char If NextChar is not Alnum { ;If previous character is a "g" and has TestStrings in same line replace the name. If ( PrevChar = "g" ) { TestAndReplaceSubName( String, SubName, "Gui,", LenString, LenSubName, StartPos) TestAndReplaceSubName( String, SubName, "Gui ", LenString, LenSubName, StartPos) ;If previous character is something else then Alnum and has TestStrings in same line replace the name. }Else If PrevChar is not Alnum { TestAndReplaceSubName( String, SubName, "Gosub" , LenString, LenSubName, StartPos ) TestAndReplaceSubName( String, SubName, "Menu" , LenString, LenSubName, StartPos ) TestAndReplaceSubName( String, SubName, "`:`:" , LenString, LenSubName, StartPos ) TestAndReplaceSubName( String, SubName, "Hotkey", LenString, LenSubName, StartPos ) } } } Else Break } } } TestAndReplaceSubName( ByRef string, Name, TestString, LenString, LenSubName, StartPos ) { ;find Positions of Teststring and LineFeed in String from the right side starting at routine position StringGetPos, PosTestString, String, %TestString%, R , LenString - StartPos + 1 StringGetPos, PosLineFeed , String, `n , R , LenString - StartPos + 1 ;If %TestString% is in the same line do replace name If ( PosLineFeed < PosTestString ) ReplaceName( String, Name, StartPos - 1, LenString - StartPos + 1 - LenSubName ) } ReplaceName( ByRef String, Name, PosLeft, PosRight ) { ;split String up into left and right StringLeft, StrLeft, String, PosLeft StringRight, StrRight, String, PosRight ;insert Name into it again String = %StrLeft%%Name%%StrRight% } ;############# If Gui closes exit all ##################################### GuiClose: ;store current position and settings and exit app Gui, Show WinGetPos, PosX, PosY, SizeW, SizeH, %ScriptName% Gui, Submit IniWrite, x%PosX% y%PosY%, %IniFile%, General, Pos_Gui IniWrite, %Extension%, %IniFile%, Settings, Extension IniWrite, %Indentation%, %IniFile%, Settings, Indentation IniWrite, %NumberSpaces%, %IniFile%, Settings, NumberSpaces IniWrite, %NumberIndentCont%, %IniFile%, Settings, NumberIndentCont IniWrite, %IndentCont%, %IniFile%, Settings, IndentCont IniWrite, %Style%, %IniFile%, Settings, Style IniWrite, %CaseCorrectCommands%, %IniFile%, Settings, CaseCorrectCommands IniWrite, %CaseCorrectVariables%, %IniFile%, Settings, CaseCorrectVariables IniWrite, %CaseCorrectBuildInFunctions%, %IniFile%, Settings, CaseCorrectBuildInFunctions IniWrite, %CaseCorrectKeys%, %IniFile%, Settings, CaseCorrectKeys IniWrite, %CaseCorrectKeywords%, %IniFile%, Settings, CaseCorrectKeywords IniWrite, %CaseCorrectDirectives%, %IniFile%, Settings, CaseCorrectDirectives IniWrite, %Statistic%, %IniFile%, Settings, Statistic IniWrite, %ChkSpecialTabIndent%, %IniFile%, Settings, ChkSpecialTabIndent IniWrite, %KeepBlockCommentIndent%, %IniFile%, Settings, KeepBlockCommentIndent IniWrite, %AHKPath%, %IniFile%, Settings, AHKPath IniWrite, %OwnHotkey%, %IniFile%, Settings, OwnHotkey ExitApp: ExitApp Return ;############# End of File #################################################