Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trigger characters in signature help #24915

Merged

Conversation

DanielRosenwasser
Copy link
Member

This change implements trigger character handling for signature help. When an editor provides us with a trigger character, the language service is now able to use that as a signal to distinguish whether a user is typing in some unrelated construct (e.g. commas in an array) and whether the user explicitly requested signature help (e.g. typing in a comma as part of an argument list).

Right now the implementation only handles filtering completion characters inside of a string literal; we can expand to other syntactic constructs later on.

Fixes #1150, one of our oldest-standing language service bugs.

@amcasey and @mjbvz, we'll need support from the VS and VS Code side.

@mjbvz
Copy link
Contributor

mjbvz commented Jun 12, 2018

TSServer Api looks good. Thank you for looking into this!

We'll need to do a little work on the vs code side (microsoft/vscode#51731) to make sure we have this info but I don't expect that to be difficult

@@ -29,6 +29,11 @@ namespace ts.SignatureHelp {
return undefined;
}

// In the middle of a string, don't provide signature help unless the user explicitly requested it.
if (triggerCharacter !== undefined && isInString(sourceFile, position, startingToken)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about , in an object literal? or < in jsxElement?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider extracting this to isValidTriggerCharacter function and handling each accordingly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually don't think you need to look at the triggerCharacter - you just need to use the startingToken and check whether you were given a trigger in the first place. That's why in #1150 we had a more abstract idea of a trigger reason rather than the character itself

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I think I'd rather handle those cases in another PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure i follow.. why would not it be sufficient, and why anohter PR?

@amcasey
Copy link
Member

amcasey commented Jun 14, 2018

It looks like it would be very easy for VS to consume this change. However, as Daniel and/or Mohamed pointed out, returning undefined while sighelp is already displayed will (apparently) dismiss it.

Edit: I've created a branch on VSTS so you can play with the new functionality.

@@ -4467,7 +4467,6 @@ declare namespace ts {
useCaseSensitiveFileNames?(): boolean;
fileExists?(path: string): boolean;
readFile?(path: string): string | undefined;
getSourceFiles?(): ReadonlyArray<SourceFile>;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there are a few breaking changes in this file.

verify.noSignatureHelpForTriggerCharacter(triggerCharacter);
edit.backspace();
}
verify.signatureHelp({ triggerCharacter: undefined });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this verify?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signature help will fail if nothing is returned, but I'll make a more explicit version.

@DanielRosenwasser
Copy link
Member Author

🔔

@@ -50,6 +57,11 @@ namespace ts.SignatureHelp {
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker));
}

function shouldCarefullyCheckContext(reason: SignatureHelpTriggerReason | undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just inline this function

@@ -29,6 +29,13 @@ namespace ts.SignatureHelp {
return undefined;
}

if (shouldCarefullyCheckContext(triggerReason)) {
// In the middle of a string, don't provide signature help unless the user explicitly requested it.
if (isInString(sourceFile, position, startingToken)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we still need to do some additional checks here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g.:
(: in a parenthesized expression
,: not in an object literal, array literal, or comma expression
default: instring | incomment | injsxtext,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants