mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-24 21:22:43 +02:00
IDE: identifier completion:
- handle "Include words" option - don't scan a unit several times if it is open in several source editor windows git-svn-id: trunk@58308 -
This commit is contained in:
parent
0db8c632c5
commit
2a34ee3ad9
@ -655,6 +655,7 @@ type
|
||||
OldCompilerFilename, OldLanguage: String;
|
||||
OIChangedTimer: TIdleTimer;
|
||||
|
||||
FIdentifierWordCompletion: TSourceEditorWordCompletion;
|
||||
FIdentifierWordCompletionWordList: TStringList;
|
||||
FIdentifierWordCompletionEnabled: Boolean;
|
||||
|
||||
@ -1676,6 +1677,7 @@ begin
|
||||
FreeThenNil(ObjectInspector1);
|
||||
FreeThenNil(SourceEditorManagerIntf);
|
||||
FreeAndNil(FIdentifierWordCompletionWordList);
|
||||
FreeAndNil(FIdentifierWordCompletion);
|
||||
|
||||
// disconnect handlers
|
||||
Application.RemoveAllHandlersOfObject(Self);
|
||||
@ -6482,10 +6484,13 @@ begin
|
||||
FIdentifierWordCompletionWordList.OwnsObjects := True;
|
||||
end else
|
||||
FIdentifierWordCompletionWordList.Clear;
|
||||
if FIdentifierWordCompletion=nil then
|
||||
FIdentifierWordCompletion := TSourceEditorWordCompletion.Create;
|
||||
|
||||
OldPriorityCount := PriorityCount;
|
||||
PriorityCount := FilteredList.Count;
|
||||
AWordCompletion.GetWordList(FIdentifierWordCompletionWordList, Sender.Prefix, Sender.ContainsFilter, False, 100);
|
||||
FIdentifierWordCompletion.IncludeWords := CodeToolsOpts.IdentComplIncludeWords;
|
||||
FIdentifierWordCompletion.GetWordList(FIdentifierWordCompletionWordList, Sender.Prefix, Sender.ContainsFilter, False, 100);
|
||||
FilteredList.Capacity := FilteredList.Count+FIdentifierWordCompletionWordList.Count;
|
||||
for I := 0 to FIdentifierWordCompletionWordList.Count-1 do
|
||||
begin
|
||||
|
@ -44,7 +44,7 @@ uses
|
||||
{$ENDIF}
|
||||
SynEditMouseCmds,
|
||||
// RTL + FCL
|
||||
Classes, SysUtils, StrUtils, types, Math, RegExpr, Laz_AVL_Tree,
|
||||
Classes, SysUtils, StrUtils, Types, Contnrs, Math, RegExpr, Laz_AVL_Tree,
|
||||
// LCL
|
||||
Controls, Forms, ComCtrls, StdCtrls, Graphics, Dialogs, Extctrls, Menus,
|
||||
LCLProc, LCLType, LCLIntf, ClipBrd, HelpIntfs, Messages, LMessages,
|
||||
@ -1192,9 +1192,6 @@ type
|
||||
Index: integer);
|
||||
protected
|
||||
procedure CodeToolsToSrcEditTimerTimer(Sender: TObject);
|
||||
procedure OnWordCompletionGetSource(var Source: TStrings;
|
||||
var {%H-}SourceTopLine,{%H-}SourceBottomLine: integer;
|
||||
var IgnoreWordPos: TPoint; SourceIndex: integer);
|
||||
procedure OnSourceCompletionTimer(Sender: TObject);
|
||||
// marks
|
||||
procedure OnSourceMarksAction(AMark: TSourceMark; {%H-}AAction: TMarksAction);
|
||||
@ -1306,6 +1303,26 @@ type
|
||||
read FOnPackageForSourceEditor write FOnPackageForSourceEditor;
|
||||
end;
|
||||
|
||||
TSourceEditorWordCompletion = class(TWordCompletion)
|
||||
private type
|
||||
TSourceListItem = class
|
||||
Source: TStrings;
|
||||
IgnoreWordPos: TPoint;
|
||||
end;
|
||||
private
|
||||
FIncludeWords: TIdentComplIncludeWords;
|
||||
FSourceList: TObjectList;
|
||||
procedure ReloadSourceList;
|
||||
protected
|
||||
procedure DoGetSource(var Source: TStrings; var {%H-}TopLine,
|
||||
{%H-}BottomLine: Integer; var IgnoreWordPos: TPoint; SourceIndex: integer); override;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
public
|
||||
property IncludeWords: TIdentComplIncludeWords read FIncludeWords write FIncludeWords;
|
||||
end;
|
||||
|
||||
function SourceEditorManager: TSourceEditorManager; inline;
|
||||
|
||||
|
||||
@ -1405,14 +1422,14 @@ var
|
||||
EnglishModifiedLGPLNotice: string;
|
||||
EnglishMITNotice: string;
|
||||
|
||||
var
|
||||
AWordCompletion: TWordCompletion = nil;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
{$R ../images/bookmark.res}
|
||||
|
||||
var
|
||||
AWordCompletion: TWordCompletion = nil;
|
||||
|
||||
var
|
||||
SRCED_LOCK, SRCED_OPEN, SRCED_CLOSE, SRCED_PAGES: PLazLoggerLogGroup;
|
||||
|
||||
@ -1774,6 +1791,89 @@ begin
|
||||
Result:=CompareFilenames(AnsiString(FileNameStr),SE1.FileName);
|
||||
end;
|
||||
|
||||
{ TSourceEditorWordCompletion }
|
||||
|
||||
constructor TSourceEditorWordCompletion.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
FSourceList := TObjectList.Create;
|
||||
FIncludeWords := icwIncludeFromAllUnits;
|
||||
end;
|
||||
|
||||
destructor TSourceEditorWordCompletion.Destroy;
|
||||
begin
|
||||
FSourceList.Free;
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TSourceEditorWordCompletion.DoGetSource(var Source: TStrings;
|
||||
var TopLine, BottomLine: Integer; var IgnoreWordPos: TPoint;
|
||||
SourceIndex: integer);
|
||||
var
|
||||
SourceItem: TSourceListItem;
|
||||
begin
|
||||
if SourceIndex=0 then
|
||||
ReloadSourceList;
|
||||
|
||||
if SourceIndex>=FSourceList.Count then
|
||||
Exit;
|
||||
|
||||
SourceItem := FSourceList[SourceIndex] as TSourceListItem;
|
||||
Source := SourceItem.Source;
|
||||
IgnoreWordPos := SourceItem.IgnoreWordPos;
|
||||
end;
|
||||
|
||||
procedure TSourceEditorWordCompletion.ReloadSourceList;
|
||||
var
|
||||
CurEditor, TempEditor: TSourceEditor;
|
||||
I: integer;
|
||||
Mng: TSourceEditorManager;
|
||||
New: TSourceListItem;
|
||||
AddedFileNames: TStringList;
|
||||
begin
|
||||
FSourceList.Clear;
|
||||
if FIncludeWords=icwDontInclude then
|
||||
Exit;
|
||||
|
||||
Mng := SourceEditorManager;
|
||||
CurEditor:=Mng.GetActiveSE;
|
||||
if (CurEditor<>nil) then
|
||||
begin
|
||||
New := TSourceListItem.Create;
|
||||
New.Source:=CurEditor.EditorComponent.Lines;
|
||||
New.IgnoreWordPos:=CurEditor.EditorComponent.LogicalCaretXY;
|
||||
Dec(New.IgnoreWordPos.Y); // LogicalCaretXY starts with 1 as top line
|
||||
FSourceList.Add(New);
|
||||
end;
|
||||
|
||||
if FIncludeWords=icwIncludeFromAllUnits then
|
||||
begin
|
||||
AddedFileNames := TStringList.Create;
|
||||
try
|
||||
AddedFileNames.Sorted := True;
|
||||
AddedFileNames.Duplicates := dupIgnore;
|
||||
for I := 0 to Mng.SourceEditorCount-1 do
|
||||
begin
|
||||
TempEditor := Mng.SourceEditors[I];
|
||||
if ( TempEditor<>CurEditor)
|
||||
and (TempEditor.FileName<>CurEditor.FileName)
|
||||
and (AddedFileNames.IndexOf(TempEditor.FileName)=-1) then
|
||||
begin
|
||||
New := TSourceListItem.Create;
|
||||
New.Source:=TempEditor.EditorComponent.Lines;
|
||||
New.IgnoreWordPos:=Point(-1,-1);
|
||||
FSourceList.Add(New);
|
||||
AddedFileNames.Add(TempEditor.FileName);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
AddedFileNames.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TBrowseEditorTabHistoryDialog }
|
||||
|
||||
procedure TBrowseEditorTabHistoryDialog.DoCreate;
|
||||
@ -10802,32 +10902,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSourceEditorManager.OnWordCompletionGetSource(var Source: TStrings;
|
||||
var SourceTopLine, SourceBottomLine: integer; var IgnoreWordPos: TPoint;
|
||||
SourceIndex: integer);
|
||||
var
|
||||
TempEditor: TSourceEditor;
|
||||
i:integer;
|
||||
begin
|
||||
TempEditor:=GetActiveSE;
|
||||
if (SourceIndex=0) and (TempEditor<>nil) then begin
|
||||
Source:=TempEditor.EditorComponent.Lines;
|
||||
IgnoreWordPos:=TempEditor.EditorComponent.LogicalCaretXY;
|
||||
Dec(IgnoreWordPos.Y); // LogicalCaretXY starts with 1 as top line
|
||||
end else begin
|
||||
i:=0;
|
||||
while (i < SourceEditorCount) do begin
|
||||
if SourceEditors[i] <> TempEditor then dec(SourceIndex);
|
||||
if SourceIndex <= 0 then begin
|
||||
Source := SourceEditors[i].EditorComponent.Lines;
|
||||
exit;
|
||||
end;
|
||||
inc(i);
|
||||
end;
|
||||
Source := nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSourceEditorManager.OnSourceCompletionTimer(Sender: TObject);
|
||||
|
||||
function CheckStartIdentCompletion: boolean;
|
||||
@ -10955,11 +11029,8 @@ begin
|
||||
|
||||
// word completion
|
||||
if aWordCompletion=nil then begin
|
||||
aWordCompletion:=TWordCompletion.Create;
|
||||
with AWordCompletion do begin
|
||||
WordBufferCapacity:=100;
|
||||
OnGetSource:=@OnWordCompletionGetSource;
|
||||
end;
|
||||
AWordCompletion:=TSourceEditorWordCompletion.Create;
|
||||
AWordCompletion.WordBufferCapacity:=100;
|
||||
end;
|
||||
|
||||
// timer for auto start identifier completion
|
||||
|
@ -34,6 +34,9 @@ type
|
||||
procedure SetWordBufferCapacity(NewCapacity: integer);
|
||||
function CaseInsensitiveIndexOf(const AWord: string):integer;
|
||||
function CaseSensitiveIndexOf(const AWord: string):integer;
|
||||
protected
|
||||
procedure DoGetSource(var Source:TStrings; var TopLine, BottomLine: Integer;
|
||||
var IgnoreWordPos: TPoint; SourceIndex:integer); virtual;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -104,7 +107,7 @@ procedure TWordCompletion.GetWordList(AWordList: TStrings;
|
||||
MaxResults: integer);
|
||||
var i, Line, x, FilterLen, MaxHash, LineLen: integer;
|
||||
UpFilter, LineText, UpLineText, UpWordBuffer: string;
|
||||
SourceText: TStringList;
|
||||
SourceText: TStrings;
|
||||
HashList: ^integer;// index list. Every entry points to a word in the AWordList
|
||||
SourceTextIndex, SourceTopLine, SourceBottomLine:integer;
|
||||
LastCharType:TCharType;
|
||||
@ -188,53 +191,52 @@ begin
|
||||
if AWordList.Count>=MaxResults then exit;
|
||||
// then search in all sources for more words that could fit
|
||||
SourceTextIndex:=0;
|
||||
if Assigned(FOnGetSource) then begin
|
||||
|
||||
SourceText:=nil;
|
||||
SourceTopLine:=0;
|
||||
SourceBottomLine:=-1;
|
||||
IgnoreWordPos:=Point(-1,-1);
|
||||
DoGetSource(SourceText,SourceTopLine,SourceBottomLine,IgnoreWordPos,SourceTextIndex);
|
||||
UpLineText:='';
|
||||
repeat
|
||||
if SourceText<>nil then begin
|
||||
Line:=SourceTopLine;
|
||||
if SourceBottomLine<0 then
|
||||
SourceBottomLine := SourceText.Count-1;
|
||||
while (Line<=SourceBottomLine) do begin
|
||||
LineText:=SourceText[line];
|
||||
LineLen:=length(LineText);
|
||||
if not CaseSensitive then
|
||||
UpLineText:=uppercase(LineText);
|
||||
x:=1;
|
||||
LastCharType:=ctNone;
|
||||
while (x<=LineLen) do begin
|
||||
if (LastCharType=ctNone) and (CharTable[LineText[x]]=ctWordBegin)
|
||||
then begin
|
||||
// word found
|
||||
i:=x;
|
||||
repeat
|
||||
inc(i);
|
||||
until (i>LineLen) or (CharTable[LineText[i]]=ctNone);
|
||||
if (i-x>=FilterLen) and not ((Line=IgnoreWordPos.Y) and (x<=IgnoreWordPos.X) and (IgnoreWordPos.X<=i)) then begin
|
||||
AddIfMatch(LineText,UpLineText,x,i-x);
|
||||
if AWordList.Count>=MaxResults then exit;
|
||||
end;
|
||||
x:=i;
|
||||
end else
|
||||
inc(x);
|
||||
LastCharType:=CharTable[LineText[x-1]];
|
||||
end;
|
||||
inc(line);
|
||||
end;
|
||||
end;
|
||||
inc(SourceTextIndex);
|
||||
SourceText:=nil;
|
||||
SourceTopLine:=0;
|
||||
SourceBottomLine:=-1;
|
||||
IgnoreWordPos:=Point(-1,-1);
|
||||
FOnGetSource(SourceText,SourceTopLine,SourceBottomLine,IgnoreWordPos,SourceTextIndex);
|
||||
UpLineText:='';
|
||||
repeat
|
||||
if SourceText<>nil then begin
|
||||
Line:=SourceTopLine;
|
||||
if SourceBottomLine<0 then
|
||||
SourceBottomLine := SourceText.Count-1;
|
||||
while (Line<=SourceBottomLine) do begin
|
||||
LineText:=SourceText[line];
|
||||
LineLen:=length(LineText);
|
||||
if not CaseSensitive then
|
||||
UpLineText:=uppercase(LineText);
|
||||
x:=1;
|
||||
LastCharType:=ctNone;
|
||||
while (x<=LineLen) do begin
|
||||
if (LastCharType=ctNone) and (CharTable[LineText[x]]=ctWordBegin)
|
||||
then begin
|
||||
// word found
|
||||
i:=x;
|
||||
repeat
|
||||
inc(i);
|
||||
until (i>LineLen) or (CharTable[LineText[i]]=ctNone);
|
||||
if (i-x>=FilterLen) and not ((Line=IgnoreWordPos.Y) and (x<=IgnoreWordPos.X) and (IgnoreWordPos.X<=i)) then begin
|
||||
AddIfMatch(LineText,UpLineText,x,i-x);
|
||||
if AWordList.Count>=MaxResults then exit;
|
||||
end;
|
||||
x:=i;
|
||||
end else
|
||||
inc(x);
|
||||
LastCharType:=CharTable[LineText[x-1]];
|
||||
end;
|
||||
inc(line);
|
||||
end;
|
||||
end;
|
||||
inc(SourceTextIndex);
|
||||
SourceText:=nil;
|
||||
SourceTopLine:=0;
|
||||
SourceBottomLine:=-1;
|
||||
IgnoreWordPos:=Point(-1,-1);
|
||||
FOnGetSource(SourceText,SourceTopLine,SourceBottomLine,IgnoreWordPos,SourceTextIndex);
|
||||
until SourceText=nil;
|
||||
end;
|
||||
DoGetSource(SourceText,SourceTopLine,SourceBottomLine,IgnoreWordPos,SourceTextIndex);
|
||||
until SourceText=nil;
|
||||
finally
|
||||
FreeMem(HashList);
|
||||
end;
|
||||
@ -298,6 +300,13 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TWordCompletion.DoGetSource(var Source: TStrings; var TopLine,
|
||||
BottomLine: Integer; var IgnoreWordPos: TPoint; SourceIndex: integer);
|
||||
begin
|
||||
if Assigned(FOnGetSource) then
|
||||
FOnGetSource(Source,TopLine,BottomLine,IgnoreWordPos,SourceIndex);
|
||||
end;
|
||||
|
||||
function TWordCompletion.GetWordBufferCapacity:integer;
|
||||
begin
|
||||
Result:=FWordBufferCapacity;
|
||||
|
Loading…
Reference in New Issue
Block a user