SynEdit: various minor speed improvements (replace selection)

git-svn-id: trunk@39835 -
This commit is contained in:
martin 2013-01-12 10:47:23 +00:00
parent b56705acf2
commit 1c99638ea5
4 changed files with 198 additions and 18 deletions

View File

@ -5491,7 +5491,7 @@ begin
FInternalBlockSelection.SetSelTextPrimitive(FInternalBlockSelection.ActiveSelectionMode,
PChar(AValue),
aMarksMode = smaKeep
(aMarksMode = smaKeep) or (aStartPoint.y = aEndPoint.y)
);
if aCaretMode = scamEnd then
FCaret.LineBytePos := FInternalBlockSelection.StartLineBytePos;

View File

@ -1536,8 +1536,10 @@ var
SetString(Str, Start, P - Start);
if BE.y > BB.y then begin
FLines.EditDelete(BB.x, BB.Y, 1+Length(FLines[BB.y-1]) - BB.x);
FLines.EditInsert(BB.x, BB.Y, Str);
// FLines.EditDelete(BB.x, BB.Y, 1+Length(FLines[BB.y-1]) - BB.x);
//// if Str <> '' then
// FLines.EditInsert(BB.x, BB.Y, Str);
FLines.EditReplace(BB.x, BB.Y, 1+Length(FLines[BB.y-1]) - BB.x, Str);
if (PasteMode = smLine) or (Value > P) then begin
inc(BB.y);
BB.x := 1;
@ -1546,16 +1548,23 @@ var
BB.X := BB.X + length(Str);
end
else begin
FLines.EditDelete(BB.x, BB.Y, BE.x - BB.x);
// BE will be block-.nd, also used by SynEdit to set caret
if (ActiveSelectionMode = smLine) or (Value > P) then begin
FLines.EditLineBreak(BB.x, BB.Y);
FLines.EditReplace(BB.x, BB.Y, BE.x - BB.x, Str);
FLines.EditLineBreak(BB.x+length(Str), BB.Y);
//FLines.EditDelete(BB.x, BB.Y, BE.x - BB.x);
//FLines.EditLineBreak(BB.x, BB.Y);
//FLines.EditInsert(BB.x, BB.Y, Str);
inc(BE.y);
BE.x := 1;
end
else
else begin
//FLines.EditDelete(BB.x, BB.Y, BE.x - BB.x);
// if Str <> '' then
//FLines.EditInsert(BB.x, BB.Y, Str);
FLines.EditReplace(BB.x, BB.Y, BE.x - BB.x, Str);
BE.X := BB.X + length(Str);
FLines.EditInsert(BB.x, BB.Y, Str);
end;
BB := BE; // end of selection
end;

View File

