# LuaSnip **Repository Path**: mirror_jedsek/LuaSnip ## Basic Information - **Project Name**: LuaSnip - **Description**: LuaSnip - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2022-04-04 - **Last Updated**: 2022-05-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [![LuaSnip](https://img.shields.io/matrix/luasnip:matrix.org?label=Matrix&logo=matrix)](https://matrix.to/#/%23luasnip:matrix.org) # 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 - Fast - Parse [LSP-Style](https://microsoft.github.io/language-server-protocol/specification#snippet_syntax) Snippets either directly in lua, as a vscode package or a snipmate snippet collection. - Expand LSP-Snippets with [nvim-compe](https://github.com/hrsh7th/nvim-compe) (or its' successor, [nvim-cmp](https://github.com/hrsh7th/nvim-cmp) (requires [cmp_luasnip](https://github.com/saadparwaiz1/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). - The LSP-parser does not support Regex-Transformations. # Requirements Neovim >= 0.5 (extmarks) # Setup ## Install Ie. With [vim-plug](https://github.com/junegunn/vim-plug) ## Keymaps
in vimscript ```vim " press to expand or jump in a snippet. These can also be mapped separately " via luasnip-expand-snippet and luasnip-jump-next. imap luasnip#expand_or_jumpable() ? 'luasnip-expand-or-jump' : '' " -1 for jumping backwards. inoremap lua require'luasnip'.jump(-1) snoremap lua require('luasnip').jump(1) snoremap lua require('luasnip').jump(-1) " For changing choices in choiceNodes (not strictly necessary for a basic setup). imap luasnip#choice_active() ? 'luasnip-next-choice' : '' smap luasnip#choice_active() ? 'luasnip-next-choice' : '' ```
or in lua (includes supertab-like functionality with nvim-cmp) ```lua local function prequire(...) local status, lib = pcall(require, ...) if (status) then return lib end return nil end local luasnip = prequire('luasnip') local cmp = prequire("cmp") local t = function(str) return vim.api.nvim_replace_termcodes(str, true, true, true) end local check_back_space = function() local col = vim.fn.col('.') - 1 if col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') then return true else return false end end _G.tab_complete = function() if cmp and cmp.visible() then cmp.select_next_item() elseif luasnip and luasnip.expand_or_jumpable() then return t("luasnip-expand-or-jump") elseif check_back_space() then return t "" else cmp.complete() end return "" end _G.s_tab_complete = function() if cmp and cmp.visible() then cmp.select_prev_item() elseif luasnip and luasnip.jumpable(-1) then return t("luasnip-jump-prev") else return t "" end return "" end vim.api.nvim_set_keymap("i", "", "v:lua.tab_complete()", {expr = true}) vim.api.nvim_set_keymap("s", "", "v:lua.tab_complete()", {expr = true}) vim.api.nvim_set_keymap("i", "", "v:lua.s_tab_complete()", {expr = true}) vim.api.nvim_set_keymap("s", "", "v:lua.s_tab_complete()", {expr = true}) vim.api.nvim_set_keymap("i", "", "luasnip-next-choice", {}) vim.api.nvim_set_keymap("s", "", "luasnip-next-choice", {}) ```
or in lua with nvim-compe ```lua local function prequire(...) local status, lib = pcall(require, ...) if (status) then return lib end return nil end local luasnip = prequire('luasnip') local t = function(str) return vim.api.nvim_replace_termcodes(str, true, true, true) end local check_back_space = function() local col = vim.fn.col('.') - 1 if col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') then return true else return false end end _G.tab_complete = function() if vim.fn.pumvisible() == 1 then return t "" elseif luasnip and luasnip.expand_or_jumpable() then return t("luasnip-expand-or-jump") elseif check_back_space() then return t "" else return vim.fn['compe#complete']() end return "" end _G.s_tab_complete = function() if vim.fn.pumvisible() == 1 then return t "" elseif luasnip and luasnip.jumpable(-1) then return t("luasnip-jump-prev") else return t "" end return "" end vim.api.nvim_set_keymap("i", "", "v:lua.tab_complete()", {expr = true}) vim.api.nvim_set_keymap("s", "", "v:lua.tab_complete()", {expr = true}) vim.api.nvim_set_keymap("i", "", "v:lua.s_tab_complete()", {expr = true}) vim.api.nvim_set_keymap("s", "", "v:lua.s_tab_complete()", {expr = true}) vim.api.nvim_set_keymap("i", "", "luasnip-next-choice", {}) vim.api.nvim_set_keymap("s", "", "luasnip-next-choice", {}) ```
For nvim-cmp, it is also possible to follow the [example recommendation](https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings#luasnip) from the nvim-cmp wiki. ## Add Snippets Check out [the doc](https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md#loaders) for a general explanation of the loaders and their benefits. The following list serves only as a short overview. - **Vscode-like**: To use existing vs-code style snippets from a plugin (eg. [rafamadriz/friendly-snippets](https://github.com/rafamadriz/friendly-snippets)) simply install the plugin and then add ```lua require("luasnip.loaders.from_vscode").lazy_load() ``` somewhere in your nvim-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: ```lua -- load snippets from path/of/your/nvim/config/my-cool-snippets require("luasnip.loaders.from_vscode").lazy_load({ paths = { "./my-cool-snippets" } }) ``` For more info on the vscode-loader, check the [examples](https://github.com/L3MON4D3/LuaSnip/blob/b5a72f1fbde545be101fcd10b70bcd51ea4367de/Examples/snippets.lua#L501) or [documentation](https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md#loaders). - **Snipmate-like**: Very similar to Vscode-packages: install a plugin that provides snippets and call the `load`-function: ```lua 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 your `runtimepath`) named `snippets`. - inside that directory, create files named `.snippets` and add snippets for the given filetype in it (for inspiration, check [honza/vim-snippets](https://github.com/honza/vim-snippets/tree/master/snippets)). ``` snipmate # comment snippet snippet if C-style if if ($1) $0 ``` Again, there are some [examples](https://github.com/L3MON4D3/LuaSnip/blob/b5a72f1fbde545be101fcd10b70bcd51ea4367de/Examples/snippets.lua#L517) and [documentation](https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md#snipmate). - **Lua**: Add the snippets by calling `require("luasnip").add_snippets(filetype, snippets)`. An example for this can be found [here](https://github.com/L3MON4D3/LuaSnip/blob/master/Examples/snippets.lua#L190). This can also be done much cleaner, with all the benefits that come with using a loader, by using the [loader for lua](https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md#lua) There's also a repository collecting snippets for various languages, [molleweide/LuaSnip-snippets.nvim](https://github.com/molleweide/LuaSnip-snippets.nvim) ## Docs and Examples Check [`DOC.md`](https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md) (or `:help luasnip`) for a short overview and in-depth explanations of the different nodes and available API. I highly recommend looking into (or better yet, `:luafile`ing) [`Examples/snippets.lua`](https://github.com/L3MON4D3/LuaSnip/blob/master/Examples/snippets.lua) before writing snippets in lua. The [Wiki](https://github.com/L3MON4D3/LuaSnip/wiki) contains some pretty useful extensions to Luasnip. # Config - `history`: If true, Snippets that were exited can still be jumped back into. As Snippets are not removed when their text is deleted, they have to be removed manually via `LuasnipUnlinkCurrent` if `delete_check_events` is not enabled (set to eg. `'TextChanged'`). - `update_events`: Choose which events trigger an update of the active nodes' dependents. Default is just `'InsertLeave'`, `'TextChanged,TextChangedI'` would update on every change. - `region_check_events`: Events on which to leave the current snippet if the cursor is outside its' 'region'. Disabled by default, `'CursorMoved'`, `'CursorHold'` or `'InsertEnter'` seem reasonable. - `delete_check_events`: When to check if the current snippet was deleted, and if so, remove it from the history. Off by default, `'TextChanged'` (perhaps `'InsertLeave'`, to react to changes done in Insert mode) should work just fine (alternatively, this can also be mapped using `luasnip-delete-check`). - `store_selection_keys`: Mapping for populating `TM_SELECTED_TEXT` and related variables (not set by default). - `enable_autosnippets`: Autosnippets are disabled by default to minimize performance penalty if unused. Set to `true` to enable. - `ext_opts`: Additional options passed to extmarks. Can be used to add passive/active highlight on a per-node-basis (more info in DOC.md) - `parser_nested_assembler`: Override the default behaviour of inserting a `choiceNode` containing the nested snippet and an empty `insertNode` for nested placeholders (`"${1: ${2: this is nested}}"`). For an example (behaviour more similar to vscode), check [here](https://github.com/L3MON4D3/LuaSnip/wiki/Nice-Configs#imitate-vscodes-behaviour-for-nested-placeholders) - `ft_func`: Source of possible filetypes for snippets. Defaults to a function, which returns `vim.split(vim.bo.filetype, ".", true)`, but check [filetype_functions](lua/luasnip/extras/filetype_functions.lua) for other options - `snip_env`: The global environment will be extended with this table in some places, eg. in files loaded by the [lua-loader](https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md#lua-snippets-loader). Setting `snip_env` to `{ some_global = "a value" }` will add the global variable `some_global` while evaluating these files. If you mind the (probably) large number of generated warnings, consider adding the keys set here to the globals recognized by lua-language-server or add `---@diagnostic disable: undefined-global` somewhere in the affected files. Inspired by [vsnip.vim](https://github.com/hrsh7th/vim-vsnip/)