Пример #1
0
    def _jump(self, backwards=False):
        # we need to set 'onemore' there, because of limitations of the vim
        # API regarding cursor movements; without that test
        # 'CanExpandAnonSnippetInJumpActionWhileSelected' will fail
        with _vim.toggle_opt('ve', 'onemore'):
            """Helper method that does the actual jump."""
            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._csnippets[:]

            # 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._cs:
                snippet_for_action = self._cs
            elif stack_for_post_jump:
                snippet_for_action = stack_for_post_jump[-1]
            else:
                snippet_for_action = None

            if self._cs:
                ntab = self._cs.select_next_tab(backwards)
                if ntab:
                    if self._cs.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
                    if ntab.number == 0:
                        self._current_snippet_is_done()
                    self._ctab = ntab
                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:
                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
Пример #2
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._csnippets, self._vstate):
            with self._action_context():
                cursor_set_in_action = snippet.do_pre_expand(
                    self._visual_content.text,
                    self._csnippets
                )

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

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

                # 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._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)

            si.update_textobjects()

            with use_proxy_buffer(self._csnippets, self._vstate):
                with self._action_context():
                    snippet.do_post_expand(
                        si._start, si._end, self._csnippets
                    )

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

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

            if self._inside_action:
                self._snip_expanded_in_action = True
Пример #3
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.toggle_opt('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._csnippets[:]

            # 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._cs:
                snippet_for_action = self._cs
            elif stack_for_post_jump:
                snippet_for_action = stack_for_post_jump[-1]
            else:
                snippet_for_action = None

            if self._cs:
                ntab = self._cs.select_next_tab(backwards)
                if ntab:
                    if self._cs.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._cs.current_placeholder = \
                        self._visual_content.placeholder
                    self._should_reset_visual = False
                    self._csnippets[0].update_textobjects()
                    self._vstate.remember_buffer(self._csnippets[0])

                    if ntab.number == 0 and self._csnippets:
                        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
Пример #4
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_helper.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_helper.buf.cursor.line
                        vim_helper.buf[lineno] = vim_helper.buf[lineno].rstrip()
                    vim_helper.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_helper.buf)
                    # Open any folds this might have created
                    vim_helper.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