mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 19:59:14 +02:00
SynEdit: Optimize parsing CompletionList. Use faster string comparison.
git-svn-id: trunk@64626 -
This commit is contained in:
parent
b82ead0cfa
commit
a523ee94b3
@ -44,8 +44,8 @@ unit SynEditAutoComplete;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, StrUtils,
|
Classes, SysUtils, StrUtils,
|
||||||
LCLIntf, LCLType, LCLProc, Controls, SysUtils, Menus,
|
LCLIntf, LCLType, Controls, LCLProc,
|
||||||
LazStringUtils, LazUTF8,
|
LazStringUtils, LazUTF8,
|
||||||
SynEdit, SynEditKeyCmds, SynEditPlugins;
|
SynEdit, SynEditKeyCmds, SynEditPlugins;
|
||||||
|
|
||||||
@ -167,16 +167,15 @@ begin
|
|||||||
inherited Create(AOwner);
|
inherited Create(AOwner);
|
||||||
fAutoCompleteList := TStringList.Create;
|
fAutoCompleteList := TStringList.Create;
|
||||||
TStringList(fAutoCompleteList).OnChange := @CompletionListChanged;
|
TStringList(fAutoCompleteList).OnChange := @CompletionListChanged;
|
||||||
fCompletions := TStringList.Create;
|
fCompletions := TStringListUTF8Fast.Create;
|
||||||
fCompletionComments := TStringList.Create;
|
fCompletionComments := TStringListUTF8Fast.Create;
|
||||||
fCompletionValues := TStringList.Create;
|
fCompletionValues := TStringListUTF8Fast.Create;
|
||||||
fEditors := TList.Create;
|
fEditors := TList.Create;
|
||||||
fEOTokenChars := '()[]{}.';
|
fEOTokenChars := '()[]{}.';
|
||||||
fAttributes:=TFPList.Create;
|
fAttributes:=TFPList.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomSynAutoComplete.GetCompletionAttributes(Index: integer
|
function TCustomSynAutoComplete.GetCompletionAttributes(Index: integer): TStrings;
|
||||||
): TStrings;
|
|
||||||
begin
|
begin
|
||||||
Result:=TStrings(fAttributes[Index]);
|
Result:=TStrings(fAttributes[Index]);
|
||||||
end;
|
end;
|
||||||
@ -405,74 +404,47 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSynAutoComplete.ParseCompletionList;
|
procedure TCustomSynAutoComplete.ParseCompletionList;
|
||||||
|
|
||||||
procedure RemoveFirstLine(var Pattern: string);
|
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
|
||||||
// remove first line (i.e. macro enabled flag)
|
|
||||||
i:=1;
|
|
||||||
while (i<=length(Pattern)) and (not (Pattern[i] in [#10,#13])) do inc(i);
|
|
||||||
if (i<length(Pattern)) and (Pattern[i+1] in [#10,#13])
|
|
||||||
and (Pattern[i+1]<>Pattern[i]) then
|
|
||||||
inc(i);
|
|
||||||
delete(Pattern,1,i);
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
BorlandDCI: boolean;
|
sComplKey, sComment, sComplValue: string;
|
||||||
i, j, Len: integer;
|
|
||||||
s, sCompl, sComment, sComplValue: string;
|
|
||||||
TemplateStarted: Boolean;
|
|
||||||
|
|
||||||
procedure SaveEntry;
|
procedure SaveEntry;
|
||||||
var
|
var
|
||||||
CurAttributes: TStrings;
|
CurAttributes: TStrings;
|
||||||
Lines: TStringList;
|
StartI, EndI: Integer;
|
||||||
LastLineHasEnding: boolean;
|
|
||||||
l: Integer;
|
|
||||||
begin
|
begin
|
||||||
fCompletions.Add(sCompl);
|
fCompletions.Add(sComplKey);
|
||||||
sCompl := '';
|
sComplKey := '';
|
||||||
fCompletionComments.Add(sComment);
|
fCompletionComments.Add(sComment);
|
||||||
sComment := '';
|
sComment := '';
|
||||||
CurAttributes:=TStringList.Create;
|
CurAttributes:=TStringListUTF8Fast.Create;
|
||||||
if copy(sComplValue,1,length(CodeTemplateMacroMagic))=CodeTemplateMacroMagic
|
Assert(not StartsStr(CodeTemplateMacroMagic, sComplValue), 'SaveEntry: Found '+CodeTemplateMacroMagic);
|
||||||
then begin
|
if StartsStr(CodeTemplateAttributesStartMagic, sComplValue) then
|
||||||
RemoveFirstLine(sComplValue);
|
|
||||||
CurAttributes.Values[CodeTemplateEnableMacros]:='true';
|
|
||||||
end else if copy(sComplValue,1,length(CodeTemplateAttributesStartMagic))
|
|
||||||
=CodeTemplateAttributesStartMagic
|
|
||||||
then begin
|
|
||||||
Lines:=TStringList.Create;
|
|
||||||
Lines.Text:=sComplValue;
|
|
||||||
LastLineHasEnding:=(sComplValue<>'') and (sComplValue[length(sComplValue)] in [#10,#13]);
|
|
||||||
Lines.Delete(0);
|
|
||||||
while (Lines.Count>0) and (Lines[0]<>CodeTemplateAttributesEndMagic) do
|
|
||||||
begin
|
begin
|
||||||
CurAttributes.Add(Lines[0]);
|
// Start of attributes
|
||||||
Lines.Delete(0);
|
StartI := Length(CodeTemplateAttributesStartMagic) + 1;
|
||||||
end;
|
while (StartI <= Length(sComplValue)) and (sComplValue[StartI] in [#10,#13]) do
|
||||||
if Lines.Count>0 then
|
Inc(StartI);
|
||||||
Lines.Delete(0);
|
EndI := Pos(CodeTemplateAttributesEndMagic, sComplValue, StartI);
|
||||||
sComplValue:=Lines.Text;
|
if EndI = 0 then
|
||||||
if not LastLineHasEnding then begin
|
raise Exception.Create('TCustomSynAutoComplete.ParseCompletionList: "'
|
||||||
l:=length(sComplValue);
|
+ CodeTemplateAttributesEndMagic + '" not found.');
|
||||||
if (l>0) and (sComplValue[l] in [#10,#13]) then begin
|
CurAttributes.Text := Copy(sComplValue, StartI, EndI-StartI);
|
||||||
dec(l);
|
// Start of value
|
||||||
if (l>0) and (sComplValue[l] in [#10,#13])
|
StartI := EndI + Length(CodeTemplateAttributesEndMagic);
|
||||||
and (sComplValue[l]<>sComplValue[l+1]) then
|
while (StartI <= Length(sComplValue)) and (sComplValue[StartI] in [#10,#13]) do
|
||||||
dec(l);
|
Inc(StartI);
|
||||||
sComplValue:=copy(sComplValue,1,l);
|
sComplValue := Copy(sComplValue, StartI, Length(sComplValue));
|
||||||
end;
|
|
||||||
end;
|
|
||||||
Lines.Free;
|
|
||||||
end;
|
end;
|
||||||
fCompletionValues.Add(sComplValue);
|
fCompletionValues.Add(sComplValue);
|
||||||
sComplValue := '';
|
sComplValue := '';
|
||||||
fAttributes.Add(CurAttributes);
|
fAttributes.Add(CurAttributes);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
BorlandDCI: boolean;
|
||||||
|
i, j, Len: integer;
|
||||||
|
S: string;
|
||||||
|
TemplateStarted: Boolean;
|
||||||
begin
|
begin
|
||||||
fCompletions.Clear;
|
fCompletions.Clear;
|
||||||
fCompletionComments.Clear;
|
fCompletionComments.Clear;
|
||||||
@ -480,62 +452,60 @@ begin
|
|||||||
ClearAttributes;
|
ClearAttributes;
|
||||||
|
|
||||||
if fAutoCompleteList.Count > 0 then begin
|
if fAutoCompleteList.Count > 0 then begin
|
||||||
s := fAutoCompleteList[0];
|
S := fAutoCompleteList[0];
|
||||||
BorlandDCI := (s <> '') and (s[1] = '[');
|
DebugLn(['TCustomSynAutoComplete.ParseCompletionList: ', S]);
|
||||||
|
BorlandDCI := (S <> '') and (S[1] = '[');
|
||||||
sCompl := '';
|
Assert((sComplKey='') and (sComment='') and (sComplValue=''), 'ParseCompletionList: strings not empty.');
|
||||||
sComment := '';
|
|
||||||
sComplValue := '';
|
|
||||||
TemplateStarted:=false;
|
TemplateStarted:=false;
|
||||||
for i := 0 to fAutoCompleteList.Count - 1 do begin
|
for i := 0 to fAutoCompleteList.Count - 1 do begin
|
||||||
s := fAutoCompleteList[i];
|
S := fAutoCompleteList[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 sCompl <> '' then
|
if sComplKey <> '' 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);
|
||||||
sCompl := Copy(s, 2, j - 2);
|
sComplKey := 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);
|
||||||
if (j <= Len) and (s[j] = '|') then
|
if (j <= Len) and (S[j] = '|') then
|
||||||
Inc(j);
|
Inc(j);
|
||||||
while (j <= Len) and (s[j] <= ' ') do
|
while (j <= Len) and (S[j] <= ' ') do
|
||||||
Inc(j);
|
Inc(j);
|
||||||
sComment := Copy(s, j, Len);
|
sComment := Copy(S, j, Len);
|
||||||
if sComment[Length(sComment)] = ']' then
|
if sComment[Length(sComment)] = ']' then
|
||||||
SetLength(sComment, Length(sComment) - 1);
|
SetLength(sComment, Length(sComment) - 1);
|
||||||
TemplateStarted:=true;
|
TemplateStarted:=true;
|
||||||
end else begin
|
end else begin
|
||||||
if not TemplateStarted then
|
if not TemplateStarted then
|
||||||
sComplValue := sComplValue + #13#10;
|
sComplValue := sComplValue + LineEnding;
|
||||||
TemplateStarted:=false;
|
TemplateStarted:=false;
|
||||||
sComplValue := sComplValue + s;
|
sComplValue := sComplValue + 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 sCompl <> '' then
|
if sComplKey <> '' then
|
||||||
SaveEntry;
|
SaveEntry;
|
||||||
// new completion entry
|
// new completion entry
|
||||||
sCompl := s;
|
sComplKey := 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 + #13#10;
|
sComplValue := sComplValue + LineEnding;
|
||||||
TemplateStarted:=false;
|
TemplateStarted:=false;
|
||||||
sComplValue := sComplValue + Copy(s, 2, Len);
|
sComplValue := sComplValue + Copy(S, 2, Len);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if sCompl <> '' then //mg 2000-11-07
|
if sComplKey <> '' then
|
||||||
SaveEntry;
|
SaveEntry;
|
||||||
end;
|
end;
|
||||||
fParsed:=true;
|
fParsed:=true;
|
||||||
|
Loading…
Reference in New Issue
Block a user