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

CompletionItem - multiple text edits, onDidAcceptCommand #6874

Closed
jrieken opened this issue May 25, 2016 · 22 comments
Closed

CompletionItem - multiple text edits, onDidAcceptCommand #6874

jrieken opened this issue May 25, 2016 · 22 comments
Assignees
Labels
api feature-request Request for new features or functionality suggest IntelliSense, Auto Complete
Milestone

Comments

@jrieken
Copy link
Member

jrieken commented May 25, 2016

We should investigate if we should allow running a command on suggest. That would allow for more advanced code actions, like 'add import', 'download typing files' etc on completion. An alternative would be the onDidExecuteCommand event which folks ask for. Internally accepting a completion is a command - if we broadcast that someone else could run a followup command.

@jrieken
Copy link
Member Author

jrieken commented May 25, 2016

[onWill|onDidExecuteCommand] is tracked here: #1431

@dbaeumer
Copy link
Member

I like the idea of running a command since it allows for cases like downloading a typings file. But there are lot of cases as well that only need to apply multiple edits. Could we have both, providing an array of edits or an command.

@jrieken
Copy link
Member Author

jrieken commented May 31, 2016

yes - I came to the same conclusion, esp when a command also wants to modify the current text document. Coordinating a command and a text edit would be hairy...

@dbaeumer
Copy link
Member

Agree on the coordination command and text. That is why I would do exclusive or.

@jrieken jrieken changed the title Run a command on suggest CompletionItem - multiple text edits, onDidAcceptCommand Jul 15, 2016
@jrieken
Copy link
Member Author

jrieken commented Jul 15, 2016

@DustinCampbell fyi

@DustinCampbell
Copy link
Member

sounds great!

@jrieken
Copy link
Member Author

jrieken commented Jul 27, 2016

Also, there is a little know thing with completions and that is placeholders... It's undocumented and somewhat internal but it would be easy to make it like snippets. That is a completion can contain placeholders, tab positions, and the final cursor position. Like so:

foo(${value}, ${another}); ${_}

It would do something like this:

jul-27-2016 16-44-13

For instance for method completion a powerful language brain could already propose arguments for function calls etc

@buehler
Copy link

buehler commented Aug 9, 2016

I really like this idea. I'm currently at the state that I'm inserting the wanted symbol at the place with the CompletionItemProvider and then let the CodeActionProvider add the import reference. But actually it would be very nice to use the completion item to add the import to the document.

👍

Cheers

@jrieken
Copy link
Member Author

jrieken commented Aug 22, 2016

@DustinCampbell @buehler We have a way to get into a 'snippet mode' when accepting a completion - that's multiple potentially linked cursors after selecting an item. We have them to help with subsequent edits and we plan to make them official (#3210). Snippet mode does conflict with additional edits and we will likely not allow both in one completion. Would that be a problem for you guys?

jrieken added a commit that referenced this issue Aug 22, 2016
@buehler
Copy link

buehler commented Aug 22, 2016

For now, fine by me :-)
For my actual usecase, it's cool to insert code at multiple lines (i.e. write the selected type and insert an import at the beginning of a file).

I dunno if this answers your question...

Cheers

@jrieken
Copy link
Member Author

jrieken commented Aug 22, 2016

Yeah, thanks. Multiple text edits is definitely on our list, the import-scenario is what we are looking at but also want to think a little out of the box

@buehler
Copy link

buehler commented Aug 22, 2016

Cool!
I don't get the "problem" with the snipped mode, could you elaborate the problem? It would be nice to understand your thinking.
So one can add multiple selections to edit several parts of the document at once with snippets?

@jrieken
Copy link
Member Author

jrieken commented Aug 22, 2016

There is an undocumented feature which we lend from text mate snippets. Basically, you can use a special syntax in your completion and the editor will enter a snippet mode. See this sample:

...
new CompletionItem('bar{{foo}}bar{{foo}}{{}}')
...

aug-22-2016 16-24-50

The double-curly-bracket is somewhat internal but we plan to allow more of the text mate snippet syntax in completions. Combining that with additional edits is tricky

@DustinCampbell
Copy link
Member

I'm primarily looking for a way to provide C# completion on override, which looks like so:

1. Before completion:

image

2. After completion:

image

Implementing this properly requires the following:

  1. Multi-line completions
  2. Multiple edits (for the using directive at the top of the file)
  3. Ability to move the caret

I'm not sure snippets will achieve the desired result.

@buehler
Copy link

buehler commented Aug 23, 2016

Oh shiny 👍
Thanks for the explanation.

@jrieken jrieken added the suggest IntelliSense, Auto Complete label Aug 23, 2016
@jrieken
Copy link
Member Author

jrieken commented Aug 24, 2016

fyi @DustinCampbell

aug-24-2016 09-55-30

With this hacked-up completion item provider (note that the filter text must be set)

    languages.registerCompletionItemProvider('csharp', {
        provideCompletionItems(doc, pos) {
            const range = doc.getWordRangeAtPosition(pos);
            const word = doc.getText(range);
            if (word === 'override') {

                const item = new vscode.CompletionItem('M1()', vscode.CompletionItemKind.Method);
                item.textEdit = vscode.TextEdit.replace(range, 'protected override void M1()\n{\n\tthrow new NotImplementedException();{{}}\n}')
                item.additionalTextEdits = [vscode.TextEdit.insert(new vscode.Position(0, 0), 'using System;\n')];
                item.filterText = word;

                return [item];
            }
        }
    });

Still on my list

  • use the 'official' text mate snippet syntax, so instead of {{}} it should be $0 for the final tab stop
  • (stretch) make all textual changes happen in a single operation (single undo)

@nwolverson
Copy link

@jrieken I notice your current implementation has a command running after the text edit is made - I think that should enable my use case, where the additional edit (again inserting/modifying an import statement) is made via an external language service (ie provided asynchronously only after an individual completion is selected).

Am I right in that? I think it could be a common enough case.

@jrieken
Copy link
Member Author

jrieken commented Aug 24, 2016

Yes and no. If you want to make additional modifications to the document I d recommend to use the additionalTextEdit-property. It will make you life easier wrt to subsequent edits, touching/overlaping edits, undo, keeping selections/multiple cursors stable etc.

is made via an external language service (ie provided asynchronously only after an individual completion is selected).

I'm obviously just guessing because I don't know anything about your language service but if you have a chance to compute those additional edits during the first request do it ;-)

Last, you might be interested in #10561 which is about expanding a snippet when being inserted.

@nwolverson
Copy link

@jrieken Unfortunately that's not possible if all edits must be provided for all completion items up front - rather than eg as a promise on the completion item (or at least the downsides you list are more acceptable than having to do so).

@jrieken
Copy link
Member Author

jrieken commented Aug 24, 2016

Running an async aftermath command isn't a show stopper. Make sure to use small edits and compare the document version before and after the long running operation.

@DustinCampbell
Copy link
Member

Very pretty @jrieken!

@jrieken
Copy link
Member Author

jrieken commented Aug 29, 2016

Closing. The remaining work is #10561

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api feature-request Request for new features or functionality suggest IntelliSense, Auto Complete
Projects
None yet
Development

No branches or pull requests

5 participants