Currently, you can only insert a string from an extension using TextEditorEdit. I am in the process of creating a jsdoc comments extension, and it can insert TextMate-style snippets, but only as a string. It would be much better if one could iterate through all the placeholders rather than manually moving the cursor.
The effect would be similar to the one in the Function Documentation section here
Would it be possible to get a feature like this?
@shardulm94 Unsure if it works but you explore adding a completion item provider that returns completions of kind Snippet. With that you should get support for placeholders
Whoa, interesting. So if a completion is of type Snippet and has the necessary formatting for placeholders, it should work as expected? This could mean interesting things for the PowerShell extension...
go for it @daviwil
@jrieken I tried this today. But it inserts the tabstops and placeholders as text itself.

the syntax is like so: new vscode.CompletionItem('hello {{world}}. hello {{world}}') using double curly brackets. Unsure, if we plan to align that to the snippet syntax that seems to be ${thing}
@jrieken Great, thanks! This fits my needs!
Is there any way to order tab stops with this syntax?
EDIT: It would be really helpful if you could point me to where this syntax is documented.
unsure. @alexandrudima will know
We didn't document it because we didn't want it to spread.
@jrieken maybe completions coming from the extension host should go through https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.ts#L226 such that we don't end up documenting and making API of our internal format.
This would be a huge step for https://github.com/joelday/vscode-docthis. (I still haven't figured out a way to change the selection position to inside the range of new edits.)
Hope to see this get formalized as an external API.
Stretch for August, likely Sept
Looking forward to this
We have basically two options for this, an easy and a complicated option. Option A (and that is the easy one) is that we simply document our internal snippet format and build on it in the future. It has the advantage of not requiring new API to signal _this completion string_ uses snippet syntax and should be handled special because already today it is like that. The obvious disadvantage is that we introduce another syntax in addition to the TM snippet syntax. Option B would be to build on the TM snippet syntax and it would mean that we need a flag/type to signal _this string is a TM snippet_ such that we don't break existing completion providers. It would also require us to reach more parity with the actual TM snippet syntax and it would raise the question if the existing, implicit, behaviour should be turned off. Suggestions welcome!
I think, if it helps, just do away with the whole textmate syntax for snippets. VSCode anyways supports only a limited subset of the snippets, writing/converting the existing tmSnippets to JSON is painful, and there are bugs even in that, such as tabs not properly jumping to the next snippet, tabs jumping to first snippet after the last one, etc, which make the snippets part a very weak part of the software. If there is a better way, why not use that? This new optionA although sounds good, will create more fragmentation in the way snippets are written/maintained IMO.
Did this make 1.7.1?
@alexandrudima @jrieken any update or decision on the syntax of snippets? I found it's really easy to write an extension that supports workspace/project level snippet (https://github.com/Microsoft/vscode/issues/8102) by leveraging CompletionProvider but the only problem is the syntax.
For now this tiny extension (I won't publish it until things are clear) works perfectly on my local box with the double curly snippet syntax you mentioned above. IMO TextMate snippet syntax will be better as people are using them already.
Sorry, it slipped for 1.7...
We have discussed this yesterday and we also figured that best would be to go with the TextMate syntax despite us only supporting a subset. The open question I have
usesSnippetSyntaxcc @dbaeumer and @ramya-rao-a I know your extensions (TypeScript and go) use the undocumented snippets feature in completions.
I am in favor of only supporting one syntax. Adding a Boolean to indicate a snippet syntax makes sense to me.
In that case, is there any roadmap to adding full textmate support to vscode snippets?
When I saw CompletionKind.Snippet the first time, I thought it was used to declare the insertText was actually a snippet but later I found that this property only contributes to the icon. An additional usesSnippetSyntax or usesTMSnippetSyntax will help a lot.
+1 on what @dbaeumer said
https://github.com/Microsoft/vscode/issues/3210#issuecomment-258497196 raises a very interesting question. When you use CompletionItemKind.Snippet should users set the useSnippetSyntax flag or not? That makes me think if we should just interpret the text mate snippet syntax by default (similar to how we do it today with the internal syntax) without a flag but offering a way to escape text easily.
I'll add some telemetry to learn how often each syntax is already used today...
@jrieken, @dbaeumer
I think we're much better off with our own syntax. We control it, we know every detail, we can evolve it. As the VSCode API is tightly coupled with the language protocol spec the syntax that goes in the VSCode API will/should also be take up by the language server protocol. And there it is essential that we are in control of it, in order to keep things simple and well documented.
Also the internal syntax is not only already used by extensions but also by our language servers (JSON, CSS/LESS/SCSS, HTML). These are already consumed by other clients (Eclipse, Orion...).
The syntax is used a lot, showing its importance: Especially JSON is a heavy user. I'm quite sure that anyone consuming a language server by now can handle our syntax by now. Changing the syntax will be a big swirl, break these clients, force them to implement a TextMate compatible for, IMO, not much gain.
Only using half the TextMate syntax is already a mess, and we are pressured to stay compatible to an very loosely spec'ed implementation.
While supporting 2 syntaxes in VSCode is a bit awkward, it doesn't impact the user experience. Users only get in touch with the TextMate syntax. Developer might get in touch with both.
But from a developer perspective and especially from the language service protocol perspective it's much more important to have a clear spec and a maybe a implementation example.
These are already consumed by other clients (Eclipse, Orion...).
Are you saying they have implemented the internal syntax? How did they know what to implement without a spec?
Only using half the TextMate syntax is already a mess, and we are pressured to stay compatible to an very loosely spec'ed implementation.
For once it's not as bad as you think and then there seems to be a subset that is accepted also in other editors, like sublime. Last, there are feature requests to support more snippet features, like variables. It won't help discoverability if we start to implement them but with a different syntax.
I have added telemetry to see how often which syntax is being used and from what extensions. I understand that @aeschli doesn't what to update his code but that is also relying on an internal undocumented features.
We could consider writing a snippet parser that understands the internal and the text mate syntax at the same time. That ensures smooth migration and a path forward (using TM)
After some infrastructure work and collecting some telemetry this is my plan
isSnippetText. When true we will interpret the _insert text_ as snippet. The CompletionItem#kind property has no effect on this. OR In addition to the TextEdit-class we will add a SnippetEdit class which describes a snippet-text and range. We will update CompletionItem#textEdit to become textEdit: TextEdit | SnippetEdit such that a completion can be a snippet.CompletionItem.insertText will become insertText: string | SnippetString. Also we will add CompletionItem.range and _deprecate_ CompletionItem.textEditengine-field in package.json)These are the API changes that will enable this.
insertText can now also be of type SnippetStringrange has been added to the completion itemtextEdit has been deprecated (but kept functional) in favour of the former two /**
* A snippet string is a template which allows to insert text
* and to control the editor cursor when insertion happens.
*
* A snippet can define tab stops and placeholders with `$1`, `$2`
* and `${3:foo}`. `$0` defines the final tab stop, it defaults to
* the end of the snippet. Placeholders with equal identifiers are linked,
* that is typing in one will update others too.
*/
export class SnippetString {
/**
* The snippet string.
*/
value: string;
constructor(value?: string);
/**
* Builder-function that appends the given string to
* the [`value`](#SnippetString.value) of this snippet string.
*
* @param string A value to append 'as given'. The string will be escaped.
*/
appendText(string: string): SnippetString;
/**
* Builder-function that appends a tabstop (`$1`, `$2` etc) to
* the [`value`](#SnippetString.value) of this snippet string.
*
* @param number The number of this tabstop, defaults to an auto-incremet
* value starting at 1.
*/
appendTabstop(number?: number): SnippetString;
/**
* Builder-function that appends a placeholder (`${1:value}`) to
* the [`value`](#SnippetString.value) of this snippet string.
*
* @param value The value of this placeholder - either a string or a function
* with which a nested snippet can be created.
* @param number The number of this tabstop, defaults to an auto-incremet
* value starting at 1.
*/
appendPlaceholder(value: string | ((snippet: SnippetString) => any), number?: number): SnippetString;
}
export class CompletionItem {
//..
/**
* A string or snippet that should be inserted in a document when selecting
* this completion. When `falsy` the [label](#CompletionItem.label)
* is used.
*/
insertText: string | SnippetString;
/**
* A range of text that should be replaced by this completion item.
*
* Defaults to a range from the start of the [current word](#TextDocument.getWordRangeAtPosition) to the
* current position.
*
* *Note:* The range must be a [single line](#Range.isSingleLine) and it must
* [contain](#Range.contains) the position at which completion has been [requested](#CompletionItemProvider.provideCompletionItems).
*/
range: Range;
/**
* @deprecated **Deprecated** in favor of `CompletionItem.insertText` and `CompletionItem.range`.
*
* ~~An [edit](#TextEdit) which is applied to a document when selecting
* this completion. When an edit is provided the value of
* [insertText](#CompletionItem.insertText) is ignored.~~
*
* ~~The [range](#Range) of the edit must be single-line and on the same
* line completions were [requested](#CompletionItemProvider.provideCompletionItems) at.~~
*/
textEdit: TextEdit;
//...
}
Is this in the insiders build? cc @yantrio
On Wed, 16 Nov 2016 at 14:26, Johannes Rieken [email protected]
wrote:
There are the API changes that will enable this.
- insertText can now also be of type SnippetString
- range has been added to the completion item
- textEdit has been deprecated (but kept functional) in favour of the
former twoexport class SnippetString {
/** * The snippet string. */ value: string; constructor(value: string);}
export class CompletionItem {//..
/** * A string or snippet that should be inserted in a document when selecting * this completion. Whenfalsythe label * is used. */
insertText: string | SnippetString;/** * A range of text that should be replaced by this completion item. * * Defaults to a range from the start of the [current word](#TextDocument.getWordRangeAtPosition) to the * current position. * * *Note:* The range must be a [single line](#Range.isSingleLine) and it must * [contain](#Range.contains) the position at which completion has been [requested](#CompletionItemProvider.provideCompletionItems). */ range: Range; /** * @deprecated **Deprecated** in favor of `CompletionItem.insertText` and `CompletionItem.range`. * * ~~An [edit](#TextEdit) which is applied to a document when selecting * this completion. When an edit is provided the value of * [insertText](#CompletionItem.insertText) is ignored.~~ * * ~~The [range](#Range) of the edit must be single-line and on the same * line completions were [requested](#CompletionItemProvider.provideCompletionItems) at.~~ */ textEdit: TextEdit;//...
}โ
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/vscode/issues/3210#issuecomment-260959818,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGaplgeB40t-iksrrM462iLqXf-2ukZks5q-xKrgaJpZM4He7xA
.
@jchannon pushed '38 minutes ago'. It'll be tomorrow or the day after that
Good work!
On Wed, 16 Nov 2016 at 15:10, Johannes Rieken [email protected]
wrote:
@jchannon https://github.com/jchannon pushed '38 minutes ago'. It'll be
tomorrow or the day after thatโ
You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub
https://github.com/Microsoft/vscode/issues/3210#issuecomment-260969496,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGapozPOrEZrTFIni131QeWLC-t7Vkgks5q-xzcgaJpZM4He7xA
.
I seriously love you people.
Just having a look at this on insiders build. Is there any sample code on this new API can work?
@jchannon I think this is the Typescript one being updated?
https://github.com/Microsoft/vscode/commit/0abf2747489e3afd263479a55c53b323742dc8ed
Cheers. I just downloaded the insiders build but I can't seem to be able
to resolve SnippetString.
That typescript example is not quite what I want I believe. I would like
to be able to write a snippet to a file/open editor/doc and for the user to
then be able to press tab where I have placeholders $1 etc
On 19 November 2016 at 15:29, Danny Tuppeny [email protected]
wrote:
@jchannon https://github.com/jchannon I think this is the Typescript
one being updated?0abf274
https://github.com/Microsoft/vscode/commit/0abf2747489e3afd263479a55c53b323742dc8edโ
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/vscode/issues/3210#issuecomment-261720375,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGappY33xk1IiVmuj8tLyH_T9jYysDtks5q_xXmgaJpZM4He7xA
.
(Note: I haven't updated to this yet, so I might be talking gibberish!)
but I can't seem to be able to resolve SnippetString
Di you need to update the vscode engine version in packages.json and run npm install to get the latest definitions downloaded?
I would like to be able to write a snippet to a file/open editor/doc and for the user to then be able to press tab where I have placeholders $1 etc
I'm not really sure what's different from what this does and what you want. There was undocumented functionality that allowed completion providers to have placeholders that the user could tab between (we use in Dart Code to pre-fill arguments) which is why this is a fairly small change for those already using that. If you weren't previously using it then there's probably additional work to get your snippets in via a completion provider.
We are done with this. Please try out things and report feedback
@jchannon Re https://github.com/Microsoft/vscode/issues/3210#issuecomment-261720704 When programming against insiders you need the latest and greatest vscode.d.ts as described here. Were you looking for a way to insert a snippet straight into the editor without going through a completion provider? So, something like editor.insert(new SnippetString('foo$0bar'), somePos)?
Yeah.
I added 1.8.0 for engine version and its seemed to download the d.ts but
then i didnt get any intellisense after that
On 22 November 2016 at 10:01, Johannes Rieken [email protected]
wrote:
@jchannon https://github.com/jchannon Re #3210 (comment)
https://github.com/Microsoft/vscode/issues/3210#issuecomment-261720704
When programming against insiders you need the latest and greatest
vscode.d.ts as described here
https://github.com/Microsoft/vscode/issues/3210#issuecomment-261721277.
Were you looking for a way to insert a snippet straight into the editor
without going through a completion provider? So, something like editor.edit(snippet:
SnippetString, rangeOrPos: Range | Position)?โ
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/vscode/issues/3210#issuecomment-262197726,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGapirzy7r0fdwJo2vGM83sppMB6RfLks5rAr2MgaJpZM4He7xA
.
Yeah - you might update your project/extension to run with TypeScript 2.0. See: http://code.visualstudio.com/updates/v1_6#_extension-authoring
I have:
"engines": {
"vscode": "^1.8.0"
},
"devDependencies": {
"typescript": "^2.0.3",
"vscode": "^1.0.0",
"mocha": "^2.3.3",
"@types/node": "^6.0.40",
"@types/mocha": "^2.2.32"
},
But get no intellisense when typing vscode.
On 22 November 2016 at 12:44, Johannes Rieken [email protected]
wrote:
Yeah - you might update your project/extension to run with TypeScript 2.0.
See: http://code.visualstudio.com/updates/v1_6#_extension-authoringโ
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/vscode/issues/3210#issuecomment-262231392,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGapubSvzUDkcbJkXdDTFxmo3M7aAjIks5rAuOwgaJpZM4He7xA
.
i have it working, had to compile ts files for some reason then vscode
behaved however the editor.edit command you mention, the intellisense
doesnt seem to match up with passing a snippetstring to the edit function
On 23 November 2016 at 09:18, Jonathan Channon jonathan.[email protected]
wrote:
I have:
"engines": {
"vscode": "^1.8.0"
},"devDependencies": {
"typescript": "^2.0.3",
"vscode": "^1.0.0",
"mocha": "^2.3.3",
"@types/node": "^6.0.40",
"@types/mocha": "^2.2.32"
},But get no intellisense when typing vscode.
On 22 November 2016 at 12:44, Johannes Rieken [email protected]
wrote:Yeah - you might update your project/extension to run with TypeScript
2.0. See: http://code.visualstudio.com/updates/v1_6#_extension-authoringโ
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/vscode/issues/3210#issuecomment-262231392,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGapubSvzUDkcbJkXdDTFxmo3M7aAjIks5rAuOwgaJpZM4He7xA
.
Yeah, TextEditor.insert(snippet: SnippetString, posOrRange) was just to confirm I didn't implement what you want ;-) I'll create a separate issue for this and I might be able to squeeze it in during Nov
@jchannon https://github.com/Microsoft/vscode/issues/15952 fyi
๐ ๐ ๐
Hi guys,
great to have this feature allowing to use snippets from CompletionItems. However I can't make it work in my case.
I want the completion to insert something before the text being completed. I know I can do that using additionalTextEdits but I also want this part to be an editable snippet. The basic PoC code is as follows:
let range = new vsc.Range(position.translate(0, -1), position)
let item = new vsc.CompletionItem('var', vsc.CompletionItemKind.Snippet)
item.insertText = `var {{name}} = `
item.range = range
Unfortunately such completion item isn't even shown in the dropdown list. What I was able to figure is that it's related to the new range field.
If the range is set as new vsc.Range(position.translate(0, 0), position) then it works fine, completion is shown and text is inserted but at the end which is not what I'm trying to achieve.
When I move the start part of the range 1 character left it stops showing. Why is it like this?
I know this range must be on a single line and overlap the position where the completion was requested but this range fulfills these need.
Am I missing something?
VS Code version:
Version 1.10.2
Commit 8076a19fdcab7e1fc1707952d652f0bb6c6db331
Date 2017-03-08T14:02:52.799Z
Shell 1.4.6
Renderer 53.0.2785.143
Node 6.5.0
@ipatalas A few things: (1) var {{name}} isn't the supported snippet syntax but an old undocumented deprecated variant, (2) use SnippetString to tell us that you want a snippet and not a string with curlies and dollar.
Then about range et al: Suggestion are filtered and score against the current text left of the cursor. What text that is defines the range of a completion item. However the rule is that the completion must match that text. Sample: The cursor sits right of the foo and suggestions are replacing foo must all start with foo, like foobar. If that isn't possible one should use the filterText property completion items have or make an append edit, e.g. not replace foo
@jrieken thanks for a very quick answer
Regarding the snippet syntax, I know. I've been just trying them all with no success and this one I ended up with so I took this example somehow by accident.
Thanks for the note about filterText. I deeply misunderstood what it's for previously. Just checked it with some examples and it works just fine. Thanks a lot for your help!
Cheers,
Irek