SynEdit (plugins: syncro,templ,complete) remove dynamic allocation of commands. Fix issue #0026329

git-svn-id: trunk@47522 -
This commit is contained in:
martin 2015-01-26 00:02:52 +00:00
parent f38736684f
commit 7832ffec7f
5 changed files with 106 additions and 126 deletions

View File

@ -435,16 +435,15 @@ type
procedure PrettyTextOut(c: TCanvas; x, y: integer; s: string);
const
ecSynCompletionExecute = ecPluginFirst + 0;
ecSynAutoCompletionExecute = ecPluginFirst + 1;
ecSynCompletionExecute = ecPluginFirstCompletion + 0;
ecSynAutoCompletionExecute = ecPluginFirstCompletion + 1;
// If extending the list, reserve space in SynEditKeyCmds
ecSynCompletionCount = 2;
implementation
var
KeyOffset: integer;
function IsIdentifierChar(p: PChar): boolean; inline;
{$IF FPC_FULLVERSION >= 20701}
var
@ -1795,7 +1794,7 @@ begin
Form.OnPaint:=@OnFormPaint;
FEndOfTokenChr := '()[].';
fShortCut := Menus.ShortCut(Ord(' '), [ssCtrl]);
FExecCommandID := KeyOffset + ecSynCompletionExecute;
FExecCommandID := ecSynCompletionExecute;
end;
procedure TSynCompletion.SetShortCut(Value: TShortCut);
@ -1923,7 +1922,7 @@ begin
FEndOfTokenChr := '()[].';
fAutoCompleteList := TStringList.Create;
fShortCut := Menus.ShortCut(Ord(' '), [ssShift]);
FExecCommandID := KeyOffset + ecSynAutoCompletionExecute;
FExecCommandID := ecSynAutoCompletionExecute;
end;
procedure TSynAutoComplete.SetShortCut(Value: TShortCut);
@ -2166,14 +2165,13 @@ const
function IdentToSynCompletionCommand(const Ident: string; var Cmd: longint): boolean;
begin
Result := IdentToInt(Ident, Cmd, SynComplutionCommandStrs);
if Result then inc(Cmd, KeyOffset);
end;
function SynCompletionCommandToIdent(Cmd: longint; var Ident: string): boolean;
begin
Result := (Cmd - ecPluginFirst >= KeyOffset) and (Cmd - ecPluginFirst < KeyOffset + ecSynCompletionCount);
Result := (Cmd >= ecPluginFirstCompletion) and (Cmd - ecPluginFirstCompletion < ecSynCompletionCount);
if not Result then exit;
Result := IntToIdent(Cmd - KeyOffset, Ident, SynComplutionCommandStrs);
Result := IntToIdent(Cmd, Ident, SynComplutionCommandStrs);
end;
procedure GetEditorCommandValues(Proc: TGetStrProc);
@ -2186,8 +2184,6 @@ end;
initialization
KeyOffset := AllocatePluginKeyRange(ecSynCompletionCount, True);
RegisterKeyCmdIdentProcs(@IdentToSynCompletionCommand,
@SynCompletionCommandToIdent);
RegisterExtraGetEditorCommandValues(@GetEditorCommandValues);

View File

@ -274,6 +274,10 @@ const
ecUserFirst = 1001; // Start of user-defined commands
ecPluginFirstCompletion = 19000;
ecPluginFirstSyncro = 19010;
ecPluginFirstTemplEdit = 19030;
ecPluginFirst = 20000;
// Plugins don't know of other plugins, so they need to map the codes

View File

@ -276,6 +276,7 @@ const
emcMax = 29;
emcPluginFirstSyncro = 19000;
emcPluginFirst = 20000;
// Options

View File

