Visual Studio-kodestykker - den endelige VS-kodestykkeguide til begyndere

Stykker kan tilføje et strejf af magi til din editor. Det er som en besværgelse. Udtal en kort sætning (skriv et præfiks), vink din tryllestav (tryk på Entereller Tab) og presto! En vidunderlig begivenhed udfolder sig foran dig. ✨

De fleste kodeditorer understøtter uddrag ud af kassen. Kodeditoren, jeg vil bruge til at fremvise uddrag, er Visual Studio Code (VS Code), den mest populære redaktør af dagen.

Der er også nogle "tekstudvidelsesapps", der giver dig mulighed for at bruge uddrag globalt (på tværs af alle apps). Jeg vil kort dække, hvordan du kan bruge disse apps til at få endnu mere ud af uddrag.

Lad os dykke ned i alle uddrag. ?

Definition

Et uddrag er en skabelon, der kan indsættes i et dokument. Det indsættes ved en kommando eller gennem en udløsertekst.

Med uddrag kan du oprette en kedelpladefil og indsætte almindeligt anvendte tekstblokke. Den generelle idé er at gemme dig ved at skrive de samme ting ud igen og igen og igen. ?

Hvorfor skal du bruge uddrag?

Jeg vil ikke chokere dig med denne erklæring: Internettet er hjemsted for mange modstridende meninger! Stykker undgår ikke denne skændsel, men jeg tror ikke, det er et emne, der får folks blodtryk til at stige!

Af hensyn til balance vil jeg præsentere et tværsnit af disse meninger her.

Du behøver ikke vælge en lejr og være all-for eller alt-imod uddrag. Jeg foreslår, at du adopterer dem i en grad, der tjener dig bedst.

Yay Camp?

  • Stykker kan øge din produktivitet, spare dig for tastetryk og reducere inputfejl.
  • Snippets giver mig mere mental CPU og nydelse at bruge på at skrive den kode, som jeg holder af og vil fokusere på.
  • Stykker kan hjælpe dig med at huske at inkludere noget vigtigt!
  • Integrering af uddrag i din arbejdsgang tilskynder dig implicit til at bruge musen sjældnere. Velskrevne uddrag tilbyder en logisk sti, som du kan gå igennem, stopper for at redigere undervejs for at udfylde skabelonen nøjagtigt som du vil, og når du er færdig, ankommer du på den anden side klar til at skrive din næste linje

Nej Camp?

  • Jeg afstår fra at bruge dem, for det meste fordi jeg ikke kan lide at være afhængig af et givet værktøj.
  • Jeg bruger aldrig uddrag. Jeg foretrækker at bruge tid på at undgå gentagelser i stedet for at gøre det lettere.
  • Jeg fandt ud af, at jeg på et tidspunkt glemte, hvordan jeg skulle skrive koden uden at bruge kodestykket. For trivielle ting, som jeg forstår, er det OK, men jeg vil ikke glemme nogle andre ting!
  • De fleste, hvis ikke alle, uddrag, jeg har set online, for kode, jeg leder efter, har fejl i dem. Jeg har ikke en gang været i stand til at finde en numerisk algoritme, der ikke havde flydende punktfejl i den. Jeg kan ikke forestille mig, at der er nogen ressource med helt rene kodestykker.

Hvornår skal du bruge uddrag?

Donald Knuth, en af ​​de store troldmænd inden for datalogi, sagde "for tidlig optimering [af kode] er roden til alt ondt".

Jeg synes, det er også relevant for uddrag. Stykker er en optimering af kodeproduktion. Hvis du ikke kender et sprog eller en ramme særlig godt, er det sandsynligvis et for tidligt skridt at implementere en række uddrag til dette sprog eller en ramme.

Hvis du har det godt, så prøv noget!

Hvad jeg bruger uddrag til

Personligt bruger jeg uddrag ofte men med omtanke. Jeg bruger et sæt uddrag til Markdown og de fleste af de sprog, jeg arbejder med.

Jeg har ikke brugt uddrag meget til rammer. Jeg begyndte at bruge nogle uddrag til Vue for nylig, men jeg bruger kun kedelpladestykket. Jeg vil sandsynligvis vedtage flere af dem, når min Vue IQ er steget.

Jeg har ikke brugt uddrag til algoritmer.

Typer af uddrag

Stykker kan klassificeres i henhold til omfanget af interaktivitet mellem uddraget og redaktøren.

Statiske uddrag

Du kan tænke på det som en kopi og indsæt en eller anden kildetekst som en enkelt kommando.

Dynamiske uddrag

Et dynamisk uddrag kan tilpasses, så det giver en guide-lignende oplevelse til færdiggørelse af et uddrag.

Det kan omfatte:

  • Tab Stops : Du kan nummerere stop, der kan fanes igennem i rækkefølge,
  • Mirrored Tab Stops : Der er tidspunkter, hvor du skal angive den samme værdi flere steder i den indsatte tekst. Du kan spejle et tabulatorstop for at opnå dette, og enhver redigering vil blive afspejlet i de relaterede tabulatorstop med det samme.
  • Pladsholdere : Det er et tabulatorstop med en standardværdi, der kan overskrives på fokus.
  • Valg : Ved et fanestop præsenteres en rulleliste over værdier at vælge imellem.
  • Variabler : Indtast værdier fra miljøet, såsom: den valgte tekst i editoren, systemdatoer eller indhold fra udklipsholderen.

Her er et eksempel på et markdown-uddrag, der tilføjer en opgaveliste med 2 opgaver. Det bruger fanestop , pladsholdere og valg til kontrol af en opgave.

opgave

Makrouddrag

Det øverste niveau af trolddom er at have evnen til at transformere input. Transformationer giver dig mulighed for at ændre værdien af ​​en variabel, før de indsættes, eller ændre en pladsholder, efter at du har foretaget en redigering.

For eksempel vil du muligvis bruge store bogstaver i et klassenavn, når det er indtastet.

Alt hvad du kan tænke dig at gøre med en regex er typisk mulig. Nogle redaktører tilbyder mere avancerede scripting-muligheder.

Stykker i Visual Studio-kode

In VS Code, snippets appear in IntelliSense (Ctrl+Space gives you a suggestion list), they are mixed in with other suggestions.

You can also access them in a dedicated snippet picker by using the 'Insert Snippet' command. This combines all user, extension, and built-in snippets for that language into a single list.

indsæt-uddrag-liste

Emmet is integrated into VS Code and has it's own CSS-selector inspired syntax for inserting HTML and CSS snippets.

Emmet is it's own thing really, but the mechanics are the same. You can learn about Emmet with the Emmet in Visual Studio Code guide.

Related User Settings

Snippets will appear as quick suggestions if the setting editor.quickSuggestions is set to true for the language you are working in. Quick suggestions are enabled by default for most languages except markdown.

hurtige forslag-js

Snippets support tab-completion. You can type a snippet prefix (the trigger text), and press Tab to insert a snippet. You can enable it with the setting editor.tabCompletion.

The values are:

  • on: Tab completion is enabled for all sources.
  • off: Disable tab completions. This is the default value.
  • onlySnippets: Tab completion only for snippets.
"editor.tabCompletion": "onlySnippets", 

If you would like to control how snippets suggestions are shown, you can edit the setting editor.snippetSuggestions.

The values are:

  • top: Show snippet suggestions on top of other suggestions. I use this value.
  • bottom: Show snippet suggestions below other suggestions.
  • inline: Show snippets suggestions with other suggestions. This is the default value.
  • none: Do not show snippet suggestions.
"editor.snippetSuggestions": "top", 

These are the most important settings for snippets, but there are a few more. You can check out this list of the default settings to explore more, or do a search in the Settings UI.

Are there built-in snippets?

Yes!

They aren't documented in the VS Code docs, though. And inside VS Code, there is no central point to browse them. So, you may not know what they are.

So, how can you find out what languages have built-in snippets?

Long story short, I was frustrated by this scenario, so I wrote an extension called Snippets Ranger to give a nice UI to explore snippets easily. Think of it as a Marauder's Map for snippets!

uddrag-ranger

But I want to find the snippets for myself?

You can, it just requires a bit more effort.

As I mentioned earlier, the 'Insert Snippet' command will show you all snippets for the language of the active document.

Remember though, this is an aggregate of all of the user, extension, and built-in snippets. So, if you want to find out if a particular language has built-in snippets, you need to open a file for that language, and run the command to see that list.

If you have an snippets extension installed for that language that makes it too hard to identify which is which, you could disable it to ensure that only the built-in snippets are showing. ?

If you want to track down the source file yourself, the built-in snippets live inside each individual language extension directory. The file is located at «app root»\resources\app\extensions\«language»\snippets\«language».code-snippets on Windows. The location is similar for Mac and Linux.

Snippets Extensions

The Visual Studio Marketplace has a snippets category where you can find snippets for almost anything.

A lot of Programming Language Pack extensions include snippets also (Python, C#, Go, Java, and C/C++ amongst others).

How do I write my own?

Snippets files are written in JSON. You can also add C-style comments if you wish (technically it is Microsoft's "JSONC" format).

You can create snippets for different scopes: global, workspace, and for a particular language.

To create the snippets file, run the 'Preferences: Configure User Snippets' command, which opens a quickpick dialog as below. Your selection will open a file for editing.

brugeruddrag

If you would prefer to write a snippet in a GUI, you can use the snippet generator web app.

uddrag generator

Let's look at an example to get familiar with the syntax.

Example

Here is a markdown snippet that comes with VS Code.

{ "Insert heading level 1": { "prefix": "heading1", "body": ["# ${1:${TM_SELECTED_TEXT}}$0"], "description" : "Insert heading level 1" } } 

This snippet inserts a level 1 heading which wraps the markdown around the current selection (if there is one).

A snippet has the following properties:

  1. "Insert heading level 1" is the snippet name. This is the value that is displayed in the IntelliSense suggestion list if no description is provided.
  2. Theprefix property defines the trigger phrase for the snippet. It can be a string or an array of strings (if you want multiple trigger phrases). Substring matching is performed on prefixes, so in this case, typing "h1" would match our example snippet.
  3. The body property is the content that is inserted into the editor. It is an array of strings, which is one or more lines of content. The content is joined together before insertion.
  4. The description property can provide more information about the snippet. It is optional.
  5. The scope property allows you to target specific languages, and you can supply a comma-separated list in the string. It is optional. Of course, it is redundant for a language-specific snippet file.

The body of this snippet has 2 tab stops and uses the variable ${TM_SELECTED_TEXT}.

Let's get into the syntax to understand this fully.

Snippet syntax

VS Code's snippet syntax is the same as the TextMate snippet syntax. However, it does not support 'interpolated shell code' and the use of the \u transformation.

The body of a snippet supports the following features:

1. Tab Stops

Tab stops are specified by a dollar sign and an ordinal number e.g. $1 . $1 will be the first location, $2 will the second location, and so on. $0 is the final cursor position, which exits the snippet mode.

For example, let's say we want to make an HTML div snippet and we want the first tab stop to be between the opening and closing tags. We also want to allow the user to tab outside of the tags to finish the snippet.

Then we could make a snippet like this:

{ "Insert div": { prefix: "div", body: [" ","$1"," ", "$0"] } } 

2. Mirrored Tab Stops

There are times when you need to provide the same value in several places in the inserted text. In these situations you can re-use the same ordinal number for tab stops to signal that you want them mirrored. Then your edits are synced.

A typical example is a for loop which uses an index variable multiple times. Below is a JavaScript example of a for loop.

{ "For Loop": { "prefix": "for", "body": [ "for (let ${1:index} = 0; ${1:index} < ${2:array}.length; ${1:index}++) {", "\tconst ${3:element} = ${2:array}[${1:index}];", "\t$0", "}" ] } } 

3. Placeholders

Placeholders are tab stops with default values. They are wrapped in curly braces, for example ${1:default}. The placeholder text is selected on focus such that it can be easily edited. Placeholders can be nested, like this: ${1:first ${2:second}}.

4. Choices

Choices present the user with a list of values at a tab stop. They are written as a comma-separated list of values enclosed in pipe-characters e.g. $1.

This is the code for the markdown example shown earlier for inserting a task list. The choices are 'x' or a blank space.

{ "Insert task list": { "prefix": "task", "body": ["- [$1] ${2:text}", "${0}"] } 

5. Variables

There is a good selection of variables you can use. You simply prefix the name with a dollar sign to use them, for example $TM_SELECTED_TEXT.

For example, this snippet will create a block comment for any language with today's date:

{ "Insert block comment with date": { prefix: "date comment", body: ["${BLOCK_COMMENT_START}", "${CURRENT_YEAR}/${CURRENT_MONTH}/${CURRENT_DATE} ${1}", "${BLOCK_COMMENT_END}"] } } 

You can specify a default for a variable if you wish, like ${TM_SELECTED_TEXT:default}. If a variable does not have a value assigned, the default or an empty string is inserted.

If you make a mistake and include a variable name that is not defined, the name of the variable is transformed into a placeholder.

The following workspace variables can be used:

  • TM_SELECTED_TEXT: The currently selected text or the empty string,
  • TM_CURRENT_LINE: The contents of the current line,
  • TM_CURRENT_WORD: The contents of the word under cursor or the empty string,
  • TM_LINE_INDEX: The zero-index based line number,
  • TM_LINE_NUMBER: The one-index based line number,
  • TM_FILENAME: The filename of the current document,
  • TM_FILENAME_BASE: The filename of the current document without its extensions,
  • TM_DIRECTORY: The directory of the current document,
  • TM_FILEPATH: The full file path of the current document,
  • CLIPBOARD: The contents of your clipboard,
  • WORKSPACE_NAME: The name of the opened workspace or folder.

The following time-related variables can be used:

  • CURRENT_YEAR: The current year,
  • CURRENT_YEAR_SHORT: The current year's last two digits,
  • CURRENT_MONTH: The month as two digits (example '07'),
  • CURRENT_MONTH_NAME: The full name of the month (example 'July'),
  • CURRENT_MONTH_NAME_SHORT: The short name of the month (example 'Jul'),
  • CURRENT_DATE: The day of the month,
  • CURRENT_DAY_NAME: The name of day (example 'Monday'),
  • CURRENT_DAY_NAME_SHORT: The short name of the day (example 'Mon'),
  • CURRENT_HOUR: The current hour in 24-hour clock format,
  • CURRENT_MINUTE: The current minute,
  • CURRENT_SECOND: The current second,
  • CURRENT_SECONDS_UNIX: The number of seconds since the Unix epoch.

The following comment variables can be used. They honour the syntax of the document's language:

  • BLOCK_COMMENT_START: For example, in HTML,
  • LINE_COMMENT: For example, // in JavaScript.

6. Transformations

Transformations can be applied to a variable or a placeholder. If you are familiar with regular expressions (regex), most of this should be familiar.

The format of a transformation is: ${«variable or placeholder»/«regex»/«replacement string»/«flags»}. It is similar to String.protoype.replace() in JavaScript. The "parameters" do the following:

  • «regex»: This is a regular expression that is matched against the value of the variable or placeholder. The JavaScript regex syntax is supported.
  • «replacement string»: This is the string you want to replace the original text with. It can reference capture groups from the «regex», perform case formatting (using the special functions: /upcase, /downcase, and /capitalize), and perform conditional insertions. See TextMate Replacement String Syntax for more in-depth information.
  • «flags»: Flags that are passed to the regular expression. The JavaScript regex flags can be used:
    • g : Global search,
    • i : Case-insensitive search,
    • m : Multi-line search,
    • s : Allows . to match newline characters,
    • u : Unicode. Treat the pattern as a sequence of Unicode code points,
    • y : Perform a "sticky" search that matches starting at the current position in the target string.

To reference a capture group, use $n where n is the capture group number. Using $0 means the entire match.

This can be a bit confusing since tab stops have the same syntax. Just remember that if it is contained within forward slashes, then it is referencing a capture group.

The easiest way to understand the syntax fully is to check out a few examples.

Snippet body Input Output Explanation
["${TM_SELECTED_TEXT/^.+$/• $0/gm}"] line1

line2

• line1

• line2

Put a bullet point before each non-empty line of the selected text.
["${TM_SELECTED_TEXT/^(\\w+)/${1:/capitalize}/}"] the cat is on the mat. The cat is on the mat. Capitalize the first word of selected text.
["${TM_FILENAME/.*/${0:/upcase}/}"] example.js EXAMPLE.JS Insert the filename of the current file uppercased.
[

"[",

"${CLIPBOARD/^(.+)$/'$1',/gm}",

"]"

]

line1

line2

['line1', 'line2',] Turn the contents of the clipboard into a string array. Each non-empty line is an element.

As you can see from the second example above, metacharacter sequences must be escaped, for example insert \\w for a word character.

Placeholder Transformations

Placeholder transforms do not allow a default value or choices! Maybe it is more suitable to call them tab stop transformations.

The example below will uppercase the text of the first tab stop.

pladsholdertransformation

{ "Uppercase first tab stop": { "prefix": "up", "body": ["${1/.*/${0:/upcase}/}", "$0"] } } 

You can have a placeholder and perform a transformation on a mirrored instance. The transformation will not be performed on the initial placeholder. ?

Would you use this behaviour somewhere? I find it confusing initially, so it may have the same affect on others.

{ "Uppercase second tab stop instance only": { "prefix": "up", "body": ["${1:title}", "${1/(.*)/${1:/upcase}/}", "$0"] } } 

How do I assign Keyboard Shortcuts for snippets?

By adding your shortcuts to keybindings.json . You can open the file by running the 'Preferences: Open Keyboard Shortcuts File (JSON)' command.

For example, to add a shortcut for the built-in markdown snippet "Insert heading level 1":

{ "key": "ctrl+m ctrl+1", "command": "editor.action.insertSnippet", "when": "editorTextFocus && editorLangId == markdown", "args": { "langId": "markdown", "name": "Insert heading level 1" } } 

You define a shortcut by specifying the key combination you want to use, the command ID, and an optional when clause context for the context when the keyboard shortcut is enabled.

Through the args object, you can target an existing snippet by using the langId and name properties. The langId argument is the language ID of the language that the snippets were written for. The name is the snippet's name as it is defined in the snippet file.

You can define an inline snippet if you wish using the snippet property.

[ { "key": "ctrl+k 1", "command": "editor.action.insertSnippet", "when": "editorTextFocus", "args": { "snippet": "${BLOCK_COMMENT_START}${CURRENT_YEAR}/${CURRENT_MONTH}/${CURRENT_DATE} ${1} ${BLOCK_COMMENT_END}" } } ] 

You can use the Keyboard Shortcuts UI also, but it does not have the ability to add a new shortcut.

Another downside of the UI is that it does not show the args object, which makes it more difficult to find and edit your custom shortcuts. ?

genveje-ui

A question of style

Something that I found offputting initially with snippets was the propensity for people to create snippets with abbreviated prefixes. Do I have to learn a big list of gibberish acronyms to use someone else's snippets?

What do I mean by abbreviated prefixes? The table below list a few of the snippets from the JavaScript (ES6) code snippets VS Code extension. You can see in the Trigger column, the prefixes listed are abbreviations, for example fre to represent a "for each" loop.

es6 uddrag uddrag

This is unnecessary in two ways.

Firstly, the quick suggestions offered by VS Code are produced from a fuzzy substring search. If I type "fe" and the prefix of a snippet is "foreach", this will match and be offered as a quick suggestion.

As you can see below, this is the second match.

fe hurtigt forslag

The first match is fre, which is a snippet from the extension. Which suggestion is more descriptive? ?

If you use the "Insert Snippet" command for snippets, it does not make much of a difference. The description field makes amends for this shortcoming. I don't use snippets in this way, so I would prefer a more descriptive prefix.

indsæt uddrag foreach

Secondly, fre is a duplicate of the built-in snippet foreach.

Some people turn off quick suggestions for snippets and use tab completion only. In this case, you need to type a prefix out without getting visual feedback. Some people may prefer to use an abbreviated prefix to save keystrokes here.

The same fuzzy substring search is being performed in the background, so the first snippet match is inserted when you hit tab.

udfyldning af uddrag-fane

Looking at the example above, you can see that typing "fr" and hitting tab inserts the fre snippet. Typing "fore" and hitting tab inserts the foreach snippet.

So, you do not need to type out the entire prefix, if you really don't want to! ? If you have many similarly named snippet prefixes for a language, it would be impractical I imagine.

It is more practical to learn the prefixes properly, and type them out entirely before hitting tab.

There are some trade-offs depending on your preferences for using snippets.

Personally, I like to use quick suggestions as I like the visual feedback. I have snippets set to be the top suggestions, that way I can type abbreviated versions of the prefixes without needing to memorise them.

Some snippet authors have rigid patterns to overcome this, but that's just something I can't get into easily.

If you use a lot of snippets for a language, you may want to choose snippets that are written in a similar style.

If you use snippets for different frameworks and libraries in a language, they can add up and overlap. I haven't needed to do this, but you may need to do it eventually.

Global Snippets

Outside of your code editor, you can benefit from snippets also. Having snippets available in every app offers more possibilities.

Common use cases are:

  • canned responses for messages,
  • autocorrecting common typos,
  • adding contact information or signatures to documents,
  • inserting dates,
  • formatting of selected text and pasted text,
  • inserting search phrases for your search engine or app,
  • HTML snippets available inside your email client,
  • adding different templates to documents.

Most of the apps for snippets are touted as "text expanders", but quite a few task and productivity apps also include snippet-esque features.

Global snippets are bit more limited that code editor snippets, as you cannot use tab stops and placeholders. In most apps you can use some dynamic variables such as dates.

App Review

Autohotkey (Windows)

AutoHotkey is a free, open-source scripting language for Windows to do all kinds of tasks.

It has it's own unique syntax. You can install the AutoHotKey extension to add language support to VS Code for a better editing experience.

For defining prefixes to trigger a snippet insertion, you use the following format: ::<>::<>. The following script will insert Rob's email address when you type "robmail" and hit space or tab or enter.

::robmail::[email protected] 

The following script will insert the text "This is the snippet text" when you press Ctrl+D.

^d:: Send This is the snippet text 

You can read the docs to learn more.

PhraseExpress (Windows, Mac, iOS)

PhraseExpress is "a text expander software, that manages frequently used text templates for insertion into any program".

It is a freemium, GUI-based app. It is aimed at a wider audience than AutoHotKey.

It is quite polished and easy to use. You set it to run on start-up and it will be active in the background.

Your snippets can be organized into custom folders and synced using cloud services.

sætning-udtryk

Espanso (Windows, Mac, Linux)

This is a open-source, cross-platform text expander written in Rust.

It uses a file-based configuration approach. The config files are written in YAML.

The default.yml file contains the main configuration. The config below will insert Rob's email address when you type "robmail" .

matches: - trigger: ":robmail" replace: "[email protected]" 

You can specify the initial cursor position, however you cannot define tab stops.

Du kan tilføje udvidelser for at øge Espansos evne. Der er udvidelser til kørsel af eksterne scripts, herunder datoer, generering af tilfældig tekst og inklusive udklipsholderdata.

Og det handler om det! Jeg håber, du har lært noget om uddrag i dag, og du kan bruge dem til at gøre dig selv mere produktiv.