@ -245,6 +245,7 @@ type
property RedoList: TSynEditUndoList read GetRedoList write fRedoList;
procedure EditInsert(LogX, LogY: Integer; AText: String); override;
function EditDelete(LogX, LogY, ByteLen: Integer): String; override;
function EditReplace(LogX, LogY, ByteLen: Integer; AText: String): String; override;
procedure EditLineBreak(LogX, LogY: Integer); override;
procedure EditLineJoin(LogY: Integer; FillText: String = ''); override;
procedure EditLinesInsert(LogY, ACount: Integer; AText: String = ''); override;
@ -1230,7 +1231,8 @@ begin
LogX := Length(s) + 1;
end;
Strings[LogY - 1] := copy(s,1, LogX - 1) + AText + copy(s, LogX, length(s));
CurUndoList.AddChange(TSynEditUndoTxtInsert.Create(LogX, LogY, Length(AText)));
if AText <> '' then
CurUndoList.AddChange(TSynEditUndoTxtInsert.Create(LogX, LogY, Length(AText)));
MarkModified(LogY, LogY);
SendNotification(senrEditAction, self, LogY, 0, LogX, length(AText), AText);
DecIsInEditAction;
@ -1240,18 +1242,60 @@ function TSynEditStringList.EditDelete(LogX, LogY, ByteLen: Integer): String;
var
s: string;
begin
if ByteLen <= 0 then
exit;
IncIsInEditAction;
s := Strings[LogY - 1];
if LogX - 1 > Length(s) then
exit;
Result := copy(s, LogX, ByteLen);
Strings[LogY - 1] := copy(s,1, LogX - 1) + copy(s, LogX + ByteLen, length(s));
CurUndoList.AddChange(TSynEditUndoTxtDelete.Create(LogX, LogY, Result));
if Result <> '' then
CurUndoList.AddChange(TSynEditUndoTxtDelete.Create(LogX, LogY, Result));
MarkModified(LogY, LogY);
SendNotification(senrEditAction, self, LogY, 0, LogX, -ByteLen, '');
DecIsInEditAction;
end;
function TSynEditStringList.EditReplace(LogX, LogY, ByteLen: Integer; AText: String): String;
var
s, s2: string;
begin
IncIsInEditAction;
if ByteLen <= 0 then
ByteLen := 0;
s := Strings[LogY - 1];
if LogX - 1 > Length(s) then begin
AText := StringOfChar(' ', LogX - 1 - Length(s)) + AText;
LogX := Length(s) + 1;
end;
if LogX - 1 + ByteLen > Length(s) then
ByteLen := Length(s) - (LogX-1);
Result := copy(s, LogX, ByteLen);
SetLength(s2, Length(s) - ByteLen + Length(AText));
if LogX > 1 then
system.Move(s[1], s2[1], LogX-1);
if AText <> '' then
system.Move(AText[1], s2[LogX], Length(AText));
if Length(s)-(LogX-1)-ByteLen > 0 then
system.Move(s[LogX+ByteLen], s2[LogX+Length(AText)], Length(s)-(LogX-1)-ByteLen);
Strings[LogY - 1] := s2;
//Strings[LogY - 1] := copy(s,1, LogX - 1) + AText + copy(s, LogX + ByteLen, length(s));
if Result <> '' then
CurUndoList.AddChange(TSynEditUndoTxtDelete.Create(LogX, LogY, Result));
if AText <> '' then
CurUndoList.AddChange(TSynEditUndoTxtInsert.Create(LogX, LogY, Length(AText)));
MarkModified(LogY, LogY);
SendNotification(senrEditAction, self, LogY, 0, LogX, -ByteLen, '');
SendNotification(senrEditAction, self, LogY, 0, LogX, length(AText), AText);
DecIsInEditAction;
end;
procedure TSynEditStringList.EditLineBreak(LogX, LogY: Integer);
var
s: string;

View File

