SirVer / ultisnips

UltiSnips - The ultimate snippet solution for Vim. Send pull requests to SirVer/ultisnips!
GNU General Public License v3.0
7.56k stars 691 forks source link

Anonymous snippets alter containing snippets #193

Open SirVer opened 10 years ago

SirVer commented 10 years ago

If an anonymous snippet inserts lines into the text of another snippet, the added lines are not recognized by the containing snippet. In effect, tabstops are placed over the added lines at the (line,column)-coordinates where the original tabstops of the containing snippet were before the insertion of the anonymous snippet.
This is in contrast with what happens when static lines (i.e. not snippets) are manually added to the containing snippet. In this case the added lines don’t alter the behavior of the containing snippet.

Example: 1) Create the two files below and type 'container' in a new buffer and expand the snippet. 2) Go through some tabstops until the second or third line beginning with "@field" 3) In insert-mode press 3. An anonymous snipped is inserted. It adds a line. This can be repeated any number of times. Each time, a new line is added. 4) After expanding/replacing the tabstops of the anonymous snippet continue typing JumpForwardTrigger. Observe that the tabstops assumes that no line has been inserted, since the tabstops follow the line-column pattern of the original containing snippet. 5) Repeat steps 1-4 but inserting lines by hand in step 3 instead of triggering the anonymous snippet via 3. Observe that the containing snippets correctly recognized the added lines and places the tabstops at the correct positions.

###### 
# .vim/plugin/anon.vim
###### 

if exists("g:loaded_anon") || &cp
  finish
endif
let g:loaded_anon = 1
let s:save_cpo = &cpo
set cpo&vim

fun s:Continue_header()
    let field = "foo"
    return "\<CR>$HEADER\<C-R>=UltiSnips#Anon('".field."${1:value of inserted field}', '$HEADER')\<CR>"
endf

inoremap <silent> 3 <C-R>=<SID>Continue_header()<CR>

let &cpo = s:save_cpo
unlet s:save_cpo
###### 
# .vim/UltiSnips/all.snippets
###### 

snippet container "Container snippet" 
${1:First line} 
${2:Second line} 
@field_A    ${10:A value} 
@field_B    ${11:B value} 
@field_C    ${12:C value} 
@field_D    ${13:D value1} -- ${14:D value2} -- ${15:D value3} 
@field_E    ${16:E value}] 
${20:@date  `!v strftime("%Y %b %d %X")`} 
${30:Some other line} 
$0
endsnippet

:py import sys; print sys.version 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)]

Launchpad Details: #LP1091466 esquifit - 2012-12-17 23:53:23 +0100

SirVer commented 10 years ago

This is a terrific bug report and I can totally reproduce the problem. However I have no immediate clue how to fix it - the problem is that vim seems to suppress some autocommand jumps which would happen if this where a regular snippet. This confuses Ultisnips. Working around the issue seems possible but would mean major work.

I know it is a little hackis, but could you try a solution that uses feedkeys() to basically type and expand a 'normal' snippet?

Launchpad Details: #LPC SirVer - 2012-12-20 20:51:00 +0100

SirVer commented 4 years ago

Still reproduces at 43b059bf1c20a1d328b7499c45332d367620c541.

piperfw commented 4 years ago

Similar to the closed #248, when an anonymous snippet is nested inside a normal snippet, <c-j> does not correctly step through the fields of the outer snippet. It does attempt to jump to the next field (unlike described by #248).

Example: https://imgur.com/a/PFrpxb7 Snippets used in example: https://pastebin.com/XFgXDzKQ