📄 synedit.pas
字号:
Width := 200;
Cursor := crIBeam;
Color := clWindow;
{$IFDEF SYN_WIN32}
fFontDummy.Name := 'Courier New';
fFontDummy.Size := 10;
{$ENDIF}
{$IFDEF SYN_KYLIX}
fFontDummy.Name := 'adobe-courier';
if fFontDummy.Name = 'adobe-courier' then
fFontDummy.Size := 12
else begin
fFontDummy.Name := 'terminal';
fFontDummy.Size := 14;
end;
{$ENDIF}
{$IFDEF SYN_COMPILER_3_UP}
fFontDummy.CharSet := DEFAULT_CHARSET;
{$ENDIF}
fWordWrap := false; //Fiala 2001-12-17
fShowSpecChar := False; //Fiala 2001-12-17
fTextDrawer := TheTextDrawer.Create([fsBold], fFontDummy);
Font.Assign(fFontDummy);
Font.OnChange := SynFontChanged;
ParentFont := False;
ParentColor := False;
TabStop := True;
fInserting := True;
fMaxLineWidth := 1024;
fScrollBars := ssBoth;
fBorderStyle := bsSingle;
fInsertCaret := ctVerticalLine;
fOverwriteCaret := ctBlock;
FSelectionMode := smNormal;
fFocusList := TList.Create;
fKbdHandler := TSynEditKbdHandler.Create;
fKeystrokes := TSynEditKeyStrokes.Create(Self);
fMarkList := TSynEditMarkList.Create(self);
fMarkList.OnChange := MarkListChange;
SetDefaultKeystrokes;
fRightEdgeColor := clSilver;
{$IFDEF SYN_MBCSSUPPORT}
fImeCount := 0;
fMBCSStepAside := False;
{$ENDIF}
fWantReturns := True;
fWantTabs := False;
fTabWidth := 8;
fLeftChar := 1;
fTopLine := 1;
fCaretX := 1;
fLastCaretX := 1; //mh 2000-10-19
fCaretY := 1;
fBlockBegin := Point(1, 1);
fBlockEnd := fBlockBegin;
// find / replace
// fTSearch := TSynEditSearch.Create; //ddh 2002-4-112 moved to SearchReplace
fOptions := SYNEDIT_DEFAULT_OPTIONS;
fScrollTimer := TTimer.Create(Self);
fScrollTimer.Enabled := False;
fScrollTimer.Interval := 100;
fScrollTimer.OnTimer := ScrollTimerHandler;
{$IFDEF SYN_CLX}
InputKeys := [ikAll];
FHScrollBar := TSynEditScrollbar.Create(self);
FHScrollBar.Kind := sbHorizontal;
FHScrollBar.Height := CYHSCROLL;
FHScrollBar.OnScroll := ScrollEvent;
FVScrollBar := TSynEditScrollbar.Create(self);
FVScrollBar.Kind := sbVertical;
FVScrollBar.Width := CXVSCROLL;
FVScrollBar.OnScroll := ScrollEvent;
// Set parent after BOTH scrollbars are created.
FHScrollBar.Parent := Self;
FHScrollBar.Color := clScrollBar;
FVScrollBar.Parent := Self;
FVScrollBar.Color := clScrollBar;
{$ENDIF}
fScrollHintColor := clInfoBk;
fScrollHintFormat := shfTopLineOnly;
fIsAltSetColumnMode := False; //Fiala 2001-12-17
FIsScrolling := False; //ddh 2002-06-22
fChainedEditor := nil; //ddh 2002-7-15
SynFontChanged(nil);
end;
{$IFDEF SYN_CLX}
{$ELSE}
procedure TCustomSynEdit.CreateParams(var Params: TCreateParams);
const
BorderStyles: array[TBorderStyle] of DWORD = (0, WS_BORDER);
ClassStylesOff = CS_VREDRAW or CS_HREDRAW;
begin
inherited CreateParams(Params);
with Params do begin
WindowClass.Style := WindowClass.Style and not ClassStylesOff;
Style := Style or BorderStyles[fBorderStyle] or WS_CLIPCHILDREN;
if NewStyleControls and Ctl3D and (fBorderStyle = bsSingle) then begin
Style := Style and not WS_BORDER;
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
end;
end;
end;
{$ENDIF}
procedure TCustomSynEdit.DecPaintLock;
begin
Dec(fPaintLock);
if (fPaintLock = 0) and HandleAllocated then begin
if sfScrollbarChanged in fStateFlags then
UpdateScrollbars;
if sfCaretChanged in fStateFlags then
UpdateCaret;
if fStatusChanges <> [] then
DoOnStatusChange(fStatusChanges);
end;
end;
destructor TCustomSynEdit.Destroy;
var
i: integer;
begin
Highlighter := nil;
RemoveLinesPointer;
inherited Destroy;
// free listeners while other fields are still valid
if Assigned(fHookedCommandHandlers) then begin
for i := 0 to fHookedCommandHandlers.Count - 1 do
THookedCommandHandlerEntry(fHookedCommandHandlers[i]).Free;
FreeAndNil(fHookedCommandHandlers);
end;
if fPlugins <> nil then begin
for i := fPlugins.Count - 1 downto 0 do
TSynEditPlugin(fPlugins[i]).Free;
fPlugins.Free;
end;
fMarkList.Free;
fBookMarkOpt.Free;
fKeyStrokes.Free;
fKbdHandler.Free;
fFocusList.Free;
fSelectedColor.Free;
fOrigUndoList.Free; //ddh 2002-7-15
fOrigRedoList.Free; //ddh 2002-7-15
fGutter.Free;
fTextDrawer.Free;
fInternalImage.Free;
fFontDummy.Free;
fOrigLines.Free; //ddh 2002-7-15
end;
function TCustomSynEdit.GetBlockBegin: TPoint;
begin
if (fBlockEnd.Y < fBlockBegin.Y)
or ((fBlockEnd.Y = fBlockBegin.Y) and (fBlockEnd.X < fBlockBegin.X))
then
Result := fBlockEnd
else
Result := fBlockBegin;
end;
function TCustomSynEdit.GetBlockEnd: TPoint;
begin
if (fBlockEnd.Y < fBlockBegin.Y)
or ((fBlockEnd.Y = fBlockBegin.Y) and (fBlockEnd.X < fBlockBegin.X))
then
Result := fBlockBegin
else
Result := fBlockEnd;
end;
function TCustomSynEdit.CaretXPix: Integer;
var
p: TPoint;
begin
p := Point(fCaretX, fCaretY);
Result := RowColumnToPixels(p).X;
end;
function TCustomSynEdit.CaretYPix: Integer;
begin
Result := RowColumnToPixels(Point(1, fCaretY)).Y;
end;
procedure TCustomSynEdit.SynFontChanged(Sender: TObject);
begin
RecalcCharExtent;
SizeOrFontChanged(TRUE);
end;
function TCustomSynEdit.GetFont: TFont;
begin
Result := inherited Font;
end;
function TCustomSynEdit.GetLineText: string;
begin
if (CaretY >= 1) and (CaretY <= Lines.Count) then
Result := Lines[CaretY - 1]
else
Result := '';
end;
function TCustomSynEdit.GetSelAvail: Boolean;
begin
Result := (fBlockBegin.X <> fBlockEnd.X) or
((fBlockBegin.Y <> fBlockEnd.Y) and (fSelectionMode <> smColumn));
end;
function TCustomSynEdit.GetSelTabBlock: Boolean;
begin
Result := (fBlockBegin.Y <> fBlockEnd.Y) and (fSelectionMode <> smColumn);
end;
function TCustomSynEdit.GetSelTabLine: Boolean;
begin
Result := (BlockBegin.X <= 1) and (BlockEnd.X > length(Lines[CaretY - 1])) and SelAvail;
end;
function TCustomSynEdit.GetSelText: string;
function CopyPadded(const S: string; Index, Count: integer): string;
var
SrcLen: Integer;
DstLen: integer;
P: PChar;
begin
SrcLen := Length(S);
DstLen := Index + Count;
if SrcLen >= DstLen then
Result := Copy(S, Index, Count)
else begin
SetLength(Result, DstLen);
P := PChar(Result);
StrPCopy(P, Copy(S, Index, Count));
Inc(P, Length(S));
FillChar(P^, DstLen - Srclen, $20);
end;
end;
procedure CopyAndForward(const S: string; Index, Count: Integer; var P:
PChar);
var
pSrc: PChar;
SrcLen: Integer;
DstLen: Integer;
begin
SrcLen := Length(S);
if (Index <= SrcLen) and (Count > 0) then begin
Dec(Index);
pSrc := PChar(S) + Index;
DstLen := Min(SrcLen - Index, Count);
Move(pSrc^, P^, DstLen);
Inc(P, DstLen);
P^ := #0;
end;
end;
function CopyPaddedAndForward(const S: string; Index, Count: Integer;
var P: PChar): Integer;
var
OldP: PChar;
Len: Integer;
begin
Result := 0;
OldP := P;
CopyAndForward(S, Index, Count, P);
Len := Count - (P - OldP);
if not (eoTrimTrailingSpaces in Options)
then begin
FillChar(P^, Len, #$20);
Inc(P, Len);
end else
Result:= Len;
end;
const
sLineBreak = #$0D#$0A;
var
First, Last, TotalLen: Integer;
ColFrom, ColTo: Integer;
I: Integer;
{$IFDEF SYN_MBCSSUPPORT}
l, r: Integer;
s: string;
{$ELSE}
ColLen: integer;
{$ENDIF}
P: PChar;
begin
if not SelAvail then
Result := ''
else begin
with BlockBegin do begin
ColFrom := X;
First := Y - 1;
end;
with BlockEnd do begin
ColTo := X;
Last := Y - 1;
end;
TotalLen := 0;
case SelectionMode of
smNormal:
if (First = Last) then
Result := Copy(Lines[First], ColFrom, ColTo - ColFrom)
else begin
// step1: calclate total length of result string
TotalLen := Max(0, Length(Lines[First]) - ColFrom + 1);
for i := First + 1 to Last - 1 do
Inc(TotalLen, Length(Lines[i]));
Inc(TotalLen, ColTo - 1);
Inc(TotalLen, Length(sLineBreak) * (Last - First));
// step2: build up result string
SetLength(Result, TotalLen);
P := PChar(Result);
CopyAndForward(Lines[First], ColFrom, MaxInt, P);
CopyAndForward(sLineBreak, 1, MaxInt, P);
for i := First + 1 to Last - 1 do begin
CopyAndForward(Lines[i], 1, MaxInt, P);
CopyAndFo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -