Giter Club home page Giter Club logo

nvim-snippy's People

Contributors

aurelweinhold avatar bjin avatar cnrrobertson avatar dcampos avatar dmitmel avatar env25 avatar fl3pp avatar hwadii avatar kafva avatar matharman avatar mg979 avatar paniash avatar pbogut avatar s1n7ax avatar saccarosium avatar telemachus avatar uga-rosa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

nvim-snippy's Issues

Regex transformed tabstop are expanded if it occurs before its source tabstop

It seems that currently, only the first occurrence of specified tabstop will be expanded, even if it's a regex transformed tabstop of a latter (real) one.

snippet readint
	scanf("%d${1/[^,]*,[^,]*/%d/g}", $1);

Here I'm trying to automatically generate scanf() format string for reading multiple ints in C/C++ (contains of multiple %ds) of arguments $1. However, snippy only tries to expand the first occurrence of $1, and it broke this snippet. Swapping these two occurrence of tabstop $1 works fine as expected.

I think it doesn't really make sense to expand transformed tabstop in the first place, since its just a substitute of a real tabstop with user input.

EDIT 1: I could confirm this snippet works as expected with VSCode.

EDIT 2: $1 set to &a, &b, &c will expand the snippet to scanf("%d%d%d", &a, &b, &c);

`snippy-cut-text` mapped to `<C-i>` without explicit mapping

Hi!

First of, thank you again for this great plugin. I really enjoy using it!

I noticed <C-i> was not working in my neovim configuration and when I started to investigate (using :map <C-i>) I noticed that I had it mapped to snippy-cut-text. But I didn't do that. verbose tells me the mapping is comming from my lua config. The relevant sections are:

local snippy = require('snippy')
snippy.setup({
    mappings = {
        is = {
            ["<Tab>"] = "expand_or_advance",
            ["<S-Tab>"] = "previous",
        },
        nx = {
            ["<Tab>"] = "cut_text",
        },
    },
})

and if it matters, cmp-snippy is also installed

local cmp = require('cmp')
cmp.setup({
    sources = cmp.config.sources({
        { name = 'snippy' },
    }),
    snippet = {
        expand = function(args)
            require('snippy').expand_snippet(args.body)
        end,
    }
})

So now I am wondering why <C-i> is being mapped to snippy-cut-text.
I've searched my whole nvim config directory for the strings that would create this mapping in VimL and Lua and could not find anything, so I'm wondering if this is perhaps a problem with snippy or cmp-snippy?
Thank you in advance!

j/k move cursor in selection mode instead of inserting letters j/k

Example case: I have a snippet for C++ for loop, which expands to

for (int i = 0; i < counter; i++)
{

}

But when I <Tab> to i (with all three of them to be edited in the selection mode), and want to repalce it with j, my cursor moves down instead, extending the selection. The same happens with k, but this time cursor goes up one line. Other letters seem to work fine, i.e. I have no problem with replacing i with, e.g., s. I tried the same with almost all of other plugins disabled (including nvim-cmp), still behavior is the same. Franky, I am surprised to see that pressing letter keys in the selection mode works like in the visual mode (not replacing the selection).

Nested expansion sometimes doesn't work

Description

It looks like there is some issue when trying to expand a snippet from inside another.

First snippet:

snippet s1
	local ${1:var} = ${0:value}

Second snippet:

snippet s2
	require(${1:modname})

Steps to Reproduce

  1. Expand the first snippet.
  2. Jump to the second tab stop.
  3. Expand the second snippet.

Expected Result

The modname placeholder gets selected.

Actual Result

The placeholder is skipped and the cursor jumps to the end of the line.

Additional Context

No response

Commit 656a232b6d03770a887ecef6d3617a3f2efed665 breaks tab stops in certain cases

I use a custom completion mechanism written in Lua (see here). This completion mechanism supports inserting snippets using Snippy and LSP snippets. One feature is that if there's a single entry, it's expanded immediately instead of requiring you to confirm it.

Today I noticed this seems to break the tab stops in snippets. For example, I have this snippet:

snippet context "Insert a context block"
	context '${1:description}' do
		${0}
	end

When I type context then trigger snippy.can_expand() through an insert mapping, all is fine and the tab stops work properly. However, when I trigger the expansion using my completion mechanism (by pressing Tab in my case), it does expand the snippet, but I can't jump to any placeholders.

