mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-18 01:09:35 +02:00
Codetools: Identifier completion, improve/fix limit for recent history items shown. issue #40332
- take into account that some items in history may not be in the current unfiltered items, and that "HistoryIndex" may have gaps
This commit is contained in:
parent
e7c438c50b
commit
9146a986b4
@ -1095,8 +1095,8 @@ begin
|
||||
{$ENDIF}
|
||||
FreeAndNil(DefaultLFMTrees);
|
||||
FreeAndNil(Positions);
|
||||
FreeAndNil(IdentifierHistory);
|
||||
FreeAndNil(IdentifierList);
|
||||
FreeAndNil(IdentifierHistory);
|
||||
FPascalTools.FreeAndClear;
|
||||
FreeAndNil(FPascalTools);
|
||||
FDirectivesTools.FreeAndClear;
|
||||
|
@ -226,6 +226,11 @@ type
|
||||
|
||||
TIdentComplSortMethod = (icsScopedAlphabetic, icsAlphabetic, icsScopedDeclaration);
|
||||
|
||||
const
|
||||
IdentComplSortMethodUsingCompatibility = [icsScopedAlphabetic, icsScopedDeclaration];
|
||||
|
||||
type
|
||||
|
||||
TOnGatherUserIdentifiersToFilteredList = procedure(Sender: TIdentifierList;
|
||||
FilteredList: TFPList; PriorityCount: Integer) of object;
|
||||
|
||||
@ -248,6 +253,7 @@ type
|
||||
FFilteredList: TFPList; // list of TIdentifierListItem
|
||||
FFlags: TIdentifierListFlags;
|
||||
FHistory: TIdentifierHistoryList;
|
||||
FFoundHistoryItems: array of TIdentifierListItem; // Items that have a HistoryIndex / list may have gaps
|
||||
FItems: TAvlTree; // tree of TIdentifierListItem (completely sorted)
|
||||
FIdentView: TAVLTree; // tree of TIdentifierListItem sorted for identifiers
|
||||
FUsedTools: TAVLTree; // tree of TFindDeclarationTool
|
||||
@ -590,7 +596,7 @@ var
|
||||
Item2: TIdentifierListItem absolute Data2;
|
||||
begin
|
||||
|
||||
if SortMethodForCompletion in [icsScopedAlphabetic, icsScopedDeclaration] then begin
|
||||
if SortMethodForCompletion in IdentComplSortMethodUsingCompatibility then begin
|
||||
// first sort for Compatibility (lower is better)
|
||||
if ord(Item1.Compatibility)<ord(Item2.Compatibility) then begin
|
||||
Result:=-1;
|
||||
@ -601,25 +607,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
if SortForHistory then begin
|
||||
// then sort for History (lower is better)
|
||||
if Item1.HistoryIndex<Item2.HistoryIndex then begin
|
||||
if Item1.HistoryIndex <SortForHistoryLimit then
|
||||
begin
|
||||
Result:=-1;
|
||||
exit;
|
||||
end;
|
||||
end else
|
||||
if Item1.HistoryIndex>Item2.HistoryIndex then
|
||||
begin
|
||||
if Item2.HistoryIndex <SortForHistoryLimit then
|
||||
begin
|
||||
Result:=1;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if SortMethodForCompletion in [icsScopedAlphabetic, icsScopedDeclaration] then begin
|
||||
// then sort for Level (i.e. scope, lower is better)
|
||||
if Item1.Level<Item2.Level then begin
|
||||
@ -680,9 +667,56 @@ end;
|
||||
procedure TIdentifierList.UpdateFilteredList;
|
||||
var
|
||||
AnAVLNode: TAvlTreeNode;
|
||||
CurItem: TIdentifierListItem;
|
||||
cPriorityCount: Integer;
|
||||
CurItem, CurItem2: TIdentifierListItem;
|
||||
cPriorityCount, TotalHistLimit, j: Integer;
|
||||
i: PtrInt;
|
||||
HistoryLimits: array [TIdentifierCompatibility] of integer;
|
||||
HasCompSort: Boolean;
|
||||
HistComp, CurItmComp: TIdentifierCompatibility;
|
||||
|
||||
procedure InsertCurItem; inline;
|
||||
begin
|
||||
if (length(Prefix)=length(CurItem.Identifier))
|
||||
and (not (iliAtCursor in CurItem.Flags)) then
|
||||
// put exact matches at the beginning
|
||||
FFilteredList.Insert(0,CurItem)
|
||||
else
|
||||
FFilteredList.Insert(cPriorityCount, CurItem);
|
||||
Inc(cPriorityCount);
|
||||
end;
|
||||
|
||||
function FilterCurItem: Integer; inline;
|
||||
begin
|
||||
if FContainsFilter then
|
||||
Result:=IdentifierPos(PChar(Pointer(Prefix)),PChar(Pointer(CurItem.Identifier)))
|
||||
else if ComparePrefixIdent(PChar(Pointer(Prefix)),PChar(Pointer(CurItem.Identifier))) then
|
||||
Result:=0
|
||||
else
|
||||
Result:=-1;
|
||||
end;
|
||||
|
||||
procedure AddHistoryCurItem(ForceComp: Boolean);
|
||||
var
|
||||
CurItmComp: TIdentifierCompatibility;
|
||||
j: integer;
|
||||
begin
|
||||
for j := 0 to length(FFoundHistoryItems) - 1 do begin
|
||||
CurItem := FFoundHistoryItems[j];
|
||||
if (CurItem = nil) then
|
||||
continue;
|
||||
if ForceComp then
|
||||
CurItmComp := low(TIdentifierCompatibility)
|
||||
else
|
||||
CurItmComp := CurItem.Compatibility;
|
||||
if (CurItmComp <> HistComp) then
|
||||
Continue;
|
||||
if (CurItem.HistoryIndex > HistoryLimits[CurItmComp]) then
|
||||
break;
|
||||
if (CurItem.Identifier<>'') and (FilterCurItem >= 0) then
|
||||
InsertCurItem;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
if not (ilfFilteredListNeedsUpdate in FFlags) then exit;
|
||||
if FFilteredList=nil then FFilteredList:=TFPList.Create;
|
||||
@ -691,39 +725,79 @@ begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn(['TIdentifierList.UpdateFilteredList Prefix="',Prefix,'"']);
|
||||
{$ENDIF}
|
||||
AnAVLNode:=FItems.FindLowest;
|
||||
|
||||
// Update HistoryLimits
|
||||
TotalHistLimit := 0;
|
||||
HasCompSort := SortMethodForCompletion in IdentComplSortMethodUsingCompatibility;
|
||||
if FSortForHistory then
|
||||
TotalHistLimit := FSortForHistoryLimit;
|
||||
for HistComp in TIdentifierCompatibility do begin
|
||||
HistoryLimits[HistComp] := -1;
|
||||
end;
|
||||
for HistComp in TIdentifierCompatibility do begin
|
||||
for j := 0 to length(FFoundHistoryItems) - 1 do begin
|
||||
if TotalHistLimit <= 0 then
|
||||
break;
|
||||
if (FFoundHistoryItems[j] <> nil) and
|
||||
( (FFoundHistoryItems[j].Compatibility = HistComp) or (not HasCompSort) ) and
|
||||
(FFoundHistoryItems[j].Identifier <> '')
|
||||
then begin
|
||||
HistoryLimits[HistComp] := FFoundHistoryItems[j].HistoryIndex;
|
||||
dec(TotalHistLimit);
|
||||
end;
|
||||
end;
|
||||
if not HasCompSort then
|
||||
break;
|
||||
end;
|
||||
|
||||
cPriorityCount := 0;
|
||||
HistComp := Low(TIdentifierCompatibility);
|
||||
AddHistoryCurItem(not HasCompSort);
|
||||
|
||||
AnAVLNode:=FItems.FindLowest;
|
||||
while AnAVLNode<>nil do begin
|
||||
CurItem:=TIdentifierListItem(AnAVLNode.Data);
|
||||
CurItem2:=TIdentifierListItem(AnAVLNode.Data);
|
||||
// history for each compatibility
|
||||
if HasCompSort then begin
|
||||
while HistComp < CurItem2.Compatibility do begin
|
||||
inc(HistComp);
|
||||
AddHistoryCurItem(False);
|
||||
end;
|
||||
end;
|
||||
|
||||
CurItem := CurItem2;
|
||||
if CurItem.Identifier<>'' then
|
||||
begin
|
||||
if FContainsFilter then
|
||||
i:=IdentifierPos(PChar(Pointer(Prefix)),PChar(Pointer(CurItem.Identifier)))
|
||||
else if ComparePrefixIdent(PChar(Pointer(Prefix)),PChar(Pointer(CurItem.Identifier))) then
|
||||
i:=0
|
||||
i := FilterCurItem;
|
||||
if HasCompSort then
|
||||
CurItmComp := CurItem.Compatibility
|
||||
else
|
||||
i:=-1;
|
||||
CurItmComp := low(TIdentifierCompatibility);
|
||||
if i=0 then begin
|
||||
{$IFDEF ShowFilteredIdents}
|
||||
DebugLn(['::: FILTERED ITEM ',FFilteredList.Count,' ',CurItem.Identifier]);
|
||||
{$ENDIF}
|
||||
if (length(Prefix)=length(CurItem.Identifier))
|
||||
and (not (iliAtCursor in CurItem.Flags)) then
|
||||
// put exact matches at the beginning
|
||||
FFilteredList.Insert(0,CurItem)
|
||||
else
|
||||
FFilteredList.Insert(cPriorityCount, CurItem);
|
||||
Inc(cPriorityCount);
|
||||
if CurItem.HistoryIndex > HistoryLimits[CurItmComp] then
|
||||
InsertCurItem;
|
||||
end
|
||||
else if i>0 then begin
|
||||
{$IFDEF ShowFilteredIdents}
|
||||
DebugLn(['::: FILTERED ITEM ',FFilteredList.Count,' ',CurItem.Identifier]);
|
||||
{$ENDIF}
|
||||
FFilteredList.Add(CurItem);
|
||||
if CurItem.HistoryIndex > HistoryLimits[CurItmComp] then
|
||||
FFilteredList.Add(CurItem);
|
||||
end;
|
||||
end;
|
||||
AnAVLNode:=FItems.FindSuccessor(AnAVLNode);
|
||||
end;
|
||||
|
||||
if HasCompSort then begin
|
||||
while HistComp < high(TIdentifierCompatibility) do begin
|
||||
inc(HistComp);
|
||||
AddHistoryCurItem(False);
|
||||
end;
|
||||
end;
|
||||
|
||||
if Assigned(FOnGatherUserIdentifiersToFilteredList) then
|
||||
FOnGatherUserIdentifiersToFilteredList(Self, FFilteredList, cPriorityCount);
|
||||
{$IFDEF CTDEBUG}
|
||||
@ -803,6 +877,9 @@ begin
|
||||
FreeMem(p);
|
||||
end;
|
||||
FCreatedIdentifiers.Clear;
|
||||
FFoundHistoryItems := nil;
|
||||
if FHistory <> nil then
|
||||
SetLength(FFoundHistoryItems, FHistory.Capacity);
|
||||
FItems.FreeAndClear;
|
||||
FIdentView.Clear;
|
||||
if FUsedTools<>nil then
|
||||
@ -826,6 +903,12 @@ begin
|
||||
if AnAVLNode=nil then begin
|
||||
if History<>nil then
|
||||
NewItem.HistoryIndex:=History.GetHistoryIndex(NewItem);
|
||||
if (NewItem.HistoryIndex >= 0) and
|
||||
(NewItem.HistoryIndex < Length(FFoundHistoryItems))
|
||||
then begin
|
||||
assert(FFoundHistoryItems[NewItem.HistoryIndex]=nil, 'TIdentifierList.Add: FFoundHistoryItems[NewItem.HistoryIndex]=nil');
|
||||
FFoundHistoryItems[NewItem.HistoryIndex] := NewItem;
|
||||
end;
|
||||
FItems.Add(NewItem);
|
||||
FIdentView.Add(NewItem);
|
||||
FFlags:=FFlags+[ilfFilteredListNeedsUpdate,ilfUsedToolsNeedsUpdate];
|
||||
|
Loading…
Reference in New Issue
Block a user