mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-07-06 19:05:54 +02:00
SynEdit, IDE: Refactoring for code template completion. Sort the list after parsing. Issue #40764.
This commit is contained in:
parent
7044a3b3df
commit
a9f0754324
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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 }
|
||||||
|
@ -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;
|
||||||
|
18
ide/main.pp
18
ide/main.pp
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user