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

Real model for snippets #236

Closed
mickaelistria opened this issue May 4, 2017 · 10 comments
Closed

Real model for snippets #236

mickaelistria opened this issue May 4, 2017 · 10 comments
Labels
feature-request Request for new features or functionality

Comments

@mickaelistria
Copy link

Currently, the snippets are defined with string conventions. That causes multiple issues:

  • Every client has to reimplement a parser for those $... strings
  • adopting snippets is somehow difficult and error-prone as it requires to make computations on the insertText. It also needs to be reimplemented by all clients
  • if the language actually wants to deal with $, { or :, it requires to escape those characters.

I believe the protocol would be better at creating a model object for those tabstops. It would make things simpler to specify, adopt and maintain.

Here is a suggestion: allow those tabstops in text edit:

interface TextEdit {
	range: Range;
	newText: string;
	editGroups?: EditGroup[]
}

interface EditGroup {
	ranges: Range[]; /* Relative to the new Text of the edit, not overlapping */
	possibleValues?: string[] /* possible suggested values for this group */
}

So instead of sending a TextEdit with newText=one$1 two${2:foo} three$1, LS would send

TextEdit: {
	range: {offset: o, length: l},
	newText: "one twofoo three",
	editGroups: [
		{
			ranges: [
				{offset: 0, length: 0},
				{offset: 16, length: 0}
			]
		},
		{
			ranges: [
				{offset: 7, length: 3}
			],
			possibleValues: [ "foo", "bar", "whatever" ]
		}
	]
}

Then applying this becomes trivial: first apply the text, and then use the editGroups to put tabstops and so on.
Some additional benefits:

  • it allows the clients that don't support tabstops to use the result anyway, as they can ignore the tabstops but still get interesting completion/edit
  • it introduces the possibleValues which are nice assistance for placeholder (widely use in Eclipse Java Development Tools)
@alanz
Copy link

alanz commented May 4, 2017

Where are these $... strings specified?

@kdvolder
Copy link

kdvolder commented May 4, 2017

The docs for InsertTextFormat as well as (redundantly) in the docs for completion capabilities. The capability to handle snippets is one of the 'optional' features a client can implement.

@mickaelistria
Copy link
Author

mickaelistria commented May 4, 2017 via email

@mickaelistria
Copy link
Author

mickaelistria commented May 4, 2017 via email

@mickaelistria
Copy link
Author

Note that with my proposal, a server wouldn't really need to make the difference between snippet support or not: the edit only would already be valuable and usable (whereas snippets don't make it nice if not supported nowadays) and then clients could -optionally- implement the support for snippets/editGroups.
So adopting such a model over some text conventions would make it simpler to write multi-IDE servers (as the snippetSupport capability could become ignored) and clients (who'd have way less string manipulation to do).

@dbaeumer dbaeumer added the feature-request Request for new features or functionality label May 17, 2017
@dbaeumer dbaeumer added this to the Backlog milestone May 17, 2017
@dbaeumer
Copy link
Member

Actually when we worked in the snippet support in VS Code we discussed such an approach. The reason why we decided against it is that creating the snippets is harder. If a character is added to the string you might need to adjust offset and length. This seemed to be very cumbersome. So you will either write code to help you with that or the client writes code to parse the snippet. We decided that overall it is better to ask the client to parse a string with a certain syntax (as other tools do as well). We took a subset of the text mate syntax so that client don't need to start from scratch.

I agree that such a support would allow clients to easier provide snippet support since applied edits is easier than parsing strings.

@mickaelistria
Copy link
Author

mickaelistria commented May 17, 2017 via email

@dbaeumer
Copy link
Member

If I change the newText to one twofoo three four and I want the last tab stop to be at the end I need to update ranges. Same is true if I for example change foo. So you need to track the positions when creating the snippet programmatically. If you use a language you can do something like this in TypeScript (back tick strings)

`one$1 two${my variable name} three$1`

@mickaelistria
Copy link
Author

If I change the newText to one twofoo three four and I want the last tab stop to be at the end I need to update ranges. Same is true if I for example change foo. So you need to track the positions when creating the snippet programmatically. If you use a language you can do something like this in TypeScript (back tick strings)

When you say "I", you mean as a user of the tool or as the provider of the language server? If it's as a user of the tool, then I'd say it's up to the tool to keep consistent range according to user input. If it's a language server provider, I imagine there could be helpers to easilty turn a string with parameter capturing into a modeled text edit.

@dbaeumer
Copy link
Member

To keep the number of issues in our inbox at a manageable level, we’re closing issues that have been on the backlog for a long time but haven’t gained traction: we look at the number of votes the issue has received and the number of duplicate issues filed. Thank you for your time and understanding.

If you disagree and feel that this issue is crucial: we’re happy to listen and to reconsider.

@vscodebot vscodebot bot locked and limited conversation to collaborators Jan 8, 2018
@dbaeumer dbaeumer removed this from the Backlog milestone Nov 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature-request Request for new features or functionality
Projects
None yet
Development

No branches or pull requests

4 participants