Running git bisect revealed this started happening with commit 656a232. Commits before that one work just fine.

Annoyingly I haven't been able to narrow this down to something simple. For example, if I do snippy.expand_snippet(snippy.snippets.ruby.context) in the completion code, it also doesn't work. Weirdly enough, it does work when I use this mapping:

imap <C-t> <cmd>lua require('snippy').expand(vim.inspect(require('snippy').snippets.ruby.context))<cr>

Delay in expanding snippets when using auto-trigger

Hi!

Thanks for the implementation of the auto-trigger feature! It works very well but the only issue so far has been the delay it takes for it to start. For example, when launching a latex file (having defined tex.snippets), when using snippets using auto-trigger, it doesn't work at all for a couple of seconds. However, after this delay it works very well. The issue is the finite time it takes from launching a file and expanding the snippet.

I know that the help.txt specifies a dip in performance when using auto-trigger. Is it an inherent issue with lua or can it be fixed in the plugin in the future?

Trigger options similar to UltiSnips

Hi!

I was wondering if like UltiSnips, nvim-snippy has options for triggers. For example, in UltiSnips

snippet ss1 "Subsection*" A
\subsection*{$1}

$0
endsnippet

would mean that typing ss1 would instantly place the template without pressing <Tab> (A in the first line means automatic). Is this sort of thing possible with nvim-snippy?

Strange conflict with miniyank

Description

With miniyank, I have p mapped to <Plug>(miniyank-autoput):

:map p
  p             <Plug>(miniyank-autoput)

Then, for example when completing this snippet:

snippet fn "Function definition"
	fn ${1:function_name}(${2})${3} {
		${0}
	}

and pressing p to type the first character of function_name, neovim appears to run the miniyank-autoput command instead of inserting the p character.

See this demo where I first yank foobar and then complete the snippet with fn<tab>, and insert p as the first character of the function name, and then press p repeatedly.

Every other character works normally, and even p works if I type something else as the first character of the function.

Kapture 2022-12-11 at 15 57 03

If I unmap p, the problem goes away.

Any ideas? Thank you!

Steps to Reproduce

See description.

Expected Result

See description.

Actual Result

See description.

Additional Context

No response

Doesn't work with compound filetypes.

I have a really niche use case here. Both Vim and Neovim have a handy feature that allows a file to be recognized as multiple filetypes, then various scripts and autogroup actions can be ran for each of the filetypes that applies. As an example I'm using the Vimwiki plugin to edit markdown files, some types of markdown can also be considered a pandoc file as well. In neovim if I open a markdown file and issue the command :set filetype it shows the current filetype as vimwiki.markdown.pandoc as expected. However, this plugin doesn't recognize this as a list of filetypes. Instead, as far as I can tell, it recognizes a single filetype vimwiki.markdown.pandoc and doesn't load until I issue the command set filetype=markdown. At any rate, thanks again for this rad plugin!

Support choices mixed with vim functions

First of all, thanks! Great plugin!

Would it be possible to enable the plugin to support mixed vim functions and static texts in the placeholder choices? Something like:

snippet today
  ${1|`strftime('%c')`,today|}

Empty replacements don't seem to work in transformations

The replacement part of regex transformations doesn't seem to work when empty. For example:

