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
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
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
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