📄 syncompletionproposal.pas
字号:
property Margin: Integer read GetMargin write SetMargin default 2;
property OnChange: TCompletionChange read GetOnChange write SetOnChange;
property OnClose: TNotifyEvent read FOnClose write FOnClose; //GBN 28/08/2002
property OnExecute: TCompletionExecute read FOnExecute write FOnExecute;
property OnMeasureItem: TSynBaseCompletionProposalMeasureItem read GetOnMeasureItem write SetOnMeasureItem;
property OnPaintItem: TSynBaseCompletionProposalPaintItem read GetOnPaintItem write SetOnPaintItem;
property OnParameterToken: TCompletionParameter read GetParameterToken write SetParameterToken;
property OnShow: TNotifyEvent read FOnShow write FOnShow; //GBN 28/08/2002
end;
TSynCompletionProposal = class(TSynBaseCompletionProposal)
private
fEditors: TList;
FShortCut: TShortCut;
FNoNextKey: Boolean;
FCompletionStart: Integer;
{$IFDEF SYN_CLX} // Missing-ShowWindow-Workaround
FIgnoreFocusCommands: Boolean;
{$ENDIF}
FOnCodeCompletion: TCodeCompletionEvent;
FTimer: TTimer;
FTimerInterval: Integer;
FEditor: TCustomSynEdit;
FOnAfterCodeCompletion: TAfterCodeCompletionEvent; //GBN 18/11/2001
FOnCancelled: TNotifyEvent; //GBN 13/11/2001
procedure SetEditor(const Value: TCustomSynEdit);
procedure HandleOnCancel(Sender: TObject);
procedure HandleOnValidate(Sender: TObject; Shift: TShiftState; EndToken: Char);
procedure HandleOnKeyPress(Sender: TObject; var Key: Char);
procedure HandleDblClick(Sender: TObject);
procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure EditorKeyPress(Sender: TObject; var Key: char);
procedure TimerExecute(Sender: TObject);
function GetPreviousToken(AEditor: TCustomSynEdit): string;
function GetCurrentInput(AEditor: TCustomSynEdit): string;
function GetTimerInterval: Integer;
procedure SetTimerInterval(const Value: Integer);
function GetEditor(i: Integer): TCustomSynEdit;
procedure InternalCancelCompletion; //GBN 25/02/2002
protected
procedure DoExecute(AEditor: TCustomSynEdit); virtual;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure SetShortCut(Value: TShortCut);
procedure SetOptions(const Value: TSynCompletionOptions); override;
procedure EditorCancelMode(Sender: TObject); override; //GBN 13/11/2001
procedure HookedEditorCommand(Sender: TObject; AfterProcessing: Boolean;
var Handled: Boolean; var Command: TSynEditorCommand; var AChar: Char;
Data: Pointer; HandlerData: Pointer); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure AddEditor(AEditor: TCustomSynEdit);
function RemoveEditor(AEditor: TCustomSynEdit): boolean;
function EditorsCount: integer;
procedure ExecuteEx(s: string; x, y: integer; Kind : SynCompletionType
{$IFDEF SYN_COMPILER_4_UP} = ctCode {$ENDIF}); override;
procedure ActivateCompletion; //GBN 13/11/2001
procedure CancelCompletion; //GBN 11/11/2001
procedure ActivateTimer(ACurrentEditor: TCustomSynEdit);
procedure DeactivateTimer;
property Editors[i: Integer]: TCustomSynEdit read GetEditor;
property CompletionStart: Integer read FCompletionStart write FCompletionStart; // ET 04/02/2003
published
property ShortCut: TShortCut read FShortCut write SetShortCut;
property Editor: TCustomSynEdit read FEditor write SetEditor;
property TimerInterval: Integer read GetTimerInterval write SetTimerInterval default 1000;
property OnAfterCodeCompletion: TAfterCodeCompletionEvent read FOnAfterCodeCompletion write FOnAfterCodeCompletion;
property OnCancelled: TNotifyEvent read FOnCancelled write FOnCancelled;
property OnCodeCompletion: TCodeCompletionEvent read FOnCodeCompletion write FOnCodeCompletion;
end;
TSynAutoComplete = class(TComponent)
private
FShortCut: TShortCut;
fEditor: TCustomSynEdit;
fAutoCompleteList: TStrings;
fNoNextKey : Boolean;
FEndOfTokenChr: string;
FOnBeforeExecute: TNotifyEvent; //GBN 2002-14-04
FOnAfterExecute: TNotifyEvent; //GBN 2002-14-04
procedure SetAutoCompleteList(List: TStrings);
procedure SetEditor(const Value: TCustomSynEdit);
protected
procedure SetShortCut(Value: TShortCut);
procedure Notification(AComponent: TComponent; Operation: TOperation);
override;
procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
virtual;
procedure EditorKeyPress(Sender: TObject; var Key: char); virtual;
function GetPreviousToken(Editor: TCustomSynEdit): string;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Execute(token: string; Editor: TCustomSynEdit);
function GetTokenList: string;
function GetTokenValue(Token: string): string;
published
property AutoCompleteList: TStrings read fAutoCompleteList
write SetAutoCompleteList;
property EndOfTokenChr: string read FEndOfTokenChr write FEndOfTokenChr;
property Editor: TCustomSynEdit read fEditor write SetEditor;
property ShortCut: TShortCut read FShortCut write SetShortCut;
property OnBeforeExecute: TNotifyEvent read FOnBeforeExecute write FOnBeforeExecute;
property OnAfterExecute: TNotifyEvent read FOnAfterExecute write FOnAfterExecute;
end;
TProposalColumn = class(TCollectionItem)
private
FBiggestWord: string;
FInternalWidth: Integer;
FFontStyle: TFontStyles;
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
published
property BiggestWord: string read FBiggestWord write FBiggestWord;
property DefaultFontStyle: TFontStyles read FFontStyle write FFontStyle default [];
end;
TProposalColumns = class(TCollection)
private
FOwner: TPersistent;
function GetItem(Index: Integer): TProposalColumn;
procedure SetItem(Index: Integer; Value: TProposalColumn);
protected
function GetOwner: TPersistent; {$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF}
public
constructor Create(AOwner: TPersistent; ItemClass: TCollectionItemClass);
function Add: TProposalColumn;
{$IFDEF SYN_COMPILER_3_UP}
function FindItemID(ID: Integer): TProposalColumn;
{$ENDIF}
{$IFDEF SYN_COMPILER_4_UP}
function Insert(Index: Integer): TProposalColumn;
{$ENDIF}
property Items[Index: Integer]: TProposalColumn read GetItem write SetItem; default;
end;
procedure FormattedTextOut(TargetCanvas: TCanvas; const Rect: TRect;
const Text: string; Selected: Boolean; Columns: TProposalColumns; Images: TImageList);
function FormattedTextWidth(TargetCanvas: TCanvas; const Text: string;
Columns: TProposalColumns; Images: TImageList): Integer;
function PrettyTextToFormattedString(const APrettyText: string;
AlternateBoldStyle: Boolean {$IFDEF SYN_COMPILER_4_UP} = False {$ENDIF}): string;
implementation
uses
{$IFDEF SYN_COMPILER_4_UP}
Math,
{$ENDIF}
{$IFDEF SYN_CLX}
QSynEditTextBuffer,
QSynEditMiscProcs,
QSynEditKeyConst;
{$ELSE}
SynEditTextBuffer,
SynEditMiscProcs,
SynEditKeyConst;
{$ENDIF}
const
TextHeightString = 'CompletionProposal';
//------------------------- Formatted painting stuff ---------------------------
type
TFormatCommand = (fcNoCommand, fcColor, fcStyle, fcColumn, fcHSpace, fcImage);
TFormatCommands = set of TFormatCommand;
PFormatChunk = ^TFormatChunk;
TFormatChunk = record
Str: string;
Command: TFormatCommand;
Data: Pointer;
end;
PFormatStyleData = ^TFormatStyleData;
TFormatStyleData = record
Style: Char;
Action: Integer; // -1 = Reset, +1 = Set, 0 = Toggle
end;
TFormatChunkList = class
private
FChunks: TList;
function GetCount: Integer;
function GetChunk(Index: Integer): PFormatChunk;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
procedure Add(AChunk: PFormatChunk);
property Count: Integer read GetCount;
property Chunks[Index: Integer]: PFormatChunk read GetChunk; default;
end;
const
AllCommands = [fcColor..High(TFormatCommand)];
function TFormatChunkList.GetCount: Integer;
begin
Result := FChunks.Count;
end;
function TFormatChunkList.GetChunk(Index: Integer): PFormatChunk;
begin
Result := FChunks[Index];
end;
procedure TFormatChunkList.Clear;
var
C: PFormatChunk;
StyleFormatData: PFormatStyleData;
begin
while FChunks.Count > 0 do
begin
C := FChunks.Last;
FChunks.Delete(FChunks.Count-1);
case C^.Command of
fcStyle:
begin
StyleFormatData := C^.Data;
Dispose(StyleFormatData);
end;
end;
Dispose(C);
end;
end;
constructor TFormatChunkList.Create;
begin
inherited Create;
FChunks := TList.Create;
end;
destructor TFormatChunkList.Destroy;
begin
Clear;
FChunks.Free;
inherited Destroy;
end;
procedure TFormatChunkList.Add(AChunk: PFormatChunk);
begin
FChunks.Add(AChunk);
end;
function ParseFormatChunks(const FormattedString: string; ChunkList: TFormatChunkList;
const StripCommands: TFormatCommands): Boolean;
var
CurChar: Char;
CurPos: Integer;
CurrentChunk: string;
PossibleErrorPos: Integer;
ErrorFound: Boolean;
procedure NextChar;
begin
inc(CurPos);
{$IFOPT R+}
// Work-around Delphi's annoying behaviour of failing the RangeCheck when
// reading the final #0 char
if CurPos = Length(FormattedString) +1 then
CurChar := #0
else
{$ENDIF}
CurChar := FormattedString[CurPos];
end;
procedure AddStringChunk;
var
C: PFormatChunk;
begin
C := New(PFormatChunk);
C^.Str := CurrentChunk;
C^.Command := fcNoCommand;
C^.Data := nil;
ChunkList.Add(C);
CurrentChunk := '';
end;
procedure AddCommandChunk(ACommand: TFormatCommand; Data: Pointer);
var
C: PFormatChunk;
begin
C := New(PFormatChunk);
C^.Str := '';
C^.Command := ACommand;
C^.Data := Data;
ChunkList.Add(C);
end;
procedure ParseEscapeSequence;
var
Command: string;
Parameter: string;
CommandType: TFormatCommand;
Data: Pointer;
begin
Assert(CurChar = '\');
NextChar;
if CurChar = '\' then
begin
CurrentChunk := CurrentChunk +'\';
NextChar;
exit;
end;
if CurrentChunk <> '' then
AddStringChunk;
Command := '';
while (CurChar <> '{') and (CurPos <= Length(FormattedString)) do
begin
Command := Command +CurChar;
NextChar;
end;
if CurChar = '{' then
begin
PossibleErrorPos := CurPos;
NextChar;
Parameter := '';
while (CurChar <> '}') and (CurPos <= Length(FormattedString)) do
begin
Parameter := Parameter +CurChar;
NextChar;
end;
if CurChar = '}' then
begin
Command := AnsiUpperCase(Command);
Data := nil;
CommandType := fcNoCommand;
if Command = 'COLOR' then
begin
try
Data := Pointer(StringToColor(Parameter));
CommandType := fcColor;
except
CommandType := fcNoCommand;
ErrorFound := True;
end;
end else
if Command = 'COLUMN' then
begin
if Parameter <> '' then
begin
CommandType := fcNoCommand;
ErrorFound := True;
end else
CommandType := fcColumn;
end else
if Command = 'HSPACE' then
begin
try
Data := Pointer(StrToInt(Parameter));
CommandType := fcHSpace;
except
CommandType := fcNoCommand;
ErrorFound := True;
end;
end else
if Command = 'IMAGE' then
begin
try
Data := Pointer(StrToInt(Parameter));
CommandType := fcImage;
except
CommandType := fcNoCommand;
ErrorFound := True;
end;
end else
if Command = 'STYLE' then
begin
if (Length(Parameter) = 2)
and (Parameter[1] in ['+', '-', '~'])
and (UpCase(Parameter[2]) in ['B', 'I', 'U', 'S']) then
begin
CommandType := fcStyle;
Data := New(PFormatStyleData);
PFormatStyleData(Data)^.Style := UpCase(Parameter[2]);
case Parameter[1] of
'+': PFormatStyleData(Data)^.Action := 1;
'-': PFormatStyleData(Data)^.Action := -1;
'~': PFormatStyleData(Data)^.Action := 0;
end;
end else
begin
CommandType := fcNoCommand;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -