SynEdit, IDE: Refactoring for code template completion. Sort the list after parsing. Issue #40764.

This commit is contained in:
Juha 2024-02-13 11:17:11 +02:00
parent 7044a3b3df
commit a9f0754324
7 changed files with 294 additions and 291 deletions

View File

@ -458,8 +458,7 @@ type
function GetTokenList: string; function GetTokenList: string;
function GetTokenValue(Token: string): string; function GetTokenValue(Token: string): string;
published published
property AutoCompleteList: TStrings read fAutoCompleteList property AutoCompleteList: TStrings read fAutoCompleteList write SetAutoCompleteList;
write SetAutoCompleteList;
property EndOfTokenChr: string read FEndOfTokenChr write FEndOfTokenChr; property EndOfTokenChr: string read FEndOfTokenChr write FEndOfTokenChr;
property ShortCut: TShortCut read FShortCut write SetShortCut; property ShortCut: TShortCut read FShortCut write SetShortCut;
property ExecCommandID: TSynEditorCommand read FExecCommandID write FExecCommandID; property ExecCommandID: TSynEditorCommand read FExecCommandID write FExecCommandID;

View File

@ -64,6 +64,37 @@ type
TOnExecuteCompletion = procedure(ASynAutoComplete: TCustomSynAutoComplete; TOnExecuteCompletion = procedure(ASynAutoComplete: TCustomSynAutoComplete;
Index: integer) of object; Index: integer) of object;
// Data for a single template item.
{ TCodeTemplate }
TCodeTemplate = class
private // The Key is Stored in a TCodeTemplateList string item.
fValue: string;
fComment: string;
fAttributes: TStringList; // List of attributes.
public
constructor Create;
constructor Create(aTemplate: TCodeTemplate);
constructor Create(aValue, aComment: string);
destructor Destroy; override;
procedure SetBooleanAttribute(aName: string; aValue: Boolean);
procedure SetValueWithoutLastEOL(aValue: string);
property Value: string read fValue write fValue;
property Comment: string read fComment write fComment;
property Attributes: TStringList read fAttributes;
end;
{ TCodeTemplateList }
TCodeTemplateList = class(TStringListUTF8Fast)
private
function GetTemplate(Index: Integer): TCodeTemplate;
procedure SetTemplate(Index: Integer; AValue: TCodeTemplate);
public
property Objects[Index: Integer]: TCodeTemplate read GetTemplate write SetTemplate;
end;
{ TCustomSynAutoComplete } { TCustomSynAutoComplete }
TCustomSynAutoComplete = class(TLazSynMultiEditPlugin) TCustomSynAutoComplete = class(TLazSynMultiEditPlugin)
@ -71,25 +102,18 @@ type
fOnTokenNotFound: TOnTokenNotFound; fOnTokenNotFound: TOnTokenNotFound;
fIndentToTokenStart: boolean; fIndentToTokenStart: boolean;
FOnExecuteCompletion: TOnExecuteCompletion; FOnExecuteCompletion: TOnExecuteCompletion;
fAttributes: TFPList;// list of TStrings
function GetCompletionAttributes(Index: integer): TStrings;
procedure ClearAttributes;
protected protected
fAutoCompleteList: TStrings; fCodeTemplSource: TStrings;
fCompletions: TStrings; fCodeTemplates: TCodeTemplateList;
fCompletionComments: TStrings;
fCompletionValues: TStrings;
fEditor: TCustomSynEdit; fEditor: TCustomSynEdit;
fEditors: TList; fEditors: TList;
fEOTokenChars: string; fEOTokenChars: string;
fCaseSensitive: boolean; fCaseSensitive: boolean;
fParsed: boolean; fParsed: boolean;
procedure CompletionListChanged(Sender: TObject); procedure CompletionListChanged(Sender: TObject);
function GetCompletions: TStrings; function GetCodeTemplates: TCodeTemplateList;
function GetCompletionComments: TStrings;
function GetCompletionValues: TStrings;
procedure ParseCompletionList; virtual; procedure ParseCompletionList; virtual;
procedure SetAutoCompleteList(Value: TStrings); virtual; procedure SetCodeTemplSource(Value: TStrings); virtual;
procedure SynEditCommandHandler(Sender: TObject; AfterProcessing: boolean; procedure SynEditCommandHandler(Sender: TObject; AfterProcessing: boolean;
var Handled: boolean; var Command: TSynEditorCommand; var Handled: boolean; var Command: TSynEditorCommand;
var AChar: TUTF8Char; var AChar: TUTF8Char;
@ -99,27 +123,17 @@ type
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
procedure AddCompletion(AToken: string; ATemplate: TCodeTemplate);
procedure AddCompletion(AToken, AValue, AComment: string; procedure AddCompletion(AToken, AValue, AComment: string);
TheAttributes: TStrings = nil);
procedure DeleteCompletion(Index: integer);
procedure Execute(AEditor: TCustomSynEdit); virtual; procedure Execute(AEditor: TCustomSynEdit); virtual;
procedure ExecuteCompletion(AToken: string; AEditor: TCustomSynEdit); procedure ExecuteCompletion(AToken: string; AEditor: TCustomSynEdit); virtual;
virtual;
public public
property AutoCompleteList: TStrings read fAutoCompleteList property CodeTemplSource: TStrings read fCodeTemplSource write SetCodeTemplSource;
write SetAutoCompleteList;
property CaseSensitive: boolean read fCaseSensitive write fCaseSensitive; property CaseSensitive: boolean read fCaseSensitive write fCaseSensitive;
property Completions: TStrings read GetCompletions; property CodeTemplates: TCodeTemplateList read GetCodeTemplates;
property CompletionComments: TStrings read GetCompletionComments;
property CompletionValues: TStrings read GetCompletionValues;
property EndOfTokenChr: string read fEOTokenChars write fEOTokenChars; property EndOfTokenChr: string read fEOTokenChars write fEOTokenChars;
property CompletionAttributes[Index: integer]: TStrings property OnTokenNotFound: TOnTokenNotFound read fOnTokenNotFound write fOnTokenNotFound;
read GetCompletionAttributes; property IndentToTokenStart: boolean read fIndentToTokenStart write fIndentToTokenStart;
property OnTokenNotFound: TOnTokenNotFound
read fOnTokenNotFound write fOnTokenNotFound;
property IndentToTokenStart: boolean
read fIndentToTokenStart write fIndentToTokenStart;
property OnExecuteCompletion: TOnExecuteCompletion read FOnExecuteCompletion property OnExecuteCompletion: TOnExecuteCompletion read FOnExecuteCompletion
write FOnExecuteCompletion; write FOnExecuteCompletion;
end; end;
@ -128,7 +142,7 @@ type
TSynEditAutoComplete = class(TCustomSynAutoComplete) TSynEditAutoComplete = class(TCustomSynAutoComplete)
published published
property AutoCompleteList; property CodeTemplSource;
property CaseSensitive; property CaseSensitive;
property Editor; property Editor;
property EndOfTokenChr; property EndOfTokenChr;
@ -139,22 +153,100 @@ type
implementation implementation
{ TCodeTemplate }
constructor TCodeTemplate.Create;
begin
inherited Create;
fAttributes := TStringListUTF8Fast.Create;
fAttributes.UseLocale := False;
fAttributes.OwnsObjects := True;
end;
constructor TCodeTemplate.Create(aTemplate: TCodeTemplate);
begin
Create;
fValue := aTemplate.Value;
fComment := aTemplate.Comment;
fAttributes.Assign(aTemplate.Attributes);
end;
constructor TCodeTemplate.Create(aValue, aComment: string);
begin
Create;
fValue := aValue;
fComment := aComment;
end;
destructor TCodeTemplate.Destroy;
begin
fAttributes.Free;
inherited Destroy;
end;
procedure TCodeTemplate.SetBooleanAttribute(aName: string; aValue: Boolean);
var
i: Integer;
begin
if aValue then
fAttributes.Values[aName] := 'true'
else begin
i := fAttributes.IndexOfName(aName);
if i >= 0 then
fAttributes.Delete(i);
end;
end;
procedure TCodeTemplate.SetValueWithoutLastEOL(aValue: string);
var
l: Integer;
begin // Remove last EOL from Value.
if aValue = '' then Exit;
l := Length(aValue);
if aValue[l] in [#10,#13] then begin
Dec(l);
if (l > 0) and (aValue[l] in [#10,#13])
and (aValue[l] <> aValue[l+1]) then
Dec(l);
SetLength(aValue, l);
end;
fValue := aValue;
end;
{ TCodeTemplateList }
function TCodeTemplateList.GetTemplate(Index: Integer): TCodeTemplate;
begin
Result := TCodeTemplate(inherited GetObject(Index));
end;
procedure TCodeTemplateList.SetTemplate(Index: Integer; AValue: TCodeTemplate);
begin
inherited PutObject(Index, AValue);
end;
{ TCustomSynAutoComplete } { TCustomSynAutoComplete }
procedure TCustomSynAutoComplete.AddCompletion(AToken, AValue, AComment: string; procedure TCustomSynAutoComplete.AddCompletion(AToken: string; ATemplate: TCodeTemplate);
TheAttributes: TStrings); var
NewTemplate: TCodeTemplate;
begin begin
if AToken <> '' then begin if aToken = '' then Exit;
if not fParsed then if not fParsed then
ParseCompletionList; ParseCompletionList;
NewTemplate := TCodeTemplate.Create(ATemplate);
fCodeTemplates.AddObject(aToken, NewTemplate);
end;
fCompletions.Add(AToken); procedure TCustomSynAutoComplete.AddCompletion(AToken, AValue, AComment: string);
fCompletionComments.Add(AComment); var
fCompletionValues.Add(AValue); NewTemplate: TCodeTemplate;
if TheAttributes=nil then begin
TheAttributes:=TStringList.Create; if aToken = '' then Exit;
fAttributes.Add(TheAttributes); if not fParsed then
end; ParseCompletionList;
NewTemplate := TCodeTemplate.Create(AValue, AComment);
fCodeTemplates.AddObject(aToken, NewTemplate);
end; end;
procedure TCustomSynAutoComplete.CompletionListChanged(Sender: TObject); procedure TCustomSynAutoComplete.CompletionListChanged(Sender: TObject);
@ -165,48 +257,18 @@ end;
constructor TCustomSynAutoComplete.Create(AOwner: TComponent); constructor TCustomSynAutoComplete.Create(AOwner: TComponent);
begin begin
inherited Create(AOwner); inherited Create(AOwner);
fAutoCompleteList := TStringList.Create; fCodeTemplSource := TStringList.Create;
TStringList(fAutoCompleteList).OnChange := @CompletionListChanged; TStringList(fCodeTemplSource).OnChange := @CompletionListChanged;
fCompletions := TStringListUTF8Fast.Create; fCodeTemplates := TCodeTemplateList.Create;
fCompletionComments := TStringListUTF8Fast.Create;
fCompletionValues := TStringListUTF8Fast.Create;
fEditors := TList.Create; fEditors := TList.Create;
fEOTokenChars := '()[]{}.'; fEOTokenChars := '()[]{}.';
fAttributes:=TFPList.Create;
end;
function TCustomSynAutoComplete.GetCompletionAttributes(Index: integer): TStrings;
begin
Result:=TStrings(fAttributes[Index]);
end;
procedure TCustomSynAutoComplete.ClearAttributes;
var
i: Integer;
begin
for i:=0 to fAttributes.Count-1 do
TObject(fAttributes[i]).Free;
fAttributes.Clear;
end;
procedure TCustomSynAutoComplete.DeleteCompletion(Index: integer);
begin
fCompletions.Delete(Index);
fCompletionComments.Delete(Index);
fCompletionValues.Delete(Index);
TObject(fAttributes[Index]).Free;
fAttributes.Delete(Index);
end; end;
destructor TCustomSynAutoComplete.Destroy; destructor TCustomSynAutoComplete.Destroy;
begin begin
fEditors.Free; fEditors.Free;
fCompletions.Free; fCodeTemplates.Free;
fCompletionComments.Free; fCodeTemplSource.Free;
fCompletionValues.Free;
fAutoCompleteList.Free;
ClearAttributes;
fAttributes.Free;
inherited Destroy; inherited Destroy;
end; end;
@ -231,7 +293,7 @@ begin
if Assigned(OnTokenNotFound) then if Assigned(OnTokenNotFound) then
OnTokenNotFound(Self,'',AEditor,i); OnTokenNotFound(Self,'',AEditor,i);
if i>=0 then if i>=0 then
ExecuteCompletion(FCompletions[i], AEditor); ExecuteCompletion(fCodeTemplates[i], AEditor);
end; end;
end; end;
end; end;
@ -245,6 +307,7 @@ var
p, p2: TPoint; p, p2: TPoint;
NewCaretPos: boolean; NewCaretPos: boolean;
Temp: TStringList; Temp: TStringList;
Template: TCodeTemplate;
begin begin
if not fParsed then if not fParsed then
ParseCompletionList; ParseCompletionList;
@ -255,15 +318,15 @@ begin
OnTokenNotFound(Self,AToken,AEditor,i); OnTokenNotFound(Self,AToken,AEditor,i);
end; end;
if (Len > 0) and (AEditor <> nil) and not AEditor.ReadOnly if (Len > 0) and (AEditor <> nil) and not AEditor.ReadOnly
and (fCompletions.Count > 0) and (fCodeTemplates.Count > 0)
then begin then begin
// find completion for this token - not all chars necessary if unambiguous // find completion for this token - not all chars necessary if unambiguous
i := fCompletions.Count - 1; i := fCodeTemplates.Count - 1;
IdxMaybe := -1; IdxMaybe := -1;
NumMaybe := 0; NumMaybe := 0;
if fCaseSensitive then begin if fCaseSensitive then begin
while i > -1 do begin while i > -1 do begin
s := fCompletions[i]; s := fCodeTemplates[i];
if s = AToken then if s = AToken then
break break
else if LazStartsStr(AToken, s) then begin else if LazStartsStr(AToken, s) then begin
@ -274,7 +337,7 @@ begin
end; end;
end else begin end else begin
while i > -1 do begin while i > -1 do begin
s := fCompletions[i]; s := fCodeTemplates[i];
if AnsiCompareText(s, AToken) = 0 then if AnsiCompareText(s, AToken) = 0 then
break break
else if AnsiCompareText(Copy(s, 1, Len), AToken) = 0 then begin else if AnsiCompareText(Copy(s, 1, Len), AToken) = 0 then begin
@ -322,8 +385,9 @@ begin
NewCaretPos := FALSE; NewCaretPos := FALSE;
Temp := TStringList.Create; Temp := TStringList.Create;
try try
Temp.Text := fCompletionValues[i]; Template := fCodeTemplates.Objects[i];
s:=fCompletionValues[i]; s:=Template.fValue;
Temp.Text := s;
if (s<>'') and (s[length(s)] in [#10,#13]) then if (s<>'') and (s[length(s)] in [#10,#13]) then
Temp.Add(''); Temp.Add('');
@ -382,62 +446,46 @@ begin
end; end;
end; end;
function TCustomSynAutoComplete.GetCompletions: TStrings; function TCustomSynAutoComplete.GetCodeTemplates: TCodeTemplateList;
begin begin
if not fParsed then if not fParsed then
ParseCompletionList; ParseCompletionList;
Result := fCompletions; Result := fCodeTemplates;
end;
function TCustomSynAutoComplete.GetCompletionComments: TStrings;
begin
if not fParsed then
ParseCompletionList;
Result := fCompletionComments;
end;
function TCustomSynAutoComplete.GetCompletionValues: TStrings;
begin
if not fParsed then
ParseCompletionList;
Result := fCompletionValues;
end; end;
procedure TCustomSynAutoComplete.ParseCompletionList; procedure TCustomSynAutoComplete.ParseCompletionList;
var var
sComplKey, sComment, sComplValue: string; sKey, sValue, sComment: string;
procedure SaveEntry; procedure SaveEntry;
var var
CurAttributes: TStrings;
StartI, EndI: Integer; StartI, EndI: Integer;
Template: TCodeTemplate;
begin begin
fCompletions.Add(sComplKey); Template := TCodeTemplate.Create;
sComplKey := ''; Assert(not LazStartsStr(CodeTemplateMacroMagic, sValue), 'SaveEntry: Found '+CodeTemplateMacroMagic);
fCompletionComments.Add(sComment); if LazStartsStr(CodeTemplateAttributesStartMagic, sValue) then
sComment := '';
CurAttributes:=TStringListUTF8Fast.Create;
Assert(not LazStartsStr(CodeTemplateMacroMagic, sComplValue), 'SaveEntry: Found '+CodeTemplateMacroMagic);
if LazStartsStr(CodeTemplateAttributesStartMagic, sComplValue) then
begin begin
// Start of attributes // Start of attributes
StartI := Length(CodeTemplateAttributesStartMagic) + 1; StartI := Length(CodeTemplateAttributesStartMagic) + 1;
while (StartI <= Length(sComplValue)) and (sComplValue[StartI] in [#10,#13]) do while (StartI <= Length(sValue)) and (sValue[StartI] in [#10,#13]) do
Inc(StartI); Inc(StartI);
EndI := PosEx(CodeTemplateAttributesEndMagic, sComplValue, StartI); EndI := PosEx(CodeTemplateAttributesEndMagic, sValue, StartI);
if EndI = 0 then if EndI = 0 then
raise Exception.Create('TCustomSynAutoComplete.ParseCompletionList: "' raise Exception.Create('TCustomSynAutoComplete.ParseCompletionList: "'
+ CodeTemplateAttributesEndMagic + '" not found.'); + CodeTemplateAttributesEndMagic + '" not found.');
CurAttributes.Text := Copy(sComplValue, StartI, EndI-StartI); Template.Attributes.Text := Copy(sValue, StartI, EndI-StartI);
// Start of value // Start of value
StartI := EndI + Length(CodeTemplateAttributesEndMagic); StartI := EndI + Length(CodeTemplateAttributesEndMagic);
while (StartI <= Length(sComplValue)) and (sComplValue[StartI] in [#10,#13]) do while (StartI <= Length(sValue)) and (sValue[StartI] in [#10,#13]) do
Inc(StartI); Inc(StartI);
sComplValue := Copy(sComplValue, StartI, Length(sComplValue)); Template.Value := Copy(sValue, StartI, Length(sValue));
end; end;
fCompletionValues.Add(sComplValue); Template.Comment := sComment;
sComplValue := ''; fCodeTemplates.AddObject(sKey, Template);
fAttributes.Add(CurAttributes); sKey := '';
sValue := '';
sComment := '';
end; end;
var var
@ -446,29 +494,28 @@ var
S: string; S: string;
TemplateStarted: Boolean; TemplateStarted: Boolean;
begin begin
fCompletions.Clear; fCodeTemplates.Clear;
fCompletionComments.Clear; sKey := '';
fCompletionValues.Clear; sValue := '';
ClearAttributes; sComment := '';
if fCodeTemplSource.Count > 0 then begin
if fAutoCompleteList.Count > 0 then begin S := fCodeTemplSource[0];
S := fAutoCompleteList[0];
BorlandDCI := (S <> '') and (S[1] = '['); BorlandDCI := (S <> '') and (S[1] = '[');
TemplateStarted:=false; TemplateStarted:=false;
for i := 0 to fAutoCompleteList.Count - 1 do begin for i := 0 to fCodeTemplSource.Count - 1 do begin
S := fAutoCompleteList[i]; S := fCodeTemplSource[i];
Len := Length(S); Len := Length(S);
if BorlandDCI then begin if BorlandDCI then begin
// the style of the Delphi32.dci file // the style of the Delphi32.dci file
if (Len > 0) and (S[1] = '[') then begin if (Len > 0) and (S[1] = '[') then begin
// save last entry // save last entry
if sComplKey <> '' then if sKey <> '' then
SaveEntry; SaveEntry;
// new completion entry // new completion entry
j := 2; j := 2;
while (j <= Len) and (S[j] > ' ') do while (j <= Len) and (S[j] > ' ') do
Inc(j); Inc(j);
sComplKey := Copy(S, 2, j - 2); sKey := Copy(S, 2, j - 2);
// start of comment in DCI file // start of comment in DCI file
while (j <= Len) and (S[j] <= ' ') do while (j <= Len) and (S[j] <= ' ') do
Inc(j); Inc(j);
@ -482,36 +529,37 @@ begin
TemplateStarted:=true; TemplateStarted:=true;
end else begin end else begin
if not TemplateStarted then if not TemplateStarted then
sComplValue := sComplValue + LineEnding; sValue := sValue + LineEnding;
TemplateStarted:=false; TemplateStarted:=false;
sComplValue := sComplValue + S; sValue := sValue + S;
end; end;
end else begin end else begin
// the original style // the original style
if (Len > 0) and (S[1] <> '=') then begin if (Len > 0) and (S[1] <> '=') then begin
// save last entry // save last entry
if sComplKey <> '' then if sKey <> '' then
SaveEntry; SaveEntry;
// new completion entry // new completion entry
sComplKey := S; sKey := S;
TemplateStarted:=true; TemplateStarted:=true;
end else if (Len > 0) and (S[1] = '=') then begin end else if (Len > 0) and (S[1] = '=') then begin
if not TemplateStarted then if not TemplateStarted then
sComplValue := sComplValue + LineEnding; sValue := sValue + LineEnding;
TemplateStarted:=false; TemplateStarted:=false;
sComplValue := sComplValue + Copy(S, 2, Len); sValue := sValue + Copy(S, 2, Len);
end; end;
end; end;
end; end;
if sComplKey <> '' then if sKey <> '' then
SaveEntry; SaveEntry;
end; end;
fCodeTemplates.Sort;
fParsed:=true; fParsed:=true;
end; end;
procedure TCustomSynAutoComplete.SetAutoCompleteList(Value: TStrings); procedure TCustomSynAutoComplete.SetCodeTemplSource(Value: TStrings);
begin begin
fAutoCompleteList.Assign(Value); fCodeTemplSource.Assign(Value);
fParsed := FALSE; fParsed := FALSE;
end; end;

View File

@ -108,8 +108,7 @@ type
end; end;
function ExecuteCodeTemplate(SrcEdit: TSourceEditorInterface; function ExecuteCodeTemplate(SrcEdit: TSourceEditorInterface;
const TemplateName, TemplateValue, {%H-}TemplateComment, Template: TCodeTemplate; const TemplateName, EndOfTokenChr: string;
EndOfTokenChr: string; Attributes: TStrings;
IndentToTokenStart: boolean): boolean; IndentToTokenStart: boolean): boolean;
implementation implementation
@ -452,8 +451,7 @@ begin
end; end;
function ExecuteCodeTemplate(SrcEdit: TSourceEditorInterface; function ExecuteCodeTemplate(SrcEdit: TSourceEditorInterface;
const TemplateName, TemplateValue, TemplateComment, Template: TCodeTemplate; const TemplateName, EndOfTokenChr: string;
EndOfTokenChr: string; Attributes: TStrings;
IndentToTokenStart: boolean): boolean; IndentToTokenStart: boolean): boolean;
var var
AEditor: TSynEdit; AEditor: TSynEdit;
@ -471,7 +469,7 @@ begin
Result:=false; Result:=false;
//debugln('ExecuteCodeTemplate ',dbgsName(SrcEdit),' ',dbgsName(SrcEdit.EditorControl)); //debugln('ExecuteCodeTemplate ',dbgsName(SrcEdit),' ',dbgsName(SrcEdit.EditorControl));
AEditor:=SrcEdit.EditorControl as TSynEdit; AEditor:=SrcEdit.EditorControl as TSynEdit;
Pattern:=TemplateValue; Pattern:=Template.Value;
Parser := TLazTemplateParser.Create(Pattern); Parser := TLazTemplateParser.Create(Pattern);
AEditor.BeginUpdate; AEditor.BeginUpdate;
try try
@ -499,8 +497,8 @@ begin
dec(BaseIndent); dec(BaseIndent);
end; end;
Parser.EnableMacros := Attributes.IndexOfName(CodeTemplateEnableMacros)>=0; Parser.EnableMacros := Template.Attributes.IndexOfName(CodeTemplateEnableMacros)>=0;
Parser.KeepSubIndent := Attributes.IndexOfName(CodeTemplateKeepSubIndent)>=0; Parser.KeepSubIndent := Template.Attributes.IndexOfName(CodeTemplateKeepSubIndent)>=0;
Parser.Indent := LogBaseIndent; Parser.Indent := LogBaseIndent;
CodeToolBossOriginalIndent := CodeToolBoss.IndentSize; CodeToolBossOriginalIndent := CodeToolBoss.IndentSize;
if Parser.KeepSubIndent then if Parser.KeepSubIndent then

View File

@ -230,7 +230,7 @@ begin
// exists // exists
if not ASkipExistCheck then if not ASkipExistCheck then
if ASynAutoComplete.Completions.IndexOf(AToken) >= 0 then if ASynAutoComplete.CodeTemplates.IndexOf(AToken) >= 0 then
begin begin
IDEMessageDialog(lisCodeTemplError, lisCodeTemplErrorAlreadyExists, mtError, [mbOK]); IDEMessageDialog(lisCodeTemplError, lisCodeTemplErrorAlreadyExists, mtError, [mbOK]);
exit(false); exit(false);
@ -280,19 +280,19 @@ var
Str: array of string; Str: array of string;
begin begin
Result:= mrCancel; Result:= mrCancel;
if (AIndex<0) or (AIndex>=ASynAutoComplete.Completions.Count) then exit; if (AIndex<0) or (AIndex>=ASynAutoComplete.CodeTemplates.Count) then exit;
SetLength(Str{%H-}, 2); SetLength(Str{%H-}, 2);
Str[0]:= ASynAutoComplete.Completions[AIndex]; Str[0] := ASynAutoComplete.CodeTemplates[AIndex];
Str[1]:= ASynAutoComplete.CompletionComments[AIndex]; Str[1] := ASynAutoComplete.CodeTemplates.Objects[AIndex].Comment;
if not InputQuery(lisCodeTemplEditCodeTemplate, if not InputQuery(lisCodeTemplEditCodeTemplate,
[lisCodeTemplToken, lisCodeTemplComment], Str) then exit; [lisCodeTemplToken, lisCodeTemplComment], Str) then exit;
if not IsCodeTemplateOk(ASynAutoComplete, Str[0], true) then exit; if not IsCodeTemplateOk(ASynAutoComplete, Str[0], true) then exit;
ASynAutoComplete.Completions[AIndex]:= Str[0]; ASynAutoComplete.CodeTemplates[AIndex] := Str[0];
ASynAutoComplete.CompletionComments[AIndex]:= Str[1]; ASynAutoComplete.CodeTemplates.Objects[AIndex].Comment := Str[1];
Result:= mrOk; Result:= mrOk;
end; end;
@ -983,7 +983,7 @@ begin
if AddCodeTemplate(SynAutoComplete,Token,Comment)=mrOk then begin if AddCodeTemplate(SynAutoComplete,Token,Comment)=mrOk then begin
SynAutoComplete.AddCompletion(Token, '', Comment); SynAutoComplete.AddCompletion(Token, '', Comment);
FillCodeTemplateListBox; FillCodeTemplateListBox;
Index := SynAutoComplete.Completions.IndexOf(Token); Index := SynAutoComplete.CodeTemplates.IndexOf(Token);
if Index >= 0 then if Index >= 0 then
Index := TemplateListBox.Items.IndexOfObject(TObject({%H-}Pointer(Index))); Index := TemplateListBox.Items.IndexOfObject(TObject({%H-}Pointer(Index)));
if Index >= 0 then if Index >= 0 then
@ -1008,11 +1008,11 @@ begin
if a < 0 then exit; if a < 0 then exit;
if IDEMessageDialog(lisConfirm, dlgDelTemplate if IDEMessageDialog(lisConfirm, dlgDelTemplate
+'"'+SynAutoComplete.Completions[a]+' - ' +'"'+SynAutoComplete.CodeTemplates[a]+' - '
+SynAutoComplete.CompletionComments[a]+'"' +SynAutoComplete.CodeTemplates[a]+'"'
+'?',mtConfirmation,[mbOk,mbCancel])=mrOK +'?',mtConfirmation,[mbOk,mbCancel])=mrOK
then begin then begin
SynAutoComplete.DeleteCompletion(a); SynAutoComplete.CodeTemplates.Delete(a);
LastTemplate := -1; // to prevent the saving of the deleted template LastTemplate := -1; // to prevent the saving of the deleted template
FillCodeTemplateListBox; FillCodeTemplateListBox;
if idx < TemplateListBox.Items.Count then begin if idx < TemplateListBox.Items.Count then begin
@ -1118,8 +1118,8 @@ begin
if EditCodeTemplate(SynAutoComplete, a)=mrOk then begin if EditCodeTemplate(SynAutoComplete, a)=mrOk then begin
TemplateListBox.Items[idx]:= TemplateListBox.Items[idx]:=
SynAutoComplete.Completions[a] SynAutoComplete.CodeTemplates[a]
+' - "'+SynAutoComplete.CompletionComments[a]+'"'; +' - "'+SynAutoComplete.CodeTemplates[a]+'"';
ShowCurCodeTemplate; ShowCurCodeTemplate;
end; end;
end; end;
@ -1184,11 +1184,12 @@ var
begin begin
sl:=TStringListUTF8Fast.Create; sl:=TStringListUTF8Fast.Create;
try try
for a:=0 to SynAutoComplete.Completions.Count-1 do begin for a:=0 to SynAutoComplete.CodeTemplates.Count-1 do begin
// Add the index in SynAutoComplete as Object, since both indexes won't // Add the index in SynAutoComplete as Object, since both indexes won't
// be in sync after sorting // be in sync after sorting
sl.AddObject(SynAutoComplete.Completions[a] sl.AddObject(SynAutoComplete.CodeTemplates[a]
+' - "'+SynAutoComplete.CompletionComments[a]+'"', TObject({%H-}Pointer(a))); +' - "'+SynAutoComplete.CodeTemplates.Objects[a].Comment+'"',
TObject({%H-}Pointer(a)));
end; end;
sl.Sort; sl.Sort;
TemplateListBox.Items.Assign(sl); TemplateListBox.Items.Assign(sl);
@ -1201,7 +1202,7 @@ procedure TCodeTemplateDialog.ShowCurCodeTemplate;
var var
EnableMacros, KeepSubIndent: boolean; EnableMacros, KeepSubIndent: boolean;
LineCount: integer; LineCount: integer;
Attributes: TStrings; Template: TCodeTemplate;
idx, a, sp, ep: integer; idx, a, sp, ep: integer;
s: string; s: string;
AutoOnCat: array[TAutoCompleteOption] of Boolean; AutoOnCat: array[TAutoCompleteOption] of Boolean;
@ -1215,7 +1216,7 @@ var
// //
function GetBooleanAttribute(const AttrName: string): boolean; inline; function GetBooleanAttribute(const AttrName: string): boolean; inline;
begin begin
result:=StrToBoolDef(Attributes.Values[AttrName], false); result:=StrToBoolDef(Template.Attributes.Values[AttrName], false);
end; end;
// //
begin begin
@ -1237,15 +1238,15 @@ begin
// debugln('TCodeTemplateDialog.ShowCurCodeTemplate A a=',dbgs(a)); // debugln('TCodeTemplateDialog.ShowCurCodeTemplate A a=',dbgs(a));
if a >= 0 if a >= 0
then begin then begin
EditTemplateGroupBox.Caption:=dbgstr(SynAutoComplete.Completions[a]) Template:=SynAutoComplete.CodeTemplates.Objects[a];
+' - '+dbgstr(SynAutoComplete.CompletionComments[a]); EditTemplateGroupBox.Caption:=dbgstr(SynAutoComplete.CodeTemplates[a])
Attributes:=SynAutoComplete.CompletionAttributes[a]; +' - '+dbgstr(Template.Comment);
EnableMacros:=GetBooleanAttribute(CodeTemplateEnableMacros); EnableMacros:=GetBooleanAttribute(CodeTemplateEnableMacros);
KeepSubIndent:=GetBooleanAttribute(CodeTemplateKeepSubIndent); KeepSubIndent:=GetBooleanAttribute(CodeTemplateKeepSubIndent);
for c:=Low(TAutoCompleteOption) to High(TAutoCompleteOption) do for c:=Low(TAutoCompleteOption) to High(TAutoCompleteOption) do
AutoOnCat[c]:=GetBooleanAttribute(AutoCompleteOptionNames[c]); AutoOnCat[c]:=GetBooleanAttribute(AutoCompleteOptionNames[c]);
LastTemplate := -1; LastTemplate := -1;
s:=SynAutoComplete.CompletionValues[a]; s:=Template.Value;
//debugln('TCodeTemplateDialog.ShowCurCodeTemplate s="',s,'"'); //debugln('TCodeTemplateDialog.ShowCurCodeTemplate s="',s,'"');
sp:=1; sp:=1;
ep:=1; ep:=1;
@ -1276,51 +1277,17 @@ end;
procedure TCodeTemplateDialog.SaveCurCodeTemplate; procedure TCodeTemplateDialog.SaveCurCodeTemplate;
var var
a: LongInt; Templ: TCodeTemplate;
procedure SetBooleanAttribute(const AttrName: string; NewValue: boolean);
var
Attributes: TStrings;
l: LongInt;
begin
Attributes:=SynAutoComplete.CompletionAttributes[a];
if NewValue then
Attributes.Values[AttrName]:='true'
else begin
l:=Attributes.IndexOfName(AttrName);
if l>=0 then
Attributes.Delete(l);
end;
end;
var
NewValue: string;
l: integer;
c: TAutoCompleteOption; c: TAutoCompleteOption;
begin begin
if LastTemplate<0 then exit; if LastTemplate<0 then exit;
a := LastTemplate; Templ:=SynAutoComplete.CodeTemplates.Objects[LastTemplate];
//DebugLn('TCodeTemplateDialog.SaveCurCodeTemplate A a=',dbgs(a)); Templ.SetValueWithoutLastEOL(TemplateSynEdit.Lines.Text);
NewValue:=TemplateSynEdit.Lines.Text; Templ.SetBooleanAttribute(CodeTemplateEnableMacros, UseMacrosCheckBox.Checked);
// remove last EOL Templ.SetBooleanAttribute(CodeTemplateKeepSubIndent, KeepSubIndentCheckBox.Checked);
if NewValue<>'' then begin
l:=length(NewValue);
if NewValue[l] in [#10,#13] then begin
dec(l);
if (l>0) and (NewValue[l] in [#10,#13])
and (NewValue[l]<>NewValue[l+1]) then
dec(l);
SetLength(NewValue,l);
end;
end;
SynAutoComplete.CompletionValues[a]:=NewValue;
SetBooleanAttribute(CodeTemplateEnableMacros,UseMacrosCheckBox.Checked);
SetBooleanAttribute(CodeTemplateKeepSubIndent,KeepSubIndentCheckBox.Checked);
for c:=low(TAutoCompleteOption) to High(TAutoCompleteOption) do for c:=low(TAutoCompleteOption) to High(TAutoCompleteOption) do
SetBooleanAttribute(AutoCompleteOptionNames[c],AutoOnOptionsCheckGroup.Checked[ord(c)]); Templ.SetBooleanAttribute(AutoCompleteOptionNames[c],
AutoOnOptionsCheckGroup.Checked[ord(c)]);
//DebugLn('TCodeTemplateDialog.SaveCurCodeTemplate NewValue="',NewValue,'" SynAutoComplete.CompletionValues[a]="',SynAutoComplete.CompletionValues[a],'"');
end; end;
{ TLazCodeMacros } { TLazCodeMacros }

View File

@ -2496,36 +2496,34 @@ const
DciFileVersionName = '!FileVersion'; DciFileVersionName = '!FileVersion';
DciVersionName = '!Version'; DciVersionName = '!Version';
function BuildBorlandDCIFile( function BuildBorlandDCIFile(ACustomSynAutoComplete: TCustomSynAutoComplete): Boolean;
ACustomSynAutoComplete: TCustomSynAutoComplete): Boolean;
// returns if something has changed // returns if something has changed
var var
sl: TStringList; sl: TStringList;
i, sp, ep, v: Integer; i, sp, ep, v: Integer;
Token, Comment, Value: String; Token, Value: String;
Attributes: TStrings; Template: TCodeTemplate;
begin begin
Result := False; Result := False;
sl := TStringList.Create; sl := TStringList.Create;
try try
for i := 0 to ACustomSynAutoComplete.Completions.Count - 1 do for i := 0 to ACustomSynAutoComplete.CodeTemplates.Count - 1 do
begin begin
Token := ACustomSynAutoComplete.Completions[i]; Token := ACustomSynAutoComplete.CodeTemplates[i];
Comment := ACustomSynAutoComplete.CompletionComments[i]; Template := ACustomSynAutoComplete.CodeTemplates.Objects[i];
Value := ACustomSynAutoComplete.CompletionValues[i]; Value := Template.Value;
sl.Add('[' + Token + ' | ' + Comment + ']'); sl.Add('[' + Token + ' | ' + Template.Comment + ']');
Attributes:=ACustomSynAutoComplete.CompletionAttributes[i];
// Store DciFileVersion as attribute to first macro // Store DciFileVersion as attribute to first macro
v := Attributes.IndexOfName(DciFileVersionName); v := Template.Attributes.IndexOfName(DciFileVersionName);
if v >= 0 then if v >= 0 then
Attributes.Delete(v); Template.Attributes.Delete(v);
if i = 0 then if i = 0 then
Attributes.Values[DciFileVersionName] := IntToStr(DciFileVersion); Template.Attributes.Values[DciFileVersionName] := IntToStr(DciFileVersion);
if (Attributes<>nil) and (Attributes.Count>0) then begin if Template.Attributes.Count>0 then begin
sl.Add(CodeTemplateAttributesStartMagic); sl.Add(CodeTemplateAttributesStartMagic);
sl.AddStrings(Attributes); sl.AddStrings(Template.Attributes);
sl.Add(CodeTemplateAttributesEndMagic); sl.Add(CodeTemplateAttributesEndMagic);
end; end;
sp := 1; sp := 1;
@ -2545,10 +2543,10 @@ begin
if (ep > sp) or ((Value <> '') and (Value[length(Value)] in [#10, #13])) then if (ep > sp) or ((Value <> '') and (Value[length(Value)] in [#10, #13])) then
sl.Add(copy(Value, sp, ep - sp)); sl.Add(copy(Value, sp, ep - sp));
end; end;
if ACustomSynAutoComplete.AutoCompleteList.Equals(sl) = False then if not ACustomSynAutoComplete.CodeTemplSource.Equals(sl) then
begin begin
Result := True; Result := True;
ACustomSynAutoComplete.AutoCompleteList := sl; ACustomSynAutoComplete.CodeTemplSource := sl;
end; end;
finally finally
sl.Free; sl.Free;
@ -5786,14 +5784,14 @@ var
s: String; s: String;
FileVersion, i, j, v: Integer; FileVersion, i, j, v: Integer;
NewAutoComplete: TSynEditAutoComplete; NewAutoComplete: TSynEditAutoComplete;
Attr, ExAtr: TStrings;
Added: Boolean; Added: Boolean;
Template: TCodeTemplate;
begin begin
s := CodeTemplateFileNameExpand; s := CodeTemplateFileNameExpand;
Result := mrAbort; Result := mrAbort;
if FileExistsUTF8(s) then begin if FileExistsUTF8(s) then begin
try try
AnAutoComplete.AutoCompleteList.LoadFromFile(s); AnAutoComplete.CodeTemplSource.LoadFromFile(s);
Result := mrOK; Result := mrOK;
except except
Result := mrAbort; Result := mrAbort;
@ -5801,35 +5799,30 @@ begin
if Result = mrAbort then if Result = mrAbort then
exit; exit;
FileVersion := AnAutoComplete.Completions.Count; FileVersion := AnAutoComplete.CodeTemplates.Count;
if (FileVersion > 0) then begin if (FileVersion > 0) then begin
ExAtr := AnAutoComplete.CompletionAttributes[0]; Template := AnAutoComplete.CodeTemplates.Objects[0];
FileVersion := ExAtr.IndexOfName(DciFileVersionName); FileVersion := Template.Attributes.IndexOfName(DciFileVersionName);
if (FileVersion >= 0) then if (FileVersion >= 0) then
FileVersion := StrToIntDef(ExAtr.ValueFromIndex[FileVersion], 0); FileVersion := StrToIntDef(Template.Attributes.ValueFromIndex[FileVersion], 0);
end; end;
if FileVersion < DciFileVersion then begin if FileVersion < DciFileVersion then begin
// Merge new entries // Merge new entries
NewAutoComplete := TSynEditAutoComplete.Create(nil); NewAutoComplete := TSynEditAutoComplete.Create(nil);
NewAutoComplete.AutoCompleteList.Text := ResourceDCIAsText; NewAutoComplete.CodeTemplSource.Text := ResourceDCIAsText;
Added := False; Added := False;
for i := 0 to NewAutoComplete.Completions.Count - 1 do begin for i := 0 to NewAutoComplete.CodeTemplates.Count - 1 do begin
ExAtr := NewAutoComplete.CompletionAttributes[i]; Template := NewAutoComplete.CodeTemplates.Objects[0];
j := ExAtr.IndexOfName(DciVersionName); j := Template.Attributes.IndexOfName(DciVersionName);
if j < 0 then if j < 0 then
continue; continue;
v := StrToIntDef(ExAtr.ValueFromIndex[j], 0); v := StrToIntDef(Template.Attributes.ValueFromIndex[j], 0);
if v <= FileVersion then if v <= FileVersion then
continue; continue;
if AnAutoComplete.Completions.IndexOf(NewAutoComplete.Completions[i]) >= 0 then if AnAutoComplete.CodeTemplates.IndexOf(NewAutoComplete.CodeTemplates[i]) >= 0 then
continue; continue;
Attr := TStringListUTF8Fast.Create; AnAutoComplete.AddCompletion(NewAutoComplete.CodeTemplates[i],
Attr.Assign(ExAtr); // will be owned by AnAutoComplete; NewAutoComplete.CodeTemplates.Objects[0]);
AnAutoComplete.AddCompletion(
NewAutoComplete.Completions[i],
NewAutoComplete.CompletionValues[i],
NewAutoComplete.CompletionComments[i],
Attr);
Added := True; Added := True;
end; end;
NewAutoComplete.Free; NewAutoComplete.Free;
@ -5839,7 +5832,7 @@ begin
end; end;
end end
else begin else begin
AnAutoComplete.AutoCompleteList.Text := ResourceDCIAsText; AnAutoComplete.CodeTemplSource.Text := ResourceDCIAsText;
end; end;
end; end;
@ -5847,7 +5840,7 @@ function TEditorOptions.SaveCodeTemplates(AnAutoComplete: TSynEditAutoComplete
): TModalResult; ): TModalResult;
begin begin
try try
AnAutoComplete.AutoCompleteList.SaveToFile(CodeTemplateFileNameExpand); AnAutoComplete.CodeTemplSource.SaveToFile(CodeTemplateFileNameExpand);
Result := mrOK; Result := mrOK;
except except
Result := mrAbort; Result := mrAbort;

View File

@ -7250,15 +7250,15 @@ var
begin begin
if not CodeToolsOpts.IdentComplIncludeCodeTemplates then if not CodeToolsOpts.IdentComplIncludeCodeTemplates then
Exit; Exit;
with SourceEditorManager.CodeTemplateModul do
for I := 0 to SourceEditorManager.CodeTemplateModul.Completions.Count-1 do for I := 0 to CodeTemplates.Count-1 do
begin begin
New := TCodeTemplateIdentifierListItem.Create(CodeTemplateCompatibility, False, CodeTemplateHistoryIndex, New := TCodeTemplateIdentifierListItem.Create(CodeTemplateCompatibility,
PChar(SourceEditorManager.CodeTemplateModul.Completions[I]), False, CodeTemplateHistoryIndex, PChar(CodeTemplates[I]),
CodeTemplateLevel, nil, nil, ctnCodeTemplate); CodeTemplateLevel, nil, nil, ctnCodeTemplate);
New.Comment := SourceEditorManager.CodeTemplateModul.CompletionComments[I]; New.Comment := CodeTemplates.Objects[I].Comment;
CodeToolBoss.IdentifierList.Add(New); CodeToolBoss.IdentifierList.Add(New);
end; end;
end; end;
procedure TMainIDE.DoCompile; procedure TMainIDE.DoCompile;

View File

@ -2488,15 +2488,16 @@ Begin
ctTemplateCompletion: ctTemplateCompletion:
begin begin
ccSelection:=''; ccSelection:='';
for I := 0 to Manager.CodeTemplateModul.Completions.Count-1 do begin with Manager.CodeTemplateModul do
NewStr := Manager.CodeTemplateModul.Completions[I]; for I := 0 to CodeTemplates.Count-1 do begin
if NewStr<>'' then begin NewStr := CodeTemplates[I];
NewStr:=#3'B'+NewStr+#3'b'; if NewStr<>'' then begin
while length(NewStr)<10+4 do NewStr:=NewStr+' '; NewStr:=#3'B'+NewStr+#3'b';
NewStr:=NewStr+' '+Manager.CodeTemplateModul.CompletionComments[I]; while length(NewStr)<10+4 do NewStr:=NewStr+' ';
SL.Add(NewStr); NewStr:=NewStr+' '+CodeTemplates.Objects[I].Comment;
SL.Add(NewStr);
end;
end; end;
end;
end; end;
end; end;
@ -5086,6 +5087,7 @@ var
SrcToken: String; SrcToken: String;
IdChars: TSynIdentChars; IdChars: TSynIdentChars;
WordToken: String; WordToken: String;
Template: TCodeTemplate;
begin begin
Result:=false; Result:=false;
Line:=GetLineText; Line:=GetLineText;
@ -5098,28 +5100,28 @@ begin
x2 := Min(x2, p.x); x2 := Min(x2, p.x);
WordToken := copy(Line, x1, x2-x1); WordToken := copy(Line, x1, x2-x1);
IdChars := FEditor.IdentChars; IdChars := FEditor.IdentChars;
for i:=0 to Manager.CodeTemplateModul.Completions.Count-1 do begin with Manager.CodeTemplateModul do
AToken:=Manager.CodeTemplateModul.Completions[i]; for i:=0 to CodeTemplates.Count-1 do begin
if AToken='' then continue; AToken:=CodeTemplates[i];
if AToken[1] in IdChars then Template:=CodeTemplates.Objects[i];
SrcToken:=WordToken if AToken='' then continue;
else if AToken[1] in IdChars then
SrcToken:=copy(Line,length(Line)-length(AToken)+1,length(AToken)); SrcToken:=WordToken
//DebugLn(['TSourceEditor.AutoCompleteChar ',AToken,' SrcToken=',SrcToken,' CatName=',CatName,' Index=',Manager.CodeTemplateModul.CompletionAttributes[i].IndexOfName(CatName)]); else
if (AnsiCompareText(AToken,SrcToken)=0) SrcToken:=copy(Line,length(Line)-length(AToken)+1,length(AToken));
and (Manager.CodeTemplateModul.CompletionAttributes[i].IndexOfName(CatName)>=0)
and ( (not FEditor.SelAvail) or
(Manager.CodeTemplateModul.CompletionAttributes[i].IndexOfName(
AutoCompleteOptionNames[acoIgnoreForSelection]) < 0) )
then begin
Result:=true;
//DebugLn(['TSourceEditor.AutoCompleteChar ',AToken,' SrcToken=',SrcToken,' CatName=',CatName,' Index=',Manager.CodeTemplateModul.CompletionAttributes[i].IndexOfName(CatName)]); //DebugLn(['TSourceEditor.AutoCompleteChar ',AToken,' SrcToken=',SrcToken,' CatName=',CatName,' Index=',Manager.CodeTemplateModul.CompletionAttributes[i].IndexOfName(CatName)]);
Manager.CodeTemplateModul.ExecuteCompletion(AToken,FEditor); if (AnsiCompareText(AToken,SrcToken)=0)
AddChar:=not Manager.CodeTemplateModul.CompletionAttributes[i].IndexOfName( and (Template.Attributes.IndexOfName(CatName)>=0)
AutoCompleteOptionNames[acoRemoveChar])>=0; and ( (not FEditor.SelAvail) or
exit; (Template.Attributes.IndexOfName(AutoCompleteOptionNames[acoIgnoreForSelection])<0) )
then begin
Result:=true;
//DebugLn(['TSourceEditor.AutoCompleteChar ',AToken,' SrcToken=',SrcToken,' CatName=',CatName,' Index=',Manager.CodeTemplateModul.CompletionAttributes[i].IndexOfName(CatName)]);
ExecuteCompletion(AToken,FEditor);
AddChar:=not Template.Attributes.IndexOfName(AutoCompleteOptionNames[acoRemoveChar])>=0;
exit;
end;
end; end;
end;
if EditorOpts.AutoBlockCompletion if EditorOpts.AutoBlockCompletion
and (FEditor.Highlighter is TSynPasSyn) then and (FEditor.Highlighter is TSynPasSyn) then
@ -11649,22 +11651,18 @@ procedure TSourceEditorManager.CodeTemplateExecuteCompletion(
ASynAutoComplete: TCustomSynAutoComplete; Index: integer); ASynAutoComplete: TCustomSynAutoComplete; Index: integer);
var var
SrcEdit: TSourceEditorInterface; SrcEdit: TSourceEditorInterface;
Template: TCodeTemplate;
TemplateName: string; TemplateName: string;
TemplateValue: string;
TemplateComment: string;
TemplateAttr: TStrings;
begin begin
SrcEdit:=FindSourceEditorWithEditorComponent(ASynAutoComplete.Editor); SrcEdit:=FindSourceEditorWithEditorComponent(ASynAutoComplete.Editor);
if SrcEdit=nil then if SrcEdit=nil then
SrcEdit := ActiveEditor; SrcEdit := ActiveEditor;
//debugln('TSourceNotebook.OnCodeTemplateExecuteCompletion A ',dbgsName(SrcEdit),' ',dbgsName(ASynAutoComplete.Editor)); //debugln('TSourceNotebook.OnCodeTemplateExecuteCompletion A ',dbgsName(SrcEdit),' ',dbgsName(ASynAutoComplete.Editor));
TemplateName:=ASynAutoComplete.Completions[Index]; TemplateName:=ASynAutoComplete.CodeTemplates[Index];
TemplateValue:=ASynAutoComplete.CompletionValues[Index]; Template:=ASynAutoComplete.CodeTemplates.Objects[Index];
TemplateComment:=ASynAutoComplete.CompletionComments[Index]; ExecuteCodeTemplate(SrcEdit,Template,TemplateName,
TemplateAttr:=ASynAutoComplete.CompletionAttributes[Index]; ASynAutoComplete.EndOfTokenChr,
ExecuteCodeTemplate(SrcEdit,TemplateName,TemplateValue,TemplateComment,
ASynAutoComplete.EndOfTokenChr,TemplateAttr,
ASynAutoComplete.IndentToTokenStart); ASynAutoComplete.IndentToTokenStart);
end; end;