Example #1
0
    def snippets_in_current_scope(self):
        """Returns the snippets that could be expanded to Vim as a global
        variable."""
        before = _vim.buf.line_till_cursor
        snippets = self._snips(before, True)

        # Sort snippets alphabetically
        snippets.sort(key=lambda x: x.trigger)
        for snip in snippets:
            description = snip.description[snip.description.find(snip.trigger) +
                len(snip.trigger) + 2:]

            key = as_unicode(snip.trigger)
            description = as_unicode(description)

            # remove surrounding "" or '' in snippet description if it exists
            if len(description) > 2:
                if (description[0] == description[-1] and
                        description[0] in "'\""):
                    description = description[1:-1]

            _vim.command(as_unicode(
                "let g:current_ulti_dict['{key}'] = '{val}'").format(
                    key=key.replace("'", "''"),
                    val=description.replace("'", "''")))
Example #2
0
    def _handle_failure(self, trigger):
        """Mainly make sure that we play well with SuperTab."""
        if trigger.lower() == "<tab>":
            feedkey = "\\" + trigger
        elif trigger.lower() == "<s-tab>":
            feedkey = "\\" + trigger
        else:
            feedkey = None
        mode = "n"
        if not self._supertab_keys:
            if _vim.eval("exists('g:SuperTabMappingForward')") != "0":
                self._supertab_keys = (
                    _vim.eval("g:SuperTabMappingForward"),
                    _vim.eval("g:SuperTabMappingBackward"),
                )
            else:
                self._supertab_keys = ['', '']

        for idx, sttrig in enumerate(self._supertab_keys):
            if trigger.lower() == sttrig.lower():
                if idx == 0:
                    feedkey = r"\<Plug>SuperTabForward"
                    mode = "n"
                elif idx == 1:
                    feedkey = r"\<Plug>SuperTabBackward"
                    mode = "p"
                # Use remap mode so SuperTab mappings will be invoked.
                break

        if (feedkey == r"\<Plug>SuperTabForward" or
                feedkey == r"\<Plug>SuperTabBackward"):
            _vim.command("return SuperTab(%s)" % _vim.escape(mode))
        elif feedkey:
            _vim.command("return %s" % _vim.escape(feedkey))
 def restore_unnamed_register(self):
     """Restores the unnamed register and forgets what we cached."""
     if not self._unnamed_reg_cached:
         return
     escaped_cache = self._unnamed_reg_cache.replace("'", "''")
     _vim.command("let @\"='%s'" % escaped_cache)
     self._unnamed_reg_cached = False
Example #4
0
 def _try_expand(self, autotrigger_only=False):
     """Try to expand a snippet in the current place."""
     before = _vim.buf.line_till_cursor
     snippets = self._snips(before, False, autotrigger_only)
     if snippets:
         # prefer snippets with context if any
         snippets_with_context = [s for s in snippets if s.context]
         if snippets_with_context:
             snippets = snippets_with_context
     if not snippets:
         # No snippet found
         return False
     _vim.command("let &undolevels = &undolevels")
     if len(snippets) == 1:
         snippet = snippets[0]
     else:
         if self._ask_snippets:
             snippet = _ask_snippets(snippets)
         else:
             snippet = snippets[0]
         if not snippet:
             return True
     self._do_snippet(snippet, before)
     _vim.command("let &undolevels = &undolevels")
     return True
Example #5
0
 def remember_unnamed_register(self, text_to_expect):
     """Save the unnamed register. 'text_to_expect' is text that we expect
     to be contained in the register the next time this method is called -
     this could be text from the tabstop that was selected and might have
     been overwritten. We will not cache that then."""
     self._unnamed_reg_cached = True
     escaped_text = self._text_to_expect.replace("'", "''")
     res = int(_vim.eval('@" != ' + "'" + escaped_text + "'"))
     if res:
         _vim.command('let g:_ultisnips_unnamed_reg_cache = @"')
     self._text_to_expect = text_to_expect
Example #6
0
 def expand_or_jump(self):
     """
     This function is used for people who wants to have the same trigger for
     expansion and forward jumping. It first tries to expand a snippet, if
     this fails, it tries to jump forward.
     """
     rv = self._try_expand()
     if  rv == "ultilsnips_action_none":
         rv = self._jump()
     if rv == "ultilsnips_action_none":
         self._handle_failure(self.expand_trigger)
     _vim.command("let g:UltiSnips.pyResult = %s" % json.dumps(rv))