@ -249,9 +249,6 @@ type
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
class function ConvertCommandToBase(Command: TSynEditorCommand): TSynEditorCommand;
class function ConvertBaseToCommand(Command: TSynEditorCommand): TSynEditorCommand;
published
property CaseSensitive: boolean read FCaseSensitive write SetCaseSensitive default false;
property GutterGlyph: TBitmap read FGutterGlyph write SetGutterGlyph;
@ -277,32 +274,31 @@ type
end;
const
emcSynPSyncroEdGutterGlyph = emcPluginFirst + 0;
emcSynPSyncroEdGutterGlyph = emcPluginFirstSyncro + 0;
emcSynPSyncroEdCount = 1;
ecSynPSyncroEdStart = ecPluginFirst + 0;
ecSynPSyncroEdStart = ecPluginFirstSyncro + 0;
ecSynPSyncroEdNextCell = ecPluginFirst + 1;
ecSynPSyncroEdNextCellSel = ecPluginFirst + 2;
ecSynPSyncroEdPrevCell = ecPluginFirst + 3;
ecSynPSyncroEdPrevCellSel = ecPluginFirst + 4;
ecSynPSyncroEdCellHome = ecPluginFirst + 5;
ecSynPSyncroEdCellEnd = ecPluginFirst + 6;
ecSynPSyncroEdCellSelect = ecPluginFirst + 7;
ecSynPSyncroEdEscape = ecPluginFirst + 8;
ecSynPSyncroEdNextFirstCell = ecPluginFirst + 9;
ecSynPSyncroEdNextFirstCellSel = ecPluginFirst + 10;
ecSynPSyncroEdPrevFirstCell = ecPluginFirst + 11;
ecSynPSyncroEdPrevFirstCellSel = ecPluginFirst + 12;
ecSynPSyncroEdNextCell = ecPluginFirstSyncro + 1;
ecSynPSyncroEdNextCellSel = ecPluginFirstSyncro + 2;
ecSynPSyncroEdPrevCell = ecPluginFirstSyncro + 3;
ecSynPSyncroEdPrevCellSel = ecPluginFirstSyncro + 4;
ecSynPSyncroEdCellHome = ecPluginFirstSyncro + 5;
ecSynPSyncroEdCellEnd = ecPluginFirstSyncro + 6;
ecSynPSyncroEdCellSelect = ecPluginFirstSyncro + 7;
ecSynPSyncroEdEscape = ecPluginFirstSyncro + 8;
ecSynPSyncroEdNextFirstCell = ecPluginFirstSyncro + 9;
ecSynPSyncroEdNextFirstCellSel = ecPluginFirstSyncro + 10;
ecSynPSyncroEdPrevFirstCell = ecPluginFirstSyncro + 11;
ecSynPSyncroEdPrevFirstCellSel = ecPluginFirstSyncro + 12;
// If extending the list, reserve space in SynEditKeyCmds
ecSynPSyncroEdCount = 13;
implementation
var
MouseOffset, KeyOffset: integer;
const
MAX_CACHE = 50; // Amount of lower-cased lines cached
MAX_SYNC_ED_WORDS = 50;// 250;
@ -1304,7 +1300,7 @@ function TSynPluginSyncroEdit.DoHandleMouseAction(AnAction: TSynEditMouseAction;
begin
Result := False;
if AnAction.Command = MouseOffset + emcSynPSyncroEdGutterGlyph then begin
if AnAction.Command = emcSynPSyncroEdGutterGlyph then begin
if Mode = spseSelecting then
StartSyncroMode
else
@ -1374,14 +1370,9 @@ begin
end;
if keys = nil then exit;
try
keys.UsePluginOffset := True;
if not FinishComboOnly then
keys.ResetKeyCombo;
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo, FinishComboOnly, ComboKeyStrokes);
finally
keys.UsePluginOffset := False;
end;
if not FinishComboOnly then
keys.ResetKeyCombo;
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo, FinishComboOnly, ComboKeyStrokes);
Handled := (Command <> ecNone) or IsStartOfCombo;
if IsStartOfCombo then
@ -1391,16 +1382,13 @@ end;
procedure TSynPluginSyncroEdit.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
var Handled: boolean; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
HandlerData: pointer);
var
Cmd: TSynEditorCommand;
begin
if Handled or AfterProcessing or not (Active or PreActive) then exit;
if Mode = spseSelecting then begin
// todo: finish word-hash calculations / check if any cells exist
Cmd := ConvertCommandToBase(Command);
Handled := True;
case Cmd of
case Command of
ecSynPSyncroEdStart: StartSyncroMode;
else
Handled := False;
@ -1408,10 +1396,8 @@ begin
end;
if Mode = spseEditing then begin
Cmd := ConvertCommandToBase(Command);
Handled := True;
case Cmd of
case Command of
ecSynPSyncroEdNextCell: NextCell(False, True);
ecSynPSyncroEdNextCellSel: NextCell(True, True);
ecSynPSyncroEdPrevCell: PreviousCell(False, True);
@ -1444,15 +1430,12 @@ begin
FKeystrokes := TSynEditSyncroEditKeyStrokes.Create(Self);
FKeystrokes.ResetDefaults;
FKeystrokes.PluginOffset := KeyOffset;
FKeyStrokesOffCell := TSynEditSyncroEditKeyStrokesOffCell.Create(self);
FKeyStrokesOffCell.ResetDefaults;
FKeyStrokesOffCell.PluginOffset := KeyOffset;
FKeystrokesSelecting := TSynEditSyncroEditKeyStrokesSelecting.Create(Self);
FKeystrokesSelecting.ResetDefaults;
FKeystrokesSelecting.PluginOffset := KeyOffset;
FGutterGlyph := TBitMap.Create;
FGutterGlyph.OnChange := @DoImageChanged;
@ -1478,27 +1461,12 @@ begin
FreeAndNil(FKeystrokesSelecting);
end;
class function TSynPluginSyncroEdit.ConvertCommandToBase(Command: TSynEditorCommand): TSynEditorCommand;
begin
if (Command >= ecPluginFirst + KeyOffset) and
(Command <= ecPluginFirst + KeyOffset + ecSynPSyncroEdCount)
then Result := Command - KeyOffset
else Result := ecNone;
end;
class function TSynPluginSyncroEdit.ConvertBaseToCommand(Command: TSynEditorCommand): TSynEditorCommand;
begin
if (Command >= ecPluginFirst) and (Command <= ecPluginFirst + ecSynPSyncroEdCount)
then Result := Command + KeyOffset
else Result := ecNone;
end;
{ TSynPluginSyncroEditMouseActions }
procedure TSynPluginSyncroEditMouseActions.ResetDefaults;
begin
Clear;
AddCommand(MouseOffset + emcSynPSyncroEdGutterGlyph, False, mbXLeft, ccAny, cdDown, [], []);
AddCommand(emcSynPSyncroEdGutterGlyph, False, mbXLeft, ccAny, cdDown, [], []);
end;
{ TSynEditSyncroEditKeyStrokesSelecting }
@ -1588,14 +1556,13 @@ const
function IdentToSyncroCommand(const Ident: string; var Cmd: longint): boolean;
begin
Result := IdentToInt(Ident, Cmd, EditorSyncroCommandStrs);
if Result then inc(Cmd, KeyOffset);
end;
function SyncroCommandToIdent(Cmd: longint; var Ident: string): boolean;
begin
Result := (Cmd - ecPluginFirst >= KeyOffset) and (Cmd - ecPluginFirst < KeyOffset + ecSynPSyncroEdCount);
Result := (Cmd >= ecPluginFirstSyncro) and (Cmd - ecPluginFirstSyncro < ecSynPSyncroEdCount);
if not Result then exit;
Result := IntToIdent(Cmd - KeyOffset, Ident, EditorSyncroCommandStrs);
Result := IntToIdent(Cmd, Ident, EditorSyncroCommandStrs);
end;
procedure GetEditorCommandValues(Proc: TGetStrProc);
@ -1608,9 +1575,6 @@ end;
initialization
MouseOffset := AllocatePluginMouseRange(emcSynPSyncroEdCount, True);
KeyOffset := AllocatePluginKeyRange(ecSynPSyncroEdCount, True);
RegisterKeyCmdIdentProcs(@IdentToSyncroCommand,
@SyncroCommandToIdent);
RegisterExtraGetEditorCommandValues(@GetEditorCommandValues);

