View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0033054 | Patches | Patch | public | 2018-01-20 03:11 | 2020-09-12 02:16 |
Reporter | regs | Assigned To | Martin Friebe | ||
Priority | normal | Severity | minor | Reproducibility | N/A |
Status | resolved | Resolution | fixed | ||
Fixed in Version | 2.2 | ||||
Summary | 0033054: Autoinvoke Identifier Completion on type | ||||
Description | Optionally Invokes Identifier Completion automatically while typing. And in case if cancelled won't bothering until next identifier. Separated Hint delay and Identifier Completion delay in config, so hint won't annoy if set to 0. I set hint delay to 1 sec and didn't add it to options, but it still can be changed via config. I guess it won't be that popular. But if crucial, additional trackbar can be added. 32972 crash issue could be a blocker for this patch https://bugs.freepascal.org/view.php?id=32972 Hope didn't forget anything. Autoinvoke after point is fixed. Work after point only now. | ||||
Tags | No tags attached. | ||||
Fixed in Revision | 63314 | ||||
LazTarget | 2.2 | ||||
Widgetset | |||||
Attached Files |
|
related to | 0032972 | assigned | Mattias Gaertner | Lazarus | Crash when calling Identifier completion in interface section |
|
autoinvoke.patch (23,561 bytes)
Index: components/codetools/identcompletiontool.pas =================================================================== --- components/codetools/identcompletiontool.pas (revision 57113) +++ components/codetools/identcompletiontool.pas (working copy) @@ -1979,6 +1979,45 @@ end; end; + ctnBeginBlock, ctnWithStatement, ctnWithVariable, ctnOnBlock, ctnOnIdentifier, + ctnOnStatement: + begin + Add('and'); + Add('as'); + Add('asm'); + Add('begin'); + Add('case'); + Add('div'); + Add('do'); + Add('downto'); + Add('else'); + Add('end'); + Add('except'); + Add('finally'); + Add('for'); + Add('goto'); + Add('if'); + Add('in'); + Add('inherited'); + Add('is'); + Add('label'); + Add('mod'); + Add('not'); + Add('of'); + Add('or'); + Add('raise'); + Add('repeat'); + Add('shl'); + Add('shr'); + Add('then'); + Add('to'); + Add('try'); + Add('until'); + Add('while'); + Add('with'); + Add('xor'); + end; + ctnProperty: CheckProperty(Node); @@ -2860,7 +2899,6 @@ end; CursorContext:=CreateFindContext(Self,CursorNode); - GatherContextKeywords(CursorContext,IdentStartPos,Beautifier); // check for incomplete context @@ -2919,6 +2957,11 @@ CurrentIdentifierList.ContextFlags+[ilcfDontAllowProcedures]; end; end; + + if not (ilcfDontAllowProcedures in CurrentIdentifierList.ContextFlags) and + not (GatherContext.Node.Desc in AllClassObjects) then + GatherContextKeywords(CursorContext,IdentStartPos,Beautifier); + // context behind if (IdentEndPos<SrcLen) then begin MoveCursorToCleanPos(IdentEndPos); Index: ide/codetoolsoptions.pas =================================================================== --- ide/codetoolsoptions.pas (revision 57113) +++ ide/codetoolsoptions.pas (working copy) @@ -110,6 +110,7 @@ // identifier completion FIdentComplAddSemicolon: Boolean; FIdentComplAddAssignOperator: Boolean; + FIdentComplAutoInvokeOnType: boolean; FIdentComplAutoStartAfterPoint: boolean; FIdentComplAutoUseSingleIdent: boolean; @@ -236,6 +237,8 @@ property IdentComplAddAssignOperator: Boolean read FIdentComplAddAssignOperator write FIdentComplAddAssignOperator; property IdentComplAddDo: Boolean read FIdentComplAddDo write FIdentComplAddDo; + property IdentComplAutoInvokeOnType: boolean read FIdentComplAutoInvokeOnType + write FIdentComplAutoInvokeOnType; property IdentComplAutoStartAfterPoint: boolean read FIdentComplAutoStartAfterPoint write FIdentComplAutoStartAfterPoint; property IdentComplAutoUseSingleIdent: boolean read FIdentComplAutoUseSingleIdent @@ -535,6 +538,8 @@ 'CodeToolsOptions/IdentifierCompletion/AddAssignOperator',true); FIdentComplAddDo:=XMLConfig.GetValue( 'CodeToolsOptions/IdentifierCompletion/AddDo',true); + FIdentComplAutoInvokeOnType:=XMLConfig.GetValue( + 'CodeToolsOptions/IdentifierCompletion/AutoInvokeOnType',true); FIdentComplAutoStartAfterPoint:=XMLConfig.GetValue( 'CodeToolsOptions/IdentifierCompletion/AutoStartAfterPoint',true); FIdentComplAutoUseSingleIdent:=XMLConfig.GetValue( @@ -703,6 +708,8 @@ FIdentComplAddAssignOperator,true); XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AddDo', FIdentComplAddDo,true); + XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AutoInvokeOnType', + FIdentComplAutoInvokeOnType,true); XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AutoStartAfterPoint', FIdentComplAutoStartAfterPoint,true); XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AutoUseSingleIdent', @@ -853,6 +860,7 @@ FIdentComplAddSemicolon:=CodeToolsOpts.FIdentComplAddSemicolon; FIdentComplAddAssignOperator:=CodeToolsOpts.FIdentComplAddAssignOperator; FIdentComplAddDo:=CodeToolsOpts.FIdentComplAddDo; + FIdentComplAutoInvokeOnType:=CodeToolsOpts.FIdentComplAutoInvokeOnType; FIdentComplAutoStartAfterPoint:=CodeToolsOpts.FIdentComplAutoStartAfterPoint; FIdentComplAutoUseSingleIdent:=CodeToolsOpts.FIdentComplAutoUseSingleIdent; FIdentComplAddParameterBrackets:=CodeToolsOpts.FIdentComplAddParameterBrackets; @@ -918,6 +926,7 @@ FIdentComplAddSemicolon:=true; FIdentComplAddAssignOperator:=true; FIdentComplAddDo:=true; + FIdentComplAutoInvokeOnType:=true; FIdentComplAutoStartAfterPoint:=true; FIdentComplAutoUseSingleIdent:=true; FIdentComplAddParameterBrackets:=true; @@ -1002,6 +1011,7 @@ and (FIdentComplAddSemicolon=CodeToolsOpts.FIdentComplAddSemicolon) and (FIdentComplAddAssignOperator=CodeToolsOpts.FIdentComplAddAssignOperator) and (FIdentComplAddDo=CodeToolsOpts.FIdentComplAddDo) + and (FIdentComplAutoInvokeOnType=CodeToolsOpts.FIdentComplAutoInvokeOnType) and (FIdentComplAutoStartAfterPoint=CodeToolsOpts.FIdentComplAutoStartAfterPoint) and (FIdentComplAutoUseSingleIdent=CodeToolsOpts.FIdentComplAutoUseSingleIdent) and (FIdentComplAddParameterBrackets=CodeToolsOpts.FIdentComplAddParameterBrackets) Index: ide/editoroptions.pp =================================================================== --- ide/editoroptions.pp (revision 57113) +++ ide/editoroptions.pp (working copy) @@ -1380,7 +1380,8 @@ // Code tools options (MG: these will move to an unit of their own) fAutoBlockCompletion: Boolean; fAutoCodeParameters: Boolean; - fAutoDelayInMSec: Integer; + fCodeCompletionDelayInMSec: Integer; + fHintDelayInMSec: Integer; FAutoRemoveEmptyMethods: Boolean; fAutoToolTipExprEval: Boolean; fAutoToolTipSymbTools: Boolean; @@ -1593,8 +1594,10 @@ property DbgHintAutoTypeCastClass: Boolean read FDbgHintAutoTypeCastClass write FDbgHintAutoTypeCastClass default True; // declaration hints public - property AutoDelayInMSec: Integer read fAutoDelayInMSec - write fAutoDelayInMSec default 1000; + property CodeCompletionDelayInMSec: Integer read fCodeCompletionDelayInMSec + write fCodeCompletionDelayInMSec default 10; + property HintDelayInMSec: Integer read fHintDelayInMSec + write fHintDelayInMSec default 1000; property CodeTemplateFileName: String read fCodeTemplateFileName write fCodeTemplateFileName; property CodeTemplateIndentToTokenStart: Boolean @@ -4762,8 +4765,10 @@ XMLConfig.GetValue('EditorOptions/CodeTools/AutoToolTipExprEval', True); fAutoToolTipSymbTools := XMLConfig.GetValue('EditorOptions/CodeTools/AutoToolTipSymbTools', True); - fAutoDelayInMSec := - XMLConfig.GetValue('EditorOptions/CodeTools/AutoDelayInMSec', 1000); + fCodeCompletionDelayInMSec := + XMLConfig.GetValue('EditorOptions/CodeTools/CodeCompletionDelayInMSec', 10); + fHintDelayInMSec := + XMLConfig.GetValue('EditorOptions/CodeTools/HintDelayInMSec', 1000); fCodeTemplateFileName := XMLConfig.GetValue('EditorOptions/CodeTools/CodeTemplateFileName' , TrimFilename(AppendPathDelim(GetPrimaryConfigPath) + DefaultCodeTemplatesFilename)); @@ -4961,8 +4966,10 @@ , fAutoToolTipExprEval, True); XMLConfig.SetDeleteValue('EditorOptions/CodeTools/AutoToolTipSymbTools' , fAutoToolTipSymbTools, True); - XMLConfig.SetDeleteValue('EditorOptions/CodeTools/AutoDelayInMSec' - , fAutoDelayInMSec, 1000); + XMLConfig.SetDeleteValue('EditorOptions/CodeTools/CodeCompletionDelayInMSec' + , fCodeCompletionDelayInMSec, 10); + XMLConfig.SetDeleteValue('EditorOptions/CodeTools/HintDelayInMSec' + , fHintDelayInMSec, 1000); XMLConfig.SetDeleteValue('EditorOptions/CodeTools/CodeTemplateFileName' , fCodeTemplateFileName, ''); XMLConfig.SetDeleteValue( Index: ide/frames/codetools_identifiercompletion_options.lfm =================================================================== --- ide/frames/codetools_identifiercompletion_options.lfm (revision 57113) +++ ide/frames/codetools_identifiercompletion_options.lfm (working copy) @@ -19,7 +19,7 @@ Top = 99 Width = 161 Caption = 'ICAddSemicolonCheckBox' - TabOrder = 3 + TabOrder = 4 end object ICAddAssignOperatorCheckBox: TCheckBox AnchorSideLeft.Control = Owner @@ -31,9 +31,9 @@ Top = 118 Width = 187 Caption = 'ICAddAssignOperatorCheckBox' - TabOrder = 4 + TabOrder = 5 end - object ICAutoStartAfterPointCheckBox: TCheckBox + object ICAutoInvokeOnTypeCheckBox: TCheckBox AnchorSideLeft.Control = Owner AnchorSideTop.Control = ICOpenDividerBevel AnchorSideTop.Side = asrBottom @@ -42,9 +42,21 @@ Height = 19 Top = 25 Width = 187 - Caption = 'ICAutoStartAfterPointCheckBox' + Caption = 'ICAutoInvokeOnTypeCheckBox' TabOrder = 0 end + object ICAutoStartAfterPointCheckBox: TCheckBox + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = ICAutoInvokeOnTypeCheckBox + AnchorSideTop.Side = asrBottom + AnchorSideRight.Side = asrBottom + Left = 0 + Height = 19 + Top = 25 + Width = 187 + Caption = 'ICAutoStartAfterPointCheckBox' + TabOrder = 1 + end object ICAutoAddParameterBracketsCheckBox: TCheckBox AnchorSideLeft.Control = Owner AnchorSideTop.Control = ICAddDoCheckBox @@ -55,7 +67,7 @@ Top = 156 Width = 229 Caption = 'ICAutoAddParameterBracketsCheckBox' - TabOrder = 6 + TabOrder = 7 end object ICShowHelpCheckBox: TCheckBox AnchorSideLeft.Control = Owner @@ -69,7 +81,7 @@ Caption = 'ICShowHelpCheckBox' ParentShowHint = False ShowHint = True - TabOrder = 2 + TabOrder = 3 end object ICReplaceCheckBox: TCheckBox AnchorSideLeft.Control = Owner @@ -83,7 +95,7 @@ Caption = 'ICReplaceCheckBox' ParentShowHint = False ShowHint = True - TabOrder = 9 + TabOrder = 10 end object ICAddDoCheckBox: TCheckBox AnchorSideLeft.Control = Owner @@ -95,7 +107,7 @@ Top = 137 Width = 120 Caption = 'ICAddDoCheckBox' - TabOrder = 5 + TabOrder = 6 end object ICSortForHistoryCheckBox: TCheckBox AnchorSideLeft.Control = Owner @@ -106,7 +118,7 @@ Top = 192 Width = 159 Caption = 'ICSortForHistoryCheckBox' - TabOrder = 7 + TabOrder = 8 end object ICSortForScopeCheckBox: TCheckBox AnchorSideLeft.Control = Owner @@ -119,7 +131,7 @@ Caption = 'ICSortForScopeCheckBox' ParentShowHint = False ShowHint = True - TabOrder = 8 + TabOrder = 9 end object ICOpenDividerBevel: TDividerBevel AnchorSideLeft.Control = Owner @@ -194,7 +206,7 @@ Caption = 'ICJumpToErrorCheckBox' ParentShowHint = False ShowHint = True - TabOrder = 10 + TabOrder = 11 end object ICAutoUseSingleIdent: TCheckBox AnchorSideLeft.Control = Owner @@ -208,6 +220,6 @@ Caption = 'ICAutoUseSingleIdent' ParentShowHint = False ShowHint = True - TabOrder = 1 + TabOrder = 2 end end Index: ide/frames/codetools_identifiercompletion_options.pas =================================================================== --- ide/frames/codetools_identifiercompletion_options.pas (revision 57113) +++ ide/frames/codetools_identifiercompletion_options.pas (working copy) @@ -37,6 +37,7 @@ ICAutoAddParameterBracketsCheckBox: TCheckBox; ICMiscDividerBevel: TDividerBevel; ICOpenDividerBevel: TDividerBevel; + ICAutoInvokeOnTypeCheckBox: TCheckBox; ICAutoStartAfterPointCheckBox: TCheckBox; ICAddAssignOperatorCheckBox: TCheckBox; ICAddSemicolonCheckBox: TCheckBox; @@ -72,6 +73,7 @@ ADialog: TAbstractOptionsEditorDialog); begin ICOpenDividerBevel.Caption:=lisIdCOpening; + ICAutoInvokeOnTypeCheckBox.Caption:=lisAutomaticallyInvokeOnType; ICAutoStartAfterPointCheckBox.Caption:=lisAutomaticallyInvokeAfterPoint; ICAutoUseSingleIdent.Caption:=lisAutomaticallyUseSinglePossibleIdent; ICAutoUseSingleIdent.Hint:= @@ -105,6 +107,7 @@ ICAddSemicolonCheckBox.Checked := IdentComplAddSemicolon; ICAddAssignOperatorCheckBox.Checked := IdentComplAddAssignOperator; ICAddDoCheckBox.Checked := IdentComplAddDo; + ICAutoInvokeOnTypeCheckBox.Checked := IdentComplAutoInvokeOnType; ICAutoStartAfterPointCheckBox.Checked := IdentComplAutoStartAfterPoint; ICAutoUseSingleIdent.Checked := IdentComplAutoUseSingleIdent; ICAutoAddParameterBracketsCheckBox.Checked:=IdentComplAddParameterBrackets; @@ -124,6 +127,7 @@ IdentComplAddSemicolon := ICAddSemicolonCheckBox.Checked; IdentComplAddAssignOperator := ICAddAssignOperatorCheckBox.Checked; IdentComplAddDo := ICAddDoCheckBox.Checked; + IdentComplAutoInvokeOnType := ICAutoInvokeOnTypeCheckBox.Checked; IdentComplAutoStartAfterPoint := ICAutoStartAfterPointCheckBox.Checked; IdentComplAutoUseSingleIdent := ICAutoUseSingleIdent.Checked; IdentComplAddParameterBrackets:=ICAutoAddParameterBracketsCheckBox.Checked; Index: ide/frames/editor_codetools_options.pas =================================================================== --- ide/frames/editor_codetools_options.pas (revision 57113) +++ ide/frames/editor_codetools_options.pas (working copy) @@ -110,7 +110,7 @@ AutoToolTipExprEvalCheckBox.Checked := AutoToolTipExprEval; AutoToolTipSymbToolsCheckBox.Checked := AutoToolTipSymbTools; DbgToolTipAutoCastClass.Checked := DbgHintAutoTypeCastClass; - AutoDelayTrackBar.Position := AutoDelayInMSec; + AutoDelayTrackBar.Position := CodeCompletionDelayInMSec; AutoRemoveEmptyMethodsOnSave.Checked := AutoRemoveEmptyMethods; AutoDisplayFuncProtoCheckBox.Checked := AutoDisplayFunctionPrototypes; ContainsFilterCheckBox.Checked := ContainsCompletionFilter; @@ -132,7 +132,7 @@ AutoToolTipExprEval := AutoToolTipExprEvalCheckBox.Checked; AutoToolTipSymbTools := AutoToolTipSymbToolsCheckBox.Checked; DbgHintAutoTypeCastClass := DbgToolTipAutoCastClass.Checked; - AutoDelayInMSec := AutoDelayTrackBar.Position; + CodeCompletionDelayInMSec := AutoDelayTrackBar.Position; AutoRemoveEmptyMethods := AutoRemoveEmptyMethodsOnSave.Checked; AutoDisplayFunctionPrototypes := AutoDisplayFuncProtoCheckBox.Checked; ContainsCompletionFilter := ContainsFilterCheckBox.Checked; Index: ide/lazarusidestrconsts.pas =================================================================== --- ide/lazarusidestrconsts.pas (revision 57113) +++ ide/lazarusidestrconsts.pas (working copy) @@ -1960,7 +1960,7 @@ dlgAutoDisplayFuncProto = 'Auto Display Function Prototypes'; lisShowDeclarationHints = 'Show declaration hints'; dlgEdDelayInSec = '(%s sec delay)'; - lisDelayForHintsAndCompletionBox = 'Delay for hints and completion box'; + lisDelayForHintsAndCompletionBox = 'Delay for completion box'; lisDelayForCompletionLongLineHint = 'Delay for long line hints in completion box'; lisCompletionLongLineHintType = 'Show long line hints'; lisCompletionLongLineHintTypeNone = 'Never'; @@ -5793,6 +5793,7 @@ +'exist. Values were not checked.'; lisInsertPrintShortTag = 'Insert PrintShort tag'; lisIdCOpening = 'Opening'; + lisAutomaticallyInvokeOnType = 'Automatically invoke on typing'; lisAutomaticallyInvokeAfterPoint = 'Automatically invoke after point'; lisAutomaticallyUseSinglePossibleIdent = 'Automatically use single possible identifier'; lisWhenThereIsOnlyOnePossibleCompletionItemUseItImmed = 'When there is only ' Index: ide/sourceeditor.pp =================================================================== --- ide/sourceeditor.pp (revision 57113) +++ ide/sourceeditor.pp (working copy) @@ -954,6 +954,7 @@ FCompletionPlugins: TFPList; FDefaultCompletionForm: TSourceEditCompletion; FActiveCompletionPlugin: TSourceEditorCompletionPlugin; + FCodeCompletionReady: Boolean; function GetDefaultCompletionForm: TSourceEditCompletion; procedure FreeCompletionPlugins; function GetScreenRectForToken(AnEditor: TCustomSynEdit; PhysColumn, PhysRow, EndColumn: Integer): TRect; @@ -973,6 +974,7 @@ procedure DeactivateCompletionForm; override; procedure RegisterCompletionPlugin(Plugin: TSourceEditorCompletionPlugin); override; procedure UnregisterCompletionPlugin(Plugin: TSourceEditorCompletionPlugin); override; + property CodeCompletionReady: Boolean read FCodeCompletionReady write FCodeCompletionReady; protected procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure IncUpdateLockInternal; @@ -1950,7 +1952,7 @@ // HintTimer FAutoHintTimer := TIdleTimer.Create(nil); with FAutoHintTimer do begin - Interval := EditorOpts.AutoDelayInMSec; + Interval := EditorOpts.HintDelayInMSec; Enabled := False; AutoEnabled := False; OnTimer := @HintTimer; @@ -2203,6 +2205,7 @@ //debugln(GetStackTrace(true)); {$ENDIF} Manager.DeactivateCompletionForm; + Manager.CodeCompletionReady := False; // prevent code completion if cancelled until identifier is completed {$IFDEF VerboseIDECompletionBox} finally DebugLnExit(['TSourceNotebook.ccCancel END']); @@ -2326,6 +2329,7 @@ end; Manager.DeactivateCompletionForm; + Manager.CodeCompletionReady := True; //DebugLn(['TSourceNotebook.ccComplete ',KeyChar,' ',OldCompletionType=ctIdentCompletion]); if (KeyChar='.') and (OldCompletionType=ctIdentCompletion) then @@ -3739,6 +3743,12 @@ end; end; + if not( + (Command = ecChar) or + (Command = ecDeleteLastChar) or + (Command = ecDeleteChar)) then + Manager.CodeCompletionReady := True; + case Command of ecSelEditorTop, ecSelEditorBottom, ecEditorTop, ecEditorBottom: @@ -3770,6 +3780,8 @@ begin AddChar:=true; //debugln(['TSourceEditor.ProcessCommand AChar="',AChar,'" AutoIdentifierCompletion=',dbgs(EditorOpts.AutoIdentifierCompletion),' Interval=',AutoStartCompletionBoxTimer.Interval,' ',Dbgs(FEditor.CaretXY),' ',FEditor.IsIdentChar(aChar)]); + if (GetWordAtCurrentCaret = '') or not(FEditor.IsIdentChar(AChar)) then + Manager.CodeCompletionReady := True; if (aChar=' ') and AutoCompleteChar(aChar,AddChar,acoSpace) then begin // completed end @@ -3776,7 +3788,9 @@ else if (not FEditor.IsIdentChar(aChar)) and AutoCompleteChar(aChar,AddChar,acoWordEnd) then begin // completed - end else if CodeToolsOpts.IdentComplAutoStartAfterPoint then begin + end else if ((aChar='.') and CodeToolsOpts.IdentComplAutoStartAfterPoint) or + (CodeToolsOpts.IdentComplAutoInvokeOnType) then + begin // store caret position to detect caret changes SourceCompletionCaretXY:=FEditor.CaretXY; // add the char @@ -9961,7 +9975,7 @@ for i := FSourceWindowList.Count - 1 downto 0 do SourceWindows[i].ReloadEditorOptions; - AutoStartCompletionBoxTimer.Interval:=EditorOpts.AutoDelayInMSec; + AutoStartCompletionBoxTimer.Interval:=EditorOpts.CodeCompletionDelayInMSec; // reload code templates with CodeTemplateModul do begin if FileExistsUTF8(EditorOpts.CodeTemplateFilename) then @@ -9979,7 +9993,7 @@ IndentToTokenStart:=EditorOpts.CodeTemplateIndentToTokenStart; end; - FHints.AutoHintTimer.Interval:=EditorOpts.AutoDelayInMSec; + FHints.AutoHintTimer.Interval:=EditorOpts.HintDelayInMSec; if FDefaultCompletionForm <> nil then begin FDefaultCompletionForm.LongLineHintTime := EditorOpts.CompletionLongLineHintInMSec; @@ -10745,17 +10759,43 @@ procedure TSourceEditorManager.OnSourceCompletionTimer(Sender: TObject); + function CheckCodeAttribute (XY: TPoint; out CodeAttri: String): Boolean; + var + SrcEdit: TSourceEditor; + Token: string; + Attri: TSynHighlighterAttributes; + begin + + Result := False; + + SrcEdit := ActiveEditor; + if SrcEdit = nil then exit; + + Token:=''; + Attri:=nil; + dec(XY.X); + if SrcEdit.EditorComponent.GetHighlighterAttriAtRowCol(XY,Token,Attri) + and (Attri<>nil) {and (Attri.StoredName=AttriName)} then + begin + CodeAttri := Attri.StoredName; + Result := True; + end; + + end; + function CheckStartIdentCompletion: boolean; var Line: String; LogCaret: TPoint; - p: Integer; - InStringConstant: Boolean; SrcEdit: TSourceEditor; - Token: string; - Attri: TSynHighlighterAttributes; + CodeAttribute: String; + aChar: Char; begin Result := false; + + if not FCodeCompletionReady then + Exit; + SrcEdit := ActiveEditor; if SrcEdit = nil then exit; if not (SrcEdit.FEditor.Highlighter is TSynPasSyn) then @@ -10765,35 +10805,40 @@ LogCaret := SrcEdit.FEditor.LogicalCaretXY; //DebugLn(['CheckStartIdentCompletion Line="',Line,'" LogCaret=',dbgs(LogCaret)]); - // check if last character is a point - if (Line='') or (LogCaret.X<=1) or (LogCaret.X-1>length(Line)) - or (Line[LogCaret.X-1]<>'.') then + // check for empty line + if (Line='') or (LogCaret.X<=1) or (LogCaret.X-1>length(Line)) then exit; + aChar := Line[LogCaret.X-1]; + + // quick check for valid letters + if not(aChar in ['a'..'z', 'A'..'Z', '_', '0'..'9', '.', '$']) then + Exit; + + if not CheckCodeAttribute(LogCaret, CodeAttribute) then + Exit; + + // check for attributes + if (aChar= '.') and not(CodeAttribute = SYNS_XML_AttrSymbol) then + Exit; + + if (aChar in ['a'..'z', 'A'..'Z', '_', '0'..'9']) and + not ((CodeAttribute = SYNS_XML_AttrIdentifier) or (CodeAttribute = SYNS_XML_AttrDirective)) then + Exit; + + if (aChar='$') and not(CodeAttribute = SYNS_XML_AttrDirective) then + Exit; + + if CodeAttribute = SYNS_XML_AttrComment then + Exit; + + if CodeAttribute = SYNS_XML_AttrString then + Exit; + // check if range operator '..' if (LogCaret.X>2) and (Line[LogCaret.X-2]='.') then exit; // this is a double point .. - // check if in a string constant - p:=1; - InStringConstant:=false; - while (p<LogCaret.X) and (p<=length(Line)) do begin - if Line[p]='''' then - InStringConstant:=not InStringConstant; - inc(p); - end; - if InStringConstant then exit; - - // check if in a comment - Token:=''; - Attri:=nil; - dec(LogCaret.X); - if SrcEdit.EditorComponent.GetHighlighterAttriAtRowCol(LogCaret,Token,Attri) - and (Attri<>nil) and (Attri.StoredName=SYNS_XML_AttrComment) then - begin - exit; - end; - // invoke identifier completion SrcEdit.StartIdentCompletionBox(false,false); Result:=true; @@ -10867,6 +10912,7 @@ inherited Create(AOwner); FDefaultCompletionForm := nil; + FCodeCompletionReady := True; // word completion if aWordCompletion=nil then begin @@ -10883,7 +10929,7 @@ Name:='AutoStartCompletionBoxTimer'; AutoEnabled := False; Enabled := false; - Interval := EditorOpts.AutoDelayInMSec; + Interval := EditorOpts.CodeCompletionDelayInMSec; OnTimer := @OnSourceCompletionTimer; end; |
|
|
|
Maybe better to fix 0032972 before indroducing autoinvoke then? |
|
Maybe. But that's quite difficult to dig in. |
|
BTW. this feature is called Identifier Completion, not Code Completion. Code Completion is invoked with Ctrl+Shift+C: http://wiki.lazarus.freepascal.org/Lazarus_IDE_Tools#Code_Completion |
|
First of all, really nice feature. But a couple of notes: 1) I am missing an option to set the time for the new HintDelayInMSec I can see it will be saved and loaded to/from the xml, but I do not see any of the options frames allowing to config it. 2) You did not mention the addition of keywords in your description. Nice feature too, but if possible: separate patch. (The changes inside of codetools itself may be handled by a different developer / So the rest of my comments ignores identcompletiontool.pas) about keywords: from a quick test, they only appear in the list, if the caret is at the begin of a new statement? Makes sense for "begin", but "xor" would have to only appear in expressions (never at the start) Have not gone through the entire list. So there may be more. 3) After cancelling a completion, if I press cursor-left, and keep typing in the same word, the completion appears again. Same after setting a bookmark. There will be plenty more... I thought about storing the start x/y of the current word. But that is not easy either. With Syncro and multi-caret, the current word may move (even to diff y pos) while you edit it (and while the caret stays at the end of the word. The same can happen if the unit is open in 2 source editors. If you edit in the other editor then the entire text + caret in the other move accordingly. It might be best to have a whitelist of commands that will reactivate the completion. Such as - whitespace - ecLeft/Right IF going over none identifier chars - ec WordLeft/Right if leaving the current word (check in afterCommand hook). Its a bit more work.... - ecUp/Down If you have a better idea... Btw, there is a case were it is not re-enabled, but maybe should. - Start typing - cancel - use mouse to position caret into another word - type => nothing 4) CheckCodeAttribute Better compare "token" to tkIdentifier or tkSymbol .... TtkTokenKind = (tkAsm, tkComment, tkIdentifier, tkKey, tkNull, tkNumber, tkSpace, tkString, tkSymbol, tkDirective, tkIDEDirective, tkUnknown); if Token = ord(tkSymbol) then Apparently that was already in the old code. Comparing the name should work, at least currently, but using the type would be better. |
|
Please test and close if ok. Implemented in a slightly different way. - setting is off by default. - added some settings for tuning Re-used the "compare attribute name" from the patch. Did not include codetool changes / Please submit as different issue, if important. |
|
Little bit forgot about it and didn't notice it was implemented in trunk until now. One thing noticed immediately. I've been placing operators on top, because when typing operators, if, do, else etc, pressing space after them would insert something else. Solution is either bring operators atop or bring atop line that is fully equal of typed identifier. Or both of those. May be little late, but i'll answer on above 1. Well, i split them, as if completion is 0 sec, 0 sec hint would be annoying. This is weird. I use TortoiseSVN for patch generation. Looks like it missed that one lfm file. But i see it's been implemented. 2. That's for a reason above. So typing space after them wouldn't bring something else. 3. Don't really remember now, i'm not sure, but i think i haven't found a way to reset it in case if identifier completely erased. Pretty sure i remember it was working. With current implementation i have to press space then backspace to get it working again. Might be idea, but i haven't found anything back then. Have to look at the code again. I didn't see it as a problem, as in most situations we only need to cancel completion for current typing. Moving cursor any direction meaning we starting over. 4. Same here. I was digging, but haven't found better way back them. Attribution comparison was already there, but rest was parsed right in the function. So instead i made everything rely on attribution, which was better then parsing right in that function. I don't think tokens brought my attention back then. |
Date Modified | Username | Field | Change |
---|---|---|---|
2018-01-20 03:11 | regs | New Issue | |
2018-01-20 03:11 | regs | File Added: autoinvoke.patch | |
2018-01-20 03:12 | regs | File Added: autoinvokecc.gif | |
2018-01-20 06:02 | Ondrej Pokorny | Relationship added | related to 0032972 |
2018-01-20 06:02 | Ondrej Pokorny | Note Added: 0105948 | |
2018-01-20 20:15 | regs | Note Added: 0105961 | |
2018-01-21 09:58 | Ondrej Pokorny | LazTarget | => - |
2018-01-21 09:58 | Ondrej Pokorny | Summary | Autoinvoke Code Completion on type => Autoinvoke Identifier Completion on type |
2018-01-21 09:58 | Ondrej Pokorny | Description Updated | View Revisions |
2018-01-21 09:58 | Ondrej Pokorny | Additional Information Updated | View Revisions |
2018-01-21 09:59 | Ondrej Pokorny | Note Added: 0105977 | |
2018-01-21 09:59 | Ondrej Pokorny | Additional Information Updated | View Revisions |
2018-07-16 00:56 | Martin Friebe | Note Added: 0109507 | |
2020-06-06 17:19 | Martin Friebe | Assigned To | => Martin Friebe |
2020-06-06 17:19 | Martin Friebe | Status | new => resolved |
2020-06-06 17:19 | Martin Friebe | Resolution | open => fixed |
2020-06-06 17:19 | Martin Friebe | Fixed in Version | => 2.2 |
2020-06-06 17:19 | Martin Friebe | Fixed in Revision | => 63314 |
2020-06-06 17:19 | Martin Friebe | LazTarget | - => 2.2 |
2020-06-06 17:19 | Martin Friebe | Note Added: 0123271 | |
2020-09-12 02:16 | regs | Note Added: 0125496 |