Example #7
0
    def __init__(self):
        self._poss = deque(maxlen=5)
        self._lvb = None

        self._text_to_expect = ''
        self._unnamed_reg_cached = False

        # We store the cached value of the unnamed register in Vim directly to
        # avoid any Unicode issues with saving and restoring the unnamed
        # register across the Python bindings.  The unnamed register can contain
        # data that cannot be coerced to Unicode, and so a simple vim.eval('@"')
        # fails badly.  Keeping the cached value in Vim directly, sidesteps the
        # problem.
        _vim.command('let g:_ultisnips_unnamed_reg_cache = ""')
Example #8
0
    def _handle_failure(self, trigger):
        """
        Mainly make sure that we play well with SuperTab or pre-existing keymaps
        """
        if trigger.lower() == _vim.eval("g:UltiSnipsExpandTrigger").lower() and _vim.eval("g:UltiSnipsExpandTriggerOverrides") != "":
            feedkey = "" + _vim.eval("g:UltiSnipsExpandTriggerOverrides")
            mode = "i"
        elif trigger.lower() == _vim.eval("g:UltiSnipsJumpForwardTrigger").lower() and _vim.eval("g:UltiSnipsJumpForwardTriggerOverrides") != "":
            feedkey = "" + _vim.eval("g:UltiSnipsJumpForwardTriggerOverrides")
            mode = "i"
        elif trigger.lower() == _vim.eval("g:UltiSnipsJumpBackwardTrigger").lower() and _vim.eval("g:UltiSnipsJumpBackwardTriggerOverrides") != "":
            feedkey = "" + _vim.eval("g:UltiSnipsJumpBackwardTriggerOverrides")
            mode = "i"
        elif trigger.lower() == "<tab>":
            feedkey = "\\" + trigger
            mode = "n"
        elif trigger.lower() == "<s-tab>":
            feedkey = "\\" + trigger
            mode = "n"
        else:
            feedkey = None
            mode = "n"
        if not self._supertab_keys:
            if _vim.eval("exists('g:SuperTabMappingForward')") != '0':
                self._supertab_keys = (
                    _vim.eval('g:SuperTabMappingForward'),
                    _vim.eval('g:SuperTabMappingBackward'),
                )
            else:
                self._supertab_keys = ['', '']

        for idx, sttrig in enumerate(self._supertab_keys):
            if trigger.lower() == sttrig.lower():
                if idx == 0:
                    feedkey = r"\<Plug>SuperTabForward"
                    mode = 'n'
                elif idx == 1:
                    feedkey = r"\<Plug>SuperTabBackward"
                    mode = 'p'
                # Use remap mode so SuperTab mappings will be invoked.
                break

        if (feedkey == r"\<Plug>SuperTabForward" or
                feedkey == r"\<Plug>SuperTabBackward"):
            _vim.command('return SuperTab(%s)' % _vim.escape(mode))
        elif feedkey:
            _vim.command('return %s' % _vim.escape(feedkey))
Example #9
0
 def _map_inner_keys(self):
     """Map keys that should only be defined when a snippet is active."""
     if self.expand_trigger != self.forward_trigger:
         _vim.command("inoremap <buffer> <silent> " + self.forward_trigger +
                 " <C-R>=UltiSnips#JumpForwards()<cr>")
         _vim.command("snoremap <buffer> <silent> " + self.forward_trigger +
                 " <Esc>:call UltiSnips#JumpForwards()<cr>")
     _vim.command("inoremap <buffer> <silent> " + self.backward_trigger +
             " <C-R>=UltiSnips#JumpBackwards()<cr>")
     _vim.command("snoremap <buffer> <silent> " + self.backward_trigger +
             " <Esc>:call UltiSnips#JumpBackwards()<cr>")
     self._inner_mappings_in_place = True
Example #10
0
    def list_snippets_dict(self):
        before, after = _vim.buf.current_line_splitted
        snippets = self._snips(before, True)

        # Sort snippets alphabetically
        snippets.sort(key=lambda x: x.trigger)
        for snip in snippets:
            description = snip.description[snip.description.find(snip.trigger) +
                len(snip.trigger) + 2:]

            key = as_unicode(snip.trigger)
            description = as_unicode(description)

            #remove surrounding "" or '' in snippet description if it exists
            if len(description) > 2:
              if description[0] == description[-1] and description[0] in ['"', "'"]:
                description = description[1:-1]

            _vim.command(as_unicode("let g:current_ulti_dict['{key}'] = '{val}'").format(
              key=key.replace("'", "''"), val=description.replace("'", "''")))
Example #11
0
 def jump_forwards(self):
     """Jumps to the next tabstop."""
     _vim.command('let g:ulti_jump_forwards_res = 1')
     _vim.command('let &undolevels = &undolevels')
     if not self._jump():
         _vim.command('let g:ulti_jump_forwards_res = 0')
         return self._handle_failure(self.forward_trigger)
Example #12
0
 def jump_backwards(self):
     """Jumps to the previous tabstop."""
     _vim.command('let g:ulti_jump_backwards_res = 1')
     _vim.command('let &undolevels = &undolevels')
     if not self._jump(True):
         _vim.command('let g:ulti_jump_backwards_res = 0')
         return self._handle_failure(self.backward_trigger)
Example #13
0
    def _do_snippet(self, snippet, before):
        """Expands the given snippet, and handles everything
        that needs to be done with it."""
        _vim.command("call UltiSnips#map_keys#MapInnerKeys()")

        # Adjust before, maybe the trigger is not the complete word
        text_before = before
        if snippet.matched:
            text_before = before[:-len(snippet.matched)]

        if self._cs:
            start = Position(_vim.buf.cursor.line, len(text_before))
            end = Position(_vim.buf.cursor.line, len(before))

            # It could be that our trigger contains the content of TextObjects
            # in our containing snippet. If this is indeed the case, we have to
            # make sure that those are properly killed. We do this by
            # pretending that the user deleted and retyped the text that our
            # trigger matched.
            edit_actions = [
                ("D", start.line, start.col, snippet.matched),
                ("I", start.line, start.col, snippet.matched),
            ]
            self._csnippets[0].replay_user_edits(edit_actions)

            si = snippet.launch(text_before, self._visual_content,
                    self._cs.find_parent_for_new_to(start), start, end)
        else:
            start = Position(_vim.buf.cursor.line, len(text_before))
            end = Position(_vim.buf.cursor.line, len(before))
            si = snippet.launch(text_before, self._visual_content,
                                None, start, end)

        self._visual_content.reset()
        self._csnippets.append(si)

        self._ignore_movements = True
        self._vstate.remember_buffer(self._csnippets[0])

        self._jump()
Example #14
0
def _text_to_vim(start, end, text):
    """Copy the given text to the current buffer, overwriting the span 'start'
    to 'end'."""
    lines = text.split('\n')

    new_end = _calc_end(lines, start)

    before = _vim.buf[start.line][:start.col]
    after = _vim.buf[end.line][end.col:]

    new_lines = []
    if len(lines):
        new_lines.append(before + lines[0])
        new_lines.extend(lines[1:])
        new_lines[-1] += after
    _vim.buf[start.line:end.line + 1] = new_lines

    # Open any folds this might have created
    _vim.buf.cursor = start
    _vim.command("normal! zv")

    return new_end
Example #15
0
 def _unmap_inner_keys(self):
     """Unmap keys that should not be active when no snippet is active."""
     if not self._inner_mappings_in_place:
         return
     try:
         if self.expand_trigger != self.forward_trigger:
             _vim.command("iunmap <buffer> %s" % self.forward_trigger)
             _vim.command("sunmap <buffer> %s" % self.forward_trigger)
         _vim.command("iunmap <buffer> %s" % self.backward_trigger)
         _vim.command("sunmap <buffer> %s" % self.backward_trigger)
         self._inner_mappings_in_place = False
     except _vim.error:
         # This happens when a preview window was opened. This issues
         # CursorMoved, but not BufLeave. We have no way to unmap, until we
         # are back in our buffer
         pass
Example #16
0
 def _unmap_inner_keys(self):
     """Unmap keys that should not be active when no snippet is active."""
     if not self._inner_mappings_in_place:
         return
     try:
         if self.expand_trigger != self.forward_trigger:
             _vim.command("iunmap <buffer> %s" % self.forward_trigger)
             _vim.command("sunmap <buffer> %s" % self.forward_trigger)
         _vim.command("iunmap <buffer> %s" % self.backward_trigger)
         _vim.command("sunmap <buffer> %s" % self.backward_trigger)
         self._inner_mappings_in_place = False
     except _vim.error:
         # This happens when a preview window was opened. This issues
         # CursorMoved, but not BufLeave. We have no way to unmap, until we
         # are back in our buffer
         pass
