diff --git a/components/codetools/basiccodetools.pas b/components/codetools/basiccodetools.pas index 30ade32f80..6d01296159 100644 --- a/components/codetools/basiccodetools.pas +++ b/components/codetools/basiccodetools.pas @@ -69,6 +69,8 @@ function FindMainUnitHint(const ASource: string; out Filename: string): boolean; procedure GetLineStartEndAtPosition(const Source:string; Position:integer; var LineStart,LineEnd:integer); function GetLineIndent(const Source: string; Position: integer): integer; +function GetLineIndentWithTabs(const Source: string; Position: integer; + TabWidth: integer): integer; function GetPosInLine(const Source: string; Position: integer): integer; function GetBlockMinIndent(const Source: string; StartPos, EndPos: integer): integer; @@ -2248,10 +2250,8 @@ begin if (LineStart<0) then LineStart:=1; if (LineStart>length(Source)+1) then LineStart:=length(Source)+1; // search beginning of line - repeat + while (LineStart>1) and not (Source[LineStart-1] in [#10,#13]) do dec(LineStart); - until (LineStart<1) or (Source[LineStart] in [#10,#13]); - inc(LineStart); // search code Result:=LineStart; while (Result<=length(Source)) and (Source[Result]=' ') do inc(Result); @@ -3724,6 +3724,34 @@ begin until false; end; +function GetLineIndentWithTabs(const Source: string; Position: integer; + TabWidth: integer): integer; +var p: integer; +begin + Result:=0; + p:=Position; + if p=0 then exit; + if (p<0) then p:=1; + if (p>length(Source)+1) then p:=length(Source)+1; + // search beginning of line + while (p>1) and not (Source[p-1] in [#10,#13]) do + dec(p); + // search code + Result:=0; + while (p<=length(Source)) do begin + case Source[p] of + ' ': inc(Result); + #9: + begin + Result:=Result+TabWidth; + Result:=Result-(Result mod TabWidth); + end; + else break; + end; + inc(p); + end; +end; + function GetPosInLine(const Source: string; Position: integer): integer; begin Result:=0; diff --git a/components/codetools/codebeautifier.pas b/components/codetools/codebeautifier.pas index 06e654d954..33c1cbbb55 100644 --- a/components/codetools/codebeautifier.pas +++ b/components/codetools/codebeautifier.pas @@ -124,10 +124,8 @@ type out CodeBuffers: TFPList) of object; TFABIndentationPolicy = record - IndentBefore: integer; - IndentBeforeValid: boolean; - IndentAfter: integer; - IndentAfterValid: boolean; + Indent: integer; + IndentValid: boolean; end; { TFABPolicies } @@ -150,6 +148,7 @@ type NestedComments: boolean; Policies: TFABPolicies); procedure FindPolicies(Types: TFABBlockTypes; Policies: TFABPolicies); public + DefaultTabWidth: integer; constructor Create; destructor Destroy; override; procedure Clear; @@ -344,23 +343,10 @@ var end; procedure EndBlock; - var - Block: PBlock; begin {$IFDEF ShowCodeBeautifierParser} DebugLn([GetIndentStr(Stack.Top*2),'EndBlock ',FABBlockTypeNames[Stack.TopType],' ',GetAtomString(@Src[AtomStart],NestedComments),' at ',PosToStr(p)]); {$ENDIF} - Block:=@Stack.Stack[Stack.Top]; - if (Policies<>nil) - and (not Policies.Indentations[Block^.Typ].IndentBeforeValid) then begin - with Policies.Indentations[Block^.Typ] do begin - IndentBefore:=-IndentAfter; - IndentBeforeValid:=IndentAfterValid; - {$IFDEF ShowCodeBeautifierParser} - DebugLn([GetIndentStr(Stack.Top*2),'Indentation learned: ',FABBlockTypeNames[Block^.Typ],' IndentBefore=',IndentBefore]); - {$ENDIF} - end; - end; Stack.EndBlock; end; @@ -438,19 +424,22 @@ begin if (Stack.Top>=0) then begin Block:=@Stack.Stack[Stack.Top]; if (Policies<>nil) - and (not Policies.Indentations[Block^.Typ].IndentAfterValid) then begin + and (not Policies.Indentations[Block^.Typ].IndentValid) then begin // set block InnerIdent if (Block^.InnerIdent<0) and (not PositionsInSameLine(Src,Block^.StartPos,AtomStart)) then begin - Block^.InnerIdent:=GetLineIndent(Src,AtomStart); + Block^.InnerIdent:=GetLineIndentWithTabs(Src,AtomStart,DefaultTabWidth); if Block^.Typ in [bbtIfThen,bbtIfElse] then - Indent:=Block^.InnerIdent-GetLineIndent(Src,Stack.Stack[Stack.Top-1].StartPos) + Indent:=Block^.InnerIdent + -GetLineIndentWithTabs(Src,Stack.Stack[Stack.Top-1].StartPos, + DefaultTabWidth) else - Indent:=Block^.InnerIdent-GetLineIndent(Src,Block^.StartPos); - Policies.Indentations[Block^.Typ].IndentAfter:=Indent; - Policies.Indentations[Block^.Typ].IndentAfterValid:=true; + Indent:=Block^.InnerIdent + -GetLineIndentWithTabs(Src,Block^.StartPos,DefaultTabWidth); + Policies.Indentations[Block^.Typ].Indent:=Indent; + Policies.Indentations[Block^.Typ].IndentValid:=true; {$IFDEF ShowCodeBeautifierParser} - DebugLn([GetIndentStr(Stack.Top*2),'Indentation learned: ',FABBlockTypeNames[Block^.Typ],' IndentAfter=',Policies.Indentations[Block^.Typ].IndentAfter]); + DebugLn([GetIndentStr(Stack.Top*2),'Indentation learned: ',FABBlockTypeNames[Block^.Typ],' Indent=',Policies.Indentations[Block^.Typ].Indent]); {$ENDIF} end; end; @@ -736,7 +725,7 @@ end; constructor TFullyAutomaticBeautifier.Create; begin - + DefaultTabWidth:=4; end; destructor TFullyAutomaticBeautifier.Destroy; diff --git a/components/codetools/examples/autoindent.pas b/components/codetools/examples/autoindent.pas index dacb3b1af1..1dcd426134 100644 --- a/components/codetools/examples/autoindent.pas +++ b/components/codetools/examples/autoindent.pas @@ -51,7 +51,7 @@ begin end else begin Filename:=ExpandFileNameUTF8('scanexamples/indentation.pas'); X:=3; - Y:=73; + Y:=74; end; // load the example unit @@ -67,8 +67,7 @@ begin exit; end; if FAB.GetIndent(Code.Source,p,true,Indentation) then begin - writeln('IndentAfter=',Indentation.IndentAfter); - writeln('IndentBefore=',Indentation.IndentBefore); + writeln('Indent=',Indentation.Indent); end else begin writeln('Error: GetIndent failed'); end;