📄 synedit.pas
字号:
{-------------------------------------------------------------------------------
单元: SynEdit.pas
作者: Pieter Zijlstra - 姚乔锋(修改) - yaoqiaofeng@sohu.com
日期: 2005.09.04
声明:代码折叠功能转载自mystix版本的synedit
-------------------------------------------------------------------------------}
{-------------------------------------------------------------------------------
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.
The Original Code is: SynEdit.pas, released 2000-04-07.
The Original Code is based on mwCustomEdit.pas by Martin Waldenburg, part of
the mwEdit component suite.
Portions created by Martin Waldenburg are Copyright (C) 1998 Martin Waldenburg.
All Rights Reserved.
Contributors to the SynEdit and mwEdit projects are listed in the
Contributors.txt file.
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.
$Id: SynEdit.pas,v 1.394 2004/10/07 14:36:39 etrusco Exp $
You may retrieve the latest version of this file at the SynEdit home page,
located at http://SynEdit.SourceForge.net
Known Issues:
- Undo is buggy when dealing with Hard Tabs (when inserting text after EOL and
when trimming).
-------------------------------------------------------------------------------}
//todo: remove SynEdit Clipboard Format?
//todo: in WordWrap mode, parse lines only once in PaintLines()
//todo: Remove checks for WordWrap. Must abstract the behaviour with the plugins instead.
//todo: Move WordWrap glyph to the WordWrap plugin.
//todo: remove fMBCSStepAside variable
//todo: remove fShowSpecChar variable
//todo: remove the several Undo block types?
{$IFNDEF QSYNEDIT}
unit SynEdit;
{$ENDIF}
{$I SynEdit.inc}
interface
uses
{$IFDEF SYN_CLX}
{$IFDEF LINUX}
Xlib,
{$ENDIF}
Qt,
Types,
QControls,
QGraphics,
QForms,
QStdCtrls,
QExtCtrls,
{$ELSE}
Controls,
Graphics,
Forms,
StdCtrls,
ExtCtrls,
Windows,
Messages,
{$IFDEF SYN_COMPILER_7}
Themes,
{$ENDIF}
{$ENDIF}
{$IFDEF SYN_MBCSSUPPORT}
Imm,
{$ENDIF}
{$IFDEF SYN_CLX}
kTextDrawer,
QSynEditTypes,
QSynEditKeyConst,
QSynEditMiscProcs,
QSynEditMiscClasses,
QSynEditTextBuffer,
QSynEditKeyCmds,
QSynEditHighlighter,
QSynEditKbdHandler,
{$ELSE}
SynEditTypes,
SynEditKeyConst,
SynEditMiscProcs,
SynEditMiscClasses,
SynEditTextBuffer,
SynEditKeyCmds,
SynEditHighlighter,
SynEditKbdHandler,
{$IFDEF CODEFOLDING}
//### Code Folding ###
SynEditCodeFolding,
SynRegExpr,
//### End Code Folding ###
{$ENDIF}
SynTextDrawer,
{$ENDIF}
Math,
SysUtils,
Classes;
const
{$IFNDEF SYN_COMPILER_3_UP}
// not defined in all Delphi versions
WM_MOUSEWHEEL = $020A;
{$ENDIF}
// maximum scroll range
MAX_SCROLL = 32767;
// Max number of book/gutter marks returned from GetEditMarksForLine - that
// really should be enough.
MAX_MARKS = 16;
SYNEDIT_CLIPBOARD_FORMAT = 'SynEdit Control Block Type';
var
SynEditClipboardFormat: UINT;
type
{$IFDEF SYN_CLX}
TSynBorderStyle = bsNone..bsSingle;
{$ELSE}
TSynBorderStyle = TBorderStyle;
{$ENDIF}
TBufferCoord = SynEditTypes.TBufferCoord;
TDisplayCoord = SynEditTypes.TDisplayCoord;
TSynReplaceAction = (raCancel, raSkip, raReplace, raReplaceAll);
ESynEditError = class(Exception);
TDropFilesEvent = procedure(Sender: TObject; X, Y: integer; AFiles: TStrings)
of object;
THookedCommandEvent = procedure(Sender: TObject; AfterProcessing: boolean;
var Handled: boolean; var Command: TSynEditorCommand; var AChar: char;
Data: pointer; HandlerData: pointer) of object;
TPaintEvent = procedure(Sender: TObject; ACanvas: TCanvas) of object;
TProcessCommandEvent = procedure(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer) of object;
TReplaceTextEvent = procedure(Sender: TObject; const ASearch, AReplace:
string; Line, Column: integer; var Action: TSynReplaceAction) of object;
TSpecialLineColorsEvent = procedure(Sender: TObject; Line: integer;
var Special: boolean; var FG, BG: TColor) of object;
TTransientType=(ttBefore,ttAfter);
TPaintTransient = procedure(Sender: TObject; Canvas: TCanvas;
TransientType: TTransientType) of object;
TScrollEvent = procedure(Sender: TObject; ScrollBar: TScrollBarKind) of object;
TGutterGetTextEvent = procedure(Sender: TObject; aLine: integer;
var aText: string) of object;
TGutterPaintEvent = procedure(Sender: TObject; aLine: integer;
X, Y: integer) of object;
TSynEditCaretType = (ctVerticalLine, ctHorizontalLine, ctHalfBlock, ctBlock);
TSynStateFlag = (sfCaretChanged, sfScrollbarChanged, sfLinesChanging,
sfIgnoreNextChar, sfCaretVisible, sfDblClicked, sfPossibleGutterClick,
sfWaitForDragging, sfInsideRedo, sfGutterDragging);
TSynStateFlags = set of TSynStateFlag;
TSynEditorOption = (
eoAltSetsColumnMode, //Holding down the Alt Key will put the selection mode into columnar format
eoAutoIndent, //Will indent the caret on new lines with the same amount of leading white space as the preceding line
eoAutoSizeMaxScrollWidth, //Automatically resizes the MaxScrollWidth property when inserting text
eoDisableScrollArrows, //Disables the scroll bar arrow buttons when you can't scroll in that direction any more
eoDragDropEditing, //Allows you to select a block of text and drag it within the document to another location
eoDropFiles, //Allows the editor accept OLE file drops
eoEnhanceHomeKey, //enhances home key positioning, similar to visual studio
eoEnhanceEndKey, //enhances End key positioning, similar to JDeveloper
eoGroupUndo, //When undoing/redoing actions, handle all continous changes of the same kind in one call instead undoing/redoing each command separately
eoHalfPageScroll, //When scrolling with page-up and page-down commands, only scroll a half page at a time
eoHideShowScrollbars, //if enabled, then the scrollbars will only show when necessary. If you have ScrollPastEOL, then it the horizontal bar will always be there (it uses MaxLength instead)
eoKeepCaretX, //When moving through lines w/o Cursor Past EOL, keeps the X position of the cursor
eoNoCaret, //Makes it so the caret is never visible
eoNoSelection, //Disables selecting text
eoRightMouseMovesCursor, //When clicking with the right mouse for a popup menu, move the cursor to that location
eoScrollByOneLess, //Forces scrolling to be one less
eoScrollHintFollows, //The scroll hint follows the mouse when scrolling vertically
eoScrollPastEof, //Allows the cursor to go past the end of file marker
eoScrollPastEol, //Allows the cursor to go past the last character into the white space at the end of a line
eoShowScrollHint, //Shows a hint of the visible line numbers when scrolling vertically
eoShowSpecialChars, //Shows the special Characters
eoSmartTabDelete, //similar to Smart Tabs, but when you delete characters
eoSmartTabs, //When tabbing, the cursor will go to the next non-white space character of the previous line
eoSpecialLineDefaultFg, //disables the foreground text color override when using the OnSpecialLineColor event
eoTabIndent, //When active <Tab> and <Shift><Tab> act as block indent, unindent when text is selected
eoTabsToSpaces, //Converts a tab character to a specified number of space characters
eoTrimTrailingSpaces, //Spaces at the end of lines will be trimmed and not saved
eoColumnEditExtension
);
TSynEditorOptions = set of TSynEditorOption;
const
SYNEDIT_DEFAULT_OPTIONS = [eoAutoIndent, eoDragDropEditing, eoEnhanceEndKey,
eoScrollPastEol, eoShowScrollHint, eoSmartTabs, eoTabsToSpaces,
eoSmartTabDelete, eoGroupUndo, eoColumnEditExtension];
type
// use scAll to update a statusbar when another TCustomSynEdit got the focus
TSynStatusChange = (scAll, scCaretX, scCaretY, scLeftChar, scTopLine,
scInsertMode, scModified, scSelection, scReadOnly);
TSynStatusChanges = set of TSynStatusChange;
TContextHelpEvent = procedure(Sender: TObject; word : string)
of object;
TStatusChangeEvent = procedure(Sender: TObject; Changes: TSynStatusChanges)
of object;
TMouseCursorEvent = procedure(Sender: TObject; const aLineCharPos: TBufferCoord;
var aCursor: TCursor) of object;
TSSBGetScrollInfoEvent = function
(ScrollBar : TScrollBarKind; var ScrollInfo : TScrollInfo) : Boolean of object;
TSSBSetScrollInfoEvent = function
(ScrollBar : TScrollBarKind; const ScrollInfo : TScrollInfo; Redraw : Boolean) : integer of object;
TSSBShowScrollBarEvent = function
(ScrollBar : TScrollBarKind; Show: Boolean): Boolean;
TSSBEnableScrollBarEvent = function
(ScrollBar : TScrollBarKind; Arrows: Integer): Boolean;
TLineSpacingRule = (lsSingle, lsOneAndHalf, lsDouble, lsSpecified);
TPlaceMarkEvent = procedure(Sender: TObject; var Mark: TSynEditMark)
of object;
TCustomSynEdit = class;
TGutterClickEvent = procedure(Sender: TObject; Button: TMouseButton;
X, Y, Line: integer; Mark: TSynEditMark; Region : Boolean) of object;
// aIndex parameters of Line notifications are 0-based.
// aRow parameter of GetRowLength() is 1-based.
ISynEditBufferPlugin = interface
// conversion methods
function BufferToDisplayPos(const aPos: TBufferCoord): TDisplayCoord;
function DisplayToBufferPos(const aPos: TDisplayCoord): TBufferCoord;
function RowCount: integer;
function GetRowLength(aRow: integer): integer;
// plugin notifications
function LinesInserted(aIndex: integer; aCount: integer): integer;
function LinesDeleted(aIndex: integer; aCount: integer): integer;
function LinesPutted(aIndex: integer; aCount: integer): integer;
// font or size change
procedure DisplayChanged;
// pretty clear, heh?
procedure Reset;
end;
TSynEditPlugin = class(TObject)
private
fOwner: TCustomSynEdit;
protected
procedure AfterPaint(ACanvas: TCanvas; const AClip: TRect;
FirstLine, LastLine: integer); virtual; abstract;
procedure LinesInserted(FirstLine, Count: integer); virtual; abstract;
procedure LinesDeleted(FirstLine, Count: integer); virtual; abstract;
protected
property Editor: TCustomSynEdit read fOwner;
public
constructor Create(AOwner: TCustomSynEdit);
destructor Destroy; override;
end;
{$IFDEF CODEFOLDING}
//### Code Folding ###
TSynEditCodeFoldingPlugin = class(TSynEditPlugin)
protected
procedure AfterPaint(ACanvas: TCanvas; const AClip: TRect;
FirstLine, LastLine: integer); override;
procedure LinesInserted(FirstLine, Count: integer); override;
procedure LinesDeleted(FirstLine, Count: integer); override;
end;
//### End Code Folding ###
{$ENDIF}
TCustomSynEdit = class(TCustomControl)
private
{$IFNDEF SYN_CLX}
procedure WMCancelMode(var Message: TMessage); message WM_CANCELMODE;
procedure WMCaptureChanged(var Msg: TMessage); message WM_CAPTURECHANGED;
procedure WMClear(var Msg: TMessage); message WM_CLEAR;
procedure WMCopy(var Message: TMessage); message WM_COPY;
procedure WMCut(var Message: TMessage); message WM_CUT;
procedure WMDropFiles(var Msg: TMessage); message WM_DROPFILES;
procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND;
procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
procedure WMGetText(var Msg: TWMGetText); message WM_GETTEXT;
procedure WMGetTextLength(var Msg: TWMGetTextLength); message WM_GETTEXTLENGTH;
procedure WMHScroll(var Msg: TWMScroll); message WM_HSCROLL;
procedure WMPaste(var Message: TMessage); message WM_PASTE;
procedure WMSetText(var Msg: TWMSetText); message WM_SETTEXT;
{$IFDEF SYN_MBCSSUPPORT}
procedure WMImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION;
procedure WMImeNotify(var Msg: TMessage); message WM_IME_NOTIFY;
{$ENDIF}
procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR;
procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
procedure WMSize(var Msg: TWMSize); message WM_SIZE;
procedure WMUndo(var Msg: TMessage); message WM_UNDO;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -