From 31d90d59f64921ee64c03035913c49e7f82a6e3b Mon Sep 17 00:00:00 2001 From: juha Date: Mon, 8 Jan 2018 17:50:59 +0000 Subject: [PATCH] IDE: Extended filter for Code Completion. Issue #32974, patch from regs. git-svn-id: trunk@57014 - --- components/codetools/identcompletiontool.pas | 37 ++++++++++++++------ ide/editoroptions.pp | 14 ++++++++ ide/frames/editor_codetools_options.lfm | 26 ++++++++++++++ ide/frames/editor_codetools_options.pas | 10 +++++- ide/lazarusidestrconsts.pas | 2 ++ ide/sourceeditor.pp | 1 + ide/sourceeditprocs.pas | 15 +++++++- 7 files changed, 92 insertions(+), 13 deletions(-) diff --git a/components/codetools/identcompletiontool.pas b/components/codetools/identcompletiontool.pas index acaa8d4657..aebba2d49e 100644 --- a/components/codetools/identcompletiontool.pas +++ b/components/codetools/identcompletiontool.pas @@ -244,6 +244,7 @@ type FIdentSearchItem: TIdentifierListSearchItem; FPrefix: string; FStartContext: TFindContext; + FExtendedFilter: Boolean; function CompareIdentListItems({%H-}Tree: TAvlTree; Data1, Data2: Pointer): integer; procedure SetHistory(const AValue: TIdentifierHistoryList); procedure SetSortForHistory(AValue: boolean); @@ -289,6 +290,7 @@ type property StartContext: TFindContext read FStartContext write FStartContext; property StartContextPos: TCodeXYPosition read FStartContextPos write FStartContextPos; + property ExtendedFilter: Boolean read FExtendedFilter write FExtendedFilter; end; //---------------------------------------------------------------------------- @@ -616,6 +618,7 @@ procedure TIdentifierList.UpdateFilteredList; var AnAVLNode: TAvlTreeNode; CurItem: TIdentifierListItem; + cPriorityCount: Integer; begin if not (ilfFilteredListNeedsUpdate in FFlags) then exit; if FFilteredList=nil then FFilteredList:=TFPList.Create; @@ -625,20 +628,32 @@ begin DebugLn(['TIdentifierList.UpdateFilteredList Prefix="',Prefix,'"']); {$ENDIF} AnAVLNode:=FItems.FindLowest; + cPriorityCount := 0; while AnAVLNode<>nil do begin CurItem:=TIdentifierListItem(AnAVLNode.Data); - if (CurItem.Identifier<>'') - and ComparePrefixIdent(PChar(Pointer(Prefix)),PChar(Pointer(CurItem.Identifier))) - 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 + if not CurItem.Identifier.IsEmpty then + begin + if ComparePrefixIdent(PChar(Pointer(Prefix)),PChar(Pointer(CurItem.Identifier))) + 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); + end; + if FExtendedFilter + and (IdentifierPos(PChar(Pointer(Prefix)),PChar(Pointer(CurItem.Identifier))) > 0) + then begin + {$IFDEF ShowFilteredIdents} + DebugLn(['::: FILTERED ITEM ',FFilteredList.Count,' ',CurItem.Identifier]); + {$ENDIF} FFilteredList.Add(CurItem); + end; end; AnAVLNode:=FItems.FindSuccessor(AnAVLNode); end; diff --git a/ide/editoroptions.pp b/ide/editoroptions.pp index 5a16c295cd..6e1bc33f95 100644 --- a/ide/editoroptions.pp +++ b/ide/editoroptions.pp @@ -1388,6 +1388,8 @@ type fCodeTemplateFileName: String; fCTemplIndentToTokenStart: Boolean; fAutoDisplayFuncPrototypes: Boolean; + fUseExtendedFilter: Boolean; + fHighlightCodeCompletionPrefix: Boolean; // Code Folding FUseCodeFolding: Boolean; @@ -1579,6 +1581,10 @@ type read fAutoToolTipSymbTools write fAutoToolTipSymbTools default True; // declaration hints property AutoDisplayFunctionPrototypes: Boolean read fAutoDisplayFuncPrototypes write fAutoDisplayFuncPrototypes default True; + property ExtendedCompletionFilter: Boolean + read fUseExtendedFilter write fUseExtendedFilter default True; + property HighlightCodeCompletionPrefix: Boolean + read fHighlightCodeCompletionPrefix write fHighlightCodeCompletionPrefix default True; published property DbgHintAutoTypeCastClass: Boolean @@ -4768,6 +4774,10 @@ begin FCompletionLongLineHintType := DefaultCompletionLongLineHintType; XMLConfig.ReadObject('EditorOptions/CodeTools/CompletionLongLineHintType', Self, Self, 'CompletionLongLineHintType'); + fUseExtendedFilter := + XMLConfig.GetValue('EditorOptions/CodeTools/ExtendedCompletionFilter', True); + fHighlightCodeCompletionPrefix := + XMLConfig.GetValue('EditorOptions/CodeTools/HighlightCodeCompletionPrefix', True); // Code Folding FUseCodeFolding := @@ -4961,6 +4971,10 @@ begin FCompletionLongLineHintInMSec, 0); XMLConfig.WriteObject('EditorOptions/CodeTools/CompletionLongLineHintType', Self, nil, 'CompletionLongLineHintType'); + XMLConfig.SetDeleteValue('EditorOptions/CodeTools/ExtendedCompletionFilter' + , fUseExtendedFilter, True); + XMLConfig.SetDeleteValue('EditorOptions/CodeTools/HighlightCodeCompletionPrefix' + , fHighlightCodeCompletionPrefix, True); // Code Folding XMLConfig.SetDeleteValue('EditorOptions/CodeFolding/UseCodeFolding', diff --git a/ide/frames/editor_codetools_options.lfm b/ide/frames/editor_codetools_options.lfm index e2948c6799..2313832e33 100644 --- a/ide/frames/editor_codetools_options.lfm +++ b/ide/frames/editor_codetools_options.lfm @@ -223,4 +223,30 @@ object EditorCodetoolsOptionsFrame: TEditorCodetoolsOptionsFrame Caption = 'AutoDisplayFuncProtoCheckBox' TabOrder = 8 end + object ExtendedFilterCheckBox: TCheckBox + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = CompletionDropDownHint + AnchorSideTop.Side = asrBottom + Left = 9 + Height = 29 + Top = 435 + Width = 217 + BorderSpacing.Left = 9 + BorderSpacing.Top = 9 + Caption = 'ExtendedFilterCheckBox' + TabOrder = 9 + end + object HighlightPrefixCheckBox: TCheckBox + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = ExtendedFilterCheckBox + AnchorSideTop.Side = asrBottom + Left = 9 + Height = 29 + Top = 473 + Width = 222 + BorderSpacing.Left = 9 + BorderSpacing.Top = 9 + Caption = 'HighlightPrefixCheckBox' + TabOrder = 10 + end end diff --git a/ide/frames/editor_codetools_options.pas b/ide/frames/editor_codetools_options.pas index eae2dc0351..a944f96693 100644 --- a/ide/frames/editor_codetools_options.pas +++ b/ide/frames/editor_codetools_options.pas @@ -49,6 +49,8 @@ type ToolTipBevel: TBevel; AutoToolTipSymbToolsCheckBox: TCheckBox; AutoRemoveEmptyMethodsOnSave: TCheckBox; + ExtendedFilterCheckBox: TCheckBox; + HighlightPrefixCheckBox: TCheckBox; procedure AutoDelayTrackBarChange(Sender: TObject); public function GetTitle: String; override; @@ -85,6 +87,8 @@ begin DbgToolTipAutoCastClass.Caption := lisDebugHintAutoTypeCastClass; AutoCompleteBlockCheckBox.Caption := dlgEdCompleteBlocks; AutoDisplayFuncProtoCheckBox.Caption := dlgAutoDisplayFuncProto; + ExtendedFilterCheckBox.Caption := dlgExtendedFilterinCompletionBox; + HighlightPrefixCheckBox.Caption := dlgHighlightPrefix; AutoHintAndCompletionDelayLabel.Caption:=lisDelayForHintsAndCompletionBox; CompletionDropDownLabel.Caption := lisDelayForCompletionLongLineHint; @@ -107,6 +111,8 @@ begin AutoDelayTrackBar.Position := AutoDelayInMSec; AutoRemoveEmptyMethodsOnSave.Checked := AutoRemoveEmptyMethods; AutoDisplayFuncProtoCheckBox.Checked := AutoDisplayFunctionPrototypes; + ExtendedFilterCheckBox.Checked := ExtendedCompletionFilter; + HighlightPrefixCheckBox.Checked := HighlightCodeCompletionPrefix; CompletionDropDownHintTrackBar.Position := CompletionLongLineHintInMSec; CompletionDropDownHint.ItemIndex := ord(CompletionLongLineHintType); @@ -126,9 +132,11 @@ begin AutoDelayInMSec := AutoDelayTrackBar.Position; AutoRemoveEmptyMethods := AutoRemoveEmptyMethodsOnSave.Checked; AutoDisplayFunctionPrototypes := AutoDisplayFuncProtoCheckBox.Checked; + ExtendedCompletionFilter := ExtendedFilterCheckBox.Checked; + HighlightCodeCompletionPrefix := HighlightPrefixCheckBox.Checked; CompletionLongLineHintInMSec := CompletionDropDownHintTrackBar.Position; - CompletionLongLineHintType := TSynCompletionLongHintType(CompletionDropDownHint.ItemIndex); + CompletionLongLineHintType := TSynCompletionLongHintType(CompletionDropDownHint.ItemIndex); end; end; diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index 6e285af6ff..3249cdcab4 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -1967,6 +1967,8 @@ resourcestring lisCompletionLongLineHintTypeRightOnly = 'Extend right only'; lisCompletionLongLineHintTypeLittleLeft = 'Extend some left'; lisCompletionLongLineHintTypeFullLeft = 'Extend far left'; + dlgExtendedFilterinCompletionBox = 'Extended filter'; + dlgHighlightPrefix = 'Highlight prefix'; lisAutomaticFeatures = 'Completion and Hints'; lisAutoMarkup = 'Markup and Matches'; diff --git a/ide/sourceeditor.pp b/ide/sourceeditor.pp index e906c728d7..40ccf01d5d 100644 --- a/ide/sourceeditor.pp +++ b/ide/sourceeditor.pp @@ -2448,6 +2448,7 @@ begin // rebuild completion list APosition:=0; CurStr:=CurrentString; + CodeToolBoss.IdentifierList.ExtendedFilter := EditorOpts.ExtendedCompletionFilter; CodeToolBoss.IdentifierList.Prefix:=CurStr; ItemCnt:=CodeToolBoss.IdentifierList.GetFilteredCount; SL:=TStringList.Create; diff --git a/ide/sourceeditprocs.pas b/ide/sourceeditprocs.pas index 1863856050..ad9c117849 100644 --- a/ide/sourceeditprocs.pas +++ b/ide/sourceeditprocs.pas @@ -250,6 +250,8 @@ var SubNode: TCodeTreeNode; IsReadOnly: boolean; ImageIndex: longint; + Prefix: String; + PrefixPosition: Integer; HintModifiers: TPascalHintModifiers; HintModifier: TPascalHintModifier; HelperForNode: TCodeTreeNode; @@ -382,9 +384,20 @@ begin else begin //DebugLn(['PaintCompletionItem ',x,',',y,' ',s]); ACanvas.TextOut(x+1,y,s); - inc(x,ACanvas.TextWidth(s)); + // highlighting the prefix + if (EditorOpts.HighlightCodeCompletionPrefix) and not(aCompletion.CurrentString.IsEmpty) then + begin + PrefixPosition := Pos(LowerCase(aCompletion.CurrentString), LowerCase(s)); + Prefix := Copy(s, PrefixPosition, Length(aCompletion.CurrentString)); + if PrefixPosition > 0 then + PrefixPosition := ACanvas.TextWidth(Copy(s, 1, PrefixPosition-1)); + SetFontColor(RGBToColor(200, 13, 13)); + ACanvas.TextOut(x+PrefixPosition+1,y,Prefix); + end; + inc(x,ACanvas.TextWidth(s)+1); if x>MaxX then exit; end; + SetFontColor(ForegroundColor); ACanvas.Font.Style:=ACanvas.Font.Style-[fsBold]; if ImageIndex <= 0 then