newlines in tabstop default text break the snippet

Bug #616315 reported by Ryan Wooden
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
UltiSnips
Fix Released
Medium
Unassigned

Bug Description

The output of :py import sys; print sys.version:
2.6.5 (r265:79063, Apr 16 2010, 13:28:26)
[GCC 4.4.3]

I attached unit tests which demonstrate the problem. All of the tests, except for the one that should, fail. Rather than jumping to the first tab stop after expanding the snippet, ultisnips causes vim to leave (and stay out of) insert mode.

I think that at least part of the problem has to do with the fact that the newline character '\n' exists at the end of the previous line. When ultisnips tries to jump to tab stop #1 in:

x${1:
}

then it tries to select a range (0,1)->(1,0), but it should only select (0,1).

I'm happy to try to fix this (and I'm looking for a way to do so), but I'm not sure where in the code it should be fixed. Any suggestions, or an actual fix would be great!

Related branches

Revision history for this message
Ryan Wooden (ryan.wooden) wrote :
Revision history for this message
SirVer (sirver) wrote :

Have you tried using the escape sequence '\n' in the snippet instead of an actual newline?

Changed in ultisnips:
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
Ryan Wooden (ryan.wooden) wrote :

I'm not entirely sure what you mean. Using the \n escape in the raw string in the unit tests (understandably) puts "\n" into the snippet, so the test passes, but not for the right reasons. If I use a regular string, and use the \n escape, or even if I use a python block to return a newline, its always the same result as with a literal newline.

Revision history for this message
SirVer (sirver) wrote :

I just looked into the problem. The bug seems to be in select_span. This is the problem with the first snippet:

r"""
x${1:
}
$2
"""

for the first tab stop, the delta = stop - start variable is 1 line and -1 column. The issued key sequence to vim is then
<ESC>v1j2h<c-g>

the problem is that after the 1j, the cursor is already in position zero (because of the newline and how vim moves and as long as virtualedit is not set to all); vim now chokes on the 2h and ignores the <c-g> to go to select mode.
If the (for this case correct) key sequence <Esc>v1j<c-g> is issued, all seems to work. I tried playing around with the codeblock

if 0 <= delta.col <= 1:
                do_select = ""
elif delta.col > 0:
                do_select = "%il" % (delta.col-1)
else:
               do_select = "%ih" % (-delta.col+1)

but kept breaking other tests.

To correctly select line breaks, we need to predict how vims cursor moves with each movement command... I guess this is not so easy currently.

I'd like to get this one fixed before 1.2 (which is immenent!). any help is very much appreciated.

Changed in ultisnips:
milestone: none → 1.2
Revision history for this message
SirVer (sirver) wrote :

Fixed in r218. I had to special case both cases (newline as first char in a tabstop and newline as last char in a tabstop) and in one case, i actually had to change the current line in vim, but all in all I think the solution I found is satisfactory like that.

The select_span function is really a mess of special casing. It could take a lot of love, but it gets the job done :/.

Are you d'accord with releasing UltiSnips 1.2 now or is there anything that anyone still wants in it/fixed for it?

Changed in ultisnips:
status: Confirmed → Fix Committed
Revision history for this message
Ryan Wooden (ryan.wooden) wrote :

I'm not sure if this is the place to say this, but I don't have anything else to add to the release, except possibly something regarding my comment on bug 427298.

Revision history for this message
Ryan Wooden (ryan.wooden) wrote :

I'm not sure if this should be reported as a new bug, or a continuation of this one, but I think the fix for this introduced another bug.
I've attached a failing test case.

When the default text for a tabstop contains more than two lines, and the tabstop is cleared (eg, with <BS>), then all of the lines after the first two get appended to the end of the snippet! For example, given:

x${1:a
b
c
d
e
f}
$2

if you expand, then <BS> the tabstop, then the result is:

x

d
e
f

instead of just "x".

SirVer (sirver)
Changed in ultisnips:
status: Fix Committed → Confirmed
Revision history for this message
SirVer (sirver) wrote :

This is likely another bug that only surfaced now. I pushed a fix in r222. Please keep on testing!

Changed in ultisnips:
status: Confirmed → Fix Committed
Revision history for this message
SirVer (sirver) wrote :

Fix released in version 1.2.

Changed in ultisnips:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.