Conditionally insert parenthesis for completion provider on functions

SyntaxEditor for WPF Forum

Posted 8 months ago by Josh
Version: 17.1.0
Avatar

Hello,

Take for example the following funcitons:

func1(int myParam){}
func2() {}

When selecting func1 from the completion provider:  If the user presses tab/space/ open parenthesis, I would like the text inserted to be "func1()" with the caret in the middle.  Then when they type the number, and press the close parenthesis, it should just skip over the end parenthesis.  When I use the DelimiterAutoCompleter and not use any autocomplete pre/post on the completion itjem, it is doing this, however the autocomplete just inserts "func1"

For func2, I would like the text inserted to be "func2()" with the caret AFTER the parenthesis, and when I commit the completion provider with an open parenthesis, I dont want a duplicated parenthesis.

Any suggestions?

Comments (2)

Posted 8 months ago by Josh
Avatar

The following code is getting me closer.  However, I need to know which key was pressed to commit the completion provider, as if the user did use the open parenthesis, then I dont want this code to run.

private void Session_Committed(object sender, EventArgs e)
{
	if (sender is CompletionSession completionSession)
	{
		var options = new TextChangeOptions
		{
			CanMergeIntoPreviousChange = true,
			OffsetDelta = TextChangeOffsetDelta.SequentialOnly
		};
		var changes = CompletionSession.View.SyntaxEditor.Document.CreateTextChange(TextChangeTypes.Typing, options);
		changes.InsertText(completionSession.View.Selection.EndOffset, "(");
		changes.Apply();
	}
}

Is there a better way to do this?

Posted 8 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Josh,

That sounds like expected behavior right now.  If the '(' is typed in and the DelimiterAutoCompleter is actively tracking it to insert the corresponding ')', then the caret should skip over the ')' if the caret is right before it, and ')' is typed.  However if you insert "()" as part of the completion item, then the DelimiterAutoCompleter isn't doing any tracking and therefore typing ')' won't skip over an existing ')'.

Typically you do not want to include parentheses in the text that completion items are inserting.  This is so that you can select a function and type '(' and it will then have DelimiterAutoCompleter tracking enabled.

There isn't anything at the moment that tracks what kind of event triggered the completion session commit.

If you do want to dynamically alter what the completion session inserts, a better way might be to make a class that inherits CompletionSession.  You could default the items to including the parens in their auto-complete text.  Then override the session's OnViewTextInput method and see if the e.Text is a '('.  If it is, then you'd want to change the selected completion item's text to not include the parens prior to calling the base method, where the Commit can occur.  You'd have to update your completion provider language service to create an instance of this custom CompletionSession class instead of the base CompletionSession class.


Actipro Software Support

The latest build of this product (v22.1.3) was released 23 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.