From 45e3775c18f6c6a9ce51f37332d8459da3c62b2a Mon Sep 17 00:00:00 2001 From: Stanislav Seletskiy Date: Tue, 8 Dec 2015 13:40:31 +0600 Subject: [PATCH] fix #616: update state on edit w/o cursor move UltiSnips tracks changes in buffer and apply user changes only on CursorMoved event. So, if placeholder is replaced completely by using , CursorMoved is not triggered and internal snippet representation is not updated, causing placeholder boundaries go out-of-sync. Fixed by triggering text objects sync forcefully if change without cursor move is detected. --- pythonx/UltiSnips/snippet_manager.py | 12 +++++++++++- test/test_Editing.py | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/pythonx/UltiSnips/snippet_manager.py b/pythonx/UltiSnips/snippet_manager.py index d9377e3..4b7c2b0 100644 --- a/pythonx/UltiSnips/snippet_manager.py +++ b/pythonx/UltiSnips/snippet_manager.py @@ -136,6 +136,8 @@ class SnippetManager(object): self.register_snippet_source('snipmate_files', SnipMateFileSource()) + self._should_update_textobjects = False + self._reinit() @err_to_scratch_buffer @@ -303,6 +305,8 @@ class SnippetManager(object): @err_to_scratch_buffer def _cursor_moved(self): """Called whenever the cursor moved.""" + self._should_update_textobjects = False + if not self._csnippets and self._inner_state_up: self._teardown_inner_state() self._vstate.remember_position() @@ -469,11 +473,14 @@ class SnippetManager(object): self._teardown_inner_state() def _jump(self, backwards=False): + """Helper method that does the actual jump.""" + if self._should_update_textobjects: + 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'): - """Helper method that does the actual jump.""" jumped = False # We need to remember current snippets stack here because of @@ -632,6 +639,7 @@ class SnippetManager(object): 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 @@ -802,6 +810,8 @@ class SnippetManager(object): @err_to_scratch_buffer def _track_change(self): + self._should_update_textobjects = True + inserted_char = _vim.eval('v:char') try: if inserted_char == '': diff --git a/test/test_Editing.py b/test/test_Editing.py index 06f4a7a..c023a68 100644 --- a/test/test_Editing.py +++ b/test/test_Editing.py @@ -120,3 +120,21 @@ class Backspace_TabStop_NotZero(_VimTest): keys = 'test' + EX + 'A' + JF + BS + 'BBB' wanted = 'AA BBB' # End: Pressing BS in TabStop #}}} + +class UpdateModifiedSnippetWithoutCursorMove(_VimTest): + snippets = ('test', '${1:one}(${2:xxx})${3:three}') + keys = 'test' + EX + 'aaaaa' + JF + BS + JF + '3333' + wanted = 'aaaaa()3333' + +class UpdateModifiedSnippetWithoutCursorMove2(_VimTest): + snippets = ('test', '''\ +private function ${1:functionName}(${2:arguments}):${3:Void} +{ + ${VISUAL}$0 +}''') + keys = 'test' + EX + 'a' + JF + BS + JF + 'Int' + JF + 'body' + wanted = '''\ +private function a():Int +{ + body +}'''