📄 synedittextbuffer.pas
字号:
end;
SetString(S1, Start, P - Start);
Add(S1);
if (P^ = #13) then
begin
fCR := True;
Inc(P);
Inc(iPos);
end;
if (P^ = #10) then
begin
fLF := True;
Inc(P);
Inc(iPos);
end;
end;
{ keep the old format of the file }
if (not AppendNewLineAtEOF) and (S[Size] in [#10,#13]) then
Add('');
end;
finally
EndUpdate;
end;
if fCR and not fLF then
fFileFormat := sffMac
else if fLF and not fCR then
fFileFormat := sffUnix
else
fFileFormat := sffDos;
end;
procedure TSynEditStringList.SaveToStream(Stream: TStream);
var
S, S1: string;
I, L, Size: Integer;
P: PChar;
LineEndLength: Integer;
begin
Size := 0;
if FileFormat in [sffMac, sffUnix] then
LineEndLength := 1
else
LineEndLength := 2;
for I := 0 to Count - 1 do Inc(Size, Length(Strings[I]) + LineEndLength);
if not AppendNewLineAtEOF then
Dec( Size, LineEndLength );
SetString(S, nil, Size);
P := Pointer(S);
for I := 0 to Count - 1 do begin
S1 := Strings[I];
L := Length(S1);
if L <> 0 then
begin
System.Move(Pointer(S1)^, P^, L);
Inc(P, L);
end;
//Do not add new line to last line
if (I < Count-1) or (AppendNewLineAtEOF) then begin
if FileFormat = sffMac then begin
P^ := #13;
Inc(P);
end else
if FileFormat = sffUnix then begin
P^ := #10;
Inc(P);
end else begin
P^ := #13;
Inc(P);
P^ := #10;
Inc(P);
end;
end;
end;
Stream.WriteBuffer(Pointer(S)^, Length(S));
end;
procedure TSynEditStringList.Put(Index: integer; const S: string);
begin
if (Index = 0) and (fCount = 0) or (fCount = Index) then
Add(S)
else begin
if (Index < 0) or (Index >= fCount) then
ListIndexOutOfBounds(Index);
BeginUpdate;
fIndexOfLongestLine := -1;
with fList^[Index] do begin
Include(fFlags, sfExpandedLengthUnknown);
Exclude(fFlags, sfHasTabs);
Exclude(fFlags, sfHasNoTabs);
fString := S;
end;
if Assigned(fOnPutted) then
fOnPutted( Self, Index, 1 );
EndUpdate;
end;
end;
procedure TSynEditStringList.PutObject(Index: integer; AObject: TObject);
begin
if (Index < 0) or (Index >= fCount) then
ListIndexOutOfBounds(Index);
BeginUpdate;
fList^[Index].fObject := AObject;
EndUpdate;
end;
procedure TSynEditStringList.PutRange(Index: integer; ARange: TSynEditRange);
begin
if (Index < 0) or (Index >= fCount) then
ListIndexOutOfBounds(Index);
BeginUpdate;
fList^[Index].fRange := ARange;
EndUpdate;
end;
procedure TSynEditStringList.SaveToFile(const FileName: string);
var
Writer: TSynEditFileWriter;
i: integer;
s: string;
begin
Writer := TSynEditFileWriter.Create(FileName);
try
Writer.FileFormat := fFileFormat;
i := 0;
while i < fCount do begin
s := Get(i);
Inc(i);
if (i<fCount) or (AppendNewLineAtEOF) then
Writer.WriteLine(s, fFileFormat)
else
Writer.Write(s);
end;
finally
Writer.Free;
end;
end;
procedure TSynEditStringList.SetCapacity(NewCapacity: integer);
begin
if NewCapacity < Count then
EListError.Create( SInvalidCapacity );
ReallocMem(fList, NewCapacity * SynEditStringRecSize);
fCapacity := NewCapacity;
end;
procedure TSynEditStringList.SetTabWidth(Value: integer);
var
i: integer;
begin
if Value <> fTabWidth then begin
fTabWidth := Value;
fConvertTabsProc := GetBestConvertTabsProcEx(fTabWidth);
fIndexOfLongestLine := -1;
for i := 0 to fCount - 1 do
with fList^[i] do begin
fExpandedLength := -1;
Exclude(fFlags, sfHasNoTabs);
Include(fFlags, sfExpandedLengthUnknown);
end;
end;
end;
procedure TSynEditStringList.SetUpdateState(Updating: Boolean);
begin
if Updating then begin
if Assigned(fOnChanging) then
fOnChanging(Self);
end else begin
if Assigned(fOnChange) then
fOnChange(Self);
end;
end;
{ TSynEditUndoItem }
procedure TSynEditUndoItem.Assign(Source: TPersistent);
begin
if (Source is TSynEditUndoItem) then
begin
fChangeReason:=TSynEditUndoItem(Source).fChangeReason;
fChangeSelMode:=TSynEditUndoItem(Source).fChangeSelMode;
fChangeStartPos:=TSynEditUndoItem(Source).fChangeStartPos;
fChangeEndPos:=TSynEditUndoItem(Source).fChangeEndPos;
fChangeStr:=TSynEditUndoItem(Source).fChangeStr;
fChangeNumber:=TSynEditUndoItem(Source).fChangeNumber;
end
else
inherited Assign(Source);
end;
{ TSynEditUndoList }
constructor TSynEditUndoList.Create;
begin
inherited Create;
fItems := TList.Create;
fMaxUndoActions := 1024;
fNextChangeNumber := 1;
end;
destructor TSynEditUndoList.Destroy;
begin
Clear;
fItems.Free;
inherited Destroy;
end;
procedure TSynEditUndoList.Assign(Source: TPersistent);
var
i: Integer;
UndoItem: TSynEditUndoItem;
begin
if (Source is TSynEditUndoList) then
begin
Clear;
for i:=0 to TSynEditUndoList(Source).fItems.Count-1 do
begin
UndoItem:=TSynEditUndoItem.Create;
UndoItem.Assign(TSynEditUndoList(Source).fItems[i]);
fItems.Add(UndoItem);
end;
fBlockChangeNumber:=TSynEditUndoList(Source).fBlockChangeNumber;
fBlockCount:=TSynEditUndoList(Source).fBlockCount;
fFullUndoImposible:=TSynEditUndoList(Source).fFullUndoImposible;
fLockCount:=TSynEditUndoList(Source).fLockCount;
fMaxUndoActions:=TSynEditUndoList(Source).fMaxUndoActions;
fNextChangeNumber:=TSynEditUndoList(Source).fNextChangeNumber;
end
else
inherited Assign(Source);
end;
procedure TSynEditUndoList.AddChange(AReason: TSynChangeReason; const AStart,
AEnd: TBufferCoord; const ChangeText: string; SelMode: TSynSelectionMode);
var
NewItem: TSynEditUndoItem;
begin
if fLockCount = 0 then begin
NewItem := TSynEditUndoItem.Create;
try
with NewItem do begin
fChangeReason := AReason;
fChangeSelMode := SelMode;
fChangeStartPos := AStart;
fChangeEndPos := AEnd;
fChangeStr := ChangeText;
if fBlockChangeNumber <> 0 then
fChangeNumber := fBlockChangeNumber
else begin
fChangeNumber := fNextChangeNumber;
if fBlockCount = 0 then begin
Inc(fNextChangeNumber);
if fNextChangeNumber = 0 then
Inc(fNextChangeNumber);
end;
end;
end;
PushItem(NewItem);
except
NewItem.Free;
raise;
end;
end;
end;
procedure TSynEditUndoList.BeginBlock;
begin
Inc(fBlockCount);
fBlockChangeNumber := fNextChangeNumber;
end;
procedure TSynEditUndoList.Clear;
var
i: integer;
begin
for i := 0 to fItems.Count - 1 do
TSynEditUndoItem(fItems[i]).Free;
fItems.Clear;
fFullUndoImposible := False;
end;
procedure TSynEditUndoList.EndBlock;
var
iBlockID: integer;
begin
if fBlockCount > 0 then begin
Dec(fBlockCount);
if fBlockCount = 0 then begin
iBlockID := fBlockChangeNumber;
fBlockChangeNumber := 0;
Inc(fNextChangeNumber);
if fNextChangeNumber = 0 then
Inc(fNextChangeNumber);
if (fItems.Count > 0) and (PeekItem.ChangeNumber = iBlockID) and
Assigned(OnAddedUndo) then
begin
OnAddedUndo( Self );
end;
end;
end;
end;
procedure TSynEditUndoList.EnsureMaxEntries;
var
Item: TSynEditUndoItem;
begin
if fItems.Count > fMaxUndoActions then begin
fFullUndoImposible := True;
while fItems.Count > fMaxUndoActions do begin
Item := fItems[0];
Item.Free;
fItems.Delete(0);
end;
end;
end;
function TSynEditUndoList.GetCanUndo: boolean;
begin
Result := fItems.Count > 0;
end;
function TSynEditUndoList.GetItemCount: integer;
begin
Result := fItems.Count;
end;
procedure TSynEditUndoList.Lock;
begin
Inc(fLockCount);
end;
function TSynEditUndoList.PeekItem: TSynEditUndoItem;
var
iLast: integer;
begin
Result := nil;
iLast := fItems.Count - 1;
if iLast >= 0 then
Result := fItems[iLast];
end;
function TSynEditUndoList.PopItem: TSynEditUndoItem;
var
iLast: integer;
begin
Result := nil;
iLast := fItems.Count - 1;
if iLast >= 0 then begin
Result := fItems[iLast];
fItems.Delete(iLast);
end;
end;
procedure TSynEditUndoList.PushItem(Item: TSynEditUndoItem);
begin
if Assigned(Item) then begin
fItems.Add(Item);
EnsureMaxEntries;
if (Item.ChangeReason <> crGroupBreak) and Assigned(OnAddedUndo) then
OnAddedUndo(Self);
end;
end;
procedure TSynEditUndoList.SetMaxUndoActions(Value: integer);
begin
if Value < 0 then
Value := 0;
if Value <> fMaxUndoActions then begin
fMaxUndoActions := Value;
EnsureMaxEntries;
end;
end;
procedure TSynEditUndoList.Unlock;
begin
if fLockCount > 0 then
Dec(fLockCount);
end;
function TSynEditUndoList.LastChangeReason: TSynChangeReason;
begin
if fItems.Count = 0 then
result := crNothing
else
result := TSynEditUndoItem(fItems[fItems.Count - 1]).fChangeReason;
end;
procedure TSynEditUndoList.AddGroupBreak;
var
vDummy: TBufferCoord;
begin
//Add the GroupBreak even if ItemCount = 0. Since items are stored in
//reverse order in TCustomSynEdit.fRedoList, a GroupBreak could be lost.
if LastChangeReason <> crGroupBreak then
begin
AddChange(crGroupBreak, vDummy, vDummy, '', smNormal);
end;
end;
procedure TSynEditUndoList.SetInitialState(const Value: boolean);
begin
if Value then
begin
if ItemCount = 0 then
fInitialChangeNumber := 0
else
fInitialChangeNumber := PeekItem.ChangeNumber;
end
else
if ItemCount = 0 then
begin
if fInitialChangeNumber = 0 then
fInitialChangeNumber := -1;
end
else if PeekItem.ChangeNumber = fInitialChangeNumber then
fInitialChangeNumber := -1;
end;
function TSynEditUndoList.GetInitialState: boolean;
begin
if ItemCount = 0 then
Result := fInitialChangeNumber = 0
else
Result := PeekItem.ChangeNumber = fInitialChangeNumber;
end;
function TSynEditUndoList.GetItems(Index: Integer): TSynEditUndoItem;
begin
Result := TSynEditUndoItem(fItems[Index]);
end;
procedure TSynEditUndoList.SetItems(Index: Integer;
const Value: TSynEditUndoItem);
begin
fItems[Index] := Value;
end;
procedure TSynEditUndoList.DeleteItem(AIndex: Integer);
begin
TSynEditUndoItem(fItems[AIndex]).Free;
fItems.Delete(AIndex);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -