mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-29 13:00:34 +01:00
SynEdit: Fixing many issues with trailing spaces. Includes bug #12383 "Smart tab un-indent", 12487 "ctrl-t at end of trailing spaces", "special char display of trailing spaces", vertical scrollbar for (many) trailing spaces.
git-svn-id: trunk@17416 -
This commit is contained in:
parent
d92cd626a3
commit
34347f789c
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1349,7 +1349,9 @@ components/synedit/syneditplugins.pas svneol=native#text/pascal
|
||||
components/synedit/syneditregexsearch.pas svneol=native#text/pascal
|
||||
components/synedit/syneditsearch.pp svneol=native#text/pascal
|
||||
components/synedit/syneditstrconst.pp svneol=native#text/pascal
|
||||
components/synedit/synedittextbase.pas svneol=native#text/plain
|
||||
components/synedit/synedittextbuffer.pp svneol=native#text/pascal
|
||||
components/synedit/synedittexttrimmer.pas svneol=native#text/plain
|
||||
components/synedit/synedittypes.pp svneol=native#text/pascal
|
||||
components/synedit/synexporthtml.pas svneol=native#text/pascal
|
||||
components/synedit/synhighlighterany.pas svneol=native#text/plain
|
||||
|
||||
@ -76,7 +76,7 @@ uses
|
||||
{$ifdef SYN_LAZARUS}
|
||||
SynEditMarkup, SynEditMarkupHighAll, SynEditMarkupBracket,
|
||||
SynEditMarkupCtrlMouseLink, SynEditMarkupSpecialLine, SynEditMarkupSelection,
|
||||
SynEditFoldedView,
|
||||
SynEditTextBase, SynEditTextTrimmer, SynEditFoldedView,
|
||||
{$ENDIF}
|
||||
SynEditMiscClasses, SynEditTextBuffer, SynEditHighlighter, SynTextDrawer;
|
||||
|
||||
@ -227,7 +227,7 @@ type
|
||||
{$ENDIF}
|
||||
);
|
||||
TSynEditorOptions = set of TSynEditorOption;
|
||||
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditorOption2 = (
|
||||
eoCaretSkipsSelection, // Caret skips selection on VK_LEFT/VK_RIGHT
|
||||
@ -419,6 +419,7 @@ type
|
||||
fBeautifier: TSynCustomBeautifier;
|
||||
fExtraCharSpacing: integer;
|
||||
fTextView : TSynEditFoldedView;
|
||||
fTrimLines: TStrings; //TSynEditStringTrimmingList;
|
||||
{$ENDIF}
|
||||
fLines: TStrings;
|
||||
fLinesInWindow: Integer;// MG: fully visible lines in window
|
||||
@ -521,6 +522,7 @@ type
|
||||
function GetSelectedColor : TSynSelectedColor;
|
||||
function GetBracketMatchColor : TSynSelectedColor;
|
||||
function GetMouseLinkColor : TSynSelectedColor;
|
||||
procedure SetRealLines(const AValue : TStrings);
|
||||
procedure SetSelectedColor(const AValue : TSynSelectedColor);
|
||||
procedure SetSpecialLineColors(const AValue : TSpecialLineColorsEvent);
|
||||
procedure SetSpecialLineMarkup(const AValue : TSpecialLineMarkupEvent);
|
||||
@ -631,7 +633,9 @@ type
|
||||
{$ENDIF}
|
||||
procedure SizeOrFontChanged(bFont: boolean);
|
||||
procedure StatusChanged(AChanges: TSynStatusChanges);
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
procedure TrimmedSetLine(ALine: integer; ALineText: string);
|
||||
{$ENDIF}
|
||||
procedure UndoRedoAdded(Sender: TObject);
|
||||
procedure UnlockUndo;
|
||||
procedure UpdateCaret;
|
||||
@ -851,7 +855,7 @@ type
|
||||
AOptions: TSynSearchOptions): integer;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function SearchReplaceEx(const ASearch, AReplace: string;
|
||||
AOptions: TSynSearchOptions; AStart: TPoint): integer;
|
||||
AOptions: TSynSearchOptions; AStart: TPoint): integer;
|
||||
{$ENDIF}
|
||||
procedure SelectAll;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
@ -905,9 +909,11 @@ type
|
||||
property LinesInWindow: Integer read fLinesInWindow; // MG: fully visible lines
|
||||
property LineText: string read GetLineText write SetLineText;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
property RealLines: TStrings read fLines write SetLines; // No trailing (trimmable) spaces
|
||||
{$ENDIF}
|
||||
property RealLines: TStrings read fLines write SetRealLines; // No trailing (trimmable) spaces
|
||||
property Lines: TStrings read fTrimLines write SetLines;
|
||||
{$ELSE}
|
||||
property Lines: TStrings read fLines write SetLines;
|
||||
{$ENDIF}
|
||||
property Marks: TSynEditMarkList read fMarkList;
|
||||
property MaxLeftChar: integer read fMaxLeftChar write SetMaxLeftChar
|
||||
default 1024;
|
||||
@ -1461,7 +1467,9 @@ begin
|
||||
fLines := TSynEditStringList.Create;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fCaret := TSynEditCaret.Create;
|
||||
fTextView := TSynEditFoldedView.Create(TSynEditStringList(fLines));
|
||||
fTrimLines := TSynEditStringTrimmingList.Create(TSynEditStrings(fLines), fCaret);
|
||||
fTextView := TSynEditFoldedView.Create(TSynEditStringList(fLines),
|
||||
TSynEditStrings(fTrimLines));
|
||||
fTextView.OnFoldChanged := {$IFDEF FPC}@{$ENDIF}FoldChanged;
|
||||
{$ENDIF}
|
||||
// with TSynEditList(fLines) do begin
|
||||
@ -1481,6 +1489,9 @@ begin
|
||||
fUndoList.OnAddedUndo := {$IFDEF FPC}@{$ENDIF}UndoRedoAdded;
|
||||
fRedoList := TSynEditUndoList.Create;
|
||||
fRedoList.OnAddedUndo := {$IFDEF FPC}@{$ENDIF}UndoRedoAdded;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditStringTrimmingList(fTrimLines).UndoList := fUndoList;
|
||||
{$ENDIF}
|
||||
{$IFDEF SYN_COMPILER_4_UP}
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
// ToDo DoubleBuffered
|
||||
@ -1518,7 +1529,7 @@ begin
|
||||
fMarkupManager.AddMarkUp(fMarkupCtrlMouse);
|
||||
fMarkupManager.AddMarkUp(fMarkupSpecialLine);
|
||||
fMarkupManager.AddMarkUp(fMarkupSelection);
|
||||
fMarkupManager.Lines := TSynEditStringList(fLines);
|
||||
fMarkupManager.Lines := TSynEditStrings(Lines);
|
||||
fMarkupManager.InvalidateLinesMethod := @InvalidateLines;
|
||||
|
||||
Color := clWhite;
|
||||
@ -1587,6 +1598,7 @@ begin
|
||||
fTSearch := TSynEditSearch.Create;
|
||||
fOptions := SYNEDIT_DEFAULT_OPTIONS;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditStringTrimmingList(fTrimLines).Enabled := eoTrimTrailingSpaces in fOptions;
|
||||
fOptions2 := SYNEDIT_DEFAULT_OPTIONS2;
|
||||
{$ENDIF}
|
||||
fScrollTimer := TTimer.Create(Self);
|
||||
@ -1707,6 +1719,7 @@ begin
|
||||
FreeAndNil(fInternalImage);
|
||||
FreeAndNil(fFontDummy);
|
||||
FreeAndNil(fTextView);
|
||||
FreeAndNil(fTrimLines);
|
||||
FreeAndNil(fLines);
|
||||
FreeAndNil(fCaret);
|
||||
{$ENDIF}
|
||||
@ -1808,6 +1821,12 @@ begin
|
||||
Result := fMarkupCtrlMouse.MarkupInfo;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetRealLines(const AValue : TStrings);
|
||||
begin
|
||||
if HandleAllocated then
|
||||
fLines.Assign(AValue);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetUseIncrementalColor(const AValue : Boolean);
|
||||
begin
|
||||
fMarkupSelection.UseIncrementalColor:=AValue;
|
||||
@ -2061,7 +2080,7 @@ end;
|
||||
|
||||
function TCustomSynEdit.SynGetText: string;
|
||||
begin
|
||||
Result := Lines.Text;
|
||||
Result := fLines.Text;
|
||||
end;
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
@ -2080,7 +2099,7 @@ end;
|
||||
|
||||
function TCustomSynEdit.RealGetText: TCaption;
|
||||
begin
|
||||
if fLines<>nil then
|
||||
if Lines<>nil then
|
||||
Result := Lines.Text
|
||||
else
|
||||
Result := '';
|
||||
@ -2780,7 +2799,7 @@ begin
|
||||
Exclude(fStateFlags, sfDblClicked);
|
||||
Exclude(fStateFlags, sfPossibleGutterClick);
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if (eoShowCtrlMouseLinks in Options)
|
||||
and not(wasDragging)
|
||||
@ -3396,7 +3415,7 @@ var
|
||||
end;
|
||||
inc(SrcPos);
|
||||
end;
|
||||
|
||||
|
||||
#32:
|
||||
// space
|
||||
if not Special then begin
|
||||
@ -3607,7 +3626,7 @@ var
|
||||
)
|
||||
// background color must be the same and
|
||||
// foreground color must be the same or token is only spaces
|
||||
and ( ((TokenAccu.BG = Background)
|
||||
and ( ((TokenAccu.BG = Background)
|
||||
and ((TokenAccu.FG = Foreground)
|
||||
or (not(eoShowSpecialChars in fOptions) and TokenIsSpaces)))
|
||||
)
|
||||
@ -3672,9 +3691,9 @@ var
|
||||
ExpandSpecialChars(sToken, nTokenByteLen, PhysicalStartPos);
|
||||
TokenCharLen := UTF8Length(sToken, nTokenByteLen);
|
||||
// Prepare position for next token
|
||||
inc(CurPhysPos, TokenCharLen);
|
||||
inc(CurPhysPos, TokenCharLen);
|
||||
if CurPhysPos <= FirstCol then exit;
|
||||
|
||||
|
||||
// Remove any Part of the Token that is before FirstCol
|
||||
if PhysicalStartPos < FirstCol then begin
|
||||
SubCharLen := FirstCol - PhysicalStartPos;
|
||||
@ -3699,7 +3718,7 @@ var
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
if Assigned(attr) then begin
|
||||
DefaultFGCol:=attr.Foreground;
|
||||
DefaultBGCol:=attr.Background;
|
||||
@ -3725,7 +3744,7 @@ var
|
||||
debugln('ERROR: Got invalid SubCharLen ',dbgs(SubCharLen),' len ',dbgs(nTokenByteLen),' Line ',dbgs(CurLine),' PhysPos ',dbgs(CurPhysPos));
|
||||
SubCharLen:=1;
|
||||
end;
|
||||
|
||||
|
||||
SubTokenByteLen := UTF8CharToByteIndex(sToken,nTokenByteLen,SubCharLen);
|
||||
if SubTokenByteLen < 0 then begin
|
||||
debugln('ERROR: Can not find pso in SubToken ',dbgs(SubCharLen),' len ',dbgs(nTokenByteLen),' Line ',dbgs(CurLine),' PhysPos ',dbgs(CurPhysPos));
|
||||
@ -4963,7 +4982,9 @@ begin
|
||||
if eoScrollPastEol in Options then
|
||||
MaxVal := fMaxLeftChar
|
||||
else
|
||||
MaxVal := TSynEditStringList(Lines).LengthOfLongestLine;
|
||||
MaxVal :=
|
||||
{$IFDEF SYN_LAZARUS}TSynEditStrings{$ELSE}TSynEditStringList{$ENDIF}
|
||||
(Lines).LengthOfLongestLine;
|
||||
Value := Min(Value, MaxVal - fCharsInWindow + 1);
|
||||
{end} //mh 2000-10-19
|
||||
Value := Max(Value, 1);
|
||||
@ -5054,17 +5075,16 @@ var
|
||||
TempString := Copy(Lines[BB.Y - 1], 1, BB.X - 1) +
|
||||
Copy(Lines[BE.Y - 1], BE.X, MaxInt);
|
||||
// Delete all lines in the selection range.
|
||||
{begin} // djlp 2000-09-13
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditStrings(Lines).DeleteLines(BB.Y-1, BE.Y - BB.Y);
|
||||
{$ELSE}
|
||||
TSynEditStringList(Lines).DeleteLines(BB.Y-1, BE.Y - BB.Y);
|
||||
// for x := BE.Y - 1 downto BB.Y do
|
||||
// Lines.Delete(x);
|
||||
{end} // djlp 2000-09-13
|
||||
// Put the stuff that was outside of selection back in.
|
||||
// if eoScrollPastEol in Options then //JGF 2000-09-23
|
||||
if Options * [eoScrollPastEol, eoTrimTrailingSpaces]
|
||||
= [eoScrollPastEol, eoTrimTrailingSpaces]
|
||||
then
|
||||
TempString := TrimRight(TempString);
|
||||
{$ENDIF}
|
||||
Lines[BB.Y - 1] := TempString;
|
||||
end;
|
||||
UpdateMarks := TRUE;
|
||||
@ -5100,7 +5120,11 @@ var
|
||||
Delete(TempString, l, r - l);
|
||||
{$ENDIF USE_UTF8BIDI_LCL}
|
||||
{$ENDIF}
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Lines[x] := TempString;
|
||||
{$ELSE}
|
||||
TrimmedSetLine(x, TempString);
|
||||
{$ENDIF}
|
||||
end;
|
||||
// Lines never get deleted completely, so keep caret at end.
|
||||
CaretXY := {$IFDEF SYN_LAZARUS}
|
||||
@ -5180,18 +5204,27 @@ var
|
||||
sLeftSide := sLeftSide + StringOfChar(' ', CaretX-1-Length(sLeftSide));
|
||||
end;
|
||||
sRightSide := Copy(LineText, CaretX, Length(LineText) - (CaretX - 1));
|
||||
{$ENDIF}
|
||||
if eoTrimTrailingSpaces in Options then
|
||||
sRightSide := TrimRight(sRightSide);
|
||||
{$ENDIF}
|
||||
// step1: insert the first line of Value into current line
|
||||
Start := PChar(Value);
|
||||
P := GetEOL(Start);
|
||||
if P^ <> #0 then begin
|
||||
SetString(Str, Value, P - Start);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Lines[CaretY - 1] := sLeftSide + Str;
|
||||
TSynEditStrings(Lines).InsertLines(CaretY, CountLines(P));
|
||||
{$ELSE}
|
||||
TrimmedSetLine(CaretY - 1, sLeftSide + Str);
|
||||
TSynEditStringList(Lines).InsertLines(CaretY, CountLines(P)); // djlp 2000-09-07
|
||||
{$ENDIF}
|
||||
end else begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Lines[CaretY - 1] := sLeftSide + Value + sRightSide;
|
||||
{$ELSE}
|
||||
TrimmedSetLine(CaretY - 1, sLeftSide + Value + sRightSide);
|
||||
{$ENDIF}
|
||||
CaretX := LogicalToPhysicalPos(
|
||||
Point(1 + Length(sLeftSide + Value),CaretY)).X;
|
||||
end;
|
||||
@ -5211,18 +5244,10 @@ var
|
||||
Lines[CaretY - 1] := sRightSide; // djlp 2000-09-07
|
||||
end else begin
|
||||
SetString(Str, Start, P - Start); //mh 2000-11-08
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if p^ <> #0 then
|
||||
TrimmedSetLine(CaretY - 1, Str)
|
||||
else begin
|
||||
TrimmedSetLine(CaretY - 1, Str + sRightSide);
|
||||
end;
|
||||
{$ELSE}
|
||||
if p^ <> #0 then
|
||||
Lines[CaretY - 1] := Str // djlp 2000-09-07
|
||||
else
|
||||
Lines[CaretY - 1] := Str + sRightSide // djlp 2000-09-07
|
||||
{$ENDIF}
|
||||
end;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if p^=#0 then
|
||||
@ -5286,7 +5311,11 @@ var
|
||||
System.Insert(Str, TempString,
|
||||
{$IFDEF SYN_LAZARUS}LogicalInsertPos{$ELSE}InsertPos{$ENDIF});
|
||||
end;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Lines[CaretY - 1] := TempString;
|
||||
{$ELSE}
|
||||
TrimmedSetLine(CaretY - 1, TempString); //JGF 2000-09-23
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
if ATag <> nil then
|
||||
@ -5336,11 +5365,17 @@ var
|
||||
Lines[CaretY - 1] := Str + Lines[CaretY - 1]
|
||||
else
|
||||
Lines.Add(Str);
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
if eoTrimTrailingSpaces in Options then
|
||||
Lines[CaretY - 1] := TrimRight(Lines[CaretY - 1]);
|
||||
{$ENDIF}
|
||||
CaretX := 1 + Length(Str);
|
||||
end else begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Lines[CaretY - 1] := Str;
|
||||
{$ELSE}
|
||||
TrimmedSetLine(CaretY - 1, Str);
|
||||
{$ENDIF}
|
||||
CaretY := CaretY + 1;
|
||||
Inc(Result);
|
||||
if P^ = #13 then
|
||||
@ -5396,6 +5431,7 @@ var
|
||||
begin
|
||||
IncPaintLock;
|
||||
Lines.BeginUpdate;
|
||||
TSynEditStringTrimmingList(fTrimLines).Lock;
|
||||
try
|
||||
BB := BlockBegin;
|
||||
BE := BlockEnd;
|
||||
@ -5418,6 +5454,7 @@ begin
|
||||
EnsureCursorPosVisible;
|
||||
{$ENDIF}
|
||||
finally
|
||||
TSynEditStringTrimmingList(fTrimLines).UnLock;
|
||||
Lines.EndUpdate;
|
||||
DecPaintLock;
|
||||
end;
|
||||
@ -5431,7 +5468,7 @@ end;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure TCustomSynEdit.RealSetText(const Value: TCaption);
|
||||
begin
|
||||
Lines.Text := Value;
|
||||
Lines.Text := Value; // Do not trim
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
@ -5634,7 +5671,11 @@ begin
|
||||
if eoScrollPastEol in Options then
|
||||
ScrollInfo.nMax := fMaxLeftChar
|
||||
else
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
ScrollInfo.nMax := TSynEditStrings(Lines).LengthOfLongestLine;
|
||||
{$ELSE}
|
||||
ScrollInfo.nMax := TSynEditStringList(Lines).LengthOfLongestLine;
|
||||
{$ENDIF}
|
||||
{end} //mh 2000-10-19
|
||||
ScrollInfo.nPage := CharsInWindow;
|
||||
ScrollInfo.nPos := LeftChar;
|
||||
@ -5925,8 +5966,8 @@ function TCustomSynEdit.ScanFrom(Index: integer
|
||||
FixFStart: Integer;
|
||||
procedure SetCodeFoldAttributes;
|
||||
begin
|
||||
TSynEditStringList(Lines).FoldMinLevel[Result-1] := fHighlighter.MinimumCodeFoldBlockLevel;
|
||||
TSynEditStringList(Lines).FoldEndLevel[Result-1] := fHighlighter.CurrentCodeFoldBlockLevel;
|
||||
TSynEditStrings(Lines).FoldMinLevel[Result-1] := fHighlighter.MinimumCodeFoldBlockLevel;
|
||||
TSynEditStrings(Lines).FoldEndLevel[Result-1] := fHighlighter.CurrentCodeFoldBlockLevel;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
@ -5946,10 +5987,10 @@ begin
|
||||
end;
|
||||
FixFStart := Index;
|
||||
if Result > 0 then
|
||||
fHighlighter.SetRange(TSynEditStringList(Lines).Ranges[Result])
|
||||
fHighlighter.SetRange(TSynEditStrings(Lines).Ranges[Result])
|
||||
else begin
|
||||
fHighlighter.ReSetRange;
|
||||
TSynEditStringList(Lines).Ranges[0] := fHighlighter.GetRange;
|
||||
TSynEditStrings(Lines).Ranges[0] := fHighlighter.GetRange;
|
||||
end;
|
||||
{$ENDIF}
|
||||
if Index >= Lines.Count - 1 then Exit;
|
||||
@ -5957,18 +5998,21 @@ begin
|
||||
fHighlighter.SetLine(Lines[Result], Result);
|
||||
inc(Result);
|
||||
fHighlighter.NextToEol;
|
||||
while (fHighlighter.GetRange <> TSynEditStringList(Lines).Ranges[Result])
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
while (fHighlighter.GetRange <> TSynEditStrings(Lines).Ranges[Result])
|
||||
or (Result<=AtLeastTilIndex)
|
||||
{$ELSE}
|
||||
while (fHighlighter.GetRange <> TSynEditStringList(Lines).Ranges[Result])
|
||||
{$ENDIF}
|
||||
do begin
|
||||
//debugln(['TSynCustomHighlighter.ScanFrom WHILE Y=',Result,' Level=',fHighlighter.CurrentCodeFoldBlockLevel,' ScannedLine="',Lines[Result-1],'"']);
|
||||
TSynEditStringList(Lines).Ranges[Result{$IFNDEF SYN_LAZARUS}-1{$ENDIF}] :=
|
||||
fHighlighter.GetRange;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditStrings(Lines).Ranges[Result] := fHighlighter.GetRange;
|
||||
SetCodeFoldAttributes;
|
||||
//if (Result and $fff)=0 then
|
||||
// debugln('TCustomSynEdit.ScanFrom A Line=', dbgs(Result),' Index=',dbgs(Index),' MinLevel=',dbgs(CodeFoldMinLevel),' EndLevel=',dbgs(CodeFoldEndLevel),' CodeFoldType=',dbgs(ord(CodeFoldType)),' ',dbgs(length(Lines[Result-1])));
|
||||
{$ELSE}
|
||||
TSynEditStringList(Lines).Ranges[Result-1] := fHighlighter.GetRange;
|
||||
{$ENDIF}
|
||||
fHighlighter.SetLine(Lines[Result], Result);
|
||||
//debugln(['TSynCustomHighlighter.ScanFrom SetLine Y=',Result,' Level=',fHighlighter.CurrentCodeFoldBlockLevel,' Line="',Lines[Result],'"']);
|
||||
@ -6557,15 +6601,28 @@ var
|
||||
begin
|
||||
Item := fRedoList.PeekItem;
|
||||
if Item <> nil then begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fUndoList.BeginBlock;
|
||||
OldChangeNumber := Item.fChangeNumber;
|
||||
{$ELSE}
|
||||
OldChangeNumber := fUndoList.BlockChangeNumber;
|
||||
fUndoList.BlockChangeNumber := Item.fChangeNumber;
|
||||
{$ENDIF}
|
||||
try
|
||||
repeat
|
||||
RedoItem;
|
||||
Item := fRedoList.PeekItem;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
until (Item = nil) or (Item.fChangeNumber <> OldChangeNumber);
|
||||
{$ELSE}
|
||||
until (Item = nil) or (Item.fChangeNumber <> fUndoList.BlockChangeNumber);
|
||||
{$ENDIF}
|
||||
finally
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fUndoList.EndBlock;
|
||||
{$ELSE}
|
||||
fUndoList.BlockChangeNumber := OldChangeNumber;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -6664,6 +6721,9 @@ begin
|
||||
*)
|
||||
{end} //mh 2000-11-20
|
||||
end;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
crTrimSpace: TSynEditStringTrimmingList(fTrimLines).ForceTrim;
|
||||
{$ENDIF}
|
||||
crLineBreak:
|
||||
{begin} //sbs 2000-11-20
|
||||
// CommandProcessor(ecLineBreak, #13, nil);
|
||||
@ -6798,15 +6858,28 @@ var
|
||||
begin
|
||||
Item := fUndoList.PeekItem;
|
||||
if Item <> nil then begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fRedoList.BeginBlock;
|
||||
OldChangeNumber := Item.fChangeNumber;
|
||||
{$ELSE}
|
||||
OldChangeNumber := fRedoList.BlockChangeNumber;
|
||||
fRedoList.BlockChangeNumber := Item.fChangeNumber;
|
||||
{$ENDIF}
|
||||
try
|
||||
repeat
|
||||
UndoItem;
|
||||
Item := fUndoList.PeekItem;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
until (Item = nil) or (Item.fChangeNumber <> OldChangeNumber);
|
||||
{$ELSE}
|
||||
until (Item = nil) or (Item.fChangeNumber <> fRedoList.BlockChangeNumber);
|
||||
{$ENDIF}
|
||||
finally
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fRedoList.EndBlock;
|
||||
{$ELSE}
|
||||
fRedoList.BlockChangeNumber := OldChangeNumber;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -6859,6 +6932,7 @@ begin
|
||||
{end} //mh 2000-11-20
|
||||
end;
|
||||
crDeleteAfterCursor, crDelete, {crDragDropDelete, crSelDelete, } //mh 2000-11-20
|
||||
{$IFDEF SYN_LAZARUS}crTrimSpace,{$ENDIF}
|
||||
crSilentDelete, crSilentDeleteAfterCursor: //mh 2000-10-30
|
||||
begin
|
||||
// If there's no selection, we have to set
|
||||
@ -6891,7 +6965,8 @@ begin
|
||||
TmpPos := Item.fChangeStartPos
|
||||
else
|
||||
TmpPos := Item.fChangeEndPos;
|
||||
if Item.fChangeReason in [crSilentDelete, crSilentDeleteAfterCursor]
|
||||
if Item.fChangeReason in [crSilentDelete, crSilentDeleteAfterCursor
|
||||
{$IFDEF SYN_LAZARUS}, crTrimSpace{$ENDIF} ]
|
||||
then
|
||||
CaretXY :={$IFDEF SYN_LAZARUS}LogicalToPhysicalPos(TmpPos)
|
||||
{$ELSE}TmpPos{$ENDIF}
|
||||
@ -6926,7 +7001,12 @@ begin
|
||||
end;
|
||||
CaretXY := {$IFDEF SYN_LAZARUS}PhysStartPos
|
||||
{$ELSE}Item.fChangeStartPos{$ENDIF};
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if Item.fChangeStr <> '' then
|
||||
Lines[CaretY - 1] := TmpStr + Item.fChangeStr;
|
||||
{$ELSE}
|
||||
TrimmedSetLine(CaretY - 1, TmpStr + Item.fChangeStr);
|
||||
{$ENDIF}
|
||||
DoLinesDeleted(CaretY, 1);
|
||||
end;
|
||||
crIndent: // remove the column that was inserted
|
||||
@ -7339,7 +7419,7 @@ begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if fHighlighter<>nil then begin
|
||||
fHighlighter.ResetRange;
|
||||
TSynEditStringList(Lines).ClearRanges(fHighlighter.GetRange);
|
||||
TSynEditStrings(Lines).ClearRanges(fHighlighter.GetRange);
|
||||
fTSearch.IdentChars:=fHighlighter.IdentChars;
|
||||
end else begin
|
||||
fTSearch.ResetIdentChars;
|
||||
@ -7605,6 +7685,10 @@ begin
|
||||
,' AChar=',AChar,' Data=',DbgS(Data)]);
|
||||
DumpStack;
|
||||
{$ENDIF}
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
try
|
||||
BeginUndoBlock;
|
||||
{$ENDIF}
|
||||
// first the program event handler gets a chance to process the command
|
||||
DoOnProcessCommand(Command, AChar, Data);
|
||||
if Command <> ecNone then begin
|
||||
@ -7625,6 +7709,11 @@ begin
|
||||
if Command <> ecNone then
|
||||
{$ENDIF}
|
||||
DoOnCommandProcessed(Command, AChar, Data);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
finally
|
||||
EndUndoBlock;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.ExecuteCommand(Command: TSynEditorCommand;
|
||||
@ -7723,7 +7812,7 @@ begin
|
||||
{begin
|
||||
MoveCaretAndSelectionPhysical(CaretXY,Point(1, CaretY),
|
||||
Command = ecSelLineStart);
|
||||
fLastCaretX := fCaretX;
|
||||
fLastCaretX := CaretX;
|
||||
end;}
|
||||
ecLineEnd, ecSelLineEnd:
|
||||
begin
|
||||
@ -7838,7 +7927,7 @@ begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if fTextView.FoldedAtTextIndex[CaretNew.Y - 1] then begin
|
||||
CY := FindNextUnfoldedLine(CaretNew.Y, False);
|
||||
CaretNew := LogicalToPhysicalPos(Point(1 + Length(fLines[CY-1]), CY));
|
||||
CaretNew := LogicalToPhysicalPos(Point(1 + Length(Lines[CY-1]), CY));
|
||||
end;
|
||||
MoveCaretAndSelectionPhysical
|
||||
{$ELSE}
|
||||
@ -7890,6 +7979,10 @@ begin
|
||||
// only move caret one column
|
||||
Helper := ' ';
|
||||
CaretX := CaretX - 1;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
// behind EOL, there was no char to delete, this wa a simple cursor move, do not undo
|
||||
Caret := CaretXY;
|
||||
{$ENDIF}
|
||||
end else if CaretX = 1 then begin
|
||||
// join this line with the last line if possible
|
||||
if CaretY > 1 then begin
|
||||
@ -7902,8 +7995,10 @@ begin
|
||||
{$ENDIF}
|
||||
Lines.Delete(CaretY);
|
||||
DoLinesDeleted(CaretY, 1);
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
if eoTrimTrailingSpaces in Options then
|
||||
Temp := TrimRight(Temp);
|
||||
{$ENDIF}
|
||||
LineText := LineText + Temp;
|
||||
Helper := {$IFDEF SYN_LAZARUS}LineEnding{$ELSE}#13#10{$ENDIF};
|
||||
end;
|
||||
@ -7941,7 +8036,7 @@ begin
|
||||
// ' LogCaretXY.X=',dbgs(LogCaretXY.X),
|
||||
// ' Temp="',DbgStr(Temp),'" Helper="',DbgStr(Helper),'"');
|
||||
Temp:=copy(Temp,1,LogSpacePos-1)+copy(Temp,LogCaretXY.X,MaxInt);
|
||||
TrimmedSetLine(CaretY - 1, Temp);
|
||||
Lines[CaretY - 1] := Temp;
|
||||
CaretX := LogicalToPhysicalCol(Temp,LogSpacePos);
|
||||
{$ELSE}
|
||||
Helper := Copy(Temp, 1, SpaceCount1 - SpaceCount2);
|
||||
@ -7968,6 +8063,7 @@ begin
|
||||
//debugln('ecDeleteLastChar delete char CaretX=',dbgs(CaretX),
|
||||
// ' Helper="',DbgStr(Helper),'" Temp="',DbgStr(Temp),'"');
|
||||
{$ENDIF USE_UTF8BIDI_LCL}
|
||||
Lines[CaretY - 1] := Temp;
|
||||
{$ELSE}
|
||||
{$IFDEF SYN_MBCSSUPPORT}
|
||||
if ByteType(Temp, CaretX - 2) = mbLeadByte then
|
||||
@ -7976,11 +8072,11 @@ begin
|
||||
CaretX := CaretX - counter;
|
||||
Helper := Copy(Temp, CaretX, counter);
|
||||
Delete(Temp, CaretX, counter);
|
||||
TrimmedSetLine(CaretY - 1, Temp);
|
||||
{$ENDIF}
|
||||
TrimmedSetLine(CaretY - 1, Temp);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
if (Caret.X <> CaretX) or (Caret.Y <> CaretY) then begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if eoGroupUndo in Options then begin
|
||||
@ -8035,7 +8131,7 @@ begin
|
||||
{$ELSE USE_UTF8BIDI_LCL}
|
||||
System.Delete(Temp, LogCaretXY.X, Counter);
|
||||
{$ENDIF USE_UTF8BIDI_LCL}
|
||||
TrimmedSetLine(CaretY - 1, Temp);
|
||||
Lines[CaretY - 1] := Temp;
|
||||
{$ELSE}
|
||||
counter := 1;
|
||||
{$IFDEF SYN_MBCSSUPPORT}
|
||||
@ -8051,7 +8147,11 @@ begin
|
||||
// join line with the line after
|
||||
if CaretY < Lines.Count then begin
|
||||
Helper := StringOfChar(' ', CaretX - 1 - Len);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Lines[CaretY - 1] := Temp + Helper + Lines[CaretY];
|
||||
{$ELSE}
|
||||
TrimmedSetLine(CaretY - 1, Temp + Helper + Lines[CaretY]);
|
||||
{$ENDIF}
|
||||
Caret := Point(1, CaretY + 1);
|
||||
Helper := {$IFDEF SYN_LAZARUS}LineEnding{$ELSE}#13#10{$ENDIF};
|
||||
Lines.Delete(CaretY);
|
||||
@ -8194,7 +8294,7 @@ begin
|
||||
// break line in two
|
||||
SpaceCount1 := LeftSpaces(Temp);
|
||||
Temp := Copy(LineText, 1, LogCaretXY.X - 1);
|
||||
TrimmedSetLine(CaretY - 1, Temp);
|
||||
Lines[CaretY - 1] := Temp;
|
||||
Delete(Temp2, 1, LogCaretXY.X - 1);
|
||||
if Assigned(Beautifier) then
|
||||
SpaceCount1:=Beautifier.GetIndentForLineBreak(Self,LogCaretXY,Temp2);
|
||||
@ -8215,8 +8315,8 @@ begin
|
||||
end;
|
||||
end else begin
|
||||
// current line is empty (len = 0)
|
||||
if fLines.Count = 0 then
|
||||
fLines.Add('');
|
||||
if Lines.Count = 0 then
|
||||
Lines.Add('');
|
||||
// linebreak after end of line
|
||||
fUndoList.AddChange(crLineBreak,
|
||||
LogCaretXY, LogCaretXY,
|
||||
@ -8235,7 +8335,7 @@ begin
|
||||
end;
|
||||
Lines.Insert(CaretY, '');
|
||||
if Command = ecLineBreak then begin
|
||||
if (SpaceCount2 > 0) and (not (eoScrollPastEol in Options)) then
|
||||
if (SpaceCount2 > 0) then
|
||||
Lines[CaretY] := StringOfChar(' ', SpaceCount2);
|
||||
CaretXY := Point(SpaceCount2 + 1, CaretY + 1);
|
||||
end;
|
||||
@ -8342,6 +8442,12 @@ begin
|
||||
{end} //mh 2000-11-20
|
||||
end else begin
|
||||
Temp := LineText;
|
||||
// Added the check for whether or not we're in insert mode.
|
||||
// If we are, we append one less space than we would in overwrite mode.
|
||||
// This is because in overwrite mode we have to put in a final space
|
||||
// character which will be overwritten with the typed character. If we put the
|
||||
// extra space in in insert mode, it would be left at the end of the line and
|
||||
// cause problems unless eoTrimTrailingSpaces is set.
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
LogCaretXY:=PhysicalToLogicalPos(CaretXY);
|
||||
{debugln('ecChar CaretXY=',dbgs(CaretXY),
|
||||
@ -8371,7 +8477,7 @@ begin
|
||||
//debugln('ecChar Temp=',DbgStr(Temp),' AChar=',DbgStr(AChar));
|
||||
CaretX := CaretX + 1;
|
||||
{$ENDIF}
|
||||
TrimmedSetLine(CaretY - 1, Temp);
|
||||
Lines[CaretY - 1] := Temp;
|
||||
fUndoList.AddChange(crInsert, StartOfBlock,
|
||||
PhysicalToLogicalPos(CaretXY), '', smNormal);
|
||||
end else begin
|
||||
@ -8392,7 +8498,7 @@ begin
|
||||
Temp:=Temp+StringOfChar(' ', LogCaretXY.X-1-Len)+AChar;
|
||||
{$ENDIF}
|
||||
CaretNew := Point((CaretX + 1), CaretY);
|
||||
TrimmedSetLine(CaretY - 1, Temp);
|
||||
Lines[CaretY - 1] := Temp;
|
||||
fUndoList.AddChange(crInsert,
|
||||
StartOfBlock, PhysicalToLogicalPos(CaretNew),
|
||||
Helper, smNormal);
|
||||
@ -8405,12 +8511,6 @@ begin
|
||||
end;
|
||||
{$ELSE below for NOT SYN_LAZARUS ----------------------------------}
|
||||
bChangeScroll := not (eoScrollPastEol in fOptions);
|
||||
// Added the check for whether or not we're in insert mode.
|
||||
// If we are, we append one less space than we would in overwrite mode.
|
||||
// This is because in overwrite mode we have to put in a final space
|
||||
// character which will be overwritten with the typed character. If we put the
|
||||
// extra space in in insert mode, it would be left at the end of the line and
|
||||
// cause problems unless eoTrimTrailingSpaces is set.
|
||||
try
|
||||
if bChangeScroll then Include(fOptions, eoScrollPastEol);
|
||||
StartOfBlock := CaretXY;
|
||||
@ -8697,7 +8797,7 @@ begin
|
||||
FindFirstNonWhiteSpaceCharInNextLine;
|
||||
end else begin
|
||||
if fHighlighter<>nil then begin
|
||||
fHighlighter.SetRange(TSynEditStringList(Lines).Ranges[CY - 1]);
|
||||
fHighlighter.SetRange(TSynEditStrings(Lines).Ranges[CY - 1]);
|
||||
fHighlighter.SetLine(Line, CY - 1);
|
||||
while not fHighlighter.GetEol do begin
|
||||
nTokenPos := fHighlighter.GetTokenPos; // zero-based
|
||||
@ -8767,7 +8867,7 @@ begin
|
||||
WhiteChars := [#1..#255] - CurIdentChars;
|
||||
{$ENDIF}
|
||||
LineLen := Length(Line);
|
||||
|
||||
|
||||
if CX >{$IFNDEF SYN_LAZARUS}={$ENDIF} LineLen then begin
|
||||
// find first IdentChar in the next line
|
||||
if CY < Lines.Count then begin
|
||||
@ -8900,6 +9000,9 @@ end;
|
||||
procedure TCustomSynEdit.BeginUndoBlock;
|
||||
begin
|
||||
fUndoList.BeginBlock;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditStringTrimmingList(fTrimLines).Lock;
|
||||
{$ENDIF}
|
||||
end;
|
||||
{end} //sbs 2000-11-19
|
||||
|
||||
@ -8911,6 +9014,11 @@ end;
|
||||
{begin} //sbs 2000-11-19
|
||||
procedure TCustomSynEdit.EndUndoBlock;
|
||||
begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
// Write all trimming info to the end of the undo block,
|
||||
// so it will be undone first, and other UndoItems do see the expected spaces
|
||||
TSynEditStringTrimmingList(fTrimLines).UnLock;
|
||||
{$ENDIF}
|
||||
fUndoList.EndBlock;
|
||||
end;
|
||||
{end} //sbs 2000-11-19
|
||||
@ -8968,7 +9076,7 @@ begin
|
||||
loop := 0;
|
||||
while (loop < (p.Y - 1)) and (loop < Lines.Count) do
|
||||
begin
|
||||
result := result + llen(lines[loop]);
|
||||
result := result + llen(Lines[loop]);
|
||||
inc(loop);
|
||||
end;
|
||||
if loop < Lines.Count then
|
||||
@ -8989,7 +9097,7 @@ begin
|
||||
loop := 0;
|
||||
count := 0;
|
||||
while (loop < Lines.Count) and (count + llen(lines[loop]) < value) do begin
|
||||
count := count + llen(lines[loop]);
|
||||
count := count + llen(Lines[loop]);
|
||||
inc(loop);
|
||||
end;
|
||||
{ CaretX := value - count;
|
||||
@ -9025,7 +9133,7 @@ begin
|
||||
result := 0;
|
||||
loop := 0;
|
||||
while (loop < (p.y - 1)) and (loop < Lines.Count) do begin
|
||||
Result := result + llen(lines[loop]);
|
||||
Result := result + llen(Lines[loop]);
|
||||
inc(loop);
|
||||
end;
|
||||
if loop<Lines.Count then
|
||||
@ -9047,7 +9155,7 @@ begin
|
||||
loop := 0;
|
||||
count := 0;
|
||||
while (loop < Lines.Count) and (count + llen(lines[loop]) < value) do begin
|
||||
count := count + llen(lines.strings[loop]);
|
||||
count := count + llen(Lines.strings[loop]);
|
||||
inc(loop);
|
||||
end;
|
||||
p.x := value - count; p.y := loop + 1;
|
||||
@ -9228,7 +9336,7 @@ begin
|
||||
Value := MinMax(Value, 1{0}, 256); //lt 2000-10-19
|
||||
if (Value <> fTabWidth) then begin
|
||||
fTabWidth := Value;
|
||||
TSynEditStringList(Lines).TabWidth := Value; //mh 2000-10-19
|
||||
TSynEditStringList(fLines).TabWidth := Value; //mh 2000-10-19
|
||||
Invalidate; // to redraw text containing tab chars
|
||||
end;
|
||||
end;
|
||||
@ -9554,6 +9662,9 @@ begin
|
||||
{$ENDIF}
|
||||
bSetDrag := (eoDropFiles in fOptions) <> (eoDropFiles in Value);
|
||||
fOptions := Value;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditStringTrimmingList(fTrimLines).Enabled := eoTrimTrailingSpaces in fOptions;
|
||||
{$ENDIF}
|
||||
// Reset column position in case Cursor is past EOL.
|
||||
if not (eoScrollPastEol in fOptions) then
|
||||
CaretX := CaretX;
|
||||
@ -10353,7 +10464,7 @@ begin
|
||||
// calculate line start position
|
||||
FirstNonBlank:=-1;
|
||||
if CaretY<=Lines.Count then begin
|
||||
s:=fLines[CaretXY.Y-1];
|
||||
s:=Lines[CaretXY.Y-1];
|
||||
|
||||
// search first non blank char pos
|
||||
FirstNonBlank:=1;
|
||||
@ -10618,7 +10729,7 @@ var
|
||||
end;
|
||||
// Init the Highlighter only once per line
|
||||
if MaxKnownTokenPos < 1 then begin
|
||||
fHighlighter.SetRange(TSynEditStringList(Lines).Ranges[PosY - 1]);
|
||||
fHighlighter.SetRange(TSynEditStrings(Lines).Ranges[PosY - 1]);
|
||||
fHighlighter.SetLine(Line, PosY - 1);
|
||||
TokenListCnt := 0;
|
||||
end
|
||||
@ -10828,7 +10939,11 @@ begin
|
||||
if Assigned(Highlighter) and (PosY >= 0) and (PosY < Lines.Count) then
|
||||
begin
|
||||
Line := Lines[PosY];
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Highlighter.SetRange(TSynEditStrings(Lines).Ranges[PosY]);
|
||||
{$ELSE}
|
||||
Highlighter.SetRange(TSynEditStringList(Lines).Ranges[PosY]);
|
||||
{$ENDIF}
|
||||
Highlighter.SetLine(Line, PosY);
|
||||
PosX := XY.X;
|
||||
if (PosX > 0) and (PosX <= Length(Line)) then begin
|
||||
@ -10900,7 +11015,7 @@ begin
|
||||
y:=Line-1;
|
||||
if y>Lines.Count then y:=Lines.Count;
|
||||
while y>=1 do begin
|
||||
s:=fLines[y-1];
|
||||
s:=Lines[y-1];
|
||||
FirstNonBlank:=1;
|
||||
while (FirstNonBlank<=length(s)) and (s[FirstNonBlank] in [' ',#9]) do
|
||||
inc(FirstNonBlank);
|
||||
@ -11296,6 +11411,7 @@ begin
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
procedure TCustomSynEdit.TrimmedSetLine(ALine: integer; ALineText: string);
|
||||
begin
|
||||
if eoTrimTrailingSpaces in Options then
|
||||
@ -11303,6 +11419,7 @@ begin
|
||||
else
|
||||
Lines[ALine] := ALineText;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{ TSynEditMark }
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ interface
|
||||
|
||||
uses
|
||||
LCLProc,
|
||||
Classes, SysUtils, SynEditTextBuffer;
|
||||
Classes, SysUtils, SynEditTypes, SynEditTextBuffer, SynEditTextBase;
|
||||
|
||||
type
|
||||
|
||||
@ -162,7 +162,7 @@ type
|
||||
|
||||
TSynEditFoldedView = class {TODO: Make a base class, that just maps everything one to one}
|
||||
private
|
||||
fLines : TSynEditStringList;
|
||||
fLines : TSynEditStrings;
|
||||
fFoldTree : TSynTextFoldAVLTree; // Folds are stored 1-based (the 1st line is 1)
|
||||
fTopLine : Integer;
|
||||
fLinesInWindow : Integer; // there may be an additional part visible line
|
||||
@ -199,7 +199,7 @@ type
|
||||
Procedure LinesDeletedAtViewPos(AStartPos, ALineCount : Integer;
|
||||
SkipFixFolding : Boolean = False);
|
||||
public
|
||||
constructor Create(aTextBuffer : TSynEditStringList);
|
||||
constructor Create(aTextBuffer : TSynEditStringList; aTextView : TSynEditStrings);
|
||||
destructor Destroy; override;
|
||||
|
||||
// Converting between Folded and Unfolded Lines/Indexes
|
||||
@ -1308,13 +1308,13 @@ end;
|
||||
|
||||
{ TSynEditFoldedView }
|
||||
|
||||
constructor TSynEditFoldedView.Create(aTextBuffer : TSynEditStringList);
|
||||
constructor TSynEditFoldedView.Create(aTextBuffer : TSynEditStringList; aTextView : TSynEditStrings);
|
||||
begin
|
||||
fLines := aTextBuffer;
|
||||
fLines := aTextView;
|
||||
fFoldTree := TSynTextFoldAVLTree.Create;
|
||||
fTopLine := 0;
|
||||
fLinesInWindow := -1;
|
||||
fLines.OnLineCountChanged := {$IFDEF FPC}@{$ENDIF}LineCountChanged;
|
||||
aTextBuffer.OnLineCountChanged := {$IFDEF FPC}@{$ENDIF}LineCountChanged;
|
||||
end;
|
||||
|
||||
destructor TSynEditFoldedView.Destroy;
|
||||
|
||||
@ -26,7 +26,7 @@ unit SynEditMarkup;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Graphics, SynEditTextBuffer, SynEditMiscClasses, Controls, SynEditHighlighter;
|
||||
Classes, SysUtils, Graphics, SynEditTextBase, SynEditTextBuffer, SynEditMiscClasses, Controls, SynEditHighlighter;
|
||||
|
||||
type
|
||||
|
||||
@ -38,7 +38,7 @@ type
|
||||
TSynEditMarkup = class(TObject)
|
||||
private
|
||||
fMarkupInfo : TSynSelectedColor;
|
||||
fLines : TSynEditStringList;
|
||||
fLines : TSynEditStrings;
|
||||
fCaret : TPoint;
|
||||
fTopLine, FLinesInWindow : Integer;
|
||||
fSynEdit : TCustomControl;
|
||||
@ -54,7 +54,7 @@ type
|
||||
procedure MarkupChanged(AMarkup: TObject);
|
||||
protected
|
||||
procedure SetInvalidateLinesMethod(const AValue : TInvalidateLines); virtual;
|
||||
procedure SetLines(const AValue : TSynEditStringList); virtual;
|
||||
procedure SetLines(const AValue : TSynEditStrings); virtual;
|
||||
procedure SetTopLine(const AValue : Integer); virtual;
|
||||
procedure SetLinesInWindow(const AValue : Integer); virtual;
|
||||
procedure SetCaret(const AValue : TPoint); virtual;
|
||||
@ -84,7 +84,7 @@ type
|
||||
property FGColor : TColor read GetFGColor;
|
||||
property BGColor : TColor read GetBGColor;
|
||||
property Style : TFontStyles read GetStyle;
|
||||
property Lines : TSynEditStringList read fLines write SetLines;
|
||||
property Lines : TSynEditStrings read fLines write SetLines;
|
||||
property Caret : TPoint read fCaret write SetCaret;
|
||||
property TopLine : Integer read fTopLine write SetTopLine;
|
||||
property LinesInWindow : Integer read fLinesInWindow write SetLinesInWindow;
|
||||
@ -99,7 +99,7 @@ type
|
||||
|
||||
protected
|
||||
procedure SetInvalidateLinesMethod(const AValue : TInvalidateLines); override;
|
||||
procedure SetLines(const AValue : TSynEditStringList); override;
|
||||
procedure SetLines(const AValue : TSynEditStrings); override;
|
||||
procedure SetTopLine(const AValue : Integer); override;
|
||||
procedure SetLinesInWindow(const AValue : Integer); override;
|
||||
procedure SetCaret(const AValue : TPoint); override;
|
||||
@ -161,7 +161,7 @@ begin
|
||||
DoMarkupChanged(AMarkup as TSynSelectedColor);
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkup.SetLines(const AValue : TSynEditStringList);
|
||||
procedure TSynEditMarkup.SetLines(const AValue : TSynEditStrings);
|
||||
begin
|
||||
if fLines = AValue then exit;
|
||||
fLines := AValue;
|
||||
@ -365,7 +365,7 @@ begin
|
||||
TSynEditMarkup(fMarkUpList[i]).SetInvalidateLinesMethod(AValue);
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupManager.SetLines(const AValue : TSynEditStringList);
|
||||
procedure TSynEditMarkupManager.SetLines(const AValue : TSynEditStrings);
|
||||
var
|
||||
i : integer;
|
||||
begin
|
||||
|
||||
@ -239,7 +239,7 @@ type
|
||||
end;
|
||||
|
||||
{ TSynInternalImage }
|
||||
|
||||
|
||||
TSynInternalImage = class(TObject)
|
||||
public
|
||||
constructor Create(const AName: string; Count: integer);
|
||||
@ -250,8 +250,8 @@ type
|
||||
LineHeight: integer; TransparentColor: TColor);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
{ TSynEditSearchCustom }
|
||||
|
||||
TSynEditSearchCustom = class(TComponent)
|
||||
@ -420,7 +420,7 @@ procedure TSynGutter.AutoSizeDigitCount(LinesCount: integer);
|
||||
var
|
||||
nDigits: integer;
|
||||
begin
|
||||
if fVisible and fAutoSize and fShowLineNumbers then begin
|
||||
if fVisible and fAutoSize and fShowLineNumbers then begin
|
||||
if fZeroStart then Dec(LinesCount);
|
||||
nDigits := Max(Length(IntToStr(LinesCount)), fDigitCount);
|
||||
if fAutoSizeDigitCount <> nDigits then begin
|
||||
@ -458,7 +458,7 @@ begin
|
||||
Result := 0;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if fShowLineNumbers then
|
||||
Result := fLeftOffset + fRightOffset + fAutoSizeDigitCount * CharWidth + 2
|
||||
else
|
||||
|
||||
102
components/synedit/synedittextbase.pas
Normal file
102
components/synedit/synedittextbase.pas
Normal file
@ -0,0 +1,102 @@
|
||||
{-------------------------------------------------------------------------------
|
||||
The contents of this file are subject to the Mozilla Public License
|
||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||
the specific language governing rights and limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
GNU General Public License Version 2 or later (the "GPL"), in which case
|
||||
the provisions of the GPL are applicable instead of those above.
|
||||
If you wish to allow use of your version of this file only under the terms
|
||||
of the GPL and not to allow others to use your version of this file
|
||||
under the MPL, indicate your decision by deleting the provisions above and
|
||||
replace them with the notice and other provisions required by the GPL.
|
||||
If you do not delete the provisions above, a recipient may use your version
|
||||
of this file under either the MPL or the GPL.
|
||||
|
||||
-------------------------------------------------------------------------------}
|
||||
unit SynEditTextBase;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, SynEditTypes;
|
||||
|
||||
type
|
||||
|
||||
{ TSynEditStrings }
|
||||
|
||||
TSynEditStrings = class(TStrings)
|
||||
protected
|
||||
function GetFoldEndLevel(Index: integer): integer; virtual; abstract;
|
||||
function GetFoldMinLevel(Index: integer): integer; virtual; abstract;
|
||||
procedure SetFoldEndLevel(Index: integer; const AValue: integer); virtual; abstract;
|
||||
procedure SetFoldMinLevel(Index: integer; const AValue: integer); virtual; abstract;
|
||||
function GetRange(Index: integer): TSynEditRange; virtual; abstract;
|
||||
procedure PutRange(Index: integer; ARange: TSynEditRange); virtual; abstract;
|
||||
function GetExpandedString(Index: integer): string; virtual; abstract;
|
||||
function GetLengthOfLongestLine: integer; virtual; abstract;
|
||||
procedure SetTextStr(const Value: string); override;
|
||||
public
|
||||
procedure DeleteLines(Index, NumLines: integer); virtual; abstract;
|
||||
procedure InsertLines(Index, NumLines: integer); virtual; abstract;
|
||||
procedure InsertStrings(Index: integer; NewStrings: TStrings); virtual; abstract;
|
||||
procedure ClearRanges(ARange: TSynEditRange); virtual; abstract;
|
||||
public
|
||||
property ExpandedStrings[Index: integer]: string read GetExpandedString;
|
||||
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
||||
property Ranges[Index: integer]: TSynEditRange read GetRange write PutRange;
|
||||
property FoldMinLevel[Index: integer]: integer read GetFoldMinLevel
|
||||
write SetFoldMinLevel;
|
||||
property FoldEndLevel[Index: integer]: integer read GetFoldEndLevel
|
||||
write SetFoldEndLevel;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
{ TSynEditStrings }
|
||||
|
||||
procedure TSynEditStrings.SetTextStr(const Value : string);
|
||||
var
|
||||
StartPos: Integer;
|
||||
p: Integer;
|
||||
Len: Integer;
|
||||
sl: TStringList;
|
||||
begin
|
||||
BeginUpdate;
|
||||
sl:=TStringList.Create;
|
||||
try
|
||||
Clear;
|
||||
p:=1;
|
||||
StartPos:=p;
|
||||
Len:=length(Value);
|
||||
while p<=Len do begin
|
||||
if not (Value[p] in [#10,#13]) then begin
|
||||
inc(p);
|
||||
end else begin
|
||||
sl.Add(copy(Value,StartPos,p-StartPos));
|
||||
inc(p);
|
||||
if (p<=Len) and (Value[p] in [#10,#13]) and (Value[p-1]<>Value[p]) then
|
||||
inc(p);
|
||||
StartPos:=p;
|
||||
end;
|
||||
end;
|
||||
if StartPos<=Len then
|
||||
sl.Add(copy(Value,StartPos,Len-StartPos+1));
|
||||
AddStrings(sl);
|
||||
finally
|
||||
sl.Free;
|
||||
EndUpdate;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@ -44,7 +44,7 @@ interface
|
||||
uses
|
||||
Classes, SysUtils,
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
FileUtil, LCLProc, FPCAdds, LCLIntf, LCLType,
|
||||
FileUtil, LCLProc, FPCAdds, LCLIntf, LCLType, SynEditTextBase,
|
||||
{$ELSE}
|
||||
Windows,
|
||||
{$ENDIF}
|
||||
@ -52,7 +52,9 @@ uses
|
||||
|
||||
type
|
||||
{begin} //mh 2000-10-10
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
TSynEditRange = pointer;
|
||||
{$ENDIF}
|
||||
|
||||
{begin} //mh 2000-10-19
|
||||
TSynEditStringFlag = (sfHasTabs, sfHasNoTabs, sfExpandedLengthUnknown);
|
||||
@ -84,14 +86,18 @@ type
|
||||
PSynEditStringRecList = ^TSynEditStringRecList;
|
||||
TSynEditStringRecList = array[0..MaxSynEditStrings - 1] of TSynEditStringRec;
|
||||
|
||||
TStringListIndexEvent = procedure(Index: Integer) of object;
|
||||
TStringListIndexEvent = procedure(Index: Integer) of object;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TStringListLineCountEvent = procedure(Index, Count: Integer) of object;
|
||||
{$ENDIF}
|
||||
|
||||
{ TSynEditStringList }
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditStringList = class(TSynEditStrings)
|
||||
{$ELSE}
|
||||
TSynEditStringList = class(TStrings)
|
||||
{$ENDIF}
|
||||
private
|
||||
fList: PSynEditStringRecList;
|
||||
fCount: integer;
|
||||
@ -111,18 +117,22 @@ type
|
||||
function ExpandedString(Index: integer): string;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function ExpandedStringLength(Index: integer): integer;
|
||||
function GetFoldEndLevel(Index: integer): integer;
|
||||
function GetFoldMinLevel(Index: integer): integer;
|
||||
procedure SetFoldEndLevel(Index: integer; const AValue: integer);
|
||||
procedure SetFoldMinLevel(Index: integer; const AValue: integer);
|
||||
function GetFoldEndLevel(Index: integer): integer; override;
|
||||
function GetFoldMinLevel(Index: integer): integer; override;
|
||||
procedure SetFoldEndLevel(Index: integer; const AValue: integer); override;
|
||||
procedure SetFoldMinLevel(Index: integer; const AValue: integer); override;
|
||||
{$ENDIF}
|
||||
{$IFNDEF SYN_LAZARUS} // protected in SynLazarus
|
||||
function GetExpandedString(Index: integer): string;
|
||||
function GetLengthOfLongestLine: integer;
|
||||
{$ENDIF}
|
||||
{end} //mh 2000-10-19
|
||||
function GetRange(Index: integer): TSynEditRange;
|
||||
{$IFDEF SYN_LAZARUS}override;{$ENDIF}
|
||||
procedure Grow;
|
||||
procedure InsertItem(Index: integer; const S: string);
|
||||
procedure PutRange(Index: integer; ARange: TSynEditRange);
|
||||
{$IFDEF SYN_LAZARUS}override;{$ENDIF}
|
||||
protected
|
||||
fOnAdded: TStringListIndexEvent;
|
||||
fOnCleared: TNotifyEvent;
|
||||
@ -131,6 +141,8 @@ type
|
||||
fOnPutted: TStringListIndexEvent;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fOnLineCountChanged : TStringListLineCountEvent;
|
||||
function GetExpandedString(Index: integer): string; override;
|
||||
function GetLengthOfLongestLine: integer; override;
|
||||
{$ENDIF}
|
||||
function Get(Index: integer): string; override;
|
||||
function GetCapacity: integer;
|
||||
@ -143,9 +155,6 @@ type
|
||||
{$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF} //mh 2000-10-18
|
||||
procedure SetTabWidth(Value: integer); //mh 2000-10-19
|
||||
procedure SetUpdateState(Updating: Boolean); override;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure SetTextStr(const Value: string); override;
|
||||
{$ENDIF}
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -154,14 +163,17 @@ type
|
||||
procedure Clear; override;
|
||||
procedure Delete(Index: integer); override;
|
||||
procedure DeleteLines(Index, NumLines: integer); // DJLP 2000-11-01
|
||||
{$IFDEF SYN_LAZARUS}override;{$ENDIF}
|
||||
procedure Exchange(Index1, Index2: integer); override;
|
||||
procedure Insert(Index: integer; const S: string); override;
|
||||
procedure InsertLines(Index, NumLines: integer); // DJLP 2000-11-01
|
||||
{$IFDEF SYN_LAZARUS}override;{$ENDIF}
|
||||
procedure InsertStrings(Index: integer; NewStrings: TStrings); // DJLP 2000-11-01
|
||||
{$IFDEF SYN_LAZARUS}override;{$ENDIF}
|
||||
procedure LoadFromFile(const FileName: string); override;
|
||||
procedure SaveToFile(const FileName: string); override;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure ClearRanges(ARange: TSynEditRange);
|
||||
procedure ClearRanges(ARange: TSynEditRange); override;
|
||||
{$ENDIF}
|
||||
public
|
||||
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
|
||||
@ -199,7 +211,7 @@ type
|
||||
crDeleteAfterCursor, crDelete, {crSelDelete, crDragDropDelete, } //mh 2000-11-20
|
||||
crLineBreak, crIndent, crUnindent,
|
||||
crSilentDelete, crSilentDeleteAfterCursor, //mh 2000-10-30
|
||||
crNothing);
|
||||
crNothing {$IFDEF SYN_LAZARUS}, crTrimSpace {$ENDIF});
|
||||
|
||||
{ TSynEditUndoItem }
|
||||
|
||||
@ -1075,42 +1087,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure TSynEditStringList.SetTextStr(const Value: string);
|
||||
var
|
||||
StartPos: Integer;
|
||||
p: Integer;
|
||||
Len: Integer;
|
||||
sl: TStringList;
|
||||
begin
|
||||
BeginUpdate;
|
||||
sl:=TStringList.Create;
|
||||
try
|
||||
Clear;
|
||||
p:=1;
|
||||
StartPos:=p;
|
||||
Len:=length(Value);
|
||||
while p<=Len do begin
|
||||
if not (Value[p] in [#10,#13]) then begin
|
||||
inc(p);
|
||||
end else begin
|
||||
sl.Add(copy(Value,StartPos,p-StartPos));
|
||||
inc(p);
|
||||
if (p<=Len) and (Value[p] in [#10,#13]) and (Value[p-1]<>Value[p]) then
|
||||
inc(p);
|
||||
StartPos:=p;
|
||||
end;
|
||||
end;
|
||||
if StartPos<=Len then
|
||||
sl.Add(copy(Value,StartPos,Len-StartPos+1));
|
||||
AddStrings(sl);
|
||||
finally
|
||||
sl.Free;
|
||||
EndUpdate;
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{ TSynEditUndoList }
|
||||
|
||||
constructor TSynEditUndoList.Create;
|
||||
@ -1191,8 +1167,8 @@ end;
|
||||
procedure TSynEditUndoList.EndBlock;
|
||||
begin
|
||||
if fBlockCount > 0 then begin
|
||||
Dec(fBlockCount);
|
||||
if fBlockCount = 0 then begin
|
||||
Dec(fBlockCount);
|
||||
if fBlockCount = 0 then begin
|
||||
fBlockChangeNumber := 0;
|
||||
Inc(fNextChangeNumber);
|
||||
if fNextChangeNumber = 0 then
|
||||
|
||||
435
components/synedit/synedittexttrimmer.pas
Normal file
435
components/synedit/synedittexttrimmer.pas
Normal file
@ -0,0 +1,435 @@
|
||||
{-------------------------------------------------------------------------------
|
||||
The contents of this file are subject to the Mozilla Public License
|
||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||
the specific language governing rights and limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
GNU General Public License Version 2 or later (the "GPL"), in which case
|
||||
the provisions of the GPL are applicable instead of those above.
|
||||
If you wish to allow use of your version of this file only under the terms
|
||||
of the GPL and not to allow others to use your version of this file
|
||||
under the MPL, indicate your decision by deleting the provisions above and
|
||||
replace them with the notice and other provisions required by the GPL.
|
||||
If you do not delete the provisions above, a recipient may use your version
|
||||
of this file under either the MPL or the GPL.
|
||||
|
||||
-------------------------------------------------------------------------------}
|
||||
|
||||
unit SynEditTextTrimmer;
|
||||
|
||||
{$I synedit.inc}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
LCLProc,
|
||||
Classes, SysUtils, SynEditTypes, SynEditTextBase, SynEditTextBuffer, SynEditMiscClasses;
|
||||
|
||||
type
|
||||
|
||||
{ TSynEditStringTrimmingList }
|
||||
|
||||
TSynEditStringTrimmingList = class(TSynEditStrings)
|
||||
private
|
||||
fSynStrings: TSynEditStrings;
|
||||
fCaret: TSynEditCaret;
|
||||
fUndoList: TSynEditUndoList;
|
||||
fSpaces: String;
|
||||
fLineText: String;
|
||||
fLineIndex: Integer;
|
||||
fEnabled: Boolean;
|
||||
fLockCount: Integer;
|
||||
fLockList : TStringList;
|
||||
procedure DoCaretChanged(Sender : TObject);
|
||||
procedure SetEnabled(const AValue : Boolean);
|
||||
function TrimLine(const S : String; Index: Integer) : String;
|
||||
function Spaces(Index: Integer) : String;
|
||||
procedure DoLinesChanged(Index, N: integer);
|
||||
procedure TrimAfterLock;
|
||||
protected
|
||||
function GetFoldEndLevel(Index: integer): integer; override;
|
||||
function GetFoldMinLevel(Index: integer): integer; override;
|
||||
procedure SetFoldEndLevel(Index: integer; const AValue: integer); override;
|
||||
procedure SetFoldMinLevel(Index: integer; const AValue: integer); override;
|
||||
function GetRange(Index: integer): TSynEditRange; override;
|
||||
procedure PutRange(Index: integer; ARange: TSynEditRange); override;
|
||||
|
||||
function GetCount: integer; override;
|
||||
function GetCapacity: integer;
|
||||
{$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF}
|
||||
procedure SetCapacity(NewCapacity: integer);
|
||||
{$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF}
|
||||
|
||||
function GetExpandedString(Index: integer): string; override;
|
||||
function GetLengthOfLongestLine: integer; override;
|
||||
function Get(Index: integer): string; override;
|
||||
function GetObject(Index: integer): TObject; override;
|
||||
procedure Put(Index: integer; const S: string); override;
|
||||
procedure PutObject(Index: integer; AObject: TObject); override;
|
||||
|
||||
procedure SetUpdateState(Updating: Boolean); override;
|
||||
public
|
||||
constructor Create(ASynStringSource: TSynEditStrings; ACaret: TSynEditCaret);
|
||||
destructor Destroy; override;
|
||||
|
||||
function Add(const S: string): integer; override;
|
||||
procedure AddStrings(AStrings: TStrings); override;
|
||||
procedure Clear; override;
|
||||
procedure Delete(Index: integer); override;
|
||||
procedure DeleteLines(Index, NumLines: integer); override;
|
||||
procedure Insert(Index: integer; const S: string); override;
|
||||
procedure InsertLines(Index, NumLines: integer); override;
|
||||
procedure InsertStrings(Index: integer; NewStrings: TStrings); override;
|
||||
procedure Exchange(Index1, Index2: integer); override;
|
||||
procedure ClearRanges(ARange: TSynEditRange); override;
|
||||
property ExpandedStrings[Index: integer]: string read GetExpandedString;
|
||||
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
||||
public
|
||||
procedure Lock;
|
||||
procedure UnLock;
|
||||
procedure ForceTrim; // for redo; redo can not wait for UnLock
|
||||
property Enabled : Boolean read fEnabled write SetEnabled;
|
||||
property UndoList: TSynEditUndoList read fUndoList write fUndoList;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
{ TSynEditStringTrimmingList }
|
||||
|
||||
constructor TSynEditStringTrimmingList.Create(ASynStringSource : TSynEditStrings; ACaret: TSynEditCaret);
|
||||
begin
|
||||
Inherited Create;
|
||||
fSynStrings := ASynStringSource;
|
||||
fCaret := ACaret;
|
||||
fCaret.AddChangeHandler(@DoCaretChanged);
|
||||
fLockList := TStringList.Create;
|
||||
fLineIndex:= -1;
|
||||
fSpaces := '';
|
||||
fEnabled:=false;
|
||||
end;
|
||||
|
||||
destructor TSynEditStringTrimmingList.Destroy;
|
||||
begin
|
||||
fCaret.RemoveChangeHandler(@DoCaretChanged);
|
||||
FreeAndNil(fLockList);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.SetUpdateState(Updating : Boolean);
|
||||
begin
|
||||
if Updating then
|
||||
fSynStrings.BeginUpdate
|
||||
else
|
||||
fSynStrings.EndUpdate;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.DoCaretChanged(Sender : TObject);
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
if (fLineIndex = TSynEditCaret(Sender).LinePos - 1) then exit;
|
||||
if (length(fSpaces) > 0) and (fLineIndex > 0)
|
||||
and (fLineIndex <= fSynStrings.Count)
|
||||
and (fLockCount = 0) then begin
|
||||
s := fSynStrings[fLineIndex];
|
||||
fSynStrings[fLineIndex] := s; // trigger OnPutted, so the line gets repainted
|
||||
fUndoList.AddChange(crTrimSpace, Point(1+length(s), fLineIndex+1),
|
||||
Point(1+length(s)+length(fSpaces), fLineIndex+1), fSpaces, smNormal);
|
||||
end;
|
||||
fLineIndex := TSynEditCaret(Sender).LinePos - 1;
|
||||
fSpaces := '';
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.SetEnabled(const AValue : Boolean);
|
||||
begin
|
||||
if fEnabled = AValue then exit;
|
||||
fEnabled:=AValue;
|
||||
fLockList.Clear;
|
||||
fLockCount:=0;
|
||||
if fEnabled and (fLineIndex >= 0) and (fLineIndex < fSynStrings.Count) then
|
||||
fSynStrings[fLineIndex] := TrimLine(fSynStrings[fLineIndex], fLineIndex);
|
||||
end;
|
||||
|
||||
function TSynEditStringTrimmingList.TrimLine(const S: String; Index: Integer): String;
|
||||
var
|
||||
l, i:integer;
|
||||
temp: String;
|
||||
begin
|
||||
if not fEnabled then exit(s);
|
||||
l := length(s);
|
||||
i := l;
|
||||
while (i>0) and (s[i] in [#9, ' ']) do dec(i);
|
||||
temp := copy(s, i+1, l-i);
|
||||
if i=l then
|
||||
result := s // No need to make a copy
|
||||
else
|
||||
result := copy(s, 1, i);
|
||||
|
||||
if fLockCount > 0 then begin
|
||||
i := fLockList.IndexOfObject(TObject(pointer(Index)));
|
||||
if i < 0 then
|
||||
fLockList.AddObject(temp, TObject(pointer(Index)))
|
||||
else
|
||||
fLockList[i] := temp;
|
||||
end
|
||||
else if (fLineIndex = Index) then begin
|
||||
fSpaces := temp;
|
||||
fLineText:=result;
|
||||
end;
|
||||
end ;
|
||||
|
||||
function TSynEditStringTrimmingList.Spaces(Index : Integer) : String;
|
||||
var
|
||||
i : Integer;
|
||||
begin
|
||||
if fLockCount > 0 then begin
|
||||
i := fLockList.IndexOfObject(TObject(Pointer(Index)));
|
||||
if i < 0 then
|
||||
result := ''
|
||||
else
|
||||
result := fLockList[i];
|
||||
exit;
|
||||
end;
|
||||
if Index <> fLineIndex then exit('');
|
||||
if (fLineIndex < 0) or (fLineIndex >= fSynStrings.Count)
|
||||
or (fLineText <> fSynStrings[fLineIndex]) then begin
|
||||
fSpaces:='';
|
||||
fLineText:='';
|
||||
end;
|
||||
Result:= fSpaces;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.DoLinesChanged(Index, N : integer);
|
||||
var
|
||||
i, j: Integer;
|
||||
begin
|
||||
if fLockCount > 0 then begin
|
||||
for i := fLockList.Count-1 downto 0 do begin
|
||||
j := Integer(Pointer(fLockList.Objects[i]));
|
||||
if (j >= Index) and (j < Index - N) then
|
||||
fLockList.Delete(i)
|
||||
else if j > Index then
|
||||
fLockList.Objects[i] := TObject(Pointer(j + N));
|
||||
end;
|
||||
end else begin
|
||||
if (fLineIndex >= Index) and (fLineIndex < Index - N) then
|
||||
fLineIndex:=-1
|
||||
else if fLineIndex > Index then
|
||||
inc(fLineIndex, N);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.Lock;
|
||||
begin
|
||||
if (fLockCount = 0) and (fLineIndex >= 0) then
|
||||
fLockList.AddObject(Spaces(fLineIndex), TObject(Pointer(fLineIndex)));
|
||||
inc(fLockCount);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.UnLock;
|
||||
var
|
||||
i, index, llen, slen: Integer;
|
||||
ltext: String;
|
||||
begin
|
||||
dec(fLockCount);
|
||||
if (fLockCount = 0) then TrimAfterLock;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.TrimAfterLock;
|
||||
var
|
||||
i, index, llen, slen: Integer;
|
||||
ltext: String;
|
||||
begin
|
||||
i := fLockList.IndexOfObject(TObject(Pointer(fLineIndex)));
|
||||
if i >= 0 then begin
|
||||
fSpaces:= fLockList[i];
|
||||
if (fLineIndex >= 0) and (fLineIndex < fSynStrings.Count) then
|
||||
fLineText := fSynStrings[fLineIndex];
|
||||
fLockList.Delete(i);
|
||||
end;
|
||||
for i := 0 to fLockList.Count-1 do begin
|
||||
index := Integer(Pointer(fLockList.Objects[i]));
|
||||
slen := length(fLockList[i]);
|
||||
if (slen > 0) and (index >= 0) and (index < fSynStrings.Count) then begin
|
||||
ltext := fSynStrings[index];
|
||||
llen := length(ltext);
|
||||
fSynStrings[index] := ltext; // trigger OnPutted, so the line gets repainted
|
||||
fUndoList.AddChange(crTrimSpace, Point(1+llen, index+1),
|
||||
Point(1+llen+slen, index+1), fLockList[i], smNormal);
|
||||
end;
|
||||
end;
|
||||
fLockList.Clear;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.ForceTrim;
|
||||
begin
|
||||
TrimAfterLock;
|
||||
end;
|
||||
|
||||
// Fold
|
||||
function TSynEditStringTrimmingList.GetFoldEndLevel(Index : integer) : integer;
|
||||
begin
|
||||
Result:= fSynStrings.FoldEndLevel[Index];
|
||||
end;
|
||||
|
||||
function TSynEditStringTrimmingList.GetFoldMinLevel(Index : integer) : integer;
|
||||
begin
|
||||
Result:= fSynStrings.FoldMinLevel[Index];
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.SetFoldEndLevel(Index : integer; const AValue : integer);
|
||||
begin
|
||||
fSynStrings.FoldEndLevel[Index] := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.SetFoldMinLevel(Index : integer; const AValue : integer);
|
||||
begin
|
||||
fSynStrings.FoldMinLevel[Index] := AValue;
|
||||
end;
|
||||
|
||||
// Range
|
||||
function TSynEditStringTrimmingList.GetRange(Index : integer) : TSynEditRange;
|
||||
begin
|
||||
Result:= fSynStrings.Ranges[Index];
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.PutRange(Index : integer; ARange : TSynEditRange);
|
||||
begin
|
||||
fSynStrings.Ranges[Index] := ARange;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.ClearRanges(ARange : TSynEditRange);
|
||||
begin
|
||||
fSynStrings.ClearRanges(ARange);
|
||||
end;
|
||||
|
||||
// Count
|
||||
function TSynEditStringTrimmingList.GetCount : integer;
|
||||
begin
|
||||
Result:= fSynStrings.Count;
|
||||
end;
|
||||
|
||||
function TSynEditStringTrimmingList.GetCapacity : integer;
|
||||
begin
|
||||
Result:= fSynStrings.Capacity;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.SetCapacity(NewCapacity : integer);
|
||||
begin
|
||||
fSynStrings.Capacity := NewCapacity;
|
||||
end;
|
||||
|
||||
// Lines
|
||||
function TSynEditStringTrimmingList.GetExpandedString(Index : integer) : string;
|
||||
begin
|
||||
Result:= fSynStrings.ExpandedStrings[Index] + Spaces(Index);
|
||||
end;
|
||||
|
||||
function TSynEditStringTrimmingList.GetLengthOfLongestLine : integer;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result:= fSynStrings.LengthOfLongestLine;
|
||||
if (fLineIndex >= 0) and (fLineIndex < Count) then begin
|
||||
i:= length(ExpandedStrings[fLineIndex]);
|
||||
if (i > Result) then Result := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynEditStringTrimmingList.Get(Index : integer) : string;
|
||||
begin
|
||||
Result:= fSynStrings.Strings[Index] + Spaces(Index);
|
||||
end;
|
||||
|
||||
function TSynEditStringTrimmingList.GetObject(Index : integer) : TObject;
|
||||
begin
|
||||
Result:= fSynStrings.Objects[Index];
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.Put(Index : integer; const S : string);
|
||||
begin
|
||||
fSynStrings.Strings[Index]:= TrimLine(S, Index);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.PutObject(Index : integer; AObject : TObject);
|
||||
begin
|
||||
fSynStrings.Objects[Index]:= AObject;
|
||||
end;
|
||||
|
||||
function TSynEditStringTrimmingList.Add(const S : string) : integer;
|
||||
var
|
||||
c : Integer;
|
||||
begin
|
||||
c := fSynStrings.Count;
|
||||
DoLinesChanged(c, 1);
|
||||
Result := fSynStrings.Add(TrimLine(S, c));
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.AddStrings(AStrings : TStrings);
|
||||
var
|
||||
i, c : Integer;
|
||||
begin
|
||||
c := fSynStrings.Count;
|
||||
DoLinesChanged(c, AStrings.Count);
|
||||
for i := 0 to AStrings.Count-1 do
|
||||
AStrings[i] := TrimLine(AStrings[i], c + i);
|
||||
fSynStrings.AddStrings(AStrings);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.Clear;
|
||||
begin
|
||||
fSynStrings.Clear;
|
||||
fLineIndex:=-1;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.Delete(Index : integer);
|
||||
begin
|
||||
fSynStrings.Delete(Index);
|
||||
DoLinesChanged(Index, -1);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.DeleteLines(Index, NumLines : integer);
|
||||
begin
|
||||
fSynStrings.DeleteLines(Index, NumLines);
|
||||
DoLinesChanged(Index, -NumLines);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.Insert(Index : integer; const S : string);
|
||||
begin
|
||||
DoLinesChanged(Index, 1);
|
||||
fSynStrings.Insert(Index, TrimLine(S, Index));
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.InsertLines(Index, NumLines : integer);
|
||||
begin
|
||||
DoLinesChanged(Index, NumLines);
|
||||
fSynStrings.InsertLines(Index, NumLines);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.InsertStrings(Index : integer; NewStrings : TStrings);
|
||||
var
|
||||
i : Integer;
|
||||
begin
|
||||
DoLinesChanged(Index, NewStrings.Count);
|
||||
for i := 0 to NewStrings.Count-1 do
|
||||
NewStrings[i] := TrimLine(NewStrings[i], Index+i);
|
||||
fSynStrings.InsertStrings(Index, NewStrings);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringTrimmingList.Exchange(Index1, Index2 : integer);
|
||||
begin
|
||||
fSynStrings.Exchange(Index1, Index2);
|
||||
if fLineIndex = Index1 then
|
||||
fLineIndex := Index2
|
||||
else if fLineIndex = Index2 then
|
||||
fLineIndex := Index1;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@ -72,6 +72,10 @@ type
|
||||
ssoRegExpr, ssoRegExprMultiLine{$ENDIF});
|
||||
TSynSearchOptions = set of TSynSearchOption;
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditRange = pointer;
|
||||
{$ENDIF}
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user