local $1 = ${1/_//g}

Entering my_snake_case_variable should result in mysnakecasevariable. Currently the transform isn't even being parsed correctly; the raw text is inserted when the snippet is expanded:

local var_name = ${1/_//g}

col value out of range

Explain the issue

Sometimes some error messages like col vlaue out of range pop up.

Steps to reproduce

  1. run nvim -u vimrc.vim test.py

  2. We can input like this
    image

  3. Then we press tab key, and the snippt will be expanded.
    image

  4. Then we go ahead and press the tab key to make the cursor jump to the comment.
    image

  5. Type something random and when we type the second letter, an error message will pop up
    image

Minimal working example

test.py

def

Minimal vimrc file

vimrc.vim

if has('vim_starting')
  set encoding=utf-8
endif
scriptencoding utf-8

if &compatible
  set nocompatible
endif

let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/plug.vim')
  execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end

execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'dcampos/nvim-snippy'
Plug 'honza/vim-snippets'
call plug#end()
PlugInstall | quit

imap <expr> <Tab> snippy#can_expand_or_advance() ? '<Plug>(snippy-expand-or-advance)' : '<Tab>'
imap <expr> <S-Tab> snippy#can_jump(-1) ? '<Plug>(snippy-previous)' : '<S-Tab>'
smap <expr> <Tab> snippy#can_jump(1) ? '<Plug>(snippy-next)' : '<Tab>'
smap <expr> <S-Tab> snippy#can_jump(-1) ? '<Plug>(snippy-previous)' : '<S-Tab>'
xmap <Tab> <Plug>(snippy-cut-text)

lua << EOF
    require('snippy').setup({
        hl_group = 'Search',
    })
EOF

Additonal information

nvim version: NVIM v0.7.0-dev+913-ge07a4b97f6
I can provide any other information if needed

What's the reason for the use of defer_fn, and is this not racy?

I was looking at the code of snippy in search of the smallest/most sensible snippet plugin there is (written in Lua). Snippy looks interesting because:

  1. The API thus far is easy to hook into my completion setup (unlike LuaSnip, which is a bit more tricky)
  2. It requires a surprisingly small amount of code
  3. You can define snippets in a sane syntax, rather than having to use JSON or LuaSnip's somewhat odd Lua API

While looking at the code I ran into the following lines:

vim.defer_fn(function ()

vim.defer_fn(function ()

The function called (

function M.setup_autocmds()
) sets up a bunch of autocmd events,

Now I don't know exactly why snippy needs this, but the combination of defer_fn and what seems to be a random delay strikes me as a bit odd. In particular, I think it's possible for the user to change text (for example) before the deferred function is called. Whatever Snippy needs these event hooks for may then not work.

Is the use of defer_fn really necessary here? If so, what are they used for? Thanks! ๐Ÿ˜ƒ

Error E5108

An error appear while delete a line which just snippy completed.
E5108: Error executing lua ...m/site/pack/packer/start/nvim-snippy/lua/snippy/stop.lua:32: attempt to index a nil value

Better documentation suggestions

I think the doc man be a bit clearer on some topics. For example, snippet_dirs is the directory containing the snippets folder. This one caused me a lot of headache as I thought snippet files had to be in snippet_dirs. Also you should mention that snippet definitions have to indented using tab. Thanks for the plugin btw. It's simple and it works like a charm.

can't expand time ,date

minimal.vim

set encoding=utf-8
"dein Scripts-----------------------------
if &compatible
    set nocompatible               " Be iMproved
endif

set runtimepath+=~/.cache/nvim/dein/repos/github.com/Shougo/dein.vim
call dein#begin($HOME . '/.cache/nvim/dein')
call dein#add($HOME . '/.cache/nvim/dein')
call dein#add('hrsh7th/nvim-cmp')
call dein#add('hrsh7th/cmp-buffer')
call dein#add('dcampos/cmp-snippy')
call dein#add('dcampos/nvim-snippy')
call dein#add('honza/vim-snippets')
call dein#end()

call dein#call_hook('source')
call dein#call_hook('post_source')
if has('vim_starting')
    let g:dein#auto_recache = 1
endif
" Required:
filetype plugin indent on
syntax enable

set background=dark

imap <expr> <Tab> snippy#can_expand_or_advance() ? '<Plug>(snippy-expand-or-next)' : '<Tab>'
smap <expr> <Tab> snippy#can_jump(1) ? '<Plug>(snippy-next)' : '<Tab>'
imap <expr> <S-Tab> snippy#can_jump(-1) ? '<Plug>(snippy-previous)' : '<Tab>'
smap <expr> <S-Tab> snippy#can_jump(-1) ? '<Plug>(snippy-previous)' : '<Tab>'

lua << EOF
    local cmp = require("cmp")
    cmp.setup({
        snippet = {
            expand = function(args)
                require 'snippy'.expand_snippet(args.body)
            end,
        },
        sources = {
            { name = "buffer" },
            { name = 'snippy' }
        },
        mapping = {
            ["<S-TAB>"] = cmp.mapping.select_prev_item(),
            ["<TAB>"] = cmp.mapping.select_next_item(),
            ["<C-Space>"] = cmp.mapping.complete(),
            ["<C-e>"] = cmp.mapping.close(),
            ['<CR>'] = cmp.mapping.confirm()
        },
    })
EOF

Repetition steps

  1. nvim -u minimal.vim a.c
  2. in insert mode ,type time , press tab , cr .

behavior

Snipaste_2021-09-20_19-56-57

Empty lines in snipMate snippets are expanded

Discussed in #82

Originally posted by raine October 11, 2022
If you use snippets such as these with snippy, you'll notice that the empty lines after the snippets (before the next snippet) are expanded as well.

Am I missing something obvious or is this a bug? A simple fix is to manually remove every blank line but the README claims snipMate compatibility so I was wondering about this.

Kapture 2022-10-11 at 16 05 15

^ Notice the extra empty line added when the snippet expands.

Thanks!

How to disable unwanted snippet sources

First of all thank you for this library. I've used most of the available snippet plugins for vim / nvim and this is my favorite.

My only problem is that there are certain snippet sources that interfere with function definitions for several languages. They often pop up when I try to use a closing parens ) or brace }. It's really driving me crazy. The additional typing that I need to do to avoid these unwanted completions pretty much negates the benifit of having the snippets that I actually use.

Screen Shot 2021-09-06 at 11 47 54 AM

I used the same snippet source (honza/vim-snippets) with UltiSnips and never had this issue in any language.

Here's my config:

  use {
    'dcampos/nvim-snippy',
    requires = {
      { 'honza/vim-snippets' },
      { 'dcampos/cmp-snippy' }
    },
  }

Any idea where these snippets are coming from and how I can disable them?

Mappings do not work with LSP snippets

Description

Hello,

when I complete a snippet from an LSP suggestion the tab stops do not work, I cannot jump between them. Instead the original meaning of the keys is applied. Regular snippets I have defined myself in snippets/*.snippets files work as expected. Here are my settings:

-- plugin/snippets.lua
local snippy = require 'snippy'
snippy.setup {
}
" plugin/snippets.vim
imap <expr> <Tab> snippy#can_expand() ? '<Plug>(snippy-expand)' : '<C-]>'
imap <expr> <C-n> snippy#can_jump(1) ? '<Plug>(snippy-next)' : '<C-j>'
imap <expr> <C-p> snippy#can_jump(-1) ? '<Plug>(snippy-previous)' : '<C-k>'
smap <expr> <C-n> snippy#can_jump(1) ? '<Plug>(snippy-next)' : '<C-j>'
smap <expr> <C-p> snippy#can_jump(-1) ? '<Plug>(snippy-previous)' : '<C-k>'

I use a patched completion.nvim as the completion plugin. Obviously I am not getting completion candidates for my own snippets, but I do get suggestions for snippets from LSP and I can accept them, which fills in the snippet contents properly.

I had been using UltiSnips before and it worked there. I am looking for a simpler replacement that does not have external dependencies, and so far snippy looks like the perfect fit if I can make LSP snippets work.

Steps to Reproduce

  1. Open a new buffer which will have any LSP server attached, I use Lua in my example
  2. Type some code to get suggestions which include a snippet (e.g. function)
  3. Accept the snippet suggestion
  4. The snippet will be expanded and inserted in place

Expected Result

I need to be able to jump between the tab stops of the snippet, i.e. function name, parameters and body in the case of function.

Actual Result

I cannot jump, snippy#can_jump is always returning false. Is there some extra step needed to be done by the completion plugin?

I also noticed that there are no placeholders inserted, but I am not sure if there are supposed to be any.

Additional Context

Screenshot_20220918_215627

Screenshot_20220918_215638

Screenshot_20220918_215653

Consolidate jumping/expanding API

Currently the <Plug> mapping is expand-or-next and the actual Lua function is expand_or_advance. I'm thinking about deprecating any 'expand-or-next' reference in favor of 'expand-or-advance', specially because there already is a can_expand_or_advance function too, which sounds better than can_expand_or_next.

Mirrored snippet expansion

Description

If you have a snippet with mirrored tabstops, and you expand a snippet in the first one, the expanded snippet is immediately mirrored to the other tabstops, except that you are in a new nested snippet, and updating this won't update the mirrored tabstops.

snippy

Steps to Reproduce

Sample lua snippets used in clip:

snippet ifr
	if $1 then
		$2
		$2
		$3
	end

snippet if
	if $1 then
		$2
	end

Complete ifr snippet up to $3, expanding if at $2, then go back to $1, change again $2, again back to $1.

Expected Result

Mirrored nested snippets are actually mirrored. Also a delayed mirroring would be ok.

Actual Result

Snippy can actually update the mirrored tabstops, but only if the parent of the newly expanded snippet gets reselected. If you just exit the snippet normally, they aren't updated.

Additional Context

This patch (sort of) fixes it for me, but tabstops are updated on snippet exit, I couldn't do it in real time.


PATCH HERE
diff --git a/lua/snippy.lua b/lua/snippy.lua
index 0b07639..adc0e3c 100644
--- a/lua/snippy.lua
+++ b/lua/snippy.lua
@@ -79,34 +79,6 @@ local function present_choices(stop, startpos)
     end, shared.config.choice_delay)
 end
 
-local function mirror_stop(number)
-    local stops = buf.stops
-    if number < 1 or number > #stops then
-        return
-    end
-    local cur_stop = stops[number]
-    local startpos, _ = cur_stop:get_range()
-    if startpos and startpos[1] + 1 > vim.fn.line('$') then
-        buf.clear_state()
-        return
-    end
-    local text = cur_stop:get_text()
-    if cur_stop.prev_text == text then
-        return
-    end
-    cur_stop.prev_text = text
-    for i, stop in ipairs(stops) do
-        if i > number and stop.id == cur_stop.id then
-            stop:set_text(text)
-        end
-    end
-    if cur_stop.spec.type == 'placeholder' then
-        if text ~= cur_stop.placeholder then
-            buf.clear_children(number)
-        end
-    end
-end
-
 local function sort_stops(stops)
     table.sort(stops, function(s1, s2)
         if s1.id == 0 then
@@ -337,7 +309,7 @@ end
 
 function M._mirror_stops()
     if buf.current_stop ~= 0 then
-        mirror_stop(buf.current_stop)
+        buf.mirror_stop(buf.current_stop)
     end
 end
 
@@ -365,7 +337,7 @@ function M._jump(stop)
         return false
     end
     if buf.current_stop ~= 0 then
-        mirror_stop(buf.current_stop)
+        buf.mirror_stop(buf.current_stop)
         buf.deactivate_stop(buf.current_stop)
     end
     local should_finish = false
@@ -374,7 +346,7 @@ function M._jump(stop)
         buf.clear_autocmds()
 
         buf.activate_stop(stop)
-        mirror_stop(stop)
+        buf.mirror_stop(stop)
 
         local value = stops[stop]
         local startpos, endpos = value:get_range()
diff --git a/lua/snippy/buf.lua b/lua/snippy/buf.lua
index 37fc3c0..0a0091d 100644
--- a/lua/snippy/buf.lua
+++ b/lua/snippy/buf.lua
@@ -11,13 +11,7 @@ M._state = {}
 
 setmetatable(M, {
     __index = function(self, key)
-        if key == 'current_stop' then
-            return self.state().current_stop
-        elseif key == 'stops' then
-            return self.state().stops
-        else
-            return rawget(self, key)
-        end
+        return self.state()[key] or rawget(self, key)
     end,
     __newindex = function(self, key, value)
         if key == 'current_stop' then
@@ -106,6 +100,7 @@ function M.state()
     if not M._state[bufnr] then
         M._state[bufnr] = {
             stops = {},
+            mirrored = {},
             current_stop = 0,
         }
     end
@@ -171,6 +166,35 @@ function M.update_state()
     M.state().before = before
 end
 
+function M.mirror_stop(number)
+    local stops = M.stops
+    if number < 1 or number > #stops then
+        return
+    end
+    local cur_stop = stops[number]
+    local startpos, _ = cur_stop:get_range()
+    if startpos and startpos[1] + 1 > vim.fn.line('$') then
+        M.clear_state()
+        return
+    end
+    local text = cur_stop:get_text()
+    if cur_stop.prev_text == text then
+        return
+    end
+    cur_stop.prev_text = text
+    for i, stop in ipairs(stops) do
+        if i > number and stop.id == cur_stop.id then
+            M.mirrored[number] = true
+            stop:set_text(text)
+        end
+    end
+    if cur_stop.spec.type == 'placeholder' then
+        if text ~= cur_stop.placeholder then
+            M.clear_children(number)
+        end
+    end
+end
+
 function M.fix_current_stop()
     local current_stop = M.stops[M.current_stop]
     if not current_stop then
@@ -187,11 +211,15 @@ function M.fix_current_stop()
 end
 
 function M.clear_state()
+    for n, _ in pairs(M.mirrored) do
+        M.mirror_stop(n)
+    end
     for _, stop in pairs(M.state().stops) do
         api.nvim_buf_del_extmark(0, shared.namespace, stop.mark)
     end
     M.state().current_stop = 0
     M.state().stops = {}
+    M.state().mirrored = {}
     M.state().before = nil
     M.clear_autocmds()
 end

Cannot undo repeated placeholders

The undo history gets really messed up with repeated placeholders.

Example lua snippet:

snippet for
	for ${1:k,v} in pairs(${2:table}) do
		${3:code}
		${3}
	done

After editing the third placeholder, pressing u repeatedly will only undo last edit.

Priority for snippets

Is there a way to provide priority for shippets?

What I'm looking for is some way to override one (or more) snippet with my own while using honza/vim-snippets. In ultisnip you could set priority in the fist line of snippet file like this:

priority -50

snippet blah "blah"
...

Then snippets in file with lower priority would be expanded in case of name conflict. Is there a way to achieve that in snippy?

Expand a snippet inside another

Is it possible to expand a snippet inside another? E.g.:

snippet qtimestamp
	`strftime("%Y-%m-%dT%H:%M:%S")`-03:00

snippet qheader
	---
	created: qtimestamp
	modified: qtimestamp
	type: Journal
	---

On the example above, on the snippet "qheader", I would like to automatically expand the qtimestamp snippet on the "created" and "modified" fields.

bad argument #1 to 'unpack' with Codi.vim plugin.

Explain the issue

Sometimes some error messages like bad argument #1 to 'unpack' pop up with Codi.vim plugin. I'm not sure if this is a bug in nvim-snippy. If not, I will close this and open issue in Codi.vim plugin.

Steps to reproduce

  1. run nvim -u vimrc.vim test.py

  2. run command :Codi

  3. We can input like this
    image

  4. Then we press tab key, and the snippt will be expanded.
    image

  5. Then we type something random and error message will pop up.
    image

Minimal working example

test.py

def

Minimal vimrc file

vimrc.vim

if has('vim_starting')
  set encoding=utf-8
endif
scriptencoding utf-8

if &compatible
  set nocompatible
endif

let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/plug.vim')
  execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end

execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'dcampos/nvim-snippy'
Plug 'honza/vim-snippets'
Plug 'metakirby5/codi.vim'
call plug#end()
PlugInstall | quit

imap <expr> <Tab> snippy#can_expand_or_advance() ? '<Plug>(snippy-expand-or-advance)' : '<Tab>'
imap <expr> <S-Tab> snippy#can_jump(-1) ? '<Plug>(snippy-previous)' : '<S-Tab>'
smap <expr> <Tab> snippy#can_jump(1) ? '<Plug>(snippy-next)' : '<Tab>'
smap <expr> <S-Tab> snippy#can_jump(-1) ? '<Plug>(snippy-previous)' : '<S-Tab>'
xmap <Tab> <Plug>(snippy-cut-text)

lua << EOF
    require('snippy').setup({
        hl_group = 'Search',
    })
EOF

Additonal information

nvim version: NVIM v0.7.0-dev+914-g7717f38d3f
I test vsnip and it works well with Codi.vim plugin.
I can provide any other information if needed

Placeholder isn't updated when nested tab stop changes

When a mirror tab stop is placed within a placeholder, its value is correctly mirrored correctly from the tab stop it refers to, but its parent placeholder's bounds aren't updated to include the mirrored value.

Steps to reproduce

  1. Define a Lua snippet like local ${1:module} = ${2:$1}.
  2. Expand the snippet.
  3. Change the first value to 'snippy'
  4. Jump to the next placeholder.

Expected behavior

Neovim should be in select mode and the word 'snippy' should become selected.

Actual behavior

Cursor is placed after the the mirrored word 'snippy' in insert mode.

snippy-nested1

Visual indicators for empty placeholders (tab stops)

Description

Is snippy expected to fill empty tab stops with placeholder text? Using lua-language-server, most of the snippets already have placeholder text at the tab stops, but the function () snippet does not. Because of that I couldn't tell where the tab stops were:
Screen Recording 2022-09-22 at 12 54 00

Steps to Reproduce

snippy config:

return {
	"dcampos/nvim-snippy",
	config = function()
		local loaded, snippy = pcall(require, "snippy")
		if not loaded then return end

		vim.api.nvim_create_autocmd("CompleteDone", {
			group = vim.api.nvim_create_augroup("snippy", { clear = true }),
			callback = function() snippy.complete_done() end,
		})

		snippy.setup({
			mappings = {
				is = {
					["<tab>"] = "next",
					["<s-tab>"] = "previous",
				},
			},
		})
	end,
}
  1. Set up lua-language-server and omnicomplete
  2. In a Lua file type local func then trigger omnicomplete with <c-x><c-o>
  3. Select the function () snippet from the pop-up menu then hit <esc> or <c-y>

Expected Result

The tab stops would have placeholder text to indicate where the tab stops are.

Actual Result

There's no placeholder text for tab stops.

Additional Context

No response

Allow indenting snippets with spaces

Right now snippets can only be indented with tabs, as per snipmate's approach. It could be a good idea to follow neosnippet here and allow indenting with spaces, as long as it is consistent.

Loading more snippets on demand

Hi, it is nice to see a snippet plugin that does not require external dependencies.

I am wondering if there is a way to load additional snippets on demand. Ie if you have snippets available for certain filetype and based a condition you would like to add more snippets for current buffer only. A practical example for this feature can be test files. Where normal snippets can be used. But you could also have test specific snippets. I know that UltiSnips have a command UltiSnipsAddFiletypes that allows to add additional snippets from a different filetype. Is something similar to this available or could be implemented with snippy?

Thanks

Error if priority is defined

Snippet file snipptes/tex.snippets:

priority 100

snippet ...
    ...
Error detected while processing FileType Autocommands for "*":
E5108: Error executing lua .../packer/start/nvim-snippy/lua/snippy/reader/snipmate.lua:110: Invalid priority in file /home/user/.config/nvim/after/snippets/tex.snippets, at line 1: 100
stack traceback:
        [C]: in function 'error'
        .../packer/start/nvim-snippy/lua/snippy/reader/snipmate.lua:110: in function 'read_snippets_file'
        .../packer/start/nvim-snippy/lua/snippy/reader/snipmate.lua:195: in function 'load_scope'
        .../packer/start/nvim-snippy/lua/snippy/reader/snipmate.lua:261: in function 'read_snippets'
        ...e/nvim/site/pack/packer/start/nvim-snippy/lua/snippy.lua:556: in function 'read_snippets'
        [string ":lua"]:1: in main chunk

Custom expand options

Problem Statement

I was wondering if it would be possible to use custom options (aside from the w,i,b,A that are included). I'm imagining defining the option letter along with a lua function in a table in the setup() call.

I should mention that I have a very specific use case in mind which is to only autoexpand certain snippets when in a "math" context in Latex. It makes it easy to define autosnippets related to math that don't expand while you are writing the body of the document. See here for examples.

Ideas or possible solutions

From a quick look at your source, I think it could be as simple as checking for a letter that is not i,w,b,A, including it in option, then looking up the corresponding function on expand.

It could also plug into can_expand as a conditional.

Alternatives you have considered

Ultisnips has this functionality as custom contexts and Luasnip has this as condition.

Variables aren't expanding

The only variable that works is $VISUAL.
I'm using nvim-cmp for autocompletion.
Am I missing something?

List all available snippets outside of completion engine

Hello again!

I searched your documentation, but I didn't find what I will just describe, so sorry if I misunderstood it.

Is there a function/command I could map on my configuration to have a list of all available snippets on the current filetype? If so, could you point me what is its' name?

E.g. of what I am looking for:

nnoremap <silent> <leader>sl <cmd>lua require'snippy'.list_snippets()<CR>| " (snippy) list snippets for current filetype

honza/vim-snippets Works But My Custom Vim Snippets do Not Work

Description

I am using honza/vim-snippets for a bunch of sensible default snippets. But I want to change the default C snippets. So I created a file ~/.config/nvim/snippets/c.snippets, and changed some snippets, but the changes do not apply.

Steps to Reproduce

  1. git clone honza/vim-snippets into ~/.local/share/nvim/site/pack/default/start
  2. copy honza/vim-snippets/snippets/c.snippets into ~/.config/nvim/snippets
  3. change some snippets

Expected Result

The changed I made to the snippets apply

Actual Result

It still uses honza's vim snippets

Additional Context

No response

Drop support for outdated versions of Neovim

Problem Statement

Currently, Snippy supports Neovim >= 0.5.0. Some features added in later versions, like Lua autocmds, may improve performance and make the code more readable.

Ideas or possible solutions

The idea is to make 0.7.0 the minimum compatible version, while possibly keeping a separate nvim-0.5.0 branch for those who aren't able to upgrade Neovim to a more recent version.

Alternatives you have considered

Neovim development is progressing at a fast speed, so keeping compatibility with outdated versions doesn't seem necessary.

Support for placeholders for VISUAL

Thanks for creating this plugin. I really like the simplicity but still being able to use regex transformations ๐Ÿ‘

I don't think this is supported in the lsp snippet standard (at least vsnip does not support it), but maybe you want to support it anyways.

snippet trig
	triggered ${VISUAL:placeholder}

Basically if VISUAL is nil (or '') use placeholder instead.

Word-based expansion doesn't work as in Ultisnips

The current behavior when using the w option/modifier is different from how Ultisnips works, at least from what is present in their help file. Ultisnips seem to check for a pattern containing iskeyworkd characters, whereas Snippy considers the whole string of characters before the cursor.

Also, the actual default behavior in Ultisnips seems to be different from the one set by the w option. There needs to be further clarification on this.

Any help or insight greatly appreciated.

Omni complete results get overwritten when triggering omni complete a second time

Description

I'm using sourcekit-lsp for Swift. When using omni complete (eg, <c-x><c-o>), selecting the result from the pop-up menu and then continuing to type seems to create a weird state in which triggering omni complete a second time enters the first result again.

Steps to Reproduce

  1. Create a new executable Swift package (eg, mkdir swift_test && cd swift_test && swift package init --type executable)
  2. nvim Sources/swift_test/swift_test.swift
  3. Create a new line at the bottom of the file
  4. Type swift_ and then use <c-x><c-o> to open the pop-up menu for omni complete
  5. Use <c-n> or <c-p> to highlight the swift_test module in the pop-up menu
  6. Type a period
  7. Use <c-x><c-o> again

Expected Result

At step 5 swift_test would be inserted as text.
At step 6 the pop-up menu would be dismissed.
At step 7 the inserted text would remain as is and the pop-up menu would open again.

Actual Result

At step 7 the text swift_test. is replaced with sswift_test. If you type two periods at step 6 instead of only one, swift_test. is replaced with swswift_test.

Additional Context

CleanShot.2022-12-10.at.10.27.42.mp4

Here's my snippy config:

return {
	"dcampos/nvim-snippy",
	config = function()
		local loaded, snippy = pcall(require, "snippy")
		if not loaded then return end

		vim.api.nvim_create_autocmd("CompleteDone", {
			group = vim.api.nvim_create_augroup("snippy", { clear = true }),
			callback = function() snippy.complete_done() end,
		})

		snippy.setup({
			mappings = {
				is = {
					["<tab>"] = "next",
					["<s-tab>"] = "previous",
				},
			},
		})
	end,
}

Highlights are wrong.

image

echo expand("%:t") -> go.snippets
set ft? -> filetype=snippets
setlocal syntax? -> syntax=snippets

Why are you hard-coding the choice timer to start at 500ms and not repeat?

500ms is a definite delay. Why don't you use a repeating?

like this.

local function present_choices(stop, startpos)
    local timer = vim.loop.new_timer()

    timer:start(0, 100, vim.schedule_wrap(function()
        if (candidates are exists) then
            fn.complete(startpos[2] + 1, make_completion_choices(stop.spec.choices))
            timer:stop()
            timer:close()
        end
    end))
end

Shell snippet for `$`

Hi,

I would like to expand $ to ${} for shells (ft=sh):

snippet $
    ${$1}

That doesn't work. How do I achieve that?

It works fine for % -> %{} for ft=spec

Show completion menu when a prefix matches multiple triggers

Maybe this is already an option, but I haven't been able to figure out how to show the completion menu with several completions without having to write the entire trigger.

For example, suppose you have several snippets with the same prefix : (e.g. :check:, :arrow: and other unicode symbols), so you may want to simply type :<Tab> and show all of the relevant triggers in a completion menu. Is this possible? I noticed there is snippy.get_completion_items(), but I don't think it is possible to use it (Unknown function: snippy#get_completion_items)

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.