added TCEStaticEditorMacro

This commit is contained in:
Basile Burg 2014-12-09 03:48:59 +01:00
parent 58483b5c63
commit 1592af26bb
4 changed files with 228 additions and 17 deletions

View File

@ -142,7 +142,7 @@
<PackageName Value="LCL"/>
</Item6>
</RequiredPackages>
<Units Count="31">
<Units Count="32">
<Unit0>
<Filename Value="coedit.lpr"/>
<IsPartOfProject Value="True"/>
@ -296,47 +296,52 @@
<ResourceBaseClass Value="Form"/>
<UnitName Value="ce_staticexplorer"/>
</Unit23>
<Unit24>
<Unit24>
<Filename Value="..\src\ce_staticmacro.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ce_staticmacro"/>
</Unit24>
<Unit25>
<Filename Value="..\src\ce_symstring.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ce_symstring"/>
</Unit24>
<Unit25>
</Unit25>
<Unit26>
<Filename Value="..\src\ce_synmemo.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ce_synmemo"/>
</Unit25>
<Unit26>
</Unit26>
<Unit27>
<Filename Value="..\src\ce_tools.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ce_tools"/>
</Unit26>
<Unit27>
</Unit27>
<Unit28>
<Filename Value="..\src\ce_toolseditor.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="CEToolsEditorWidget"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="ce_toolseditor"/>
</Unit27>
<Unit28>
</Unit28>
<Unit29>
<Filename Value="..\src\ce_txtsyn.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ce_txtsyn"/>
</Unit28>
<Unit29>
</Unit29>
<Unit30>
<Filename Value="..\src\ce_widget.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="CEWidget"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="ce_widget"/>
</Unit29>
<Unit30>
</Unit30>
<Unit31>
<Filename Value="..\src\ce_writablecomponent.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ce_writableComponent"/>
</Unit30>
</Unit31>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -7,7 +7,8 @@ uses
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, Forms, lazcontrols, runtimetypeinfocontrols, ce_libman, ce_tools,
ce_dcd, ce_observer, ce_main, ce_writableComponent, ce_options, ce_symstring;
ce_dcd, ce_observer, ce_main, ce_writableComponent, ce_options, ce_symstring,
ce_staticmacro;
{$R *.res}

202
src/ce_staticmacro.pas Normal file
View File

