draivin / hsnips

HyperSnips: a powerful snippet engine for VS Code, inspired by vim's UltiSnips
MIT License
154 stars 25 forks source link

HyperSnips

HyperSnips is a snippet engine for vscode heavily inspired by vim's UltiSnips.

Usage

To use HyperSnips you create .hsnips files on a directory which depends on your platform:

You can open this directory by running the command HyperSnips: Open snippets directory. This directory may be customized by changing the setting hsnips.hsnipsPath. If this setting starts with ~ or ${workspaceFolder}, then it will be replaced with your home directory or the current workspace folder, respectively.

The file should be named based on the language the snippets are meant for (e.g. latex.hsnips for snippets which will be available for LaTeX files). Additionally, you can create an all.hsnips file for snippets that should be available on all languages.

Snippets file

A snippets file is a file with the .hsnips extension, the file is composed of two types of blocks: global blocks and snippet blocks.

Global blocks are JavaScript code blocks with code that is shared between all the snippets defined in the current file. They are defined with the global keyword, as follows:

global
// JavaScript code
endglobal

Snippet blocks are snippet definitions. They are defined with the snippet keyword, as follows:

context expression
snippet trigger "description" flags
body
endsnippet

where the trigger field is required and the fields description and flags are optional.

Trigger

A trigger can be any sequence of characters which does not contain a space, or a regular expression surrounded by backticks (`).

Flags

The flags field is a sequence of characters which modify the behavior of the snippet, the available flags are the following:

*: This flag will only affect snippets which have non-regex triggers.

Snippet body

The body is the text that will replace the trigger when the snippet is expanded, as in usual snippets, the tab stops $1, $2, etc. are available.

The full power of HyperSnips comes when using JavaScript interpolation: you can have code blocks inside your snippet delimited by two backticks (``) that will run when the snippet is expanded, and every time the text in one of the tab stops is changed.

Code interpolation

Inside the code interpolation, you have access to a few special variables:

Additionally, every variable defined in one code block will be available in all the subsequent code blocks in the snippet.

The require function can also be used to import NodeJS modules.

Context matching

Optionally, you can have a context line before the snippet block, it is followed by any javascript expression, and the snippet is only available if the context expression evaluates to true.

Inside the context expression you can use the context variable, which has the following type:

interface Context {
  scopes: string[];
}

Here, scopes stands for the TextMate scopes at the current cursor position, which can be viewed by running the Developer: Inspect Editor Tokens and Scopes command in vscode.

As an example, here is an automatic LaTeX snippet that only expands when inside a math block:

global
function math(context) {
    return context.scopes.some(s => s.startsWith("meta.math"));
}
endglobal

context math(context)
snippet inv "inverse" Ai
^{-1}
endsnippet

Examples

snippet dategreeting "Gives you the current date!"
Hello from your hsnip at ``rv = new Date().toDateString()``!
endsnippet
snippet box "Box" A
``rv = '┌' + '─'.repeat(t[0].length + 2) + '┐'``
│ $1 │
``rv = '└' + '─'.repeat(t[0].length + 2) + '┘'``
endsnippet
snippet filename "Current Filename"
``rv = require('path').basename(path)``
endsnippet