ultisnips icon indicating copy to clipboard operation
ultisnips copied to clipboard

Nested snippets producing tabstop error

Open tbrazel opened this issue 4 years ago • 2 comments

Hey, I wanted to report a bug I noticed while trying to write some post-jump snippets for LaTeX. I've been working with @andresnmejiaa who has been able to replicate this error on a second device.

I was trying to expand the dynamic tabstop snippet example as described on the page here. When expanding it at the start of the line, everything works as expected:

testing1

The problem is when I try to do it inside of another snippet. For example, I have a snippet that puts me in an aligned math mode

snippet [[ "display math" bA
\\begin{align*}
	$1
\\end{align*}
$0
endsnippet

When I am at the $1 tabstop of this snippet, and I try expanding the dynamic snippet tr9, I get the following error where tabstops are repeated: testing2

I'm worried that tabstops are multiplying in some way. Any help would be highly appreciated!

tbrazel avatar Feb 27 '20 00:02 tbrazel

Fun bug! I can reproduce, but have no immediate clue where this might be coming from. Thanks for reporting!

SirVer avatar Feb 27 '20 09:02 SirVer

I'm not entirely sure if this related but it seems fairly similar. I am using the following snippets:

global !p
def create_matrix_placeholders(snip):
	# Create anonymous snippet body
	anon_snippet_body = ""

	# Get start and end line number of expanded snippet
	start = snip.snippet_start[0]
	end = snip.snippet_end[0]

  # Append current line into anonymous snippet
	for i in range(start, end + 1):
		anon_snippet_body += snip.buffer[i]
		anon_snippet_body += "" if i == end else "\n"

	# Delete expanded snippet line till second to last line
	for i in range(start, end):
		del snip.buffer[start]

	# Empty last expanded snippet line while preserving the line
	snip.buffer[start] = ''

	# Expand anonymous snippet
	snip.expand_anon(anon_snippet_body)

def create_matrix(snip, cols, rows, sep, end):
	placeholder = 1
	snip >> 1
	for _ in range(0, int(rows)):
		line = f"${placeholder} "
		placeholder += 1
		for _ in range(0, int(cols) - 1):
			line += sep + f" ${placeholder} "
			placeholder += 1
		snip += line+end
	snip << 1
endglobal

post_jump "create_matrix_placeholders(snip)"
snippet 'pmat(\d+)x(\d+)' "LaTeX pmatrix" r
\begin{pmatrix}`!p create_matrix(snip, match.group(1), match.group(2), "&", "\\\\\\\\")`
\end{pmatrix}$0
endsnippet

snippet mk "Math" wA
$${1}$`!p
if t[2] and t[2][0] not in [',', '.', '?', '-', ' ']:
	snip.rv = ' '
else:
	snip.rv = ''
`$2
endsnippet

If I now do say mk<tab>pmat5x5<tab> I get the following error:

An error occured. This is either a bug in UltiSnips or a bug in a
snippet definition. If you think this is a bug, please report it to
https://github.com/SirVer/ultisnips/issues/new
Please read and follow:
https://github.com/SirVer/ultisnips/blob/master/CONTRIBUTING.md#reproducing-bugs

Following is the full stack trace:
Traceback (most recent call last):
  File "/home/jewe37/.local/share/nvim/plugged/ultisnips/pythonx/UltiSnips/err_to_scratch_buffer.py", line 18, in wrapper
    return func(self, *args, **kwds)
  File "/home/jewe37/.local/share/nvim/plugged/ultisnips/pythonx/UltiSnips/snippet_manager.py", line 302, in expand_anon
    self._do_snippet(snip, before)
  File "/home/jewe37/.local/share/nvim/plugged/ultisnips/pythonx/UltiSnips/snippet_manager.py", line 779, in _do_snippet
    self._jump(JumpDirection.FORWARD)
  File "/home/jewe37/.local/share/nvim/plugged/ultisnips/pythonx/UltiSnips/snippet_manager.py", line 590, in _jump
    self._active_snippets[0].update_textobjects(vim_helper.buf)
  File "/home/jewe37/.local/share/nvim/plugged/ultisnips/pythonx/UltiSnips/text_objects/snippet_instance.py", line 93, in update_textobjects
    if obj._update(done, buf):
  File "/home/jewe37/.local/share/nvim/plugged/ultisnips/pythonx/UltiSnips/text_objects/python_code.py", line 253, in _update
    ct = self.current_text
  File "/home/jewe37/.local/share/nvim/plugged/ultisnips/pythonx/UltiSnips/text_objects/base.py", line 113, in current_text
    return vim_helper.buf[self._start.line][self._start.col : self._end.col]
  File "/home/jewe37/.local/share/nvim/plugged/ultisnips/pythonx/UltiSnips/buffer_proxy.py", line 124, in __getitem__
    return self._buffer[key]
  File "/usr/lib/python3.9/site-packages/pynvim/api/buffer.py", line 45, in __getitem__
    return self.request('nvim_buf_get_lines', i, i + 1, True)[0]
  File "/usr/lib/python3.9/site-packages/pynvim/api/common.py", line 58, in request
    return self._session.request(name, self, *args, **kwargs)
  File "/usr/lib/python3.9/site-packages/pynvim/api/nvim.py", line 182, in request
    res = self._session.request(name, *args, **kwargs)
  File "/usr/lib/python3.9/site-packages/pynvim/msgpack_rpc/session.py", line 102, in request
    raise self.error_wrapper(err)
pynvim.api.common.NvimError: Index out of bounds

Similarly to the issue #1339 that I recently reported this behavior only ocurrs in nested snippets. I am assuming somehow information from the outer snippet must be leaking into the processing of the inner snippet.

JeWe37 avatar Apr 10 '21 14:04 JeWe37