Здравейте

Използвал съм Visual studio и преди курса в Телерик и съм писал код и без да използвам snippet-и. От както ги открих обаче се влюбих в тях. На пръв поглед може да не е страшно впечатляващо да спестиш няколко знака с cw+tab+tab, но тъй като езика е key sensitive и неща като for цикъл или Console.WriteLine() се използват постоянно, реално snippet-ите спестяват доста време и досадно преписване на един и същ код хиляди пъти. Понеже забелязах, че въпреки предложените snippet-и доста код се повтаря често. Тъй като съм голям мързел и не обичам да пиша едно и също нещо отново и отново, реших да разуча как да създам свои. Сигурен съм, че има такива от вас, които споделят мързела ми, така че реших да споделя как и какво открих и какво успях да сътворя сам. Надявам се да ви  е полезно.            

Добавяне на snippet

Ще започна с добавянето на вече готов snippet към вашето Visual studio. Това всъщност е доста елементарно, но все пак реших да подготвя няколко screenshot-а за улеснение.

Първо в менюто, под Tools трябва да изберете. Code snippets manager. Може да използвате и бързата клавишна комбинация Ctrl+K, Ctrl+B.

Menu Tools Tutorial

В Code snippets manager-а трябва да изберете подходящият език. В случая CSharp. Из папките може да разгледате предложените snippet-и. Цъкайки на snippet ще видите по детайлна информация за него в дясно. Повечето от snippet-ите които използваме са в папка Visual C#. За удобство вече е създадена папката MySnippets, където въпреки че не е задължително е препоръчително да запазвате вашите snippet-и. Забележете и пътя в Location. Така може да намерите къде Visual studio съхранява snippet-ите и да ги отворите за да ги анализирате.  И накрая с бутона Import може да добавите готов snippet към Visual studio.

Snippets Manager Tutorial

След като изберете snippet трябва да изберете и папката в която той ще се запази и да цъкнете finish. Така snippet-ът ви вече е актуален и може да го използвате чрез зададеният му shortcut.

Finnish Importing Tutorial

Създаване на snippet

След кратко проучване, установих че snippet-ите се пишат на XML. Проблема е, че не разбирам от XML и няма да мога да ви дам ясно упътване как да направите собствен snippet от нулата. Езика обаче се оказа доста user friendly и лесен за разчитане, така че чрез анализиране на вече готови snippet-и и малка промяна в кода им лесно успях да направя няколко по-елементарни свои. Snippet-ите могат да бъдат отваряни с Notepad, Notepad++ и предполагам с всякакъв текстови редактор. Също така може да направите и snippet от нулата като създадете нов текстови документ, който по-късно запаметите с  разширението .snippet.

Сега нека анализираме кода на два популярни snippet-а – cw за Console.WriteLine(); и for за for цикъл. Ще се опитам да ви обясня какво забелязах и разбрах от кода им с надеждата да успеете да създадете собствен с информацията.

CW Snippet

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
   <Header>
      <Title>cw</Title>
      <Shortcut>cw</Shortcut>
      <Description>Code snippet for Console.WriteLine</Description>
     
<Author>Microsoft Corporation</Author>
      <SnippetTypes>
         <SnippetType>Expansion</SnippetType>
       </SnippetTypes>
    </Header>
    <Snippet>
       <Declarations>
          <Literal Editable="false">
            <ID>SystemConsole</ID>
             <Function>SimpleTypeName(global::System.Console)</Function>
          </Literal>
       </Declarations>
       <Code Language="csharp"><![CDATA[$SystemConsole$.WriteLine($end$);]]>
       </Code>
   </Snippet>
</CodeSnippet>
</CodeSnippets>

Първото нещо което се вижда е Title, където очевидно е заглавието. Shortcut е начина по който извиквате snippet-а. В случая Shortcut е cw и snippet-а се извиква с cw+tab+tab. Description е мястото в което се дава описание, което в последствие се показва когато snippet-а е посочен. Под автор може да се изфукате и да напишете собственото си име. Под Snippet types явно се описват типовете на snippet-а, но така и не разбрах дали това играе някаква специална роля освен да дава по-ясно описание на потребителя. Всичко това е оградено с Header и веднага правя аналогия с HTML. Най-вероятно това са мета данните или с други думи описанието за snippet-а. Следващата секция е Snippet, което най-вероятно е еквивалентно на body в HTML документ. Под Declarations виждам, че се декларират литерали, които да използваме в кода, подобно на C#, въпреки че декларацията е доста различна. ID разбира се е името на литерала, а Function е  функция която да му присвоява подходяща стойност в зависимост от ситуацията. Не разбирам много синтаксиса, но по начина по който се държи cw snippet-а съдя че тази функция казва следното на литерала: замествай със System.Console. Ако има using System; замествай само с Console. Literal Editable=”false” премахва опцията след като използваме snippet-а да можем да се прехвърлим на литерала веднага с Tab. В snippet-а за for цикъл се вижда по-ясно какво имам предвид. В Code тага явно е същинският код. Отново не разбирам синтаксиса, така че преписвам. Забелязвам, че кода се намира в скобите на <![CDATA[  ]]> и че вътре създаденият литерал е използван като е заграден с “$”. Там има и непознат литерал endОтново по поведението на snippet-а предполагам, че това е default-ен литерал, който служи за да указва мястото на което ще бъде курсора след използването на snippet-а.
След съвсем малко промяна в този код направих
snippet-a cr - Console ReadLine.

for Snippet

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
   <Header>
    <Title>for</Title>
    <Shortcut>for</Shortcut>
    <Description>Code snippet for 'for' loop</Description>
    <Author>Microsoft Corporation</Author>
    <SnippetTypes>
       <SnippetType>Expansion</SnippetType>
        <SnippetType>SurroundsWith</SnippetType>
    </SnippetTypes>
    </Header>
    <Snippet>
       <Declarations>
          <Literal>
             <ID>index</ID>
             <Default>i</Default>
             <ToolTip>Index</ToolTip>
          </Literal>
          <Literal>
             <ID>max</ID>
             <Default>length</Default>
             <ToolTip>Max length</ToolTip>
         </Literal>
      </Declarations>
      <Code Language="csharp"><![CDATA[for (int $index$ = 0; $index$ < $max$; $index$++)
      {
      $selected$ $end$
      }]]>
      </Code>
   </Snippet>
</CodeSnippet>
</CodeSnippets>

Тук виждаме почти същият код с малко разлики. В Snippet types е зададен втори тип. Все още нямам представа дали това дава някаква функционалност или играе роля само на описание. В Declarations се вижда че могат да бъдат декларирани няколко литерала. Default е стойността която ще бъде изписана в кода, а ToolTip е подсказка която ще бъде показана ако литерала бъде посочен. В Code първо забелязвам, че не е проблем кода да е на повече от един ред. След малко тестване обаче също така разбрах, че всеки ред, празно място или табулация директно се пренасят в кода ви във Visual studio. Друго което забелязвам е че литерала index е използван три пъти. Ако сте ползвали for snippet-а сигурно сте забелязали, как ако промените i-то което е default-ната стойност на брояча то се променя на всичките три места. Е това явно е защото е един и същ литерал. Също така веднага след използването на for+tab+tab с tab може да се прехвърляте между i-тата и length. Това е защото тук на литералите не им е зададено Literal Editable=”false”. В скобите виждаме познатият ни end, но и непознатият selected литерал. Най-вероятно и той е default-ен, който изпълнява някаква функция, но така и не разбрах точно какво прави.

Надявам се да съм ви дал достатъчно информация за да може да направите нещо, което ще е полезно и на вас. Имайте предвид, че snippet-ите се пазят локално след като ги добавите към вашето Visual studio, така че ако искате да ги ползвате на друг компютър ще се наложи да ги влачите на flash-ка или да ги качите в GitHub например.

Моите snippet

 Хранилище с моите snippet-и 
Ето и простичките
snippet-и, които скалъпих. Не са нищо особено, но свикнах с тях и ми вършат доста работа. Ако ви харесат използвайте ги. Ако имате идеи за тяхната редакция, ще се радвам на pull request.

- cr snippet – Console ReadLine 
Описание: Винаги съм се чудел защо има cw, но няма cr snippet. Е ето го. Върши ми доста работа като спестява досадното изписване на Console.ReadLine(); за всяка нова задача от домашното.
Shortcut: cr+tab+tab
Код: Console.ReadLine();

- crp snippet – Parse Console ReadLine
Описание: След като си добавих cr snippet-а усетих, че все още остава досадно писане около четенето от конзолата. Тъй като Console ReadLine връща винаги String винаги Parse-ваме резултата. Този snippet идва направо с parse-ването. Направих го да не parse-ва специфичен тип ами само да дописва. int input = int crp става лесно на int intput = int.Parse(Console.ReadLine());
Shortcut: crp+tab (Не знам защо работи само с един tab, но е така)
Код: .
Parse(Console.ReadLine());

- cwr – Console Write
Описание: Имаме Console WriteLine, но понякога се налага да използваме Console Write за да не добавяме нов ред. Не е върха на технологията, но понякога спестява малко код.
Shortcut: cwr+tab+tab
Код: Console.Write();

- test snippet – Loops the main method
Описание: Няколко реда код, които просто въртят main метода. Използвам го за тестване на задачи за да си спестя пускането на програмата отново и отново. За да работи обаче трябва да го поставите в самият край на main метода и да махнете string[] args. Имайте предвид, че това помага за тестване, но на практика прави безкраен цикъл и за да спрете програмата ще се наложи да затворите конзолата ръчно с X. Също така в BG Coder се очаква да имате един вход и един изход. За да работят коректно задачите ви махнете кода генериран от snippet-а преди да качите кода си в BG Coder.
Shortcut: test+tab+tab
Код:
Console.WriteLine(“Press enter to start over.”);
Console.ReadLine();
Console.Clear();
Main();

Извинявам се за огромния пост. Имам навика много да прекалявам, когато започна да пиша нещо. Благодаря на всички, които са успели да стигнат до края и се надявам, че съм успял да помогна и да ви спестя работа. Предложете и своите варианти за snippet-и.