mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-16 07:21:38 +02:00
codetools: complete block: use first atom for inner indent
git-svn-id: trunk@20280 -
This commit is contained in:
parent
9938f293e5
commit
178f494111
@ -49,7 +49,7 @@ begin
|
|||||||
writeln('Usage: '+ParamStrUTF8(0)+' filename line column define1 define2');
|
writeln('Usage: '+ParamStrUTF8(0)+' filename line column define1 define2');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
Filename:=ParamStrUTF8(1);
|
Filename:=ExpandFileNameUTF8(ParamStrUTF8(1));
|
||||||
Y:=StrToInt(ParamStrUTF8(2));
|
Y:=StrToInt(ParamStrUTF8(2));
|
||||||
X:=StrToInt(ParamStrUTF8(3));
|
X:=StrToInt(ParamStrUTF8(3));
|
||||||
for p:=4 to Paramcount do
|
for p:=4 to Paramcount do
|
||||||
|
@ -5163,6 +5163,7 @@ type
|
|||||||
TBlock = record
|
TBlock = record
|
||||||
Typ: TBlockType;
|
Typ: TBlockType;
|
||||||
StartPos: integer;
|
StartPos: integer;
|
||||||
|
InnerIndent: integer;
|
||||||
end;
|
end;
|
||||||
PBlock = ^TBlock;
|
PBlock = ^TBlock;
|
||||||
TBlockStack = record
|
TBlockStack = record
|
||||||
@ -5206,6 +5207,7 @@ var
|
|||||||
Block:=@Stack.Stack[Stack.Top];
|
Block:=@Stack.Stack[Stack.Top];
|
||||||
Block^.Typ:=Typ;
|
Block^.Typ:=Typ;
|
||||||
Block^.StartPos:=StartPos;
|
Block^.StartPos:=StartPos;
|
||||||
|
Block^.InnerIndent:=-1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure EndBlock(var Stack: TBlockStack);
|
procedure EndBlock(var Stack: TBlockStack);
|
||||||
@ -5226,22 +5228,44 @@ var
|
|||||||
|
|
||||||
function Replace(NewCode: string; FromPos, ToPos, Indent: integer;
|
function Replace(NewCode: string; FromPos, ToPos, Indent: integer;
|
||||||
FrontGap, AfterGap: TGapTyp; BeautifyFlags: TBeautifyCodeFlags): boolean;
|
FrontGap, AfterGap: TGapTyp; BeautifyFlags: TBeautifyCodeFlags): boolean;
|
||||||
|
var
|
||||||
|
p: LongInt;
|
||||||
begin
|
begin
|
||||||
if NewCode='' then exit(true);
|
if NewCode='' then exit(true);
|
||||||
|
// avoid changing current line
|
||||||
|
if (FrontGap=gtEmptyLine) then begin
|
||||||
|
p:=FromPos;
|
||||||
|
while (p>1) and (Src[p-1] in [' ',#9]) do dec(p);
|
||||||
|
if (p=1) or (Src[p] in [#10,#13]) then begin
|
||||||
|
while (p<=SrcLen) and (Src[p] in [' ',#9]) do inc(p);
|
||||||
|
if (p>SrcLen) or (Src[p] in [#10,#13]) then begin
|
||||||
|
// inserting at an empty line
|
||||||
|
inc(p);
|
||||||
|
if (p<=SrcLen) and (Src[p] in [#10,#13]) and (Src[p]<>Src[p-1]) then
|
||||||
|
inc(p);
|
||||||
|
FrontGap:=gtNewLine;
|
||||||
|
FromPos:=p;
|
||||||
|
if ToPos<FromPos then ToPos:=FromPos;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
// use existing semicolon
|
||||||
while (ToPos<=SrcLen) and (Src[ToPos] in [' ',#9]) do inc(ToPos);
|
while (ToPos<=SrcLen) and (Src[ToPos] in [' ',#9]) do inc(ToPos);
|
||||||
if (NewCode[length(NewCode)]=';')
|
if (NewCode[length(NewCode)]=';')
|
||||||
and (ToPos<=SrcLen) and (Src[ToPos]=';') then begin
|
and (ToPos<=SrcLen) and (Src[ToPos]=';') then begin
|
||||||
AfterGap:=gtNone;
|
AfterGap:=gtNone;
|
||||||
inc(ToPos);
|
inc(ToPos);
|
||||||
end;
|
end;
|
||||||
|
// beautify
|
||||||
NewCode:=SourceChangeCache.BeautifyCodeOptions.BeautifyStatement(
|
NewCode:=SourceChangeCache.BeautifyCodeOptions.BeautifyStatement(
|
||||||
NewCode,Indent,BeautifyFlags);
|
NewCode,Indent,BeautifyFlags);
|
||||||
|
// insert
|
||||||
if not SourceChangeCache.Replace(FrontGap,AfterGap,
|
if not SourceChangeCache.Replace(FrontGap,AfterGap,
|
||||||
FromPos,ToPos,NewCode) then exit;
|
FromPos,ToPos,NewCode) then exit;
|
||||||
if not SourceChangeCache.Apply then exit;
|
if not SourceChangeCache.Apply then exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ReadStatements(var Stack: TBlockStack): Boolean;
|
function CompleteStatements(var Stack: TBlockStack): Boolean;
|
||||||
var
|
var
|
||||||
CursorBlockLvl: Integer; // the stack level of the cursor
|
CursorBlockLvl: Integer; // the stack level of the cursor
|
||||||
LastPos: Integer;
|
LastPos: Integer;
|
||||||
@ -5282,6 +5306,12 @@ var
|
|||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
|
|
||||||
//DebugLn(['ReadStatements Atom=',GetAtom,' TopTyp=',ord(TopBlockType(Stack)),' Top=',Stack.Top]);
|
//DebugLn(['ReadStatements Atom=',GetAtom,' TopTyp=',ord(TopBlockType(Stack)),' Top=',Stack.Top]);
|
||||||
|
if (Stack.Top>=0) and (Stack.Stack[Stack.Top].InnerIndent<0)
|
||||||
|
and (PositionsInSameLine(Src,Stack.Stack[Stack.Top].StartPos,CurPos.StartPos))
|
||||||
|
then begin
|
||||||
|
// the first atom of this block on a new line
|
||||||
|
Stack.Stack[Stack.Top].InnerIndent:=GetLineIndent(Src,CurPos.StartPos);
|
||||||
|
end;
|
||||||
|
|
||||||
// check if cursor reached
|
// check if cursor reached
|
||||||
if (CurPos.StartPos>=CleanCursorPos) and (CursorBlockLvl<0) then begin
|
if (CurPos.StartPos>=CleanCursorPos) and (CursorBlockLvl<0) then begin
|
||||||
@ -5293,7 +5323,7 @@ var
|
|||||||
end else begin
|
end else begin
|
||||||
CursorBlock:=Stack.Stack[CursorBlockLvl];
|
CursorBlock:=Stack.Stack[CursorBlockLvl];
|
||||||
CursorBlockOuterIndent:=GetLineIndent(Src,CursorBlock.StartPos);
|
CursorBlockOuterIndent:=GetLineIndent(Src,CursorBlock.StartPos);
|
||||||
CursorBlockInnerIndent:=GetLineIndent(Src,CurPos.StartPos);
|
CursorBlockInnerIndent:=Stack.Stack[Stack.Top].InnerIndent;
|
||||||
end;
|
end;
|
||||||
//DebugLn(['ReadStatements CursorBlockLvl=',CursorBlockLvl,' Indent=',CursorBlockIndent]);
|
//DebugLn(['ReadStatements CursorBlockLvl=',CursorBlockLvl,' Indent=',CursorBlockIndent]);
|
||||||
end;
|
end;
|
||||||
@ -5421,7 +5451,10 @@ var
|
|||||||
end else if UpAtomIs('ASM') then begin
|
end else if UpAtomIs('ASM') then begin
|
||||||
BeginBlock(Stack,btAsm,CurPos.StartPos);
|
BeginBlock(Stack,btAsm,CurPos.StartPos);
|
||||||
end else if UpAtomIs('IF') then begin
|
end else if UpAtomIs('IF') then begin
|
||||||
BeginBlock(Stack,btIf,CurPos.StartPos)
|
BeginBlock(Stack,btIf,CurPos.StartPos);
|
||||||
|
end else if UpAtomIs('THEN') then begin
|
||||||
|
if TopBlockType(Stack)=btIf then
|
||||||
|
Stack.Stack[Stack.Top].InnerIndent:=-1;
|
||||||
end else if UpAtomIs('CASE') then begin
|
end else if UpAtomIs('CASE') then begin
|
||||||
BeginBlock(Stack,btCase,CurPos.StartPos)
|
BeginBlock(Stack,btCase,CurPos.StartPos)
|
||||||
end else if UpAtomIs('OF') then begin
|
end else if UpAtomIs('OF') then begin
|
||||||
@ -5491,9 +5524,9 @@ var
|
|||||||
|
|
||||||
if NeedCompletion then begin
|
if NeedCompletion then begin
|
||||||
InsertPos:=CleanCursorPos;
|
InsertPos:=CleanCursorPos;
|
||||||
Indent:=CursorBlockInnerIndent;
|
Indent:=CursorBlockOuterIndent;
|
||||||
NewCode:='';
|
NewCode:='';
|
||||||
FrontGap:=gtNewLine;
|
FrontGap:=gtEmptyLine;
|
||||||
AfterGap:=gtNewLine;
|
AfterGap:=gtNewLine;
|
||||||
BeautifyFlags:=[bcfIndentExistingLineBreaks];
|
BeautifyFlags:=[bcfIndentExistingLineBreaks];
|
||||||
case CursorBlock.Typ of
|
case CursorBlock.Typ of
|
||||||
@ -5514,13 +5547,15 @@ var
|
|||||||
else
|
else
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
if (CursorBlockLvl=0) and (AfterGap=gtNewLine) then
|
||||||
|
AfterGap:=gtEmptyLine;
|
||||||
if not Replace(NewCode,InsertPos,InsertPos,Indent,FrontGap,AfterGap,
|
if not Replace(NewCode,InsertPos,InsertPos,Indent,FrontGap,AfterGap,
|
||||||
BeautifyFlags) then exit;
|
BeautifyFlags) then exit;
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ReadClassSection(var Stack: TBlockStack): Boolean;
|
function CompleteClassSection(var Stack: TBlockStack): Boolean;
|
||||||
{ type
|
{ type
|
||||||
TMyClass = class
|
TMyClass = class
|
||||||
|
|
|
|
||||||
@ -5553,7 +5588,7 @@ var
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ReadClassInterface(var Stack: TBlockStack): Boolean;
|
function CompleteClassInterface(var Stack: TBlockStack): Boolean;
|
||||||
{ type
|
{ type
|
||||||
TMyClass = interface
|
TMyClass = interface
|
||||||
|
|
|
|
||||||
@ -5585,7 +5620,7 @@ var
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ReadRecord(var Stack: TBlockStack): Boolean;
|
function CompleteRecord(var Stack: TBlockStack): Boolean;
|
||||||
{ type
|
{ type
|
||||||
TMyClass = record
|
TMyClass = record
|
||||||
|
|
|
|
||||||
@ -5634,16 +5669,16 @@ begin
|
|||||||
if (StartNode.Parent<>nil)
|
if (StartNode.Parent<>nil)
|
||||||
and (StartNode.Parent.Desc in AllPascalStatements) then
|
and (StartNode.Parent.Desc in AllPascalStatements) then
|
||||||
StartNode:=StartNode.Parent;
|
StartNode:=StartNode.Parent;
|
||||||
if not ReadStatements(Stack) then exit;
|
if not CompleteStatements(Stack) then exit;
|
||||||
end;
|
end;
|
||||||
if StartNode.Desc in AllClassSections then begin
|
if StartNode.Desc in AllClassSections then begin
|
||||||
if not ReadClassSection(Stack) then exit;
|
if not CompleteClassSection(Stack) then exit;
|
||||||
end;
|
end;
|
||||||
if StartNode.Desc=ctnClassInterface then begin
|
if StartNode.Desc=ctnClassInterface then begin
|
||||||
if not ReadClassInterface(Stack) then exit;
|
if not CompleteClassInterface(Stack) then exit;
|
||||||
end;
|
end;
|
||||||
if StartNode.Desc=ctnRecordType then begin
|
if StartNode.Desc=ctnRecordType then begin
|
||||||
if not ReadRecord(Stack) then exit;
|
if not CompleteRecord(Stack) then exit;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
FreeStack(Stack);
|
FreeStack(Stack);
|
||||||
|
Loading…
Reference in New Issue
Block a user