View File

@ -71,8 +71,6 @@ type
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
class function ConvertCommandToBase(Command: TSynEditorCommand): TSynEditorCommand;
class function ConvertBaseToCommand(Command: TSynEditorCommand): TSynEditorCommand;
procedure SetTemplate(aTmpl: String; aLogCaretPos: TPoint); // Replaces current selection
// Coords relativ to the template. base (1, 1)
@ -86,41 +84,38 @@ type
end;
const
ecSynPTmplEdNextCell = ecPluginFirst + 0;
ecSynPTmplEdNextCellSel = ecPluginFirst + 1;
ecSynPTmplEdNextCellRotate = ecPluginFirst + 2;
ecSynPTmplEdNextCellSelRotate = ecPluginFirst + 3;
ecSynPTmplEdPrevCell = ecPluginFirst + 4;
ecSynPTmplEdPrevCellSel = ecPluginFirst + 5;
ecSynPTmplEdCellHome = ecPluginFirst + 6;
ecSynPTmplEdCellEnd = ecPluginFirst + 7;
ecSynPTmplEdCellSelect = ecPluginFirst + 8;
ecSynPTmplEdFinish = ecPluginFirst + 9;
ecSynPTmplEdEscape = ecPluginFirst + 10;
ecSynPTmplEdNextFirstCell = ecPluginFirst + 11;
ecSynPTmplEdNextFirstCellSel = ecPluginFirst + 12;
ecSynPTmplEdNextFirstCellRotate = ecPluginFirst + 13;
ecSynPTmplEdNextFirstCellSelRotate = ecPluginFirst + 14;
ecSynPTmplEdPrevFirstCell = ecPluginFirst + 15;
ecSynPTmplEdPrevFirstCellSel = ecPluginFirst + 16;
ecSynPTmplEdNextCell = ecPluginFirstTemplEdit + 0;
ecSynPTmplEdNextCellSel = ecPluginFirstTemplEdit + 1;
ecSynPTmplEdNextCellRotate = ecPluginFirstTemplEdit + 2;
ecSynPTmplEdNextCellSelRotate = ecPluginFirstTemplEdit + 3;
ecSynPTmplEdPrevCell = ecPluginFirstTemplEdit + 4;
ecSynPTmplEdPrevCellSel = ecPluginFirstTemplEdit + 5;
ecSynPTmplEdCellHome = ecPluginFirstTemplEdit + 6;
ecSynPTmplEdCellEnd = ecPluginFirstTemplEdit + 7;
ecSynPTmplEdCellSelect = ecPluginFirstTemplEdit + 8;
ecSynPTmplEdFinish = ecPluginFirstTemplEdit + 9;
ecSynPTmplEdEscape = ecPluginFirstTemplEdit + 10;
ecSynPTmplEdNextFirstCell = ecPluginFirstTemplEdit + 11;
ecSynPTmplEdNextFirstCellSel = ecPluginFirstTemplEdit + 12;
ecSynPTmplEdNextFirstCellRotate = ecPluginFirstTemplEdit + 13;
ecSynPTmplEdNextFirstCellSelRotate = ecPluginFirstTemplEdit + 14;
ecSynPTmplEdPrevFirstCell = ecPluginFirstTemplEdit + 15;
ecSynPTmplEdPrevFirstCellSel = ecPluginFirstTemplEdit + 16;
// If extending the list, reserve space in SynEditKeyCmds
ecSynPTmplEdCount = 17;
implementation
var
KeyOffset: integer;
{ TSynPluginTemplateEdit }
constructor TSynPluginTemplateEdit.Create(AOwner: TComponent);
begin
FKeystrokes := TSynEditTemplateEditKeyStrokes.Create(Self);
FKeystrokes.ResetDefaults;
FKeystrokes.PluginOffset := KeyOffset;
FKeyStrokesOffCell := TSynEditTemplateEditKeyStrokesOffCell.Create(self);
FKeyStrokesOffCell.ResetDefaults;
FKeyStrokesOffCell.PluginOffset := KeyOffset;
inherited Create(AOwner);
CellParserEnabled := True;
end;
@ -132,22 +127,6 @@ begin
FreeAndNil(FKeyStrokesOffCell);
end;
class function TSynPluginTemplateEdit.ConvertCommandToBase
(Command: TSynEditorCommand): TSynEditorCommand;
begin
if (Command >= ecPluginFirst + KeyOffset) and
(Command <= ecPluginFirst + KeyOffset + ecSynPTmplEdCount)
then Result := Command - KeyOffset
else Result := ecNone;
end;
class function TSynPluginTemplateEdit.ConvertBaseToCommand(Command: TSynEditorCommand): TSynEditorCommand;
begin
if (Command >= ecPluginFirst) and (Command <= ecPluginFirst + ecSynPTmplEdCount)
then Result := Command + KeyOffset
else Result := ecNone;
end;
procedure TSynPluginTemplateEdit.DoEditorRemoving(AValue: TCustomSynEdit);
begin
if Editor <> nil then begin
@ -197,14 +176,9 @@ begin
else
keys := FKeyStrokes;
try
keys.UsePluginOffset := True;
if not FinishComboOnly then
keys.ResetKeyCombo;
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo, FinishComboOnly, ComboKeyStrokes);
finally
keys.UsePluginOffset := False;
end;
if not FinishComboOnly then
keys.ResetKeyCombo;
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo, FinishComboOnly, ComboKeyStrokes);
Handled := (Command <> ecNone) or IsStartOfCombo;
if IsStartOfCombo then
@ -214,14 +188,11 @@ end;
procedure TSynPluginTemplateEdit.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
var Handled: boolean; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
HandlerData: pointer);
var
Cmd: TSynEditorCommand;
begin
if Handled or AfterProcessing or not Active then exit;
Cmd := ConvertCommandToBase(Command);
Handled := True;
case Cmd of
case Command of
ecSynPTmplEdNextCell: NextCellOrFinal(False);
ecSynPTmplEdNextCellSel: NextCellOrFinal(True);
ecSynPTmplEdNextCellRotate: NextCell(False);
@ -498,8 +469,52 @@ begin
AddKey(ecSynPTmplEdEscape, VK_ESCAPE, []);
end;
const
EditorTmplEditCommandStrs: array[0..16] of TIdentMapEntry = (
(Value: ecSynPTmplEdNextCell; Name: 'ecSynPTmplEdNextCell'),
(Value: ecSynPTmplEdNextCellSel; Name: 'ecSynPTmplEdNextCellSel'),
(Value: ecSynPTmplEdNextCellRotate; Name: 'ecSynPTmplEdNextCellRotate'),
(Value: ecSynPTmplEdNextCellSelRotate; Name: 'ecSynPTmplEdNextCellSelRotate'),
(Value: ecSynPTmplEdPrevCell; Name: 'ecSynPTmplEdPrevCell'),
(Value: ecSynPTmplEdPrevCellSel; Name: 'ecSynPTmplEdPrevCellSel'),
(Value: ecSynPTmplEdCellHome; Name: 'ecSynPTmplEdCellHome'),
(Value: ecSynPTmplEdCellEnd; Name: 'ecSynPTmplEdCellEnd'),
(Value: ecSynPTmplEdCellSelect; Name: 'ecSynPTmplEdCellSelect'),
(Value: ecSynPTmplEdFinish; Name: 'ecSynPTmplEdFinish'),
(Value: ecSynPTmplEdEscape; Name: 'ecSynPTmplEdEscape'),
(Value: ecSynPTmplEdNextFirstCell; Name: 'ecSynPTmplEdNextFirstCell'),
(Value: ecSynPTmplEdNextFirstCellSel; Name: 'ecSynPTmplEdNextFirstCellSel'),
(Value: ecSynPTmplEdNextFirstCellRotate; Name: 'ecSynPTmplEdNextFirstCellRotate'),
(Value: ecSynPTmplEdNextFirstCellSelRotate; Name: 'ecSynPTmplEdNextFirstCellSelRotate'),
(Value: ecSynPTmplEdPrevFirstCell; Name: 'ecSynPTmplEdPrevFirstCell'),
(Value: ecSynPTmplEdPrevFirstCellSel; Name: 'ecSynPTmplEdPrevFirstCellSel')
);
function IdentToTmplEditCommand(const Ident: string; var Cmd: longint): boolean;
begin
Result := IdentToInt(Ident, Cmd, EditorTmplEditCommandStrs);
end;
function TmplEditCommandToIdent(Cmd: longint; var Ident: string): boolean;
begin
Result := (Cmd >= ecPluginFirstTemplEdit) and (Cmd - ecPluginFirstTemplEdit < ecSynPTmplEdCount);
if not Result then exit;
Result := IntToIdent(Cmd, Ident, EditorTmplEditCommandStrs);
end;
procedure GetEditorCommandValues(Proc: TGetStrProc);
var
i: integer;
begin
for i := Low(EditorTmplEditCommandStrs) to High(EditorTmplEditCommandStrs) do
Proc(EditorTmplEditCommandStrs[I].Name);
end;
initialization
KeyOffset := AllocatePluginKeyRange(ecSynPTmplEdCount + 1, True);
RegisterKeyCmdIdentProcs(@IdentToTmplEditCommand,
@TmplEditCommandToIdent);
RegisterExtraGetEditorCommandValues(@GetEditorCommandValues);
end.