LuaSnip
Snippet Engine for Neovim written in Lua.
Install / Use
/learn @L3MON4D3/LuaSnipREADME
LuaSnip
https://user-images.githubusercontent.com/41961280/122515860-5179fa00-d00e-11eb-91f7-331893f61fbf.mp4
Features
- Tabstops
- Text-Transformations using Lua functions
- Conditional Expansion
- Defining nested Snippets
- Filetype-specific Snippets
- Choices
- Dynamic Snippet creation
- Regex-Trigger
- Autotriggered Snippets
- Easy Postfix Snippets
- Fast
- Parse LSP-Style Snippets either directly in Lua, as a VSCode package or a SnipMate snippet collection.
- Expand LSP-Snippets with nvim-compe (or its' successor, nvim-cmp (requires cmp_luasnip))
- Snippet history (jump back into older snippets)
- Resolve filetype at the cursor using Treesitter
Drawbacks
- Snippets that make use of the entire functionality of this plugin have to be defined in Lua (but 95% of snippets can be written in LSP-syntax).
Requirements
Neovim >= 0.7 (extmarks)
jsregexp for lsp-snippet-transformations (see here for some tips on installing it).
Setup
Install
-
With your preferred plugin manager i.e. vim-plug, Packer or lazy
Packer:use({ "L3MON4D3/LuaSnip", -- follow latest release. tag = "v2.*", -- Replace <CurrentMajor> by the latest released major (first number of latest release) -- install jsregexp (optional!:). run = "make install_jsregexp" })lazy:
{ "L3MON4D3/LuaSnip", -- follow latest release. version = "v2.*", -- Replace <CurrentMajor> by the latest released major (first number of latest release) -- install jsregexp (optional!). build = "make install_jsregexp" }vim-plug:
" follow latest release and install jsregexp. Plug 'L3MON4D3/LuaSnip', {'tag': 'v2.*', 'do': 'make install_jsregexp'} " Replace <CurrentMajor> by the latest released major (first number of latest release)Check the
Releases-section to the right for the latest major version. -
LuaSnip uses Semantic Versioning (with some leeway, big patches might end up as a Minor version)!
Releases will be tagged asvMajor.Minor.Patch, we recommend following the latest Major release.
Consider watching the repository's releases so you're notified when a new version becomes available.
[!NOTE] On Windows, you need a C compiler and
maketo installjsregexp. If your compiler choice is notgcc,clang, orzig, you need to explicitly specify theCCvariable in the build command:make install_jsregexp CC=your_compiler_program. Also, make sure%GIT%/bindirectory is added in the$PATHso thatmakecan use%GIT%/bin/sh.exe.On FreeBSD (and/or systems that do not install the GNU make package as the default) make commands will fail as the Makefile does not align with the expected syntax of the BSD variant of make. The solution is to install the GNU variant of make: 'pkg install gmake' on FreeBSD.
Keymaps
In Vim script, with <Tab> for jumping forward/expanding a snippet, <Shift-Tab> for
jumping backward, and <Ctrl-E> for changing the current choice when in a
choiceNode...
" press <Tab> to expand or jump in a snippet. These can also be mapped separately
" via <Plug>luasnip-expand-snippet and <Plug>luasnip-jump-next.
imap <silent><expr> <Tab> luasnip#expand_or_jumpable() ? '<Plug>luasnip-expand-or-jump' : '<Tab>'
" -1 for jumping backwards.
inoremap <silent> <S-Tab> <cmd>lua require'luasnip'.jump(-1)<Cr>
snoremap <silent> <Tab> <cmd>lua require('luasnip').jump(1)<Cr>
snoremap <silent> <S-Tab> <cmd>lua require('luasnip').jump(-1)<Cr>
" For changing choices in choiceNodes (not strictly necessary for a basic setup).
imap <silent><expr> <C-E> luasnip#choice_active() ? '<Plug>luasnip-next-choice' : '<C-E>'
smap <silent><expr> <C-E> luasnip#choice_active() ? '<Plug>luasnip-next-choice' : '<C-E>'
... or in Lua, with a different set of keys: <Ctrl-K> for expanding, <Ctrl-L>
for jumping forward, <Ctrl-J> for jumping backward, and <Ctrl-E> for
changing the active choice.
local ls = require("luasnip")
vim.keymap.set({"i"}, "<C-K>", function() ls.expand() end, {silent = true})
vim.keymap.set({"i", "s"}, "<C-L>", function() ls.jump( 1) end, {silent = true})
vim.keymap.set({"i", "s"}, "<C-J>", function() ls.jump(-1) end, {silent = true})
vim.keymap.set({"i", "s"}, "<C-E>", function()
if ls.choice_active() then
ls.change_choice(1)
end
end, {silent = true})
nvim-cmp's wiki also contains an example for
setting up a super-tab-like mapping.
Add Snippets
Check out the doc for a general explanation of the loaders and their benefits. The following list serves only as a short overview.
-
VS Code-like: To use existing VS Code style snippets from a plugin (e.g. rafamadriz/friendly-snippets) simply install the plugin and then add
require("luasnip.loaders.from_vscode").lazy_load()somewhere in your Neovim config. LuaSnip will then load the snippets contained in the plugin on startup. You can also easily load your own custom VSCode style snippets by passing the path to the custom snippet-directory to the load function:
-- load snippets from path/of/your/nvim/config/my-cool-snippets require("luasnip.loaders.from_vscode").lazy_load({ paths = { "./my-cool-snippets" } })> NOTE: > It's mandatory to have a `package.json` file in the snippet directory. For examples, see [friendly-snippets](https://github.com/rafamadriz/friendly-snippets/blob/main/package.json).For more info on the VS Code loader, check the examples or documentation.
-
SnipMate-like: Very similar to VS Code packages; install a plugin that provides snippets and call the
load-function:require("luasnip.loaders.from_snipmate").lazy_load()The SnipMate format is very simple, so adding custom snippets only requires a few steps:
- add a directory beside your
init.vim(or any other place that is in yourruntimepath) namedsnippets. - inside that directory, create files named
<filetype>.snippetsand add snippets for the given filetype in it (for inspiration, check honza/vim-snippets).# comment snippet <trigger> <description> <snippet-body> snippet if C-style if if ($1) $0
Again, there are some examples and documentation.
- add a directory beside your
-
Lua: Add the snippets by calling
require("luasnip").add_snippets(filetype, snippets). An example for this can be found here.
This can also be done much cleaner, with all the benefits that come with using a loader, by using the loader for Lua
There's also a repository collecting snippets for various languages, molleweide/LuaSnip-snippets.nvim
Documentation
Getting started
You have two main choices: use SnipMate/VS Code snippets (easier) or write snippets in Lua (more complex but also more feature-rich). Here are some suggestions for getting started in either case:
- SnipMate or VS Code snippets: if you only want to write/load SnipMate or VS Code snippets and ignore Lua snippets (and this is definitely recommended if you don't yet need Lua snippets' more complicated features), check out the sections on loading VS Code or SnipMate packages in
DOC.md. Of those two, SnipMate is definitely the more comfortable way of writing snippets. - Lua snippets: we suggest first watching or reading one of the introductory guides in the Resources for new users section below.
After getting familiar with the basics, you should check out the important LuaSnip features in the following list:
config: Notable:region_check_eventsfor jumping to the end of snippets the cursor is no longer inside of,delete_check_eventsfor cleaning up snippets whose text was deleted, andenable_autosnippetsto enable automatic snippet expansion.extras: This module contains many functions that make writing snippets significantly easier;fmtandlambdaare especially useful.lua-loader: A very useful way to load snippets, more comfortable than callingadd_snippets.
Also supports hot reload (limited to buffers in the same Neovim instance as the edited file) and [jumping to the files that provide snippets to the current buffer](https://github.com
