In the previous blog post, I demonstrated how to use several code snippets in Visual Studio. I also mentioned that there is a problem – here I’m going to look at it more closely.
Let me introduce yet another snippet, just to make it a little bit more interesting.
propfull is modeled on a snippet of the same in C#, where it creates a property with a backing field (member variable). Because X++ doesn’t have properties, it creates an accessor method instead.
This is the expected behaviour, when you can replace the data type (int by default), the variable name (myVar) and the method name (MyProperty).
But it doesn’t always work. In some cases, you get only static code and you would have to replace all values by hand (three occurrences of the type, three of the variable name, one method name).
This is clearly wrong and renders the snippet much less valuable.
The obvious question is why it works in some cases and it doesn’t in other situations. It took me a while to spot it, nevertheless it seems that I’ve finally found the cause.
The snippet works (you get the option to replace placeholders) if the editor doesn’t try to indent it.
Here are a several examples of what I mean.
I insert propfull snippet at the beginning of the line.
What I get is nicely indented code, but it’s static, without the option to replace literals.
Now I do same, but I do it with the cursor indented with four spaces.
Voilà, now literals work.
I believe it’s because the starting point was already indented.
Just to prove the point, let’s try indention with eight spaces.
As expected, code is indented but static.
The snippet also works if I use it in an invalid context.
The following code doesn’t even compile, but replacements work as expected.
I think that the editor doesn’t bother to indent code, because it has no idea how to deal with code that doesn’t make sense.
Speaking of invalid contexts, let’s try to put a for loop directly inside a class declaration.
It might look like that editor actually did some indentation, but it’s not the case. It merely copied the definition of the snippet, which in this case includes some spaces.
If we insert the snippet at the right place including indentation, it works.
As expected, using the snippet with different indentation results in indented code without replacements.
I mentioned that the editor doesn’t indent invalid code. If I do exactly the same as in the previous example, but my definition of For snippet has an error, the result is different.
The code doesn’t compile because of the extra hash character (#). Unlike in Example 7, not it’s not indented correctly but replacement works.
I hope this sufficiently explains when replacements in snippets work and when they don’t. In short, I believe that what’s responsible is the feature indenting code in the editor. I didn’t discuss in detail when exactly code indentation kicks in – it’s a bit a more complex than demonstrated above and I don’t know exact rules, but I think this is good enough to give you an idea.
It should help Microsoft to reproduce and fix the problem and I hope it will happen soon, because this issue makes snippets confusing and less useful. Code snippets are extremely helpful and every developer should use them and become more productive. Having such an issue doesn’t help the adoption.
This explanation should also help you to use snippets even before the problem is fixed. Without understanding why it works only in some cases, using snippets can be frustrating. It should be a bit easier with this knowledge.