Skip to content

Completion list is filtered on leading whitespace #69542

Closed

Description

@DanTup

I raised this previous in #66860, see there for details. The suggested fix was to prefix filterText on CompletionItems with spaces, however this doesn't work correctly because it results in the space being removed when you accept the completion:

context.subscriptions.push(vs.languages.registerCompletionItemProvider("markdown", {
		provideCompletionItems(document: vs.TextDocument, position: vs.Position, token: vs.CancellationToken, context: vs.CompletionContext): vs.CompletionItem[] {
			const item = new vs.CompletionItem("test");
			item.filterText = " test"; // Prefix with space so it doesn't vanish if the user wants a space after the trigger character like `foo: test`
			return [item];
		},
	}, ":"));

Then the user types foo: and the completion opens. The press space, and the test item remains visible (good), but then they accept the completion and the space vanishes - they get foo:test (bad).

I used to have <space> as a trigger character, but it caused other bugs when users were typing quickly, and it also significantly increases the number of times the completion opens unexpectedly.

Activity

  1. DanTup commented on Feb 27, 2019

    @DanTup
    ContributorAuthor
  2. jrieken commented on Feb 27, 2019

    @jrieken
    Contributor

    CompletionItem#insertText?

  3. DanTup commented on Feb 27, 2019

    @DanTup
    ContributorAuthor

    Johannes Rieken (@jrieken) But if I prefix a space onto that, then users will get spaces inserted where they might not want them. For example if the trigger character had been an open parent, the user wouldn't want foo( test);. We can't tell in advance whether the user wants to add whitespace or not, because the completion provider is called before they type the space and then it's too late (and we don't want to dictating where the user has whitespace).

    It feels a bit wrong to be messing with the completion items to try and solve this issue, when the problem is really just that the user wants to insert some whitespace without it messing with what's in the completion list.

  4. vscodebot commented on Feb 27, 2019

    @vscodebot

    We have a great developer community over on slack where extension authors help each other. This is a great place for you to ask questions and find support.

    Happy Coding!

  5. jrieken commented on Feb 27, 2019

    @jrieken
    Contributor

    We can't tell in advance whether the user wants to add whitespace or not, because the completion provider is called before they type the space and then it's too late

    Then keep you result open, e.g. CompletionList#isIncomplete

  6. DanTup commented on Feb 27, 2019

    @DanTup
    ContributorAuthor

    Johannes Rieken (@jrieken) How would we know when to set it? If we set it always, then won't the completion provider be invoked on every keystroke and the performance much worse (essentially bypassing all of VS Code's client-side filtering)?

  7. jrieken commented on Feb 27, 2019

    @jrieken
    Contributor

    Johannes Rieken (@jrieken) How would we know when to set it?

    Whenever your use-case applies, according to #66860 whenever you type named arguments.

    performance much worse (essentially bypassing all of VS Code's client-side filtering)?

    Performance depends on the extension, the cost of roundtrips are low. Filtering still works as before, no bypassing of anything.

  8. DanTup commented on Feb 27, 2019

    @DanTup
    ContributorAuthor

    Whenever your use-case applies, according to #66860 whenever you type named arguments.

    It's not just named arguments, since it can happen after commas too (foo(a, b, c)). The VS Code extension doesn't have the correct knowledge to know this (it's just the proxy to the language server).

    Do you know how other extensions handle this? It seems like a common scenario, it seems weird to have to jump through so many hoops just to allow whitespace after trigger characters 😞

  9. DanTup commented on Feb 28, 2019

    @DanTup
    ContributorAuthor

    It seems like other extensions don't have so many trigger characters (possibly because of issues like this), so I've just removed those that might have whitespace from ours instead. I'll put them back if it ever becomes easier to support - going back to the server on every keystroke while completion is open seems excessive (not only because the server isn't stateful so will do some work to compute the list, it also sends back a potentially huge list that is JSON serialised/deserialised).

  10. locked and limited conversation to collaborators on Apr 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

*dev-questionVS Code Extension Development Questioninfo-neededIssue requires more information from poster

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions