From 118045a24a4355a564513ffead35fafae44e4290 Mon Sep 17 00:00:00 2001 From: Holger Rapp Date: Thu, 16 Jul 2009 17:00:25 +0200 Subject: [PATCH] Added more test cases for recursive tabstops, fixed some bugs that occured --- plugin/UltiSnips/TextObjects.py | 29 ++++--- plugin/UltiSnips/__init__.py | 15 ++-- test.py | 131 +++++++++++++++++++++++++++++--- 3 files changed, 147 insertions(+), 28 deletions(-) diff --git a/plugin/UltiSnips/TextObjects.py b/plugin/UltiSnips/TextObjects.py index 834ccac..5ad9688 100644 --- a/plugin/UltiSnips/TextObjects.py +++ b/plugin/UltiSnips/TextObjects.py @@ -215,9 +215,10 @@ class _TOParser(object): start, end = self._get_start_end(self._v,start_pos,end_pos) - ts = TabStop(self._p, start, end, def_text) + no = int(m.group(1)) + ts = TabStop(no, self._p, start, end, def_text) - self._p._add_tabstop(int(m.group(1)),ts) + self._p._add_tabstop(no,ts) self._overwrite_area(start_pos, end_pos) @@ -267,7 +268,7 @@ class _TOParser(object): if ts is not None: rv = Mirror(self._p, ts, start, end) else: - rv = TabStop(self._p, start, end) + rv = TabStop(no, self._p, start, end) self._p._add_tabstop(no,rv) self._overwrite_area(*m.span()) @@ -654,8 +655,13 @@ class TabStop(TextObject): This is the most important TextObject. A TabStop is were the cursor comes to rest when the user taps through the Snippet. """ - def __init__(self, parent, start, end, default_text = ""): + def __init__(self, no, parent, start, end, default_text = ""): TextObject.__init__(self, parent, start, end, default_text) + self._no = no + + def no(self): + return self._no + no = property(no) def __repr__(self): return "TabStop(%s -> %s, %s)" % (self._start, self._end, @@ -684,11 +690,11 @@ class SnippetInstance(TextObject): # Check if we have a zero Tab, if not, add one at the end debug("type(parent): %s" % (type(parent))) - if not isinstance(parent, StartMarker): - # We are recursively called, if we have a zero tab, remove - # it. This might be fatal if the zero tab is somehow mirrored - # TODO: This needs doing - pass + if isinstance(parent, TabStop) and not parent.no == 0: + # We are recursively called, if we have a zero tab, remove it. + if 0 in self._tabstops: + self._tabstops[0].current_text = "" + del self._tabstops[0] elif 0 not in self._tabstops: delta = self._end - self._start col = self.end.col @@ -696,7 +702,7 @@ class SnippetInstance(TextObject): col -= self.start.col start = Position(delta.line, col) end = Position(delta.line, col) - ts = TabStop(self, start, end, "") + ts = TabStop(0, self, start, end, "") self._add_tabstop(0,ts) self.update() @@ -704,6 +710,9 @@ class SnippetInstance(TextObject): def __repr__(self): return "SnippetInstance(%s -> %s)" % (self._start, self._end) + def has_tabs(self): + return len(self._tabstops) + has_tabs = property(has_tabs) def _get_tabstop(self, requester, no): # SnippetInstances are completly self contained, diff --git a/plugin/UltiSnips/__init__.py b/plugin/UltiSnips/__init__.py index ac8e14b..da629ae 100644 --- a/plugin/UltiSnips/__init__.py +++ b/plugin/UltiSnips/__init__.py @@ -257,18 +257,19 @@ class SnippetManager(object): debug(" pos: %s" % (pos)) debug(" start: %s, end: %s" % (start, end)) - + # Launch this snippet as a child of the current snippet si = SnippetInstance(self._ctab, snippet.value, start, end) - + self._cs.update() self._update_vim_buffer() - self._csnippets.append(si) - self._ctab = si.select_next_tab() - if self._ctab is not None: - self._vstate.select_span(self._ctab.abs_span) - self._span_selected = self._ctab.abs_span + if si.has_tabs: + self._csnippets.append(si) + self._ctab = si.select_next_tab() + if self._ctab is not None: + self._vstate.select_span(self._ctab.abs_span) + self._span_selected = self._ctab.abs_span else: text_before = before.rstrip()[:-len(word)] self._vb = VimBuffer(text_before, after) diff --git a/test.py b/test.py index def4d77..b9960d8 100755 --- a/test.py +++ b/test.py @@ -418,17 +418,15 @@ class TabStop_VimScriptInterpolation_SimpleExample(_VimTest): # TODO: pasting with while mirroring, also multiline # TODO: expandtab and therelikes # TODO: Multiline text pasting -# -# + + print "Recursive Tabstops: TODO: this will still take some time" -# TODO: recursive, not at beginning of TS -# TODO: recursive, not at beginning of TS not at beginning of LINE -# TODO: recursive, not at beginning on same line as parent tabstop # TODO: leaving all nested snippets at onec # TODO: only leaving one nested snippet -# TODO: Recursive inner without any TS -# TODO: Mirror of recursive -# + +############################### +# Recursive (Nested) Snippets # +############################### class RecTabStops_SimpleCase_ExceptCorrectResult(_VimTest): snippets = ("m", "[ ${1:first} ${2:sec} ]") keys = "m" + EX + "m" + EX + "hello" + JF + "world" + JF + "end" @@ -442,9 +440,120 @@ class RecTabStops_SimpleCaseLeaveFirstSecond_ExceptCorrectResult(_VimTest): keys = "m" + EX + "m" + EX + "hello" + JF + JF + "world" + JF + "end" wanted = "[ [ hello sec ] world ]end" -# ########### -# # MIRRORS # -# ########### +class RecTabStops_InnerWOTabStop_ECR(_VimTest): + snippets = ( + ("m1", "Just some Text"), + ("m", "[ ${1:first} ${2:sec} ]"), + ) + keys = "m" + EX + "m1" + EX + "hi" + JF + "two" + JF + "end" + wanted = "[ Just some Texthi two ]end" +class RecTabStops_InnerWOTabStopTwiceDirectly_ECR(_VimTest): + snippets = ( + ("m1", "JST"), + ("m", "[ ${1:first} ${2:sec} ]"), + ) + keys = "m" + EX + "m1" + EX + " m1" + EX + "hi" + JF + "two" + JF + "end" + wanted = "[ JST JSThi two ]end" +class RecTabStops_InnerWOTabStopTwice_ECR(_VimTest): + snippets = ( + ("m1", "JST"), + ("m", "[ ${1:first} ${2:sec} ]"), + ) + keys = "m" + EX + "m1" + EX + JF + "m1" + EX + "hi" + JF + "end" + wanted = "[ JST JSThi ]end" +class RecTabStops_OuterOnlyWithZeroTS_ECR(_VimTest): + snippets = ( + ("m", "A $0 B"), + ("m1", "C $1 D $0 E"), + ) + keys = "m" + EX + "m1" + EX + "CD" + JF + "DE" + wanted = "A C CD D DE E B" +class RecTabStops_OuterOnlyWithZero_ECR(_VimTest): + snippets = ( + ("m", "A $0 B"), + ("m1", "C $1 D $0 E"), + ) + keys = "m" + EX + "m1" + EX + "CD" + JF + "DE" + wanted = "A C CD D DE E B" +class RecTabStops_ExpandedInZeroTS_ECR(_VimTest): + snippets = ( + ("m", "A $0 B $1"), + ("m1", "C $1 D $0 E"), + ) + keys = "m" + EX + "hi" + JF + "m1" + EX + "CD" + JF + "DE" + wanted = "A C CD D DE E B hi" +class RecTabStops_ExpandedInZeroTSTwice_ECR(_VimTest): + snippets = ( + ("m", "A $0 B $1"), + ("m1", "C $1 D $0 E"), + ) + keys = "m" + EX + "hi" + JF + "m" + EX + "again" + JF + "m1" + \ + EX + "CD" + JF + "DE" + wanted = "A A C CD D DE E B again B hi" +class RecTabStops_ExpandedInZeroTSSecondTimeIgnoreZTS_ECR(_VimTest): + snippets = ( + ("m", "A $0 B $1"), + ("m1", "C $1 D $0 E"), + ) + keys = "m" + EX + "hi" + JF + "m" + EX + "m1" + EX + "CD" + JF + "DE" + wanted = "A A DE B C CD D E B hi" + +class RecTabStops_MirrorInnerSnippet_ECR(_VimTest): + snippets = ( + ("m", "[ $1 $2 ] $1"), + ("m1", "ASnip $1 ASnip $2 ASnip"), + ) + keys = "m" + EX + "m1" + EX + "Hallo" + JF + "Hi" + JF + "two" + JF + "end" + wanted = "[ ASnip Hallo ASnip Hi ASnip two ] ASnip Hallo ASnip Hi ASnipend" + +class RecTabStops_NotAtBeginningOfTS_ExceptCorrectResult(_VimTest): + snippets = ("m", "[ ${1:first} ${2:sec} ]") + keys = "m" + EX + "hello m" + EX + "hi" + JF + "two" + JF + "three" + \ + JF + "end" + wanted = "[ hello [ hi two ] three ]end" +class RecTabStops_InNewlineInTabstop_ExceptCorrectResult(_VimTest): + snippets = ("m", "[ ${1:first} ${2:sec} ]") + keys = "m" + EX + "hello\nm" + EX + "hi" + JF + "two" + JF + "three" + \ + JF + "end" + wanted = "[ hello\n[ hi two ] three ]end" +class RecTabStops_InNewlineInTabstopNotAtBeginOfLine_ECR(_VimTest): + snippets = ("m", "[ ${1:first} ${2:sec} ]") + keys = "m" + EX + "hello\nhello again m" + EX + "hi" + JF + "two" + \ + JF + "three" + JF + "end" + wanted = "[ hello\nhello again [ hi two ] three ]end" + +# TODO: keep correct indent inside tabstop at expansion +# TODO: especially if last tabstop is zero +# TODO: also when it is not zero +# class RecTabStops_InNewlineMultiline_ECR(_VimTest): +# snippets = ("m", "M START\n $0\nM END") +# keys = "m" + EX + "m" + EX +# wanted = "M START\n M START\n" + + + +class RecTabStops_IgnoreZeroTS_ECR(_VimTest): + snippets = ( + ("m1", "[ ${1:first} $0 ${2:sec} ]"), + ("m", "[ ${1:first} ${2:sec} ]"), + ) + keys = "m" + EX + "m1" + EX + "hi" + JF + "two" + \ + JF + "three" + JF + "end" + wanted = "[ [ hi two ] three ]end" +class RecTabStops_MirroredZeroTS_ECR(_VimTest): + snippets = ( + ("m1", "[ ${1:first} ${0:Year, some default text} $0 ${2:sec} ]"), + ("m", "[ ${1:first} ${2:sec} ]"), + ) + keys = "m" + EX + "m1" + EX + "hi" + JF + "two" + \ + JF + "three" + JF + "end" + wanted = "[ [ hi two ] three ]end" + + + +########### +# MIRRORS # +########### class TextTabStopTextAfterTab_ExceptCorrectResult(_VimTest): snippets = ("test", "$1 Hinten\n$1") keys = "test" + EX + "hallo"