Example #17
0
    def snippets_in_current_scope(self, searchAll):
        """Returns the snippets that could be expanded to Vim as a global
        variable."""
        before =  '' if searchAll else _vim.buf.line_till_cursor
        snippets = self._snips(before, True)

        # Sort snippets alphabetically
        snippets.sort(key=lambda x: x.trigger)
        for snip in snippets:
            description = snip.description[snip.description.find(snip.trigger) +
                                           len(snip.trigger) + 2:]

            location = snip.location if snip.location else ''

            key = as_unicode(snip.trigger)
            description = as_unicode(description)

            # remove surrounding "" or '' in snippet description if it exists
            if len(description) > 2:
                if (description[0] == description[-1] and
                        description[0] in "'\""):
                    description = description[1:-1]

            _vim.command(as_unicode(
                "let g:current_ulti_dict['{key}'] = '{val}'").format(
                    key=key.replace("'", "''"),
                    val=description.replace("'", "''")))

            if searchAll:
                _vim.command(as_unicode(
                    ("let g:current_ulti_dict_info['{key}'] = {{"
                     "'description': '{description}',"
                     "'location': '{location}',"
                     "}}")).format(
                        key=key.replace("'", "''"),
                        location=location.replace("'", "''"),
                        description=description.replace("'", "''")))
Example #18
0
 def _try_expand(self):
     """Try to expand a snippet in the current place."""
     before = _vim.buf.line_till_cursor
     if not before:
         return False
     snippets = self._snips(before, False)
     if snippets:
         # prefer snippets with context if any
         snippets_with_context = [s for s in snippets if s.context]
         if snippets_with_context:
             snippets = snippets_with_context
     if not snippets:
         # No snippet found
         return False
     _vim.command('let &undolevels = &undolevels')
     if len(snippets) == 1:
         snippet = snippets[0]
     else:
         snippet = _ask_snippets(snippets)
         if not snippet:
             return True
     self._do_snippet(snippet, before)
     _vim.command('let &undolevels = &undolevels')
     return True
Example #19
0
def _replace_text(buf, start, end, text):
    """Copy the given text to the current buffer, overwriting the span 'start'
    to 'end'."""
    lines = text.split('\n')

    new_end = _calc_end(lines, start)

    before = buf[start.line][:start.col]
    after = buf[end.line][end.col:]

    new_lines = []
    if len(lines):
        new_lines.append(before + lines[0])
        new_lines.extend(lines[1:])
        new_lines[-1] += after
    buf[start.line:end.line + 1] = new_lines

    # Open any folds this might have created
    # TODO(sirver): This leaks that we are still inside Vim, while this code should
    # only care that it is modifying 'buf'.
    _vim.buf.cursor = start
    _vim.command('normal! zv')

    return new_end
Example #20
0
 def expand_or_jump(self):
     """
     This function is used for people who wants to have the same trigger for
     expansion and forward jumping. It first tries to expand a snippet, if
     this fails, it tries to jump forward.
     """
     _vim.command('let g:ulti_expand_or_jump_res = 1')
     rv = self._try_expand()
     if not rv:
         _vim.command('let g:ulti_expand_or_jump_res = 2')
         rv = self._jump()
     if not rv:
         _vim.command('let g:ulti_expand_or_jump_res = 0')
         self._handle_failure(self.expand_trigger)
Example #21
0
 def expand_or_jump(self):
     """
     This function is used for people who wants to have the same trigger for
     expansion and forward jumping. It first tries to expand a snippet, if
     this fails, it tries to jump forward.
     """
     _vim.command('let g:ulti_expand_or_jump_res = 1')
     rv = self._try_expand()
     if not rv:
         _vim.command('let g:ulti_expand_or_jump_res = 2')
         rv = self._jump()
     if not rv:
         _vim.command('let g:ulti_expand_or_jump_res = 0')
         self._handle_failure(self.expand_trigger)
Example #22
0
 def expand(self):
     rv = self._try_expand()
     if rv == "ultisnips_action_none":
         self._handle_failure(self.expand_trigger)
     _vim.command("let g:UltiSnips.pyResult = %s" % json.dumps(rv))
Example #23
0
 def restore_unnamed_register(self):
     """Restores the unnamed register and forgets what we cached."""
     if not self._unnamed_reg_cached:
         return
     _vim.command('let @" = g:_ultisnips_unnamed_reg_cache')
     self._unnamed_reg_cached = False
Example #24
0
 def jump_backwards(self):
     """Jumps to the previous tabstop."""
     _vim.command("let g:ulti_jump_backwards_res = 1")
     if not self._jump(True):
         _vim.command("let g:ulti_jump_backwards_res = 0")
         return self._handle_failure(self.backward_trigger)
Example #25
0
 def expand(self):
     """Try to expand a snippet at the current position."""
     _vim.command("let g:ulti_expand_res = 1")
     if not self._try_expand():
         _vim.command("let g:ulti_expand_res = 0")
         self._handle_failure(self.expand_trigger)
Example #26
0
    def _do_snippet(self, snippet, before):
        """Expands the given snippet, and handles everything that needs to be
        done with it."""
        self._setup_inner_state()

        self._snip_expanded_in_action = False
        self._should_update_textobjects = False

        # Adjust before, maybe the trigger is not the complete word
        text_before = before
        if snippet.matched:
            text_before = before[:-len(snippet.matched)]

        with use_proxy_buffer(self._active_snippets, self._vstate):
            with self._action_context():
                cursor_set_in_action = snippet.do_pre_expand(
                    self._visual_content.text,
                    self._active_snippets
                )

        if cursor_set_in_action:
            text_before = _vim.buf.line_till_cursor
            before = _vim.buf.line_till_cursor

        with suspend_proxy_edits():
            start = Position(_vim.buf.cursor.line, len(text_before))
            end = Position(_vim.buf.cursor.line, len(before))
            parent = None
            if self._current_snippet:
                # If cursor is set in pre-action, then action was modified
                # cursor line, in that case we do not need to do any edits, it
                # can break snippet
                if not cursor_set_in_action:
                    # It could be that our trigger contains the content of
                    # TextObjects in our containing snippet. If this is indeed
                    # the case, we have to make sure that those are properly
                    # killed. We do this by pretending that the user deleted
                    # and retyped the text that our trigger matched.
                    edit_actions = [
                        ('D', start.line, start.col, snippet.matched),
                        ('I', start.line, start.col, snippet.matched),
                    ]
                    self._active_snippets[0].replay_user_edits(edit_actions)
                parent = self._current_snippet.find_parent_for_new_to(start)
            snippet_instance = snippet.launch(text_before,
                    self._visual_content, parent, start, end)
            # Open any folds this might have created
            _vim.command('normal! zv')

            self._visual_content.reset()
            self._active_snippets.append(snippet_instance)

            with use_proxy_buffer(self._active_snippets, self._vstate):
                with self._action_context():
                    snippet.do_post_expand(
                        snippet_instance._start, snippet_instance._end, self._active_snippets
                    )

            self._vstate.remember_buffer(self._active_snippets[0])

            if not self._snip_expanded_in_action:
                self._jump()
            elif self._current_snippet.current_text != '':
                self._jump()
            else:
                self._current_snippet_is_done()

            if self._inside_action:
                self._snip_expanded_in_action = True
Example #27
0
 def expand(self):
     _vim.command("let g:ulti_expand_res = 1")
     if not self._try_expand():
         _vim.command("let g:ulti_expand_res = 0")
         self._handle_failure(self.expand_trigger)
Example #28
0
    def _setup_inner_state(self):
        """Map keys and create autocommands that should only be defined when a
        snippet is active."""
        if self._inner_state_up:
            return
        if self.expand_trigger != self.forward_trigger:
            _vim.command('inoremap <buffer> <silent> ' + self.forward_trigger +
                         ' <C-R>=UltiSnips#JumpForwards()<cr>')
            _vim.command('snoremap <buffer> <silent> ' + self.forward_trigger +
                         ' <Esc>:call UltiSnips#JumpForwards()<cr>')
        _vim.command('inoremap <buffer> <silent> ' + self.backward_trigger +
                     ' <C-R>=UltiSnips#JumpBackwards()<cr>')
        _vim.command('snoremap <buffer> <silent> ' + self.backward_trigger +
                     ' <Esc>:call UltiSnips#JumpBackwards()<cr>')

        # Setup the autogroups.
        _vim.command('augroup UltiSnips')
        _vim.command('autocmd!')
        _vim.command('autocmd CursorMovedI * call UltiSnips#CursorMoved()')
        _vim.command('autocmd CursorMoved * call UltiSnips#CursorMoved()')

        _vim.command(
            'autocmd InsertLeave * call UltiSnips#LeavingInsertMode()')

        _vim.command('autocmd BufLeave * call UltiSnips#LeavingBuffer()')
        _vim.command(
            'autocmd CmdwinEnter * call UltiSnips#LeavingBuffer()')
        _vim.command(
            'autocmd CmdwinLeave * call UltiSnips#LeavingBuffer()')

        # Also exit the snippet when we enter a unite complete buffer.
        _vim.command('autocmd Filetype unite call UltiSnips#LeavingBuffer()')

        _vim.command('augroup END')

        _vim.command('silent doautocmd <nomodeline> User UltiSnipsEnterFirstSnippet')
        self._inner_state_up = True
Example #29
0
 def _error(self, msg):
     msg = _vim.escape("UltiSnips: " + msg)
     if self._test_error:
         msg = msg.replace('"', r'\"')
         msg = msg.replace('|', r'\|')
         _vim.command("let saved_pos=getpos('.')")
         _vim.command("$:put =%s" % msg)
         _vim.command("call setpos('.', saved_pos)")
     elif False:
         _vim.command("echohl WarningMsg")
         _vim.command("echomsg %s" % msg)
         _vim.command("echohl None")
     else:
         _vim.command("echoerr %s" % msg)
Example #30
0
 def jump_backwards(self):
     _vim.command("let g:ulti_jump_backwards_res = 1")
     if not self._jump(True):
         _vim.command("let g:ulti_jump_backwards_res = 0")
         return self._handle_failure(self.backward_trigger)
Example #31
0
 def expand(self):
     _vim.command("let g:ulti_expand_res = 1")
     if not self._try_expand():
         _vim.command("let g:ulti_expand_res = 0")
         self._handle_failure(self.expand_trigger)
Example #32
0
    def _jump(self, backwards=False):
        """Helper method that does the actual jump."""
        if self._should_update_textobjects:
            self._should_reset_visual = False
            self._cursor_moved()

        # we need to set 'onemore' there, because of limitations of the vim
        # API regarding cursor movements; without that test
        # 'CanExpandAnonSnippetInJumpActionWhileSelected' will fail
        with _vim.option_set_to('ve', 'onemore'):
            jumped = False

            # We need to remember current snippets stack here because of
            # post-jump action on the last tabstop should be able to access
            # snippet instance which is ended just now.
            stack_for_post_jump = self._active_snippets[:]

            # If next tab has length 1 and the distance between itself and
            # self._ctab is 1 then there is 1 less CursorMove events.  We
            # cannot ignore next movement in such case.
            ntab_short_and_near = False

            if self._current_snippet:
                snippet_for_action = self._current_snippet
            elif stack_for_post_jump:
                snippet_for_action = stack_for_post_jump[-1]
            else:
                snippet_for_action = None

            if self._current_snippet:
                ntab = self._current_snippet.select_next_tab(backwards)
                if ntab:
                    if self._current_snippet.snippet.has_option('s'):
                        lineno = _vim.buf.cursor.line
                        _vim.buf[lineno] = _vim.buf[lineno].rstrip()
                    _vim.select(ntab.start, ntab.end)
                    jumped = True
                    if (self._ctab is not None
                            and ntab.start - self._ctab.end == Position(0, 1)
                            and ntab.end - ntab.start == Position(0, 1)):
                        ntab_short_and_near = True

                    self._ctab = ntab

                    # Run interpolations again to update new placeholder
                    # values, binded to currently newly jumped placeholder.
                    self._visual_content.conserve_placeholder(self._ctab)
                    self._current_snippet.current_placeholder = \
                        self._visual_content.placeholder
                    self._should_reset_visual = False
                    self._active_snippets[0].update_textobjects(_vim.buf)
                    # Open any folds this might have created
                    _vim.command('normal! zv')
                    self._vstate.remember_buffer(self._active_snippets[0])

                    if ntab.number == 0 and self._active_snippets:
                        self._current_snippet_is_done()
                else:
                    # This really shouldn't happen, because a snippet should
                    # have been popped when its final tabstop was used.
                    # Cleanup by removing current snippet and recursing.
                    self._current_snippet_is_done()
                    jumped = self._jump(backwards)

            if jumped:
                if self._ctab:
                    self._vstate.remember_position()
                    self._vstate.remember_unnamed_register(
                        self._ctab.current_text)
                if not ntab_short_and_near:
                    self._ignore_movements = True

            if len(stack_for_post_jump) > 0 and ntab is not None:
                with use_proxy_buffer(stack_for_post_jump, self._vstate):
                    snippet_for_action.snippet.do_post_jump(
                        ntab.number, -1 if backwards else 1,
                        stack_for_post_jump, snippet_for_action)

        return jumped
Example #33
0
 def jump_forwards(self):
     """Jumps to the next tabstop."""
     _vim.command("let g:ulti_jump_forwards_res = 1")
     if not self._jump():
         _vim.command("let g:ulti_jump_forwards_res = 0")
         return self._handle_failure(self.forward_trigger)
Example #34
0
 def expand(self):
     """Try to expand a snippet at the current position."""
     _vim.command('let g:ulti_expand_res = 1')
     if not self._try_expand():
         _vim.command('let g:ulti_expand_res = 0')
         self._handle_failure(self.expand_trigger)
Example #35
0
 def jump_backwards(self):
     rv = self._jump(True)
     if rv == "ultisnips_action_none":
         return self._handle_failure(self.backward_trigger)
     _vim.command("let g:UltiSnips.pyResult = %s" % json.dumps(rv))
Example #36
0
 def restore_unnamed_register(self):
     """Restores the unnamed register and forgets what we cached."""
     if not self._unnamed_reg_cached:
         return
     _vim.command('let @" = g:_ultisnips_unnamed_reg_cache')
     self._unnamed_reg_cached = False
Example #37
0
 def _current_snippet_is_done(self):
     """The current snippet should be terminated."""
     self._csnippets.pop()
     if not self._csnippets:
         _vim.command("call UltiSnips#map_keys#RestoreInnerKeys()")
Example #38
0
 def _teardown_inner_state(self):
     """Reverse _setup_inner_state."""
     if not self._inner_state_up:
         return
     try:
         _vim.command('silent doautocmd <nomodeline> User UltiSnipsExitLastSnippet')
         if self.expand_trigger != self.forward_trigger:
             _vim.command('iunmap <buffer> %s' % self.forward_trigger)
             _vim.command('sunmap <buffer> %s' % self.forward_trigger)
         _vim.command('iunmap <buffer> %s' % self.backward_trigger)
         _vim.command('sunmap <buffer> %s' % self.backward_trigger)
         _vim.command('augroup UltiSnips')
         _vim.command('autocmd!')
         _vim.command('augroup END')
         self._inner_state_up = False
     except _vim.error:
         # This happens when a preview window was opened. This issues
         # CursorMoved, but not BufLeave. We have no way to unmap, until we
         # are back in our buffer
         pass
Example #39
0
 def jump_backwards(self):
     rv = self._jump(True)
     if rv == "ultisnips_action_none":
         return self._handle_failure(self.backward_trigger)
     _vim.command("let g:UltiSnips.pyResult = %s" % json.dumps(rv))
Example #40
0
    def _jump(self, backwards=False):
        """Helper method that does the actual jump."""
        if self._should_update_textobjects:
            self._should_reset_visual = False
            self._cursor_moved()

        # we need to set 'onemore' there, because of limitations of the vim
        # API regarding cursor movements; without that test
        # 'CanExpandAnonSnippetInJumpActionWhileSelected' will fail
        with _vim.option_set_to('ve', 'onemore'):
            jumped = False

            # We need to remember current snippets stack here because of
            # post-jump action on the last tabstop should be able to access
            # snippet instance which is ended just now.
            stack_for_post_jump = self._active_snippets[:]

            # If next tab has length 1 and the distance between itself and
            # self._ctab is 1 then there is 1 less CursorMove events.  We
            # cannot ignore next movement in such case.
            ntab_short_and_near = False

            if self._current_snippet:
                snippet_for_action = self._current_snippet
            elif stack_for_post_jump:
                snippet_for_action = stack_for_post_jump[-1]
            else:
                snippet_for_action = None

            if self._current_snippet:
                ntab = self._current_snippet.select_next_tab(backwards)
                if ntab:
                    if self._current_snippet.snippet.has_option('s'):
                        lineno = _vim.buf.cursor.line
                        _vim.buf[lineno] = _vim.buf[lineno].rstrip()
                    _vim.select(ntab.start, ntab.end)
                    jumped = True
                    if (self._ctab is not None
                            and ntab.start - self._ctab.end == Position(0, 1)
                            and ntab.end - ntab.start == Position(0, 1)):
                        ntab_short_and_near = True

                    self._ctab = ntab

                    # Run interpolations again to update new placeholder
                    # values, binded to currently newly jumped placeholder.
                    self._visual_content.conserve_placeholder(self._ctab)
                    self._current_snippet.current_placeholder = \
                        self._visual_content.placeholder
                    self._should_reset_visual = False
                    self._active_snippets[0].update_textobjects(_vim.buf)
                    # Open any folds this might have created
                    _vim.command('normal! zv')
                    self._vstate.remember_buffer(self._active_snippets[0])

                    if ntab.number == 0 and self._active_snippets:
                        self._current_snippet_is_done()
                else:
                    # This really shouldn't happen, because a snippet should
                    # have been popped when its final tabstop was used.
                    # Cleanup by removing current snippet and recursing.
                    self._current_snippet_is_done()
                    jumped = self._jump(backwards)

            if jumped:
                if self._ctab:
                    self._vstate.remember_position()
                    self._vstate.remember_unnamed_register(self._ctab.current_text)
                if not ntab_short_and_near:
                    self._ignore_movements = True

            if len(stack_for_post_jump) > 0 and ntab is not None:
                with use_proxy_buffer(stack_for_post_jump, self._vstate):
                    snippet_for_action.snippet.do_post_jump(
                        ntab.number,
                        -1 if backwards else 1,
                        stack_for_post_jump,
                        snippet_for_action
                    )

        return jumped
