codetools: indentations: considering tabs

git-svn-id: trunk@20297 -
This commit is contained in:
mattias 2009-05-29 10:40:52 +00:00
parent bb721d48bf
commit 8ac8d4e9f9
3 changed files with 47 additions and 31 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;