mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-10 14:59:26 +01:00
SynEdit: improved keeping track of longest line
git-svn-id: trunk@49084 -
This commit is contained in:
parent
3de4e18d3f
commit
f06680177d
@ -26,7 +26,7 @@ unit SynEditTextTabExpander;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
LCLProc, Classes, SysUtils, LazSynEditText, SynEditTextBase;
|
LCLProc, Classes, SysUtils, math, LazSynEditText, SynEditTextBase;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -55,11 +55,13 @@ type
|
|||||||
private
|
private
|
||||||
FTabWidth: integer;
|
FTabWidth: integer;
|
||||||
FIndexOfLongestLine: Integer;
|
FIndexOfLongestLine: Integer;
|
||||||
|
FFirstUnknownLongestLine, FLastUnknownLongestLine: Integer;
|
||||||
FTabData: TSynEditStringTabData;
|
FTabData: TSynEditStringTabData;
|
||||||
FLastLineHasTab: Boolean; // Last line, parsed by GetPhysicalCharWidths
|
FLastLineHasTab: Boolean; // Last line, parsed by GetPhysicalCharWidths
|
||||||
FLastLinePhysLen: Integer;
|
FLastLinePhysLen: Integer;
|
||||||
FViewChangeStamp: int64;
|
FViewChangeStamp: int64;
|
||||||
procedure TextBufferChanged(Sender: TObject);
|
procedure TextBufferChanged(Sender: TObject);
|
||||||
|
procedure LineTextChanged(Sender: TSynEditStrings; aIndex, aCount: Integer);
|
||||||
procedure LineCountChanged(Sender: TSynEditStrings; AIndex, ACount : Integer);
|
procedure LineCountChanged(Sender: TSynEditStrings; AIndex, ACount : Integer);
|
||||||
function ExpandedString(Index: integer): string;
|
function ExpandedString(Index: integer): string;
|
||||||
function ExpandedStringLength(Index: integer): Integer;
|
function ExpandedStringLength(Index: integer): Integer;
|
||||||
@ -135,6 +137,8 @@ end;
|
|||||||
constructor TSynEditStringTabExpander.Create(ASynStringSource: TSynEditStrings);
|
constructor TSynEditStringTabExpander.Create(ASynStringSource: TSynEditStrings);
|
||||||
begin
|
begin
|
||||||
FIndexOfLongestLine := -1;
|
FIndexOfLongestLine := -1;
|
||||||
|
FFirstUnknownLongestLine := -1;
|
||||||
|
FLastUnknownLongestLine := -1;
|
||||||
inherited Create(ASynStringSource);
|
inherited Create(ASynStringSource);
|
||||||
TextBufferChanged(nil);
|
TextBufferChanged(nil);
|
||||||
TabWidth := 8;
|
TabWidth := 8;
|
||||||
@ -155,7 +159,7 @@ begin
|
|||||||
Data.Free;
|
Data.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
fSynStrings.RemoveChangeHandler(senrLineChange, @LineCountChanged);
|
fSynStrings.RemoveChangeHandler(senrLineChange, @LineTextChanged);
|
||||||
fSynStrings.RemoveChangeHandler(senrLineCount, @LineCountChanged);
|
fSynStrings.RemoveChangeHandler(senrLineCount, @LineCountChanged);
|
||||||
fSynStrings.RemoveNotifyHandler(senrTextBufferChanged, @TextBufferChanged);
|
fSynStrings.RemoveNotifyHandler(senrTextBufferChanged, @TextBufferChanged);
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
@ -178,6 +182,8 @@ begin
|
|||||||
|
|
||||||
FTabWidth := AValue;
|
FTabWidth := AValue;
|
||||||
FIndexOfLongestLine := -1;
|
FIndexOfLongestLine := -1;
|
||||||
|
FFirstUnknownLongestLine := -1;
|
||||||
|
FLastUnknownLongestLine := -1;
|
||||||
for i := 0 to Count - 1 do
|
for i := 0 to Count - 1 do
|
||||||
if not(FTabData[i] >= NO_TAB_IN_LINE_OFFSET) then
|
if not(FTabData[i] >= NO_TAB_IN_LINE_OFFSET) then
|
||||||
FTabData[i] := LINE_LEN_UNKNOWN;
|
FTabData[i] := LINE_LEN_UNKNOWN;
|
||||||
@ -219,14 +225,47 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
FTabData.IncRefCount;
|
FTabData.IncRefCount;
|
||||||
LineCountChanged(TSynEditStrings(Sender), 0, Count);
|
LineTextChanged(TSynEditStrings(Sender), 0, Count);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditStringTabExpander.LineTextChanged(Sender: TSynEditStrings; aIndex,
|
||||||
|
aCount: Integer);
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
if (FIndexOfLongestLine >= AIndex) and (FIndexOfLongestLine < AIndex+ACount) then
|
||||||
|
FIndexOfLongestLine := -1;
|
||||||
|
if (FFirstUnknownLongestLine < 0) or (AIndex < FFirstUnknownLongestLine) then
|
||||||
|
FFirstUnknownLongestLine := AIndex;
|
||||||
|
if AIndex+ACount-1 > FLastUnknownLongestLine then
|
||||||
|
FLastUnknownLongestLine := AIndex+ACount-1;
|
||||||
|
for i := AIndex to AIndex + ACount - 1 do
|
||||||
|
FTabData[i] := LINE_LEN_UNKNOWN;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditStringTabExpander.LineCountChanged(Sender: TSynEditStrings; AIndex, ACount: Integer);
|
procedure TSynEditStringTabExpander.LineCountChanged(Sender: TSynEditStrings; AIndex, ACount: Integer);
|
||||||
var
|
var
|
||||||
i: integer;
|
i: integer;
|
||||||
begin
|
begin
|
||||||
|
if ACount < 0 then begin
|
||||||
|
if (FIndexOfLongestLine >= AIndex) and (FIndexOfLongestLine < AIndex-ACount) then
|
||||||
FIndexOfLongestLine := -1;
|
FIndexOfLongestLine := -1;
|
||||||
|
if (FFirstUnknownLongestLine >= 0) then begin
|
||||||
|
if (AIndex < FFirstUnknownLongestLine) then
|
||||||
|
FFirstUnknownLongestLine := Max(AIndex, FFirstUnknownLongestLine + ACount);
|
||||||
|
if (AIndex < FLastUnknownLongestLine) then
|
||||||
|
FLastUnknownLongestLine := Max(AIndex, FLastUnknownLongestLine + ACount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (FIndexOfLongestLine >= AIndex) then
|
||||||
|
FIndexOfLongestLine := FIndexOfLongestLine + ACount;
|
||||||
|
if (FFirstUnknownLongestLine < 0) or (AIndex < FFirstUnknownLongestLine) then
|
||||||
|
FFirstUnknownLongestLine := AIndex;
|
||||||
|
if (AIndex < FLastUnknownLongestLine) or (FLastUnknownLongestLine < 0) then
|
||||||
|
FLastUnknownLongestLine := Max(AIndex, FLastUnknownLongestLine) +ACount;
|
||||||
for i := AIndex to AIndex + ACount - 1 do
|
for i := AIndex to AIndex + ACount - 1 do
|
||||||
FTabData[i] := LINE_LEN_UNKNOWN;
|
FTabData[i] := LINE_LEN_UNKNOWN;
|
||||||
end;
|
end;
|
||||||
@ -334,20 +373,40 @@ var
|
|||||||
i, j, m: Integer;
|
i, j, m: Integer;
|
||||||
Line1, Line2: Integer;
|
Line1, Line2: Integer;
|
||||||
begin
|
begin
|
||||||
|
Result := 0;
|
||||||
Line1 := 0;
|
Line1 := 0;
|
||||||
Line2 := Count - 1;
|
Line2 := Count - 1;
|
||||||
|
|
||||||
if (fIndexOfLongestLine >= 0) and (fIndexOfLongestLine < Count) then begin
|
if (fIndexOfLongestLine >= 0) and (fIndexOfLongestLine < Count) then begin
|
||||||
Result := FTabData[fIndexOfLongestLine];
|
Result := FTabData[fIndexOfLongestLine];
|
||||||
if Result <> LINE_LEN_UNKNOWN then begin
|
if Result <> LINE_LEN_UNKNOWN then begin
|
||||||
if Result >= NO_TAB_IN_LINE_OFFSET then Result := Result - NO_TAB_IN_LINE_OFFSET;
|
if Result >= NO_TAB_IN_LINE_OFFSET then Result := Result - NO_TAB_IN_LINE_OFFSET;
|
||||||
|
if (FFirstUnknownLongestLine < 0) then
|
||||||
exit;
|
exit;
|
||||||
end;
|
// Result has the value from index
|
||||||
|
Line1 := FFirstUnknownLongestLine;
|
||||||
|
if (FLastUnknownLongestLine < Line2) then
|
||||||
|
Line2 := FLastUnknownLongestLine;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
Result := 0;
|
||||||
|
if (FFirstUnknownLongestLine < 0) then begin
|
||||||
Line1 := fIndexOfLongestLine;
|
Line1 := fIndexOfLongestLine;
|
||||||
Line2 := fIndexOfLongestLine;
|
Line2 := fIndexOfLongestLine;
|
||||||
|
end
|
||||||
|
else begin // TODO: Calculate for fIndexOfLongestLine, instead of extending the range
|
||||||
|
Line1 := Min(fIndexOfLongestLine, FFirstUnknownLongestLine);
|
||||||
|
if (FLastUnknownLongestLine < Line2) then
|
||||||
|
Line2 := Max(fIndexOfLongestLine, FLastUnknownLongestLine);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
FFirstUnknownLongestLine := -1;
|
||||||
|
FLastUnknownLongestLine := -1;
|
||||||
|
|
||||||
try
|
try
|
||||||
Result := 0;
|
//Result := 0;
|
||||||
m := 0;
|
m := 0;
|
||||||
CharWidths := nil;
|
CharWidths := nil;
|
||||||
for i := Line1 to Line2 do begin
|
for i := Line1 to Line2 do begin
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user