@ -124,6 +124,7 @@ type
public
procedure EditInsert(LogX, LogY: Integer; AText: String); override;
Function EditDelete(LogX, LogY, ByteLen: Integer): String; override;
function EditReplace(LogX, LogY, ByteLen: Integer; AText: String): String; override;
procedure EditLineBreak(LogX, LogY: Integer); override;
procedure EditLineJoin(LogY: Integer; FillText: String = ''); override;
procedure EditLinesInsert(LogY, ACount: Integer; AText: String = ''); override;
@ -932,19 +933,29 @@ begin
exit;
end;
t := fSynStrings[LogY - 1];
Len := length(t);
if ( (LogX <= Len) and not(t[Len] in [#9, #32]) ) or
( AText = '') or
( (LogX <= Len+1) and not(AText[Length(AText)] in [#9, #32]) )
then begin
fSynStrings.EditInsert(LogX, LogY, AText);
exit;
end;
IncIsInEditAction;
if Count = 0 then fSynStrings.Add('');
FlushNotificationCache;
IgnoreSendNotification(senrEditAction, True);
SaveText := AText;
SaveLogX := LogX;
t := Strings[LogY - 1]; // include trailing
if LogX - 1 > Length(t) then begin
AText := StringOfChar(' ', LogX - 1 - Length(t)) + AText;
LogX := 1 + Length(t);
Len := Length(t) + Length(Spaces(LogY-1));
if LogX - 1 > Len then begin
AText := StringOfChar(' ', LogX - 1 - Len) + AText;
LogX := 1 + Len;
end;
IsSpaces := LastNoneSpacePos(AText) = 0;
t := fSynStrings[LogY - 1];
Len := length(t);
LenNS := LastNoneSpacePos(t);
if (LenNS < LogX - 1) and not IsSpaces then
@ -992,7 +1003,14 @@ var
Len: Integer;
SaveByteLen: LongInt;
begin
if (not fEnabled) then begin
if (not fEnabled) or (ByteLen <= 0) then begin
fSynStrings.EditDelete(LogX, LogY, ByteLen);
exit;
end;
t := fSynStrings[LogY - 1];
Len := length(t);
if (LogX + ByteLen <= Len) and not(t[Len] in [#9, #32]) then begin
fSynStrings.EditDelete(LogX, LogY, ByteLen);
exit;
end;
@ -1001,11 +1019,9 @@ begin
FlushNotificationCache;
SaveByteLen := ByteLen;
Result := '';
t := fSynStrings[LogY - 1];
Len := length(t);
IgnoreSendNotification(senrEditAction, True);
// Delete uncommited spaces (could laso be ByteLen too big, due to past EOL)
// Delete uncommited spaces (could also be ByteLen too big, due to past EOL)
if LogX + ByteLen > Len + 1 then begin
if LogX > Len + 1 then
ByteLen := ByteLen - (LogX - (Len + 1));
@ -1030,6 +1046,117 @@ begin
DecIsInEditAction;
end;
function TSynEditStringTrimmingList.EditReplace(LogX, LogY, ByteLen: Integer;
AText: String): String;
var
t: String;
SaveByteLen: LongInt;
Len, LenNS, SaveLogX: Integer;
IsSpaces: Boolean;
SaveText: String;
begin
if (not fEnabled) then begin
Result := inherited EditReplace(LogX, LogY, ByteLen, AText);
exit;
end;
if (Count = 0) or (ByteLen <= 0)
then begin
Result := '';
EditInsert(LogX, LogY, AText);
exit;
end;
t := fSynStrings[LogY - 1];
Len := length(t);
if ( (LogX + ByteLen <= Len) and not(t[Len] in [#9, #32]) ) or
( AText = '') or
( (LogX + ByteLen <= Len+1) and not(AText[Length(AText)] in [#9, #32]) )
then begin
Result := inherited EditReplace(LogX, LogY, ByteLen, AText);
exit;
end;
IncIsInEditAction;
FlushNotificationCache;
IgnoreSendNotification(senrEditAction, True);
SaveByteLen := ByteLen;
SaveText := AText;
SaveLogX := LogX;
Result := '';
// Delete uncommited spaces (could also be ByteLen too big, due to past EOL)
if LogX + ByteLen > Len + 1 then begin
if LogX > Len + 1 then
ByteLen := ByteLen - (LogX - (Len + 1));
Result := EditDeleteTrim(max(LogX - Len, 1), LogY, LogX - 1 + ByteLen - Len);
ByteLen := Len + 1 - LogX;
end;
if ByteLen > 0 then
Result := inherited EditDelete(LogX, LogY, ByteLen) + Result
else
begin
SendNotification(senrLineChange, self, LogY - 1, 1);
end;
//// Trim any existing (committed/real) spaces
//t := fSynStrings[LogY - 1];
//EditMoveToTrim(LogY, length(t) - LastNoneSpacePos(t));
// Insert
t := fSynStrings[LogY - 1];
Len := Length(t) + Length(Spaces(LogY-1));
if LogX - 1 > Len then begin
AText := StringOfChar(' ', LogX - 1 - Len) + AText;
LogX := 1 + Len;
end;
IsSpaces := LastNoneSpacePos(AText) = 0;
Len := length(t);
LenNS := LastNoneSpacePos(t);
if (LenNS < LogX - 1) and not IsSpaces then
LenNs := LogX - 1;
// Trim any existing (committed/real) spaces // skip if we append none-spaces
if (LenNS < Len) and (IsSpaces or (LogX <= len)) then
begin
EditMoveToTrim(LogY, Len - LenNS);
Len := LenNS;
end;
if LogX > len then begin
if IsSpaces then begin
EditInsertTrim(LogX - Len, LogY, AText);
AText := '';
end else begin
// Get Fill Spaces
EditMoveFromTrim(LogY, LogX - 1 - len);
// Trim
Len := length(AText);
LenNS := LastNoneSpacePos(AText);
if LenNS < Len then begin
EditInsertTrim(1, LogY, copy(AText, 1 + LenNS, Len));
AText := copy(AText, 1, LenNS);
end;
end;
end;
if AText <> '' then
inherited EditInsert(LogX, LogY, AText)
else
SendNotification(senrLineChange, self, LogY - 1, 1);
// update spaces
UpdateLineText(LogY);
IgnoreSendNotification(senrEditAction, False);
SendNotification(senrEditAction, self, LogY, 0, LogX, -SaveByteLen, '');
SendNotification(senrEditAction, self, LogY, 0, SaveLogX, length(SaveText), SaveText);
DecIsInEditAction;
end;
procedure TSynEditStringTrimmingList.EditLineBreak(LogX, LogY: Integer);
var
s, t: string;