l3mon4d3 / luasnip Goto Github PK
View Code? Open in Web Editor NEWSnippet Engine for Neovim written in Lua.
License: Apache License 2.0
Snippet Engine for Neovim written in Lua.
License: Apache License 2.0
Sometimes it happens that require('luasnip').choice_active()
returns true
even if no snippet exists, for example after LuaSnipUnlinkCurrent
execution or because history = false
.
Moreover if no snippets exists, LuaSnipUnlinkCurrent
raises an error: 'LuaSnip/lua/luasnip/init.lua:82: attempt to index a nil value'. I think having a print('Hey! no more snippet here')
should be cooler.
As this has a pull request into nvim-compe would be good to add name and description into snippets so can be displayed in completion list.
I have been using Snippets and i like how there is window so I know where I am at, I was wondering if this could do a same thing,
I don't mean enter text in the pop up window,
I meant something like to show info/hint, for example with choice,
we can see a list of choice and select one without going through all to see what we need? same with input ( so we know we are at $1 or $0 etc)?
We can set this as default disable and allow user to enable it manually
Hi,
Can you also include a lua based example on how to map this plugin?
For now I've gotten it like this but I think this is not the best way.
cmd([[
imap luasnip#expand_or_jumpable() ? 'luasnip-expand-or-jump' : ''
inoremap lua require'luasnip'.jump(-1)
snoremap lua require('luasnip').jump(1)
snoremap lua require('luasnip').jump(-1)
imap luasnip#choice_active() ? 'luasnip-next-choice' : ''
smap luasnip#choice_active() ? 'luasnip-next-choice' : ''
]])
when trying to autocomplete I get this
Error detected while processing function luasnip#expand_or_jumpable:
E5108: Error executing lua ...hare/nvim/site/pack/packer/start/LuaSnip/lua/luasnip.lua:12: attempt to index global 'ls' (a nil value)
edit. looks like is related to this https://stackoverflow.com/questions/52500913/lua-attempt-to-index-global-nil-value
One very common task in snippets is to insert the typed input in multiple places (possibly with a transformation), for example replacing whitespace with underscores to add a label or header guard. This can be done with a function or dynamic node, of course, but it's so common that I feel having this built-in would reduce boilerplate and make writing snippets much more convenient.
So my proposal would be to add a new node type "repeat node" that would look like
r(1, {match = "[^.]+$", upper = true, gsub = {"%s+", "_"}})
to insert the current value of the input node 1, with everything after the first .
stripped, converted to upper case, then with whitespace replaced by underscore. (Maybe that's not the best interface; comments welcome :))
Hi,
I am very new with LuaSnip, been used to UltiSnips but wanted to switch to full Lua.
Is there a way to have auto-complete with LuaSnip on only certain snippets?
Let's say I want to enter math mode with 'mk' (or whatever the snippet), I am not sure how I would define an auto-trigger/auto-complete to enter math-mode in Latex.
Besides that, in-line math mode in Latex is '$YOUR MATH HERE$', how do you define a snippet to include those '$'?
Thanks for your help!
In init.lua
, you define
s = snip_mod.S,
sn = snip_mod.SN,
t = require("luasnip.nodes.textNode").T,
f = require("luasnip.nodes.functionNode").F,
i = require("luasnip.nodes.insertNode").I,
c = require("luasnip.nodes.choiceNode").C,
d = require("luasnip.nodes.dynamicNode").D,
which is nice and terse, but not super user-friendly. I know that it put me off when I first checked out this plugin and I keep needing to look up what they mean every once in a while.
Since most users will alias those functions anyways (e.g. local s = ls.s
), would you be open to adding more verbose variants as well? local s = ls.snippet
would be much more readable for most people and barely more verbose in the context of a full config. Of course the current ones would stay, if only for backwards compatibility.
I'd be happy to submit a PR with this and adjusting the documentation if that sounds good to you.
Thanks for LuaSnip btw, it looks like a really solid plugin from what I've seen so far!
local ls = require("luasnip")
local s = ls.s
local t = ls.t
local i = ls.i
local f = ls.f
local function date()
return {os.date("%Y-%m-%d")}
end
ls.snippets = {
all = {
s({trig = "date", wordTrig = true}, {f(date, {}), i(0)}),
s({trig = "date2", wordTrig = true}, {f(date, {}), t({" "}), i(0)})
}
}
date
renders to
␣2021-05-24
instead of 2021-05-24␣
.
while date2
renders to
2021-05-24 ␣
Error output:
Error executing vim.schedule lua callback: .../pack/packer/start/nvim-compe/lua/compe_luasnip/init.lua:27: attempt to concatenate a table value
Minimal init.lua to reproduce:
-- This file is a minimal `init.lua` example for debuggin plugins.
-- Open with `nvim -u debug.lua`
local fn = vim.fn
local install_path = "/tmp/nvim/site/pack/packer/start/packer.nvim"
vim.cmd([[set packpath=/tmp/nvim/site]])
local function load_plugins()
local use = require("packer").use
require("packer").startup({
function()
use("wbthomason/packer.nvim")
-- Put plugins to install here:
use("hrsh7th/nvim-compe")
use("L3MON4D3/LuaSnip")
use("rafamadriz/friendly-snippets")
end,
config = { package_root = "/tmp/nvim/site/pack" },
})
end
_G.load_config = function()
vim.o.completeopt = "menuone,noselect"
require("compe").setup({
enabled = true,
preselect = 'enable',
autocomplete = true,
source = {
luasnip = true,
},
})
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("<C-n>")
elseif luasnip and luasnip.expand_or_jumpable() then
return t("<Plug>luasnip-expand-or-jump")
elseif check_back_space() then
return t("<Tab>")
else
return vim.fn["compe#complete"]()
end
end
_G.s_tab_complete = function()
if vim.fn.pumvisible() == 1 then
return t("<C-p>")
elseif luasnip and luasnip.jumpable(-1) then
return t("<Plug>luasnip-jump-prev")
else
return t("<S-Tab>")
end
end
local map = vim.api.nvim_set_keymap
vim.cmd("inoremap <silent><expr> <CR> compe#confirm('<CR>')")
map("i", "<Tab>", "v:lua._G.tab_complete()", { expr = true })
map("s", "<Tab>", "v:lua._G.s_tab_complete()", { expr = true })
map("i", "<S-Tab>", "v:lua.MUtils.s_tab_complete()", { expr = true })
map("s", "<S-Tab>", "v:lua.MUtils.s_tab_complete()", { expr = true })
require("luasnip.loaders.from_vscode").load()
end
if fn.isdirectory(install_path) == 0 then
-- install packer
fn.system({ "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path })
load_plugins()
require("packer").sync()
vim.cmd("autocmd User PackerComplete ++once lua load_config()")
else
load_plugins()
_G.load_config()
end
Steps:
Here a video.
In this case I'm trying to use the shebang
snippet which has multiple options, (see here)
Is there any step by step guide on how to set up LuaSnip. I just see one line in the README where it says Snippets have to be added to the require'luasnip'.snippets-table.
, but couldn't make any progress with that.
I'm trying to integrate the plugin with https://github.com/rafamadriz/friendly-snippets basically by doing the same magic that vsnipet does (iterating over runtimepath looking for packages.json pointing to snippet files). That part is done, but then I discovered that vscode snippets can be ( and most of the time are) defined as a list of strings instead of a single one. If parse_snippet
were able to read those it will be easy pie to proceed and I could even contribute the code for the snippets loading upstream.
Amazing plugin, thanks!
Is it possible to make snippet available only if triggered from the beginning of the line? I have tried:
ps({ name = "Conventional: build", trig = "^build", regTrig = true }, "build(${1:scope}): ${2:subject}")
But it does not seem to do what I want.
Also, is compe suppose to expand snippets in preview window? I only get to see this:
Preface:
This error only occurs when bdelete
is used. When bwipeout
is used, the error doesn't occur.
Steps to reproduce:
bdelete
the bufferSteps to reproduce:
<Plug>luasnip-expand-or-jump
bind on the same line as the snippet till error pops upLuaSnip Configuration:
local function char_count_same(c1, c2)
local line = vim.api.nvim_get_current_line()
local _, ct1 = string.gsub(line, c1, '')
local _, ct2 = string.gsub(line, c2, '')
return ct1 == ct2
end
local function even_count(c)
local line = vim.api.nvim_get_current_line()
local _, ct = string.gsub(line, c, '')
return ct % 2 == 0
end
local function neg(fn, ...)
return not fn(...)
end
local ls = require'luasnip'
local s = ls.s
local t = ls.t
local i = ls.i
ls.snippets = {
all = {
s({trig="("}, { t({"("}), i(1), t({")"}), i(0) }, neg, char_count_same, '%(', '%)'),
s({trig="{"}, { t({"{"}), i(1), t({"}"}), i(0) }, neg, char_count_same, '%{', '%}'),
s({trig="["}, { t({"["}), i(1), t({"]"}), i(0) }, neg, char_count_same, '%[', '%]') ,
s({trig="<"}, { t({"<"}), i(1), t({">"}), i(0) }, neg, char_count_same, '<', '>'),
s({trig="'"}, { t({"'"}), i(1), t({"'"}), i(0) }, neg, even_count, '\''),
s({trig="\""}, { t({"\""}), i(1), t({"\""}), i(0) }, neg, even_count, '"'),
s({trig="{;"}, { t({"{","\t"}), i(1), t({"", "}"}), i(0) }),
},
}
P.S. Stole the snippets from your configuration and they work nicely! Thanks.
When testing the pr for the loader I found some snippets that fail. For the record:
ls.parser.parse_snippet({trig="for_i", wordTrig=true}, "for ((${0:i} = 0; ${0:i} < ${1:10}; ${0:i}++)); do\n\techo \"$${0:i}\"\ndone\n"),
ls.parser.parse_snippet({trig="for_in", wordTrig=true}, "for ${0:VAR} in $${1:LIST}\ndo\n\techo \"$${0:VAR}\"\ndone\n"),
ls.parser.parse_snippet({trig="case", wordTrig=true}, "case \"$${0:VAR}\" in\n\t${1:1}) echo 1\n\t;;\n\t${2:2|3}) echo 2 or 3\n\t;;\n\t*) echo default\n\t;;\nesac\n"),
ls.parser.parse_snippet({trig="texlr", wordTrig=true}, "\\left\\{ ${1:${TM_SELECTED_TEXT}} \\right\\\\}"),
Updating to latest version I now have this error:
Here is my simple config (based off stripped down version of the example) that used to work a few commits ago:
local luasnip = require('luasnip')
luasnip.config.set_config({
history = true,
updateevents = 'TextChanged,TextChangedI',
})
require('luasnip/loaders/from_vscode').load()
I've tried playing with opts and add an include but I think the issue is with handling the path. Sadly I can't help much more than this bug report as my lua and neovim is still pretty limited.
I have this error with the following configuration:
vim.api.nvim_set_keymap('i', '<Tab>', 'luasnip#expand_or_jumpable() ? "<Plug>luasnip-expand-or-jump" : "<Tab>"', { expr = true, silent = true })
vim.api.nvim_set_keymap('i', '<S-Tab>', [[luaeval('require("luasnip").jump(-1)')]], { noremap = true, expr = true, silent = true })
vim.api.nvim_set_keymap('i', '<C-e>', 'luasnip#choice_active() ? "<Plug>luasnip-next-choice" : "<C-E>"', { expr = true, silent = true })
vim.api.nvim_set_keymap('s', '<Tab>', [[luaeval('require("luasnip").jump(1)')]], { noremap = true, expr = true, silent = true })
vim.api.nvim_set_keymap('s', '<S-Tab>', [[luaeval('require("luasnip").jump(-1)')]], { noremap = true, expr = true, silent = true })
Even if I just call the following in cmd:
echo luasnip#expand_or_jumpable()
This morning, when I decided to see what's new in nvim-compe these days, I did a double-take when I found that it supported a new snippets plugin. "LuaSnip?", I thought, "Huh. Gotta check that one out."
And lo and behold, it was glorious. With select mode and extmarks, the presentation is really simple and non-surprising—exactly as I like it. The snippets syntax is a bit bewildering at first, but pretty ingenious overall.
When I realized that I wasn't shackled to my previous snippets plugins anymore, a single tear rolled down my face.
Thank you, @L3MON4D3. I feel at home.
🍆
If I use <S-Tab>
when no snippets are active, then false is inserted.
Is there a way to check if snippet is available instead of just using jump(-1)
?
My configuration (as in README, but in lua):
vim.api.nvim_set_keymap('i', '<S-Tab>', [[luaeval('require("luasnip").jump(-1)')]], { noremap = true, expr = true, silent = true })
vim.api.nvim_set_keymap('s', '<S-Tab>', [[luaeval('require("luasnip").jump(-1)')]], { noremap = true, expr = true, silent = true })
So I'm trying to replace vim-snip with this plugin, right now I'm using the exemple setup in nvim-compe README.md
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
-- Use (s-)tab to:
--- move to prev/next item in completion menuone
--- jump to prev/next snippet's placeholder
MUtils.tab_complete = function()
if vim.fn.pumvisible() == 1 then
return t "<C-n>"
elseif vim.fn.call("vsnip#available", {1}) == 1 then
return t "<Plug>(vsnip-expand-or-jump)"
elseif check_back_space() then
return t "<Tab>"
else
return vim.fn['compe#complete']()
end
end
MUtils.s_tab_complete = function()
if vim.fn.pumvisible() == 1 then
return t "<C-p>"
elseif vim.fn.call("vsnip#jumpable", {-1}) == 1 then
return t "<Plug>(vsnip-jump-prev)"
else
return t "<S-Tab>"
end
end
and
map("i", "<Tab>", "v:lua.MUtils.tab_complete()", {expr = true})
map("s", "<Tab>", "v:lua.MUtils.tab_complete()", {expr = true})
map("i", "<S-Tab>", "v:lua.MUtils.s_tab_complete()", {expr = true})
map("s", "<S-Tab>", "v:lua.MUtils.s_tab_complete()", {expr = true})
What would be the best way to use a similar setup with LuaSnip?
I want to choice as follows.
\left( \right)
↓
\left\{ \right\}
↓
\left[ \right]
↓
So, I defined the following snippet.
s("brackets", {
t("\\left"),
c(1, {t("("), t("\\{"), t("["),}),
i(0),
t("\\right"),
f(close_bracket, 1),
}),
The function close_bracket to get the corresponding parentheses, but I don't know how to write it...
Is there any way to match the current indentation for multi-line snippets?
For example, with snippets.nvim, I have a few snippets similar to this:
def = U.match_indentation [[
def ${1:function}($2) do
$0
end]];
When inserted, each line is prepended with the current indentation of the trigger.
Is there a way to do this, or even more generally, operate on each line of the snippet's result to be able to do things like add a comment prefix, line numbers, etc. to be able to build the match indent functionality in user space?
Thank you!
Hi,
I've started to use LuaSnip and I am wondering if there is a way to list all available snippets for current file?
Also wondering if there could be example for using bash command output as a snippet?
Hi 👋🏾 ,
I'm curious about potentially using this plugin but having done a migration from ultisnips based snippets, to json based snippets. I'd rather not/won't (😆 ) do yet another migration/conversion to lua based snippets and leave everything I've created behind. I see there's some functionality for parsing json based snippets from friendly-snippets
but I can't tell how I would do this with a custom set of json snippets I've created and have in my dotfiles.
For vim-vsnip and ultisnips they both accept a directory option which is used to source personal snippets of their particular format, all namespaced by filetype. Now, with that pre-amble over, my question is can I do something like that with this plugin?
I'm not sure if this is an issue with the texlab language server or LuaSnip. Let me know and I'll close this issue and create one on their repo.
Here's the v:completed_item dictionary if that might be helpful
{'word': 'begin{', 'menu': '[LSP]', 'user_data': {'compe': {'completion_item': {'label': 'begin', 'data':
'commandSnippet', 'preselect': v:false, 'sortText': '00', 'kind': 15, 'detail': 'built-in', 'insertText':
'begin{$1}^@^I$0^@\end{$1}', 'insertTextFormat': 2}, 'request_position': {'character': 1, 'line': 4}}}, 'info': '', 'kind': '', 'abbr': 'begin~'}
I don't how this relates to this plugin but if I try to fmt.Pr| and select Print from completion menu somehow this plugin causes cursor to be moved to (|) and virtualbox show a useless error like so
It's weird bc I don't even select a snippet from completion menu
use {
"L3MON4D3/LuaSnip",
requires = {
{
"rafamadriz/friendly-snippets",
}
},
config = function()
require"luasnip/loaders/from_vscode".lazy_load()
end
}
This one is more borderline in usefulness, but may be nice to have: A "simple" function node that just inserts the output of a Lua statement, e.g.,
a(os.date('%Y-%m-%d'))
as syntactic sugar for
f(function() return os.date '%Y-%m-%d' end, {})
When I enable compe lsp snippet support I can't complete lsp entries. Instead the selected text simply gets deleted.
Completion works as expected when I disable lsp snippet support (as in doesn't delete the text) or use vsnip instead of luasnip.
I'm using the configuration below.
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true
require'lspconfig'.rust_analyzer.setup {
capabilities = capabilities,
}
require'compe'.setup {
enabled = true;
autocomplete = true;
preselect = 'enable';
documentation = true;
source = {
buffer = true;
nvim_lsp = true;
nvim_lua = true;
luasnip = true;
vsnip = false;
};
}
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 = function()
if vim.fn.pumvisible() == 1 then
return t "<C-n>"
elseif require'luasnip'.expand_or_jumpable() then
return t "<Plug>(luasnip-expand-or-jump)"
elseif check_back_space() then
return t "<Tab>"
else
return vim.fn['compe#complete']()
end
end
_G.s_tab = function()
if vim.fn.pumvisible() == 1 then
return t "<C-p>"
elseif require'luasnip'.jumpable(-1) then
return t "<Plug>(luasnip-jump-prev)"
else
-- If <S-Tab> is not working in your terminal, change it to <C-h>
return t "<S-Tab>"
end
end
nvim_set_keymap('i', '<Tab>', 'v:lua.tab()', {expr=true})
nvim_set_keymap('i', '<S-Tab>', 'v:lua.s_tab()', {expr=true})
nvim_set_keymap('i', '<cr>', 'compe#confirm("<cr>")', {expr=true})
nvim_set_keymap('i', '<c-space>', 'compe#complete()', {expr=true})
<Plug>luasnip-expand-or-jump
raises sometimes an error after an expansion of a LSP snippet . It happens "randomly", because actually I haven't found yet a way to reproduce it.
The error:
LuaSnip/lua/luasnip/nodes/snippet.lua:318: end_row out of bounds
I know that require('luasnip').expand_or_jumpable()
returns true.
I have this snippet
local function replace_each(replacer)
return function(args)
local len = #args[1][1]
return {replacer:rep(len)}
end
end
ls.snippets = {
all = {
s({trig = "bbox", wordTrig=true},
{
t{"╔"}, f(replace_each("═"), {1}), t{"╗", "║"},
i(1, {"content"}), t{"║", "╚"},
f(replace_each("═"), {1}),
t{"╝"},
i(0)}
)
}
}
When it renders the first time instead of selecting content
it selects content
.
I tested with different characters for the corners and sides of the box ( *
, "|" and "-") and it works fine, so I guess is something related to unicode runes counting.
If I have this
ls.parser.parse_snippet(
{
trig = "te",
name = "ternary",
dscr = ""
},
"${1:cond} ? ${2:true} : ${3:false}"
),
ls.parser.parse_snippet(
{
trig = "e",
name = "module export",
dscr = ""
},
"export ${1:member}"
),
and I have editing
te|
must expand to |cond ? true : false
but was expanded as texport |member
where | is the cursor
I currently have two types of keybinds for LuaSnip. One keybind expands or jumps, this is <cr>
for me, and I have one type of keybind that only jumps, like <tab>
and shift + <tab>
. What I actually want is for <cr>
to only allow expansion of snippets, not jump in snippets.
What sometimes happens is that I'm inside a snippet and want to add a new line. But in order to do that I first have to remove all snippet jump locations. One way to resolve this would be to expand snippets with <tab>
instead of <cr>
but I really don't want to move snippet expansion to <tab>
, because I view snippet expansion as a type of completion and I like having all completions on <cr>
. So I don't like that way of resolving this.
Is there currently a way to bind <cr>
to only expand and not jump? If yes, is there also some kind of function like luasnip#expandable()
? I tried looking through the source code and I don't think I found anything that looks like what I want.
Continuing in my quest for more "convenience nodes" to make writing snippets in LuaSnip's powerful syntax more convenient and concise, I'd like to suggest adding a "conditional text" that add text if and only if a placeholder is non-empty, so you could do something like
t"\usepackage", cond("[",2), i(2), cond("]",2), t"{", i(1), t"}"
which would expand to \usepackage[bar]{foo}
in general but \usepackage{bar}
if $2
was left empty.
(One could generalize this with an arbitrary regex that is matched against the insert node, but this might be overkill?)
See #39.
On top of that, I'd like to:
{ trig = the_string_here }
i(0)
at the end of snippets that don't have anyWith all of those merged, a short snippet could look something like:
s('sh', t'#!/bin/bash')
Arguably, we could also auto-convert strings/tables of strings into text nodes and numbers/{ number, text_node }
into insert nodes, or something like that. It would be a bit more questionable and a quite big addition, but the user-experience/snippet readability would be improved IMO.
What's your opinion on all that? :)
In my case, once I leave insert mode, I don't jump to a previous history. It's my fault for leaving without jumping to the end...
That will allow, for instance, to implement a snippet like
lorem -> full lorem ipsum
lorem20 -> first 20 chars of lorem ipsum
It could be the result of regex.match as a table if it's a regex snippet or {trigger} if it's not.
Hey, I've been getting some bug reports regarding to errors triggered by LuaSnip
when running commands like Telescope
or PackerSync
. After debugging for a while I've found that LuaSnip
was working fine until the commit c1ed401f8281925f5cc842e29767656e5c8e7735
was pushed and the line that is causing this error is L#26.
Hope that information can help to debug and fix this behavior. Thanks in advance!
Watch this issue to be notified of any breaking changes.
thanks to @clason for recommending this
Hi,
I've being trying to get friendly-snippets to work or figure out how to.
Although my aim is to actually alter them for my own needs.
Seems like there have being few mentions found, but I still couldn't get it to work.
https://old.reddit.com/r/neovim/comments/o66q3d/which_snippet_plugin_do_you_prefer_moving_out/h2x7enh/?context=10000
#35
From Folke's comment.
You need to add the below in your config to load friendly snippets:
lua require("luasnip/loaders/from_vscode").load()
I actually took and use
https://github.com/L3MON4D3/LuaSnip/blob/master/Examples/snippets.lua
So its included.
I also have friendly-snippets installed using packer.
use 'rafamadriz/friendly-snippets'
Regarding the runtimepath
The plugins are and snippets seems to be here.
~/.local/share/nvim/site/pack/packer/start/friendly-snippets/snippets
So I copied them to here
~/.config/nvim/lua/friendly-snippets
Not really sure how to continue.
I guess the missing part is the setting of runtimepath, but I dont fully grasp this.
Add the snippet-directory to your runtimepath (:set runtimepath+=snipdir)
Modify the package.json to match your layout and put it into snipdir's root
Hi!
Thanks for making a lua snippet engine for neovim! I was wondering if this plugin is as feature rich as UltiSnips.
Thanks!
I have a problem with empty lines apparently terminating a snippet definition. Consider the following simple snippet:
s('foo', {t('bar'','','baz')}),
which should expand to
bar
baz|
(with |
the cursor). But what happens is
bar|
When rendering the snippet in the buffer, if expandtab
is on \t
should be replaced by the tabstop
amount of spaces.
As title: <Plug>luasnip-expand-or-jump
doesn't work in select/visual mode.
To reproduce the issue, map
smap <silent><expr> <Tab> luasnip#expand_or_jumpable() ? '<Plug>luasnip-expand-or-jump' : '<Tab>'
or use my configuration.
local vim = vim
local nvim_set_keymap = vim.api.nvim_set_keymap
local prequire = require('plugins.utils').prequire
local luasnip = prequire('luasnip')
local compe = require('compe')
-- Completation
compe.setup {
preselect = 'enable',
documentation = true,
source = {
path = {menu = '', priority = 7}, -- this do not work
nvim_lsp = {menu = '歷', priority = 9},
spell = {menu = '暈', priority = 6},
nvim_lua = {menu = '', priority = 8},
luasnip = {menu = '', priority = 10},
treesitter = false
}
}
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
-- Use (s-)tab to:
--- move to prev/next item in completion menuone
--- jump to prev/next snippet's placeholder
_G.tab_complete = function()
if vim.fn.pumvisible() == 1 then
print('c-n') -- debug
return t '<C-n>'
elseif luasnip and luasnip.expand_or_jumpable() then
print('luasnip') -- debug
return t '<Plug>luasnip-expand-or-jump'
elseif check_back_space() then
print('Tab') -- debug
return t '<Tab>'
end
print('compe#complete') -- debug
return vim.fn['compe#complete']()
end
_G.s_tab_complete = function()
if vim.fn.pumvisible() == 1 then
return t '<C-p>'
elseif luasnip and luasnip.jumpable(-1) then
return t '<Plug>luasnip-jump-prev'
end
return t '<S-Tab>'
end
_G.enter_complete = function()
if luasnip and luasnip.choice_active() then
return t '<Plug>luasnip-next-choice'
end
return vim.fn['compe#confirm'](t '<CR>')
end
local opts = {expr = true, noremap = false, silent = true}
nvim_set_keymap('i', '<Tab>', 'v:lua.tab_complete()', opts)
nvim_set_keymap('s', '<Tab>', 'v:lua.tab_complete()', opts) -- s or v
nvim_set_keymap('i', '<S-Tab>', 'v:lua.s_tab_complete()', opts)
nvim_set_keymap('s', '<S-Tab>', 'v:lua.s_tab_complete()', opts) -- s or v
nvim_set_keymap('i', '<CR>', 'v:lua.enter_complete()', opts)
nvim_set_keymap('s', '<CR>', '<cmd>lua print(require("luasnip").expand_or_jumpable())<CR>', {}) -- debug too for s or v
apparently $MYVIMRC is not set which throws at
LuaSnip/lua/luasnip/loaders/from_vscode.lua:168
:h $MYVIMRC
*VIMINIT* *EXINIT* *$MYVIMRC*
b. Locations searched for initializations, in order of preference:
- $VIMINIT environment variable (Ex command line).
- User |config|: $XDG_CONFIG_HOME/nvim/init.vim.
- Other config: {dir}/nvim/init.vim where {dir} is any directory
in $XDG_CONFIG_DIRS.
- $EXINIT environment variable (Ex command line).
|$MYVIMRC| is set to the first valid location unless it was already
set or when using $VIMINIT.
also i try to lazy load like this
require("luasnip/loaders/from_vscode").lazy_load(
{paths = {"~/.local/share/nvim/site/pack/packer/start/friendly-snippets"}}
)
i use init.lua as cfg
nvim version
NVIM v0.5.0-dev+1375-gca802046b
Build type: RelWithDebInfo
LuaJIT 2.0.5
Compilation: /usr/bin/cc -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -Wp,-U_FORTIFY_SOURCE -Wp,-D_FORTIFY_SOURCE=1 -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/dnehrig/.cache/yay/neovim-git/src/build/config -I/home/dnehrig/.cache/yay/neovim-git/src/neovim-git/src -I/usr/include -I/home/dnehrig/.cache/yay/neovim-git/src/build/src/nvim/auto -I/home/dnehrig/.cache/yay/neovim-git/src/build/include
Compiled by dnehrig
Features: +acl +iconv +tui
See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/share/nvim"
Run :checkhealth for more info
Sorry, I opened an issue by accident.
I've used LuaSnip for a few days and I've been super happy with it so far. But just now I realized that I want LuaSnip to also handle automatic expansion of common paired symbols like (), '', [], {}, ""
. Right now I can make (<cr>
expand into (|)
where |
is the cursor and by pressing <tab>
I get ()|
so I can jump out. I would like this to work without having to press <cr>
for expanding the snippet. I tried to achieve this in the following way(and some other similar ways)
imap <silent><expr> ( ('<plug>luasnip-expand-or-jump'
and later I would have intended to add some treesitter things disable this for example inside comments. But this key bind doesn't work. I suspect that this isn't possible to do currently. If it is possible and I'm just failing at configuting LuaSnip then I would very much appreciate some help. If it isn't possible, then I hope this issue raises awareness of a feature that some would appreciate.
Since I've previously seen some resistance to adding this kind of feature to other snippet plugins before, I'll below give two arguments why I think this automatic pair expansion is better handled by a snippet plugin than by a dedicated automatic pair expansion plugin.
First reason. If I use both a snippet plugin and a auto pair plugin then pairs can come from two different sources: snippets or autopair. If the pair comes from snippets then I jump in and out of the pair as I want but if the pair comes from autopair then I can't jump around. This is an annoying inconsitency. I'd much prefer to always be able to jump around, meaning that I'd prefer to let automatic pair expansion be the job of the snippet plugin as well.
Second reason. So I want to easily jump out of a pair like ().
If this is pair is generated by nvim-autopairs(the autopair plugin I currently use) then I can't jump out the snippet way. But people say that if you just want to leave the pair the just press )
and you'll jump out, or at least you would jump out if the cursor was right before the automatically generated closing perenthesis. At least on my nordic keyboard layout, )
is Shift+9
. So jumping out of a pair ()
by writing the closing parenthesis is much more awkward than simply jumping out the snippet way, by pressing <tab>
. So having snippets handle auto pair expansion also gives a much more convenient way to jump out of auto expanded pairs.
So my conclusion is that if the snippet plugin handles automatic expansion of pairs instead of having a non-snippet plugin doing this then we get an experience which is 1) more consistent, and 2) more convenient.
Would you be open to using https://github.com/JohnnyMorganz/StyLua on this project? I want to contribute some stuff, but your lua style is like the opposite of what I have set up for all my other lua projects, so it makes it hard to write it the right way for this project 😆
Stylua supports using tabs and all that, so if you want to keep doing that, that's totally fine with me, you (or I in a PR) could just add a stylua.toml
file in the base of the repo and then I don't have to worry about messing up your style haha
Currently, the behaviour I have is that if there exists a saved location(do these have a name in snippet lingo? tabstop?) and if I press a key which I have mapped to <plug>luasnip-expand-or-jump
then my cursor is moved to the next saved location regardless of how far away from that saved location I may have been. This has happened quite a few times when I have snippets with saved locations that I don't necessarily have to touch. Then instead of jumping through all the locations I may just enter normal mode and exit the snippet that way. But then the snippet jump locations are not removed and I jump to them the next time I want to insert a new line, because I have <cr>
bound with a condition to first complete with compe, then LuaSnip and then insert a new line.
I wonder, is it possible to make it so that I only jump to a saved location if I am within the start and end points of the code that was inserted by the snippet?
If this is not possible, is this a feature you think makes sense for the plugin to have? The plugin works with nested snippets and I think it might be important to note that this shouldn't interfere with that, since in a nested snippet you are still within the body of the outer snippet.
I'm trying to migrate my snippets but I don't understand well how I'm supposed to use the f
node
all = {
s({trig = "date", wordTrig = true},
{f(function() os.date() end, {})}
),
s({trig = "date1", wordTrig = true},
{f(function() t{os.date()} end, {})}
),
}
None of those work so no idea what should I do.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.