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 ].

    proto

    sample

    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 as
      start ::=
        | 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.

    Also popular now: