microsoft / microsoft/language-server-protocol

Extend snippets to include optionals

Open
#1,189 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

completion feature-request
Dominant language
TypeScript
Stars
13k
Forks
1k
Avg merge
6d 1h
Merged PRs (30d)
10

Description

Would it be possible to extend the snippet syntax to support optional snippets.
I'm thinking a syntax for this could be of the form be ${ int ? any } or ${ int * any }.
As an example this is probably how an editor should treat these syntaxes:

  • The ? case would be for when its unlikely to be needed and the user should opt in.
    • Tabbing past it should remove the snippet.
    • Hitting return (or starting to type if there is a nested placeholder) should keep it.
  • The * case would be for when its expected to be needed and the user should opt out.
    • Tabbing past it should keep the snippet.
    • Hitting delete should remove the snippet.

These would be able to nest items inside them (like how placeholders work) enabling complex optional blocks that can be completely removed with one hit of a button, like in the examples below.
If this is a little too complex it may be better to just have the single ? syntax, the * syntax probably isn't as useful.

Some use cases of this would be:

  • Defaulted arguments
    • Say a function has the signature greet(Greeting, Audience="World"), a snippet could look like
      greet(${0:Greeting}${1?, ${2:"World"}})
      As can be seen here, the comma is part of the optional block, So the user doesn't want to specify an explicit argument, the comma will be removed as well, so no malformed code like greet("Bonjour", ).
  • Declaring a variable with a type that's not usually necessary, but an initializer which usually is important.
    • let ${0:Name} ${1? : ${2:Type}}${3* = {$4:Initializer}; Again The : and = are in the optional blocks so they would be removed along with Type and Initializer if the user didn't want them.
  • A snippet for an if that includes the else.
    • if (${0:Condition}) then ${1:Statement} ${2*else ${3:Statement} }endif
  • Modifier on some language construct
    • if ${0?constexpr }(${1:Condition}){${2:Statements}}

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the language-server protocol's existing snippet syntax and placeholder behavior; the issue names no files or tests. Define how nested optional blocks, tabbing, typing, return, and deletion interact, and establish an agreed syntax and specification before implementation.

Written by the indexing model from the issue text.

Assessment

Domain
api
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.