IDE: identifier completion words: better performance in big units (add words around the active line, not from the whole unit)

git-svn-id: trunk@58140 -
This commit is contained in:
ondrej 2018-06-05 16:47:44 +00:00
parent 9715cc6e22
commit a282a46751
3 changed files with 59 additions and 27 deletions

View File

@ -155,7 +155,7 @@ uses
CleanDirDlg, CodeContextForm, AboutFrm, CompatibilityRestrictions,
RestrictionBrowser, ProjectWizardDlg, IDECmdLine, IDEGuiCmdLine, CodeExplOpts,
EditorMacroListViewer, SourceFileManager, EditorToolbarStatic,
IDEInstances, NotifyProcessEnd,
IDEInstances, NotifyProcessEnd, WordCompletion,
// main ide
MainBar, MainIntf, MainBase;
@ -170,7 +170,6 @@ type
TMainIDE = class(TMainIDEBase)
private
FIdentCompletionWords: TStringList;
// event handlers
procedure MainIDEFormClose(Sender: TObject; var {%H-}CloseAction: TCloseAction);
procedure MainIDEFormCloseQuery(Sender: TObject; var CanClose: boolean);
@ -650,11 +649,17 @@ type
FFixingGlobalComponentLock: integer;
OldCompilerFilename, OldLanguage: String;
OIChangedTimer: TIdleTimer;
FIdentifierWordCompletionWordList: TStringList;
FIdentifierWordCompletion: TWordCompletion;
procedure DoDropFilesAsync(Data: PtrInt);
procedure RenameInheritedMethods(AnUnitInfo: TUnitInfo; List: TStrings);
function OIHelpProvider: TAbstractIDEHTMLProvider;
// form editor and designer
procedure IdentifierWordCompletionGetSource(var Source: TStrings;
var SourceTopLine,SourceBottomLine: integer; SourceIndex: integer);
procedure DoAddWordsToIdentCompletion(const Prefix: string);
// form editor and designer
procedure DoBringToFrontFormOrUnit;
procedure DoBringToFrontFormOrInspector(ForceInspector: boolean);
procedure DoShowSourceOfActiveDesignerForm;
@ -1666,7 +1671,8 @@ begin
FreeThenNil(SearchResultsView);
FreeThenNil(ObjectInspector1);
FreeThenNil(SourceEditorManagerIntf);
FreeAndNil(FIdentCompletionWords);
FreeAndNil(FIdentifierWordCompletionWordList);
FreeAndNil(FIdentifierWordCompletion);
// disconnect handlers
Application.RemoveAllHandlersOfObject(Self);
@ -3393,6 +3399,23 @@ begin
(aCaption,aMsg,DlgType,Buttons,HelpKeyword);
end;
procedure TMainIDE.IdentifierWordCompletionGetSource(var Source: TStrings;
var SourceTopLine, SourceBottomLine: integer; SourceIndex: integer);
var
ActiveSrcEdit: TSourceEditor;
ActiveUnitInfo: TUnitInfo;
const
LinesAround = 100;
begin
if SourceIndex<>0 then
Exit;
GetCurrentUnit(ActiveSrcEdit,ActiveUnitInfo);
if ActiveSrcEdit=nil then exit;
Source := ActiveSrcEdit.Source;
SourceTopLine := Max(0, ActiveSrcEdit.EditorComponent.CaretY-LinesAround);
SourceBottomLine := Min(Source.Count-1, ActiveSrcEdit.EditorComponent.CaretY+LinesAround);
end;
function TMainIDE.IDEQuestionDialogHandler(const aCaption, aMsg: string;
DlgType: TMsgDlgType; Buttons: array of const; const HelpKeyword: string): Integer;
begin
@ -6441,16 +6464,22 @@ var
New: TIdentifierListItem;
I: Integer;
begin
if FIdentCompletionWords=nil then
FIdentCompletionWords:=TStringList.Create
if FIdentifierWordCompletionWordList=nil then
FIdentifierWordCompletionWordList:=TStringList.Create
else
FIdentCompletionWords.Clear;
AWordCompletion.GetWordList(FIdentCompletionWords, '', False, 10000, True); // do not get words with prefix because the identifier list isn't reloaded when prefix changes
for I := FIdentCompletionWords.Count-1 downto 0 do
if FIdentCompletionWords[I]<>Prefix then // ignore prefix
FIdentifierWordCompletionWordList.Clear;
if FIdentifierWordCompletion=nil then
begin
FIdentifierWordCompletion := TWordCompletion.Create;
FIdentifierWordCompletion.OnGetSource := @IdentifierWordCompletionGetSource;
end;
FIdentifierWordCompletion.GetWordList(FIdentifierWordCompletionWordList, '', False, 1000); // do not get words with prefix because the identifier list isn't reloaded when prefix changes
for I := FIdentifierWordCompletionWordList.Count-1 downto 0 do
if FIdentifierWordCompletionWordList[I]<>Prefix then // ignore prefix
begin
New := CIdentifierListItem.Create(WordCompatibility, False, WordHistoryIndex,
PChar(FIdentCompletionWords[I]), WordLevel, nil, nil, ctnWord);
PChar(FIdentifierWordCompletionWordList[I]), WordLevel, nil, nil, ctnWord);
CodeToolBoss.IdentifierList.Add(New);
end;
end;