Example #41
0
    def _do_snippet(self, snippet, before):
        """Expands the given snippet, and handles everything that needs to be
        done with it."""
        self._setup_inner_state()

        self._snip_expanded_in_action = False
        self._should_update_textobjects = False

        # Adjust before, maybe the trigger is not the complete word
        text_before = before
        if snippet.matched:
            text_before = before[:-len(snippet.matched)]

        with use_proxy_buffer(self._active_snippets, self._vstate):
            with self._action_context():
                cursor_set_in_action = snippet.do_pre_expand(
                    self._visual_content.text, self._active_snippets)

        if cursor_set_in_action:
            text_before = _vim.buf.line_till_cursor
            before = _vim.buf.line_till_cursor

        with suspend_proxy_edits():
            start = Position(_vim.buf.cursor.line, len(text_before))
            end = Position(_vim.buf.cursor.line, len(before))
            parent = None
            if self._current_snippet:
                # If cursor is set in pre-action, then action was modified
                # cursor line, in that case we do not need to do any edits, it
                # can break snippet
                if not cursor_set_in_action:
                    # It could be that our trigger contains the content of
                    # TextObjects in our containing snippet. If this is indeed
                    # the case, we have to make sure that those are properly
                    # killed. We do this by pretending that the user deleted
                    # and retyped the text that our trigger matched.
                    edit_actions = [
                        ('D', start.line, start.col, snippet.matched),
                        ('I', start.line, start.col, snippet.matched),
                    ]
                    self._active_snippets[0].replay_user_edits(edit_actions)
                parent = self._current_snippet.find_parent_for_new_to(start)
            snippet_instance = snippet.launch(text_before,
                                              self._visual_content, parent,
                                              start, end)
            # Open any folds this might have created
            _vim.command('normal! zv')

            self._visual_content.reset()
            self._active_snippets.append(snippet_instance)

            with use_proxy_buffer(self._active_snippets, self._vstate):
                with self._action_context():
                    snippet.do_post_expand(snippet_instance._start,
                                           snippet_instance._end,
                                           self._active_snippets)

            self._vstate.remember_buffer(self._active_snippets[0])

            if not self._snip_expanded_in_action:
                self._jump()
            elif self._current_snippet.current_text != '':
                self._jump()
            else:
                self._current_snippet_is_done()

            if self._inside_action:
                self._snip_expanded_in_action = True
Example #42
0
 def _current_snippet_is_done(self):
     """The current snippet should be terminated."""
     self._csnippets.pop()
     if not self._csnippets:
         _vim.command("call UltiSnips#map_keys#RestoreInnerKeys()")
Example #43
0
 def _error(self, msg):
     msg = _vim.escape("UltiSnips: " + msg)
     if self._test_error:
         msg = msg.replace('"', r'\"')
         msg = msg.replace('|', r'\|')
         _vim.command("let saved_pos=getpos('.')")
         _vim.command("$:put =%s" % msg)
         _vim.command("call setpos('.', saved_pos)")
     elif False:
         _vim.command("echohl WarningMsg")
         _vim.command("echomsg %s" % msg)
         _vim.command("echohl None")
     else:
         _vim.command("echoerr %s" % msg)
Example #44
0
 def jump_forwards(self):
     """Jumps to the next tabstop."""
     _vim.command("let g:ulti_jump_forwards_res = 1")
     if not self._jump():
         _vim.command("let g:ulti_jump_forwards_res = 0")
         return self._handle_failure(self.forward_trigger)
Example #45
0
 def expand(self):
     rv = self._try_expand()
     if rv == "ultisnips_action_none":
         self._handle_failure(self.expand_trigger)
     _vim.command("let g:UltiSnips.pyResult = %s" % json.dumps(rv))
Example #46
0
 def jump_backwards(self):
     """Jumps to the previous tabstop."""
     _vim.command("let g:ulti_jump_backwards_res = 1")
     if not self._jump(True):
         _vim.command("let g:ulti_jump_backwards_res = 0")
         return self._handle_failure(self.backward_trigger)
Example #47
0
 def jump_backwards(self):
     _vim.command("let g:ulti_jump_backwards_res = 1")
     if not self._jump(True):
         _vim.command("let g:ulti_jump_backwards_res = 0")
         return self._handle_failure(self.backward_trigger)