EditorMacros: Refactor, do not inherit TSynMacroRecorder

git-svn-id: trunk@38372 -
This commit is contained in:
martin 2012-08-25 13:37:05 +00:00
parent d80920b427
commit 1ffcfe06cd
2 changed files with 163 additions and 67 deletions

View File

@ -6,34 +6,63 @@ interface
uses uses
Classes, SysUtils, FileUtil, Laz2_XMLCfg, SynMacroRecorder, SynEdit, SynEditKeyCmds, Classes, SysUtils, FileUtil, Laz2_XMLCfg, SynMacroRecorder, SynEdit, SynEditKeyCmds,
FileProcs, Forms, Controls, Graphics, Dialogs, StdCtrls, ButtonPanel, ComCtrls, ExtCtrls, FileProcs, Forms, Controls, Dialogs, StdCtrls, ButtonPanel, ComCtrls, ExtCtrls,
Spin, Menus, LCLType, MainBar, IDEWindowIntf, IDEImagesIntf, LazarusIDEStrConsts, Spin, Menus, LCLType, IDEWindowIntf, IDEImagesIntf, LazarusIDEStrConsts,
ProjectDefs, LazConf, Project, KeyMapping, KeyMapShortCutDlg, SrcEditorIntf, IDEHelpIntf, ProjectDefs, LazConf, Project, KeyMapping, KeyMapShortCutDlg, SrcEditorIntf, IDEHelpIntf,
IDECommands, LazIDEIntf; IDECommands, LazIDEIntf;
type type
TSynEditorMacro = class(TSynMacroRecorder) end;
TEditorMacroState = (emStopped, emRecording, emPlaying, emPaused); // msPaused = paused recording
{ TEditorMacro } { TEditorMacro }
TEditorMacro = class(TSynMacroRecorder) TEditorMacro = class
private private
FMacroName: String;
FHasError: Boolean; FHasError: Boolean;
FFailedText: String; FFailedText: String;
FIdeCmd: TIDECommand; FIdeCmd: TIDECommand;
procedure ExecMacro(Sender: TObject); FOnStateChange: TNotifyEvent;
FSynMacro: TSynEditorMacro;
function GetCurrentEditor: TCustomSynEdit;
function GetIdeCmd: TKeyCommandRelation; function GetIdeCmd: TKeyCommandRelation;
procedure DoMacroRecorderState(Sender: TObject);
procedure DoMacroRecorderUserCommand(aSender: TCustomSynMacroRecorder;
aCmd: TSynEditorCommand; var aEvent: TSynMacroEvent);
protected protected
procedure SetMacroName(AValue: string); override; procedure ExecMacro(Sender: TObject);
procedure SetMacroName(AValue: string);
function GetState: TEditorMacroState;
property IdeCmd: TKeyCommandRelation read GetIdeCmd; property IdeCmd: TKeyCommandRelation read GetIdeCmd;
public public
constructor Create(aOwner: TComponent); override; constructor Create(aOwner: TComponent);
destructor Destroy; override; destructor Destroy; override;
procedure AssignEventsFrom(AMacroRecorder: TEditorMacro);
function AddEditor(AValue: TCustomSynEdit): integer;
procedure RecordMacro(aEditor: TCustomSynEdit);
procedure PlaybackMacro(aEditor: TCustomSynEdit);
procedure Stop;
procedure Pause;
procedure Resume;
procedure Clear;
function GetAsText: String; function GetAsText: String;
procedure SetFromText(const AText: String); procedure SetFromText(const AText: String);
procedure WriteToXmlConf(AConf: TXMLConfig; const APath: String); procedure WriteToXmlConf(AConf: TXMLConfig; const APath: String);
procedure ReadFromXmlConf(AConf: TXMLConfig; const APath: String); procedure ReadFromXmlConf(AConf: TXMLConfig; const APath: String);
function ShortCutAsText: String; function ShortCutAsText: String;
function IsEmpty: Boolean;
property HasError: Boolean read FHasError; property HasError: Boolean read FHasError;
property MacroName: String read FMacroName write SetMacroName;
property State: TEditorMacroState read GetState;
property CurrentEditor: TCustomSynEdit read GetCurrentEditor; // while recording
property OnStateChange: TNotifyEvent read FOnStateChange write FOnStateChange;
end; end;
{ TIdeMacroEventWriter } { TIdeMacroEventWriter }
@ -246,10 +275,10 @@ procedure DoEditorMacroStateChanged;
begin begin
if EditorMacroRecorder= nil then exit; if EditorMacroRecorder= nil then exit;
if not(EditorMacroRecorder.State in [msRecording, msPaused]) and if not(EditorMacroRecorder.State in [emRecording, emPaused]) and
(CurrentRecordingMacro <> nil) (CurrentRecordingMacro <> nil)
then begin then begin
// finished recarding // finished recording
if EditorMacroRecorder.IsEmpty then begin if EditorMacroRecorder.IsEmpty then begin
EditorMacroListRec.Remove(CurrentRecordingMacro); EditorMacroListRec.Remove(CurrentRecordingMacro);
FreeAndNil(CurrentRecordingMacro); FreeAndNil(CurrentRecordingMacro);
@ -260,7 +289,7 @@ begin
end; end;
end; end;
if (EditorMacroRecorder.State = msRecording) and (CurrentRecordingMacro = nil) then begin if (EditorMacroRecorder.State = emRecording) and (CurrentRecordingMacro = nil) then begin
CurrentRecordingMacro := TEditorMacro.Create(nil); CurrentRecordingMacro := TEditorMacro.Create(nil);
CurrentRecordingMacro.MacroName := Format(lisNewMacroName, [MacroRecCounter]); CurrentRecordingMacro.MacroName := Format(lisNewMacroName, [MacroRecCounter]);
inc(MacroRecCounter); inc(MacroRecCounter);
@ -310,7 +339,7 @@ end;
procedure TEditorMacro.ExecMacro(Sender: TObject); procedure TEditorMacro.ExecMacro(Sender: TObject);
begin begin
if EditorMacroRecorder.State <> msStopped then exit; if EditorMacroRecorder.State <> emStopped then exit;
try try
EditorMacroRecorder.AssignEventsFrom(Self); EditorMacroRecorder.AssignEventsFrom(Self);
EditorMacroRecorder.PlaybackMacro(TCustomSynEdit(SourceEditorManagerIntf.ActiveEditor.EditorControl)); EditorMacroRecorder.PlaybackMacro(TCustomSynEdit(SourceEditorManagerIntf.ActiveEditor.EditorControl));
@ -324,9 +353,44 @@ begin
Result := TKeyCommandRelation(FIdeCmd); Result := TKeyCommandRelation(FIdeCmd);
end; end;
procedure TEditorMacro.DoMacroRecorderState(Sender: TObject);
begin
if Assigned(FOnStateChange) then
FOnStateChange(Sender);
end;
procedure TEditorMacro.DoMacroRecorderUserCommand(aSender: TCustomSynMacroRecorder;
aCmd: TSynEditorCommand; var aEvent: TSynMacroEvent);
begin
case aCmd of
ecToggleFormUnit..ecViewThreads, ecViewHistory,
ecNextEditor, ecPrevEditor, ecNextWindow, ecPrevWindow,
ecGotoEditor1..ecGotoEditor0:
aEvent := TSynIgnoredEvent.Create;
else
;//
end;
end;
function TEditorMacro.GetCurrentEditor: TCustomSynEdit;
begin
Result := FSynMacro.CurrentEditor;
end;
function TEditorMacro.GetState: TEditorMacroState;
begin
case FSynMacro.state of
msStopped: Result := emStopped;
msRecording: Result := emRecording;
msPlaying: Result := emPlaying;
msPaused: Result := emPaused;
end;
end;
procedure TEditorMacro.SetMacroName(AValue: string); procedure TEditorMacro.SetMacroName(AValue: string);
begin begin
inherited SetMacroName(AValue); FMacroName := AValue;
FSynMacro.MacroName := AValue;
if (IDECommandList = nil) then if (IDECommandList = nil) then
exit; exit;
@ -361,8 +425,15 @@ end;
constructor TEditorMacro.Create(aOwner: TComponent); constructor TEditorMacro.Create(aOwner: TComponent);
begin begin
inherited Create(aOwner); FSynMacro := TSynEditorMacro.Create(aOwner);
FHasError := False; FHasError := False;
FSynMacro.OnUserCommand := @DoMacroRecorderUserCommand;
FSynMacro.OnStateChange := @DoMacroRecorderState;
FSynMacro.RecordCommandID := ecSynMacroRecord;
FSynMacro.PlaybackCommandID := ecSynMacroPlay;
FSynMacro.RecordShortCut := 0;
FSynMacro.PlaybackShortCut := 0;
end; end;
destructor TEditorMacro.Destroy; destructor TEditorMacro.Destroy;
@ -372,6 +443,50 @@ begin
(IDECommandList as TKeyCommandRelationList).RemoveCommand(FIdeCmd); (IDECommandList as TKeyCommandRelationList).RemoveCommand(FIdeCmd);
FreeAndNil(FIdeCmd); FreeAndNil(FIdeCmd);
end; end;
FreeAndNil(FSynMacro);
end;
procedure TEditorMacro.AssignEventsFrom(AMacroRecorder: TEditorMacro);
begin
if AMacroRecorder = nil then
Clear
else
FSynMacro.AssignEventsFrom(AMacroRecorder.FSynMacro);
end;
function TEditorMacro.AddEditor(AValue: TCustomSynEdit): integer;
begin
Result := FSynMacro.AddEditor(AValue);
end;
procedure TEditorMacro.RecordMacro(aEditor: TCustomSynEdit);
begin
FSynMacro.RecordMacro(aEditor);
end;
procedure TEditorMacro.PlaybackMacro(aEditor: TCustomSynEdit);
begin
FSynMacro.PlaybackMacro(aEditor);
end;
procedure TEditorMacro.Stop;
begin
FSynMacro.Stop;
end;
procedure TEditorMacro.Pause;
begin
FSynMacro.Pause;
end;
procedure TEditorMacro.Resume;
begin
FSynMacro.Resume;
end;
procedure TEditorMacro.Clear;
begin
FSynMacro.Clear;
end; end;
function TEditorMacro.GetAsText: String; function TEditorMacro.GetAsText: String;
@ -387,15 +502,12 @@ begin
W := TIdeMacroEventWriter.Create; W := TIdeMacroEventWriter.Create;
W.UseLineFeed := True; W.UseLineFeed := True;
try try
if Assigned(fEvents) then for i := 0 to FSynMacro.EventCount -1 do
begin
for i := 0 to fEvents.Count -1 do
begin begin
W.BeginEvent; W.BeginEvent;
Events[i].SaveToWriter(W); FSynMacro.Events[i].SaveToWriter(W);
W.FinishEvent; W.FinishEvent;
end; end;
end;
Result := w.Text; Result := w.Text;
finally finally
W.Free; W.Free;
@ -408,16 +520,15 @@ var
R: TIdeMacroEventReader; R: TIdeMacroEventReader;
begin begin
Stop; Stop;
Clear; FSynMacro.Clear;
FHasError := False; FHasError := False;
fEvents := TList.Create;
R := TIdeMacroEventReader.Create(AText); R := TIdeMacroEventReader.Create(AText);
try try
while R.ParseNextEvent do begin while R.ParseNextEvent do begin
iEvent := CreateMacroEvent(R.EventCommand); iEvent := FSynMacro.CreateMacroEvent(R.EventCommand);
iEvent.LoadFromReader(R); iEvent.LoadFromReader(R);
fEvents.Add(iEvent); FSynMacro.InsertCustomEvent(FSynMacro.EventCount, iEvent);
end; end;
if R.HasError then begin if R.HasError then begin
FHasError := True; FHasError := True;
@ -430,7 +541,7 @@ begin
end; end;
procedure TEditorMacro.WriteToXmlConf(AConf: TXMLConfig; const APath: String); procedure TEditorMacro.WriteToXmlConf(AConf: TXMLConfig; const APath: String);
procedure Clear(const SubPath: string); procedure ClearKey(const SubPath: string);
begin begin
AConf.DeleteValue(SubPath+'Key1'); AConf.DeleteValue(SubPath+'Key1');
AConf.DeleteValue(SubPath+'Shift1'); AConf.DeleteValue(SubPath+'Shift1');
@ -460,8 +571,8 @@ begin
AConf.SetValue(APath + 'Code/Value', GetAsText); AConf.SetValue(APath + 'Code/Value', GetAsText);
if (FIdeCmd = nil) then begin if (FIdeCmd = nil) then begin
Clear(APath + 'KeyA/'); ClearKey(APath + 'KeyA/');
Clear(APath + 'KeyB/'); ClearKey(APath + 'KeyB/');
end else begin end else begin
Store(APath + 'KeyA/', FIdeCmd.ShortcutA); Store(APath + 'KeyA/', FIdeCmd.ShortcutA);
Store(APath + 'KeyB/', FIdeCmd.ShortcutB); Store(APath + 'KeyB/', FIdeCmd.ShortcutB);
@ -484,7 +595,7 @@ begin
if s <> '' then MacroName := s; if s <> '' then MacroName := s;
s := AConf.GetValue(APath + 'Code/Value', ''); s := AConf.GetValue(APath + 'Code/Value', '');
SetFromText(s); SetFromText(s);
if (not FHasError) and (EventCount = 0) then begin if (not FHasError) and (FSynMacro.EventCount = 0) then begin
FHasError := True; FHasError := True;
FFailedText := s; FFailedText := s;
end; end;
@ -511,6 +622,11 @@ begin
Result := Result + ' (' + KeyAndShiftStateToEditorKeyString(FIdeCmd.ShortcutB) + ')'; Result := Result + ' (' + KeyAndShiftStateToEditorKeyString(FIdeCmd.ShortcutB) + ')';
end; end;
function TEditorMacro.IsEmpty: Boolean;
begin
Result := FSynMacro.IsEmpty;
end;
{ TIdeMacroEventReader } { TIdeMacroEventReader }
function TIdeMacroEventReader.GetParamAsInt(Index: Integer): Integer; function TIdeMacroEventReader.GetParamAsInt(Index: Integer): Integer;
@ -777,7 +893,7 @@ procedure TMacroListView.btnPlayClick(Sender: TObject);
var var
i: Integer; i: Integer;
begin begin
if EditorMacroRecorder.State <> msStopped then exit; if EditorMacroRecorder.State <> emStopped then exit;
if lbRecordedView.ItemIndex < 0 then exit; if lbRecordedView.ItemIndex < 0 then exit;
i := 1; i := 1;
@ -834,15 +950,15 @@ end;
procedure TMacroListView.btnRecordClick(Sender: TObject); procedure TMacroListView.btnRecordClick(Sender: TObject);
begin begin
if EditorMacroRecorder.State = msStopped then begin if EditorMacroRecorder.State = emStopped then begin
EditorMacroRecorder.RecordMacro(TCustomSynEdit(SourceEditorManagerIntf.ActiveEditor.EditorControl)); EditorMacroRecorder.RecordMacro(TCustomSynEdit(SourceEditorManagerIntf.ActiveEditor.EditorControl));
end end
else else
if EditorMacroRecorder.State = msRecording then begin if EditorMacroRecorder.State = emRecording then begin
EditorMacroRecorder.Pause; EditorMacroRecorder.Pause;
end end
else else
if EditorMacroRecorder.State = msPaused then begin if EditorMacroRecorder.State = emPaused then begin
EditorMacroRecorder.Resume; EditorMacroRecorder.Resume;
end; end;
SourceEditorManagerIntf.ActiveEditor.EditorControl.SetFocus; SourceEditorManagerIntf.ActiveEditor.EditorControl.SetFocus;
@ -856,7 +972,7 @@ end;
procedure TMacroListView.btnSelectClick(Sender: TObject); procedure TMacroListView.btnSelectClick(Sender: TObject);
begin begin
if EditorMacroRecorder.State <> msStopped then exit; if EditorMacroRecorder.State <> emStopped then exit;
if lbRecordedView.ItemIndex >= 0 then if lbRecordedView.ItemIndex >= 0 then
CurrentActiveMacro := CurrentEditorMacroList.Macros[lbRecordedView.ItemIndex] CurrentActiveMacro := CurrentEditorMacroList.Macros[lbRecordedView.ItemIndex]
else else
@ -927,7 +1043,7 @@ begin
try try
NewMacro := TEditorMacro.Create(nil); NewMacro := TEditorMacro.Create(nil);
NewMacro.ReadFromXmlConf(Conf, 'EditorMacros/Macro1/'); NewMacro.ReadFromXmlConf(Conf, 'EditorMacros/Macro1/');
if NewMacro.EventCount > 0 then if not NewMacro.IsEmpty then
CurrentEditorMacroList.Add(NewMacro) CurrentEditorMacroList.Add(NewMacro)
else else
NewMacro.Free; NewMacro.Free;
@ -1005,7 +1121,7 @@ begin
NewItem.ImageIndex := FImageRec NewItem.ImageIndex := FImageRec
else else
if (CurrentRecordingMacro = nil) and (m = CurrentActiveMacro) then begin if (CurrentRecordingMacro = nil) and (m = CurrentActiveMacro) then begin
if (EditorMacroRecorder.State = msPlaying) then if (EditorMacroRecorder.State = emPlaying) then
NewItem.ImageIndex := FImagePlay NewItem.ImageIndex := FImagePlay
else else
NewItem.ImageIndex := FImageSel; NewItem.ImageIndex := FImageSel;
@ -1026,7 +1142,7 @@ var
M: TEditorMacro; M: TEditorMacro;
begin begin
IsSel := (lbRecordedView.ItemIndex >= 0); IsSel := (lbRecordedView.ItemIndex >= 0);
IsStopped := (EditorMacroRecorder.State = msStopped); IsStopped := (EditorMacroRecorder.State = emStopped);
if IsSel then if IsSel then
M := CurrentEditorMacroList.Macros[lbRecordedView.ItemIndex]; M := CurrentEditorMacroList.Macros[lbRecordedView.ItemIndex];
IsErr := IsSel and M.HasError; IsErr := IsSel and M.HasError;
@ -1042,12 +1158,12 @@ begin
chkRepeat.Enabled := IsStopped and (not FIsPlaying); chkRepeat.Enabled := IsStopped and (not FIsPlaying);
edRepeat.Enabled := IsStopped and (not FIsPlaying); edRepeat.Enabled := IsStopped and (not FIsPlaying);
btnRecord.Enabled := (EditorMacroRecorder.State in [msStopped, msPaused, msRecording]) and (not FIsPlaying); btnRecord.Enabled := (EditorMacroRecorder.State in [emStopped, emPaused, emRecording]) and (not FIsPlaying);
btnRecordStop.Enabled := (not IsStopped) or FIsPlaying; btnRecordStop.Enabled := (not IsStopped) or FIsPlaying;
if (EditorMacroRecorder.State = msRecording) then if (EditorMacroRecorder.State = emRecording) then
btnRecord.Caption := lisPause btnRecord.Caption := lisPause
else if (EditorMacroRecorder.State = msPaused) then else if (EditorMacroRecorder.State = emPaused) then
btnRecord.Caption := lisContinue btnRecord.Caption := lisContinue
else else
btnRecord.Caption := lisRecord; btnRecord.Caption := lisRecord;

View File

@ -52,14 +52,14 @@ uses
SynEditLines, SynEditStrConst, SynEditTypes, SynEdit, SynRegExpr, SynEditLines, SynEditStrConst, SynEditTypes, SynEdit, SynRegExpr,
SynEditHighlighter, SynEditAutoComplete, SynEditKeyCmds, SynCompletion, SynEditHighlighter, SynEditAutoComplete, SynEditKeyCmds, SynCompletion,
SynEditMiscClasses, SynEditMarkupHighAll, SynEditMarks, SynEditMiscClasses, SynEditMarkupHighAll, SynEditMarks,
SynBeautifier, SynEditTextBase, LazSynEditText, SynBeautifier, LazSynEditText,
SynPluginSyncronizedEditBase, SourceSynEditor, SynMacroRecorder, SynPluginSyncronizedEditBase, SourceSynEditor, SynMacroRecorder,
SynExportHTML, SynExportHTML,
// Intf // Intf
SrcEditorIntf, MenuIntf, LazIDEIntf, PackageIntf, IDEHelpIntf, IDEImagesIntf, SrcEditorIntf, MenuIntf, LazIDEIntf, PackageIntf, IDEHelpIntf, IDEImagesIntf,
IDEWindowIntf, ProjectIntf, IDEWindowIntf, ProjectIntf,
// IDE units // IDE units
IDEDialogs, DialogProcs, LazarusIDEStrConsts, IDECommands, EditorOptions, IDEDialogs, LazarusIDEStrConsts, IDECommands, EditorOptions,
EnvironmentOpts, WordCompletion, FindReplaceDialog, IDEProcs, IDEOptionDefs, EnvironmentOpts, WordCompletion, FindReplaceDialog, IDEProcs, IDEOptionDefs,
IDEHelpManager, MacroPromptDlg, TransferMacros, CodeContextForm, IDEHelpManager, MacroPromptDlg, TransferMacros, CodeContextForm,
SrcEditHintFrm, MsgView, InputHistory, SrcEditHintFrm, MsgView, InputHistory,
@ -949,8 +949,6 @@ type
FMacroRecorder: TEditorMacro; FMacroRecorder: TEditorMacro;
FOnCurrentCodeBufferChanged: TNotifyEvent; FOnCurrentCodeBufferChanged: TNotifyEvent;
procedure DoMacroRecorderState(Sender: TObject); procedure DoMacroRecorderState(Sender: TObject);
procedure DoMacroRecorderUserCommand(aSender: TCustomSynMacroRecorder;
aCmd: TSynEditorCommand; var aEvent: TSynMacroEvent);
public public
property OnCurrentCodeBufferChanged: TNotifyEvent property OnCurrentCodeBufferChanged: TNotifyEvent
read FOnCurrentCodeBufferChanged write FOnCurrentCodeBufferChanged; read FOnCurrentCodeBufferChanged write FOnCurrentCodeBufferChanged;
@ -7403,14 +7401,14 @@ begin
PanelFileMode := PanelFileMode + uepReadonly; PanelFileMode := PanelFileMode + uepReadonly;
end; end;
if (Manager.MacroRecorder.State = msRecording) and if (Manager.MacroRecorder.State = emRecording) and
(Manager.MacroRecorder.CurrentEditor = CurEditor) (Manager.MacroRecorder.CurrentEditor = CurEditor)
then begin then begin
if PanelFileMode <> '' then if PanelFileMode <> '' then
PanelFileMode := PanelFileMode + lisUEModeSeparator; PanelFileMode := PanelFileMode + lisUEModeSeparator;
PanelFileMode := PanelFileMode + ueMacroRecording; PanelFileMode := PanelFileMode + ueMacroRecording;
end; end;
if (Manager.MacroRecorder.State = msPaused) and if (Manager.MacroRecorder.State = emPaused) and
(Manager.MacroRecorder.CurrentEditor = CurEditor) (Manager.MacroRecorder.CurrentEditor = CurEditor)
then begin then begin
if PanelFileMode <> '' then if PanelFileMode <> '' then
@ -7436,7 +7434,7 @@ begin
StatusBar.Panels[2].Text := PanelFileMode; StatusBar.Panels[2].Text := PanelFileMode;
Statusbar.Panels[3].Text := PanelCharMode; Statusbar.Panels[3].Text := PanelCharMode;
Statusbar.Panels[4].Text := PanelFilename; Statusbar.Panels[4].Text := PanelFilename;
if (Manager.MacroRecorder.State in [msRecording, msPaused]) and if (Manager.MacroRecorder.State in [emRecording, emPaused]) and
(Manager.MacroRecorder.CurrentEditor = CurEditor) (Manager.MacroRecorder.CurrentEditor = CurEditor)
then then
Statusbar.Panels[1].Width := 20 Statusbar.Panels[1].Width := 20
@ -8205,19 +8203,6 @@ begin
DoEditorMacroStateChanged; DoEditorMacroStateChanged;
end; end;
procedure TSourceEditorManagerBase.DoMacroRecorderUserCommand(aSender: TCustomSynMacroRecorder;
aCmd: TSynEditorCommand; var aEvent: TSynMacroEvent);
begin
case aCmd of
ecToggleFormUnit..ecViewThreads, ecViewHistory,
ecNextEditor, ecPrevEditor, ecNextWindow, ecPrevWindow,
ecGotoEditor1..ecGotoEditor0:
aEvent := TSynIgnoredEvent.Create;
else
;//
end;
end;
procedure TSourceEditorManagerBase.FreeSourceWindows; procedure TSourceEditorManagerBase.FreeSourceWindows;
var var
s: TSourceEditorWindowInterface; s: TSourceEditorWindowInterface;
@ -8644,11 +8629,6 @@ var
begin begin
FMacroRecorder := TEditorMacro.Create(self); FMacroRecorder := TEditorMacro.Create(self);
FMacroRecorder.OnStateChange := @DoMacroRecorderState; FMacroRecorder.OnStateChange := @DoMacroRecorderState;
FMacroRecorder.OnUserCommand := @DoMacroRecorderUserCommand;
FMacroRecorder.RecordCommandID := ecSynMacroRecord;
FMacroRecorder.PlaybackCommandID := ecSynMacroPlay;
FMacroRecorder.RecordShortCut := 0;
FMacroRecorder.PlaybackShortCut := 0;
EditorMacroRecorder := FMacroRecorder; EditorMacroRecorder := FMacroRecorder;