garbas / vim-snipmate

snipMate.vim aims to be a concise vim script that implements some of TextMate's snippets features in Vim.
www.vim.org/scripts/script.php?script_id=2540
2.01k stars 181 forks source link

Snippet expansion fails intermittently #275

Closed victoriastuart closed 4 years ago

victoriastuart commented 4 years ago

Apologies if this is a FAQ. Examples:

So, I constantly have to reposition the cursor and press <tab> to complete the expansion.

It appears to be an issue with completion of the second of two concurrent snippet expansions, perhaps exacerbated by the cursor repositioning (${1})?

For reference, here are the snippets mentioned:

snippet pp
    <p>${1:}</p>

snippet li
    <li> ${1:}

snippet b
    <b>${1:}</b>

snippet i
    <i>${1:}</i>
ajzafar commented 4 years ago

This is actually working as intended, though your confusion is totally understandable.

For each of your snippets, SnipMate adds a $0 to the end of it, which indicates where the cursor should be when the snippet is done with. By default SnipMate maps <tab> to a function that first tries to jump to the next tabstop. If none exists, only then does it trigger the snippet before the cursor. So when you're hitting tab, SnipMate jumps to that zero tabstop instead of triggering your snippet like you expect.

There are two possible solutions here: you can change your snippets so that the zero tabstop is inside the HTML tag, something like <p>$0</p>, or you can create another insert mode mapping that always triggers a snippet, whether you're in one already or not. That would look like :imap <C-J> <Plug>snipMateTrigger where ` is the key you want to map to. The map probably makes more sense for you.

The relevant sections in the help are :h SnipMate-zero-tabstop and :h SnipMate-mappings.

victoriastuart commented 4 years ago

Hi Adnan: thank you for your reply. I played around a bit, finding a solution. In the second example above,

I type li <tab> pp <tab> expecting to get <li> <p><cursor</p>, but instead get <li> pp, with the [block] cursor positioned over the first p in pp

... I solved this by removing the ${1:} in my li snippet:

snippet li
    <li> 

not

snippet li
    <li> ${1:}

Likewise I solved the other examples shown by editing my snippets (replacing ${1:} with ${0}:

snippet b
    <b>${0:}</b>

snippet i
    <i>${0:}</i>

not

snippet b
    <b>${1:}</b>

snippet i
    <i>${1:}</i>

Now, I can get <b><i><cursor></i></b> (or the reciprocal, <i><b><cursor></b></i>) through a b <tab> i <tab> (etc.) keypress sequence. :-)

While I could have simply defined a "two-in-one snippet," e.g.

snippet bi
    <b><i>${1:}</i></b> ${0:}

... I needed to understand this behavior, as it affects some other tandem snippet combinations.

Thank you for your kind response and your work; much appreciated! :-)