@ -0,0 +1,202 @@
unit ce_staticmacro;
{$I ce_defines.inc}
interface
uses
Classes, Sysutils, SynEdit, SynEditAutoComplete,
ce_interfaces, ce_writableComponent, ce_synmemo;
type
(**
* TCEStaticEditorMacro is used to insert static macros (parameter-less code snippets)
* in an editor. A macro begins with the dollar symbol and ends with an alphanum.
*
* The dollar symbol is used as starter because it's usually accessible without
* modifier: no CTRL, no ALT, no SHIFT.
* Erroneous insertion is avoided because in D '$' is either followed
* by a symbol: '$-1', '$]' or by a blank '$ ]'
*
* Shift + SPACE works automatically on the right editor (ICEMultiDocObserver)
* Automatic insertion is handled in TCESynMemo.KeyUp()
*)
TCEStaticEditorMacro = class(TWritableComponent, ICEMultiDocObserver)
private
fCompletor: TSynEditAutoComplete;
fMacros: TStringList;
fDoc: TCESynMemo;
fAutomatic: boolean;
procedure sanitize;
procedure addDefaults;
procedure updateCompletor;
procedure setMacros(aValue: TStringList);
// ICEMultiDocObserver
procedure docNew(aDoc: TCESynMemo);
procedure docFocused(aDoc: TCESynMemo);
procedure docChanged(aDoc: TCESynMemo);
procedure docClosing(aDoc: TCESynMemo);
published
// list of string with the format $<..>alnum=<..>
property macros: TStringList read fMacros write setMacros;
property automatic: boolean read fAutomatic write fAutomatic default true;
public
constructor create(aOwner: TComponent); override;
destructor destroy; override;
// execute using the editor
procedure Execute; overload;
// execute in aEditor, according to aToken
procedure Execute(aEditor: TCustomSynEdit; const aToken: string); overload;
end;
const
macFname = 'staticMacros.txt';
defMacros: array[0..5] of string = (
'$a=auto',
'$c=class {}',
'$s=struct {}',
'$ut=unittest{}',
'$fo=for(auto i = 0; ; )',
'$fe=foreach(elem; )'
);
var
StaticEditorMacro: TCEStaticEditorMacro = nil;
implementation
uses
ce_observer, ce_common;
{$REGION Standard Comp/Obj -----------------------------------------------------}
constructor TCEStaticEditorMacro.create(aOwner: TComponent);
var
fname: string;
begin
inherited;
fAutomatic := true;
fCompletor := TSynEditAutoComplete.Create(self);
fMacros := TStringList.Create;
fMacros.Delimiter := '=';
//
fname := getDocPath + macFname;
if fileExists(fname) then loadFromFile(fname);
addDefaults;
//
sanitize;
updateCompletor;
//
EntitiesConnector.addObserver(Self);
EntitiesConnector.endUpdate;
end;
destructor TCEStaticEditorMacro.destroy;
begin
saveToFile(getDocPath + macFname);
EntitiesConnector.removeObserver(Self);
//
fMacros.Free;
inherited;
end;
procedure TCEStaticEditorMacro.setMacros(aValue: TStringList);
begin
fMacros.Assign(aValue);
addDefaults;
sanitize;
updateCompletor;
end;
{$ENDREGION}
{$REGION ICEMultiDocObserver ---------------------------------------------------}
procedure TCEStaticEditorMacro.docNew(aDoc: TCESynMemo);
begin
fDoc := aDoc;
end;
procedure TCEStaticEditorMacro.docFocused(aDoc: TCESynMemo);
begin
fDoc := aDoc;
end;
procedure TCEStaticEditorMacro.docChanged(aDoc: TCESynMemo);
begin
if aDoc <> fDoc then
exit;
end;
procedure TCEStaticEditorMacro.docClosing(aDoc: TCESynMemo);
begin
if aDoc <> fDoc then
exit;
fDoc := nil;
end;
{$ENDREGION}
{$REGION Macros things ---------------------------------------------------------}
procedure TCEStaticEditorMacro.sanitize;
var
i: Integer;
text: string;
macro: string;
begin
for i := fMacros.Count-1 downto 0 do
begin
text := fMacros.Strings[i];
if length(text) >= 4 then
if text[1] = '$' then
if Pos('=', text) > 2 then
begin
macro := fMacros.Names[i];
if (macro[length(macro)] in ['a'..'z', 'A'..'Z', '0'..'9']) then
continue;
end;
fMacros.Delete(i);
end;
end;
procedure TCEStaticEditorMacro.addDefaults;
var
i: Integer;
begin
for i := 0 to high(defMacros) do
if fMacros.IndexOf(defMacros[i]) = -1 then
fMacros.Add(defMacros[i]);
end;
procedure TCEStaticEditorMacro.updateCompletor;
var
i: Integer;
tok, val: string;
begin
fCompletor.AutoCompleteList.Clear;
for i := 0 to fMacros.Count-1 do
begin
tok := fMacros.Names[i];
val := fMacros.ValueFromIndex[i];
fCompletor.AutoCompleteList.Add(tok);
fCompletor.AutoCompleteList.Add('=' + val);
end;
end;
procedure TCEStaticEditorMacro.Execute;
begin
if fDoc <> nil then
fCompletor.ExecuteCompletion(fDoc.Identifier, fDoc);
end;
procedure TCEStaticEditorMacro.Execute(aEditor: TCustomSynEdit; const aToken: string);
begin
if aEditor <> nil then
fCompletor.ExecuteCompletion(aToken, aEditor);
end;
{$ENDREGION}
initialization
StaticEditorMacro := TCEStaticEditorMacro.create(nil);
finalization
StaticEditorMacro.Free;;
end.

View File

@ -76,7 +76,7 @@ var
implementation
uses
graphics, ce_interfaces;
graphics, ce_interfaces, ce_staticmacro;
{$REGION TCESynMemoPositions ---------------------------------------------------}
constructor TCESynMemoPositions.create(aMemo: TCustomSynEdit);
@ -314,6 +314,9 @@ begin
if Key in [VK_PRIOR, VK_NEXT, Vk_UP] then
fPositions.store;
inherited;
//
if StaticEditorMacro.automatic then
StaticEditorMacro.Execute;
end;
procedure TCESynMemo.MouseMove(Shift: TShiftState; X, Y: Integer);