Snippets
Snippets are small pieces of code that can be inserted via the completion box. Based on a trigger a piece of code is inserted that can have one or more areas that can be filled by the user using [TAB]
to switch between them.
The following example shows a snippet that is triggered by typing ife[TAB]
.
snippet ife
if (${1:true}) {
${2}
} else {
${0}
}
It inserts the if else construct and starts by selecting the word true
. After changing that and pressing [TAB]
the cursor moves to the body of the if. The last [TAB]
will move the cursor to the body of the else.
Creating a Snippets File
Snippets work in a similar way as those for TextMate and Sublime Text
A snippets file is a collection of multiple snippets for a specific mode. It consists of a header with some meta data and a list of snippets below that. Currently, the only way to add custom snippets to a project is to create a plugin (as described here).
Header
The header specifies the scope for the snippets. The scope is a string that specifies the name of the mode to which these snippets are applied.
# scope: javascript
Use _
to specify snippets for all scopes. Use a comma separated list if these snippets apply to several modes.
Snippets
The rest of the file contains snippets. Snippets start with a list of variable definitions and then a list of lines that contain the code of the snippet itself.
# Comment
<field> <value>
<field> <value>
<tab>snippetcontents
<tab>snippetcontents
snippet ended
A file can contain any number of these underneath each other.
Creating a Snippet
Insertion Points
After inserting the snippet text the cursor will move to the first position after the inserted text, when there are no insertion points specified. Specifying insertion points using the $
character and a number to specify their sequence.
${1}
${2}
etc
The ${0}
insertion point is always last in line. You can specify the text that is selected when jumping from one insertion point to the next one.
${1:some_text}
In addition, it's possible to reuse the same variable multiple times. All instances will be selected using multiple cursors and changed at the same time when the user types.
for (var ${1:i}=0; $1 < ${2}; $1++) {
${0}
}
Using Special Variables
When triggering a snippet through a menu or command you can configure it to use the text selected prior to inserting the snippet in the resulting code.
(function(${1}) {
${0:${SELECTED_TEXT:/* code */}}
}(${1}));
Similarly the following variables can be used to insert other special text.
CURRENT_WORD | The word at the cursor at the. |
---|---|
SELECTION | The selected text. |
SELECTED_TEXT | The selected text. |
CURRENT_LINE | The current line. |
PREV_LINE | The previous line. |
LINE_INDEX | The index of the current line. |
LINE_NUMBER | The line number (index + 1). |
SOFT_TABS | "YES" or "NO". |
TAB_SIZE | The tab size. |
Formatting Strings
Variables that are inserted can be formatted using the following command:
${«int»/«regexp»/«format»/«options»}
The following example comes from the markdown snippets and takes the contents of the previous line transforming each character into a =
. That results in a line full of ===
exactly matching the length of the line above it.
snippet ===
regex /^/=+/=*//
${PREV_LINE/./=/g}
${0}
In addition the following characters can be used to toggle case.
\u uppercase next letter
\l lowercase next letter
\U uppercase until \ULE
\E ends \U or \L
Triggers & Guards
The examples above used a simple string of characters to define how a snippet is triggered. The snippet definition allows for more control in triggering snippets, introducing two concepts; triggers
and guards
. Both have a beginning marker called trigger
and guard
and an end marker called endTrigger
and endGuard
. These are all optional.
Guards are pieces of a regular expression (regex) that define the context in which a trigger is allowed. Whatever is matched by a guard remains after insertion of the snippet - guards are not replaced.
Triggers are also pieces of a regex that define the start (before the cursor) and end (after the cursor) of the text that will be replaced by the snippet contents.
Lets start with a simple example.
snippet for
This can also be written like this.
guard \b
trigger for
endGuard
endTrigger
Of course since the endGuard
and endTrigger
are empty they can be left out.
Here's a more advanced example using a trigger to match (f(|)
or f(|)
or f(|
where |
is the cursor.
# Immediate function
trigger \(?f\(
endTrigger \)?
snippet f(
(function(${1}) {
${0:${SELECTED_TEXT:/* code */}}
}(${1}));
Using a RegEx
It's possible to replace the guards and trigger fields with a single regex that describes each.
This regex below matches the start of a line (allowing white spaces) as a guard. It then is triggered by the for
characters and textafter
after the cursor, requiring at least 1 white space character, guarding the end of the sequence.
regex /^\s*/for/textafter/\s+/
Use the regex capture groups to allow variables inserted in snippets. The captured items are available as variables M1
, M2
, etc.
${M1?$M1: ${1:functionName}}
This allows you to create snippets with arguments; for 1 5|
-> for (var i| = 1 i < 5; i++) {}
. (|
is the cursor again).
Scope
Finally it's possible to set a different scope for each snippet in a file, overwriting the main mode set in the header. Use the scope variable to do this.
scope markdown
Adding Snippets to a Bundle
A bundle can contain one or more snippet files. Each snippet file must be placed in the snippets
directory.
Suppose your snippets file is called markdown.snippets
. Your file structure will look something like this:
└─ your.plugin
├─ snippets
| └─ markdown.snippets
├─ package.json
└─ README.md
Using snippets inside a project
To load the snippets you created inside a project, add it's name to the `package.json.
package.json
{
"name":"your.plugin",
"plugins": {}
}
Then open the init script from the cloud9 menu and add your.plugin
to the plugins loaded at startup.
services.pluginManager.loadPackage([
"~/.c9/plugins/your.plugin/package.json"
])
Updated almost 2 years ago