View File

@ -1192,7 +1192,8 @@ type
Index: integer);
protected
procedure CodeToolsToSrcEditTimerTimer(Sender: TObject);
procedure OnWordCompletionGetSource(var Source: TStrings; SourceIndex: integer);
procedure OnWordCompletionGetSource(var Source: TStrings;
var {%H-}SourceTopLine,{%H-}SourceBottomLine: integer; SourceIndex: integer);
procedure OnSourceCompletionTimer(Sender: TObject);
// marks
procedure OnSourceMarksAction(AMark: TSourceMark; {%H-}AAction: TMarksAction);
@ -1403,9 +1404,6 @@ var
EnglishModifiedLGPLNotice: string;
EnglishMITNotice: string;
var
AWordCompletion: TWordCompletion = nil;
implementation
{$R *.lfm}
@ -1425,6 +1423,7 @@ const
SoftCenterMaximum = 8;
var
AWordCompletion: TWordCompletion = nil;
AutoStartCompletionBoxTimer: TIdleTimer = nil;
SourceCompletionCaretXY: TPoint;
PasBeautifier: TSynBeautifierPascal;
@ -10780,7 +10779,7 @@ begin
end;
procedure TSourceEditorManager.OnWordCompletionGetSource(var Source: TStrings;
SourceIndex: integer);
var SourceTopLine, SourceBottomLine: integer; SourceIndex: integer);
var
TempEditor: TSourceEditor;
i:integer;

View File

@ -22,7 +22,8 @@ uses
type
TWordCompletionGetSource =
procedure(var Source:TStrings; SourceIndex:integer) of object;
procedure(var Source:TStrings; var TopLine, BottomLine: Integer;
SourceIndex:integer) of object;
TWordCompletion = class
private
@ -40,7 +41,7 @@ type
property WordBufferCapacity:integer
read GetWordBufferCapacity write SetWordBufferCapacity;
procedure GetWordList(AWordList:TStrings; const Prefix:String;
CaseSensitive:boolean; MaxResults:integer; OnlyCurrentUnit: Boolean = False);
CaseSensitive:boolean; MaxResults:integer);
procedure CompletePrefix(const Prefix: string; var CompletedPrefix: string;
CaseSensitive:boolean);
public
@ -71,13 +72,12 @@ end;
{ TWordCompletion }
procedure TWordCompletion.GetWordList(AWordList: TStrings;
const Prefix: String; CaseSensitive: boolean; MaxResults: integer;
OnlyCurrentUnit: Boolean);
const Prefix: String; CaseSensitive: boolean; MaxResults: integer);
var i, j, Line, x, PrefixLen, MaxHash, LineLen: integer;
UpPrefix, LineText, UpLineText, NewWord: string;
SourceText: TStringList;
HashList: ^integer;// index list. Every entry points to a word in the AWordList
SourceTextIndex:integer;
SourceTextIndex, SourceTopLine, SourceBottomLine:integer;
LastCharType:TCharType;
procedure Add(const AWord:string);
@ -138,12 +138,16 @@ begin
SourceTextIndex:=0;
if Assigned(FOnGetSource) then begin
SourceText:=nil;
FOnGetSource(SourceText,SourceTextIndex);
SourceTopLine:=0;
SourceBottomLine:=-1;
FOnGetSource(SourceText,SourceTopLine,SourceBottomLine,SourceTextIndex);
repeat
if SourceText<>nil then begin
Line:=0;
Line:=SourceTopLine;
if SourceBottomLine<0 then
SourceBottomLine := SourceText.Count-1;
UpLineText:='';
while (Line<SourceText.Count) do begin
while (Line<=SourceBottomLine) do begin
LineText:=SourceText[line];
LineLen:=length(LineText);
if not CaseSensitive then
@ -184,9 +188,9 @@ begin
end;
inc(SourceTextIndex);
SourceText:=nil;
if OnlyCurrentUnit then
break;
FOnGetSource(SourceText,SourceTextIndex);
SourceTopLine:=0;
SourceBottomLine:=-1;
FOnGetSource(SourceText,SourceTopLine,SourceBottomLine,SourceTextIndex);
until SourceText=nil;
end;
finally