IDE: fix Invert assignment's extra linefeed. Issue #20571

git-svn-id: trunk@33105 -
This commit is contained in:
juha 2011-10-26 21:13:59 +00:00
parent e71ce3c870
commit b73ac7c339
2 changed files with 61 additions and 98 deletions

View File

@ -19,7 +19,7 @@
*************************************************************************** ***************************************************************************
Author: Sérgio Marcelo S. Gomes <smace at smace.com.br> Author: Sérgio Marcelo S. Gomes <smace at smace.com.br>
Modified by Andrew Haines Modified by Andrew Haines and Juha Manninen
Abstract: Invert Assignment Code. Abstract: Invert Assignment Code.
@ -36,7 +36,7 @@ interface
uses uses
Classes, SysUtils; Classes, SysUtils;
function InvertAssignment(ALines:TStrings):TStrings; function InvertAssignment(InText: string): string;
implementation implementation
@ -48,48 +48,29 @@ end;
procedure DivideLines(Lines: TStrings; var PreList, AList, BList, PostList: TStrings); procedure DivideLines(Lines: TStrings; var PreList, AList, BList, PostList: TStrings);
var var
X: Integer; ALine, TrueFalse: String;
ALine: String; X, I, EqPos, SemiPos, WordBeforeEqPos: Integer;
EqPos: Integer;
SemiPos: Integer;
WordBeforeEqPos: Integer;
TrueFalse: String;
function FindWordBeforeEquals(ALine: String): Integer;
var
X: Integer;
fPos: Integer;
begin
Result := 0;
fPos := Pos(':=', ALine);
if fPos > 0 then begin
ALine := Trim(Copy(ALine,1,fPos-1));
for X := Length(ALine) downto 1 do begin
if ALine[X] = ' ' then begin
Result := X+1;
Exit;
end;
end;
end;
end;
begin begin
AList.Clear;
BList.Clear;
for X := 0 to Lines.Count-1 do begin for X := 0 to Lines.Count-1 do begin
ALine := Trim(Lines.Strings[X]); ALine := Trim(Lines[X]);
EqPos := Pos(':=', ALine); EqPos := Pos(':=', ALine);
SemiPos := Pos(';', ALine); if EqPos > 0 then begin
WordBeforeEqPos := FindWordBeforeEquals(ALine); SemiPos := Pos(';', ALine);
if SemiPos = 0 then
if (EqPos > 0) and (SemiPos > 0) then begin SemiPos:=Length(ALine)+1;
WordBeforeEqPos := 0;
I := EqPos-1;
while (I > 0) and (ALine[I] = ' ') do // Skip initial spaces
Dec(I);
while (I > 0) and (ALine[I] <> ' ') do // The word before :=
Dec(I);
WordBeforeEqPos := I+1;
Alist.Add(Trim(Copy(ALine, WordBeforeEqPos+Ord(WordBeforeEqPos=0), EqPos - (WordBeforeEqPos+Ord(WordBeforeEqPos=0))))); Alist.Add(Trim(Copy(ALine, WordBeforeEqPos+Ord(WordBeforeEqPos=0), EqPos - (WordBeforeEqPos+Ord(WordBeforeEqPos=0)))));
BList.Add(Trim(Copy(ALine, EqPos + 2, (SemiPos-1) -(EqPos+1)))); BList.Add(Trim(Copy(ALine, EqPos + 2, (SemiPos-1) -(EqPos+1))));
PreList.Add(Trim(Copy(ALine,1, WordBeforeEqPos-1))); PreList.Add(Trim(Copy(ALine,1, WordBeforeEqPos-1)));
PostList.Add(Trim(Copy(ALine, SemiPos, Length(ALine)-(SemiPos-1)))); PostList.Add(Trim(Copy(ALine, SemiPos, Length(ALine)-(SemiPos-1))));
if Length(PreList.Strings[X]) > 0 then if Length(PreList[X]) > 0 then
PreList.Strings[X] := PreList.Strings[X] + ' '; PreList[X] := PreList[X] + ' ';
end end
else begin // not a valid line else begin // not a valid line
PreList.Add(''); PreList.Add('');
@ -98,15 +79,15 @@ begin
PostList.Add(''); PostList.Add('');
end; end;
// Check if is being assigned true or false // Check if is being assigned true or false
if CompareText(BList.Strings[X], 'True') = 0 then begin if CompareText(BList[X], 'True') = 0 then begin
TrueFalse := AList.Strings[X]; TrueFalse := AList[X];
AList.Strings[X] := 'False'; AList[X] := 'False';
BList.Strings[X] := TrueFalse; BList[X] := TrueFalse;
end; end;
if CompareText(BList.Strings[X], 'False') = 0 then begin if CompareText(BList[X], 'False') = 0 then begin
TrueFalse := AList.Strings[X]; TrueFalse := AList[X];
AList.Strings[X] := 'True'; AList[X] := 'True';
BList.Strings[X] := TrueFalse; BList[X] := TrueFalse;
end; end;
end; end;
end; end;
@ -165,74 +146,64 @@ end;
// This function inverts all Assignments operation. // This function inverts all Assignments operation.
// like valuea := valueb; to valueb := valuea; // like valuea := valueb; to valueb := valuea;
// or valuea := False; to valuea := True; // or valuea := False; to valuea := True;
function InvertAssignment(ALines:TStrings):TStrings; function InvertAssignment(InText: string): string;
var var
Lines: TStringList; InLines, TempLines: TStringList;
PreList, PreList, AList, BList, PostList: TStrings;
AList,
BList,
PostList: TStrings;
Indents: PInteger;
X, Y: Integer;
EqPos: Integer;
ALine: String; ALine: String;
Indents: array of integer;
X, Y, EqPos: Integer;
HasLinefeed: Boolean;
begin begin
if ALines.Count = 0 then begin if InText = '' then
Result := ALines;
Exit; Exit;
end; HasLinefeed := InText[Length(InText)] in [#10,#13];
InLines := TStringList.Create;
InLines.Text := InText;
SetLength(Indents, InLines.Count);
TempLines := TStringList.Create;
Lines := TStringList.Create; // Join many lines to one
GetMem(Indents,SizeOf(Integer)*ALines.Count);
// Put a line on multiple lines, on one line
ALine := ''; ALine := '';
for X := 0 to ALines.Count-1 do begin for X := 0 to InLines.Count-1 do begin
ALine := ALine + ALines.Strings[X]; ALine := ALine + InLines[X];
if IsAWholeLine(ALine) then begin if IsAWholeLine(ALine) then begin
Indents[Lines.Add(ALine)] := GetIndent(ALine); Indents[TempLines.Add(ALine)] := GetIndent(ALine);
ALine := ''; ALine := '';
end; end;
end; end;
if Length(ALine) > 0 then
Indents[TempLines.Add(ALine)] := GetIndent(ALine);
// exited the loop without finding the end of a line InLines.Clear;
if Length(ALine) > 0 then begin
X := Lines.Add(ALine);
Indents[X] := GetIndent(ALine);
end;
ALines.Clear;
PreList := TStringList.Create; PreList := TStringList.Create;
AList := TStringList.Create; AList := TStringList.Create;
BList := TStringList.Create; BList := TStringList.Create;
PostList := TStringList.Create; PostList := TStringList.Create;
DivideLines(Lines, PreList, AList, BList, PostList); DivideLines(TempLines, PreList, AList, BList, PostList);
Lines.Free; TempLines.Free;
//Find where the ':=' should be // Find where the ':=' should be
EqPos := 0; EqPos := 0;
for X := 0 to BList.Count-1 do begin for X := 0 to BList.Count-1 do begin
Y := Length(BList.Strings[X]); Y := Length(BList[X]);
if Y > EqPos then EqPos := Y; if Y > EqPos then
EqPos := Y;
end; end;
for X := 0 to AList.Count-1 do begin for X := 0 to AList.Count-1 do
ALines.Add(InvertLine(PreList.Strings[X], InLines.Add(InvertLine(PreList[X],Alist[X],BList[X],PostList[X],Indents[X],EqPos));
Alist.Strings[X],
BList.Strings[X],
PostList.Strings[X],
Indents[X],
EqPos));
end;
PreList.Free; PreList.Free;
AList.Free; AList.Free;
BList.Free; BList.Free;
PostList.Free; PostList.Free;
ReAllocMem(Indents,0); Result := InLines.Text;
InLines.Free;
Result := ALines; if not HasLinefeed then begin
// TODO: How do you stop this from adding a new line at the end of the last item while Result[Length(Result)] in [#10,#13] do
SetLength(Result, Length(Result)-1);
end;
end; end;
end. end.

View File

@ -3484,21 +3484,13 @@ begin
end; end;
procedure TSourceEditor.InvertAssignment; procedure TSourceEditor.InvertAssignment;
var
codelines: TStringList;
begin begin
if ReadOnly then exit; if ReadOnly then exit;
if not EditorComponent.SelAvail then exit; if not EditorComponent.SelAvail then exit;
FEditor.BeginUpdate; FEditor.BeginUpdate;
FEditor.BeginUndoBlock; FEditor.BeginUndoBlock;
// ToDo: replace step by step to keep bookmarks and breakpoints // ToDo: replace step by step to keep bookmarks and breakpoints
codelines := TStringList.Create; FEditor.SelText := InvertAssignTool.InvertAssignment(FEditor.SelText);
try
codelines.Text := FEditor.SelText;
FEditor.SelText := InvertAssignTool.InvertAssignment( codelines ).Text;
finally
codelines.Free;
end;
FEditor.EndUndoBlock; FEditor.EndUndoBlock;
FEditor.EndUpdate; FEditor.EndUpdate;
end; end;