Adapting ZenCoding to C # - ZenSharp
Many probably know that for HTML & CSS there is a great tool ZenCoding (emmet), which allows you to greatly simplify the input of routine language constructs by defining a special mnemonic language. C # is a less verbose language than Html, but, nevertheless, the input of its constructions can be greatly optimized.
I propose a dynamic expansion of the idea of mnemonics, which I first heard from Dmitry Nesteruk [ 1 ].


The result was a small plug-in for ReSharper, mnemonics for which can be configured through a special language similar to formal grammar.
The plugin for ReSharper is available in the extension gallery. GitHub source code
The main idea that is embedded in ZenSharp is to create a language in which you can immediately define two languages - the abbreviation language and the corresponding full spelling.
The entire abbrev definition file (* .ltg) consists of two parts:
A simple example of a rule definition: if we want the text to be expanded into an expand text by a set of ex , then the start rule must be defined as follows:
I call such rules “defining abbreviations.”
There are three types of rules in total:
There is some sugar in the template description language:
It’s easier to explain why all this is needed with a real example. Take a small
part of the standard rules:
Suppose we introduced some abcadabra of the form pсSome in the studio. Understanding how this rule will be disclosed is necessary, starting from the start rule start. This rule defines two alternatives - class or interface. The grammar works on the principle of PEG (parsing expression grammar), i.e. operator | is an ordered selection operator.
The alternative to the class is checked. Inside the class, access is successfully expanded and takes the first letter p, revealing in its extended spelling “public”. Next comes the lazy part of "sealed" = s. Our abracadabra has the cSome part left, and it does not fit this part, so we skip it, we don’t remove anything from
abbreviations and do not add anything to the disclosure. The following is an alternative from class or static class. The class is suitable for us, so we have the expansion of “public class” and the short string Some.
The special identifier rule takes all alphabetic characters from the abbreviation and without any changes transfers them to a long spelling (this is done for convenience).
As a result, our pcSome abracadabra turned into a public class Some {$ END $}.
I repeat that the plugin for ReSharper 8.2 is available in the gallery.
Source Code at github.com/ulex/ZenSharp
This is the first of two upcoming articles. I tried to describe the insides of the work of ZenSharp. In the second article I will talk a little more about standard templates. I myself use ZenSharp for work no more than a month, from time to time adding convenient rules. I will be glad to feedback.
I propose a dynamic expansion of the idea of mnemonics, which I first heard from Dmitry Nesteruk [ 1 ].


The result was a small plug-in for ReSharper, mnemonics for which can be configured through a special language similar to formal grammar.
The plugin for ReSharper is available in the extension gallery. GitHub source code
Small description
The main idea that is embedded in ZenSharp is to create a language in which you can immediately define two languages - the abbreviation language and the corresponding full spelling.
The entire abbrev definition file (* .ltg) consists of two parts:
- definitions of rules (i.e. what and how what is revealed),
- determining the scope of these rules.
A simple example of a rule definition: if we want the text to be expanded into an expand text by a set of ex , then the start rule must be defined as follows:
start ::= "expand text"="ex"
I call such rules “defining abbreviations.”
There are three types of rules in total:
- Defining abbreviation. It consists of a pair of rows, defined as "expand" = "short" Ie if you want to get an abbreviation so that by entering p you get public, then such a rule is declared as "public" = "p"
- String Just a string that will always be used when expanding the reduction rule. In other words, just a text that does not depend on which letter we use when abbreviation. A string rule is the same as a shorthand definition rule with an empty shrink string.
- Wildcard. A special type that is introduced specifically to support the ability to enter a variable / function name in the abbreviation language. You can use two rules written by default for the type and name of the variable.
Syntactic sugar
There is some sugar in the template description language:
- brackets
- the question mark after brackets rewrite the rule to (x)? => ((x) | "")
- if the abbreviation does not contain special characters, then it can be defined
without quotation marks, that is, "some" = s, not "some" = "s" - multi-line definition of alternatives. This is done to conveniently record the start rule so as not to create garbage in VCS.
start :: = rulea | ruleb
is the same asstart ::= | rulea | ruleb
Explanation of examples
It’s easier to explain why all this is needed with a real example. Take a small
part of the standard rules:
interface ::= access "interface"=i space classBody
class ::= access ("sealed "=s)? ("class"=c | "static class"=C) space classBody
access ::= (internal=i | public=p | private=_ | protected=P) space
classBody ::= identifier "{" cursor "}"
scope "InCSharpTypeAndNamespace" {
start ::= class | interface
}
Suppose we introduced some abcadabra of the form pсSome in the studio. Understanding how this rule will be disclosed is necessary, starting from the start rule start. This rule defines two alternatives - class or interface. The grammar works on the principle of PEG (parsing expression grammar), i.e. operator | is an ordered selection operator.
The alternative to the class is checked. Inside the class, access is successfully expanded and takes the first letter p, revealing in its extended spelling “public”. Next comes the lazy part of "sealed" = s. Our abracadabra has the cSome part left, and it does not fit this part, so we skip it, we don’t remove anything from
abbreviations and do not add anything to the disclosure. The following is an alternative from class or static class. The class is suitable for us, so we have the expansion of “public class” and the short string Some.
The special identifier rule takes all alphabetic characters from the abbreviation and without any changes transfers them to a long spelling (this is done for convenience).
As a result, our pcSome abracadabra turned into a public class Some {$ END $}.
I repeat that the plugin for ReSharper 8.2 is available in the gallery.
Source Code at github.com/ulex/ZenSharp
This is the first of two upcoming articles. I tried to describe the insides of the work of ZenSharp. In the second article I will talk a little more about standard templates. I myself use ZenSharp for work no more than a month, from time to time adding convenient rules. I will be glad to feedback.