-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Semantic Snippets #56541
Comments
Notes from Design Review:
Proposal: Update current snippet provider to show description text in completion list. Validate the idea by porting the most used snippets. |
One thing that I don't think we can break is the presence of snippets in the completion list. Typing Also another important aspect of the experience is TAB TAB (snippet insertion) can create several fields and linked fields (represented as tags in text) that you can tab through, edit and finally commit using Enter. VB snippets work differently. Also note that some snippets have special sauce, e.g. Two invocation shortcuts are also important: Ctrl+K,X (Insert Snippet) and Ctrl+K,S (Surround With). Surround With is heavily used, Insert Snippet perhaps not as much. From the implementation perspective, I think if you get your prototype working in VS Windows, it should be relatively straightforward to make it work in VSMac as well. I anticipate no significant hurdles there. So I'd say when a preview of the working functionality is ready, we can take another look and try to make it work in VSMac as well. |
@mikadumont the merged spec can be found here: https://github.com/dotnet/roslyn/blob/feature/semantic-snippets/docs/ide/specs/semantic_snippets.md |
related to #5574 |
ConsoleStream only has sync write. In other words, I don't think Async makes sense. |
Console.Out creates |
Feel free to give the runtime feedback if you feel that WriteLineAsync will have problems on console streams. In the worst case, you will have an impl that is as bad as WriteLine would be. In hte best case, you have an impl that is a good async citizen. The snippets encode best practices for async code to ensure that you're doing the right hting, and you can benefit from any improvements the runtime makes now and in the future. Emitting WriteLine would make that not possible. |
Will there ever be a truly asynchronous implementation of ConsoleOut? If not, we should revise the snippet after such an implementation is established. As it stands, we're implementing a snippet that performs worse than WriteLine and is less user-friendly. However, if we're concerned about performance, we should avoid writing to the console every time in the first place. |
I’m more worried about breaking people’s muscle memory. Why not add ‘cwa’ for the Async version and keep ‘cw’ the classic version. Anecdotally, 100% of usages I’m seeing is console apps that are sync, as well as small throwaway Program.cs programs and tools. I’ve never seen Console.WriteLine in an async context. |
I don't see any reason why not. Esp. as many OS' are happy to provide async io.
The very intentional idea here was that you just use one snippet and you get the best emit per context. It's not on you to remember which to use and when, the system figures it out for you. |
If you have a sync app, then we'll emit C.WL. We only emit WLA if it's an async context. :-) |
Why would it perform worse than WL? |
I see no relation between those ideas. You can want to write to the console and still not block a thread. Perf and async IO go hand in hand. |
Sync over Async is a BAD PRACTICE for async, right? |
Note that using ConsoleWrite for StandardOut is slow, so I have created my own library to handle this. |
I understand that it is generally preferred to use async methods within async contexts, and I think that the ability to switch snippets according to the context is great. However, when it comes to Above all, For example, if I write a simple console tool with top-level statements and have a line like I think it would be best to keep them separate as |
If |
Console.Out is always a synchronized text writer ( |
VS 17.8.0 Preview 2.0 is still |
Unclear what is left here @akhera99 . Can yuo please update or close this out? |
Unclear what is left here @akhera99 . Can yuo please update or close this out? |
Closing since the working list of snippets is being updated here: #64144 |
Snippets as they exist today for .NET developers only do text expansion (cw -> Console.WriteLine) and have lacked any significant improvements in the last 10+ years. We would like to iterate on this experience for .NET developers using Visual Studio. Snippets based on the rich analysis capabilities of the roslyn api that can change based on context.
Proposal
cw
->Console.WriteLine();
will workAdvantages
The CompletionProvider api has lots of advanced capabilities that allow us to be semantically aware of what is around the snippet. I've been playing around with what the API is capable of and there are a lot of possibilities.
Open Implementation Questions
Open Design Questions
Appendix
C# Snippet Behavior in Visual Studio
List of all snippets C# included in Visual Studio
Here is a list of all 39 "Expansion" snippets we ship for C# today. These appear in the completion list as their snippet text entry.#if
#region
attribute
checked
class
ctor
cw
do
else
enum
equals
Equals(object obj)
and `GetHashCode() methods (27 lines)exception
for
foreach
forr
if
indexer
interface
iterindex
iterator
IEnumerator<ElementType> GetEnumerator()
methodlock
mbox
System.Windows.Forms.MessageBox.Show("Test");
)namespace
prop
public int MyProperty { get; set; }
propfull
propg
sim
struct
svm
switch
testc
testm
try
tryf
unchecked
unsafe
using
while
~
Here is a list of all 21 "Surrounds With" snippets we ship for C# today. These require the user to select text and press te "Surround With" cord (Ctrl+K+S) and are never shown in the completion list.
#if
#region
checked
class
do
else
enum
for
foreach
forr
if
interface
lock
namespace
struct
try
tryf
unchecked
unsafe
using
while
Visual Basic Snippet Behavior in Visual Studio
The VB snippet design is different they ship about 100 snippets that offer a more expansive set of capabilities however, they do not show them in the completion list and it is not expected that the user types out text such as
cw
orprop
and gets the text expanded. Instead the user is expected to invoke the snippet menu (Ctrl+K+X).Visual Studio Snippet Capabilities
Some relevant details pulled from docs
See the snipper schema docs here for more information.
There are two kinds of snippets that exist today in Visual Studio
These VS snippets are allowed to have the following pre-defined variables
$selected$
is a predefined variable. It represents the text that was selected in the editor before invoking the snippet. The placement of this variable determines where the selected text appears in the code snippet that surrounds that selection.$end$
is a predefined variable. When the user presses Enter to finish editing the code snippet fields, this variable determines where the caret (^) is moved to.You can also define your own variables in the VS snippet engine and give them a default text but allow the user to tab to them and edit them on snippet insertion.
Each snippets can also have an Assembly element indicating that an
<AssemblyReference>
should be added to the project file if not present and an Import element that adds usings to the top of the file if not present.VS Code Snippet Capabilities
Some relevant details pulled from docs
For more information see the docs here
VS Code's snippet system is similar to Visual Studio's in that it has a "trigger phrase" (such as
for
) that it uses as the decider for when to begin expansion, however its text transformation capabilities are a more dynamic as it allows regular expressions to be run over the output of a snippet.The EBNF form of the regex syntax is defined as follows:
They have the following predefined variables:
TM_SELECTED_TEXT
The currently selected text or the empty stringTM_CURRENT_LINE
The contents of the current lineTM_CURRENT_WORD
The contents of the word under cursor or the empty stringTM_LINE_INDEX
The zero-index based line numberTM_LINE_NUMBER
The one-index based line numberTM_FILENAME The
filename of the current documentTM_FILENAME_BASE
The filename of the current document without its extensionsTM_DIRECTORY
The directory of the current documentTM_FILEPATH
The full file path of the current documentRELATIVE_FILEPATH
The relative (to the opened workspace or folder) file path of the current documentCLIPBOARD
The contents of your clipboardWORKSPACE_NAME
The name of the opened workspace or folderWORKSPACE_FOLDER
The path of the opened workspace or folde${TM_FILENAME/[\\.]/_/}
${TM_FILENAME/[\\.-]/_/g}
${TM_FILENAME/(.*)/${1:/upcase}/}
${TM_FILENAME/[^0-9^a-z]//gi}
User Experiences
1.1 Snippet Discovery
A user starts typing
new
so they can start writing a new constructor. They are unaware of the built-in snippets Visual Studio provides but start typing the code for what they are trying to accomplish:We will show the snippet for a constructer as soon as the type
new
as it is on our list of synonyms for that snippet:If the user commits the snippet, it is persisted to the buffer as the “ghost text” preview had shown:
If the user dismisses the completion list then the editor is placed back as it was with
new
being left alone:1.2 Using an Existing Snippet
A user types
ctor
(the text expansion for an existing snippet into the editor):When completion comes up, we will do custom filtering to: A. Select the
new constructor
completion item even though none of the text they’ve entered matches the text in this item. B. Use theghost text
API to show the user what will happen if they commit the completion item.If the user commits the snippet, it is persisted to the buffer as the
ghost text
preview had shown:If the user dismissed the completion list then the editor is placed back as it was with
ctor
being left alone:1.3 Semantic Awareness
Today the editor shows and commits snippets even if they do not make sense. Here the developer is being suggested the “for” snippet even though it can never be valid inside of a type:
In the new experience snippets will be aware of the context they are appearing in and only show if
they are reasonable. Notice we will now suggest
FormattableString
as a completion item assuming theuser is writing out a new property or field in this type:
However if the user is in a situation where this snippet makes sense we will: A. Filter to it in the completion list based on hard-coded synonyms. B. Show a
ghost text
preview of what the committed code will look like. C. Populate the snippet based on the semantic context in which it appears (notice howpoints.Length
is automatically used in the snippet).If the user commits the snippet, we will use the existing snippet expansion experience that Visual Studio offers today to allow the user to fill in the
placeholders
that are automatically generated for them:If the user dismisses completion, they are left with the same contents in their buffer as they had before:
Tracking Issues
foreach
autocompletion should be offered when ctrl+. is pressed on a variable representing a collection #60628The text was updated successfully, but these errors were encountered: