From fc955453787491127c557b4e18a4757960ea8c2c Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 2 May 2015 16:38:47 +0200 Subject: [PATCH 1/7] rename: save/restore tab/windows; not via `new_buffer` Ref: https://github.com/davidhalter/jedi-vim/pull/364#discussion-diff-25785992 --- jedi_vim.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/jedi_vim.py b/jedi_vim.py index 475885c..8894fbe 100644 --- a/jedi_vim.py +++ b/jedi_vim.py @@ -428,10 +428,13 @@ def rename(): vim_command('normal! diw') vim_command(':startinsert') else: - window_path = vim.current.buffer.name # reset autocommand vim_command('autocmd! jedi_rename InsertLeave') + # Save original window / tab. + saved_tab = int(vim_eval('tabpagenr()')) + saved_win = int(vim_eval('winnr()')) + replace = vim_eval("expand('')") vim_command('normal! u') # undo new word cursor = vim.current.window.cursor @@ -458,9 +461,10 @@ def rename(): vim.current.window.cursor = r.start_pos vim_command('normal! cw%s' % replace) - result = new_buffer(window_path) - if not result: - return + # Restore previous tab and window. + vim_command('tabnext {:d}'.format(saved_tab)) + vim_command('{:d}wincmd w'.format(saved_win)) + vim.current.window.cursor = cursor echo_highlight('Jedi did %s renames!' % len(temp_rename)) From 7539614f090d9ef979a59a59572e628a0fba9230 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 2 May 2015 16:41:13 +0200 Subject: [PATCH 2/7] rename: display number of affected buffers --- jedi_vim.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/jedi_vim.py b/jedi_vim.py index 8894fbe..88f6682 100644 --- a/jedi_vim.py +++ b/jedi_vim.py @@ -449,6 +449,7 @@ def rename(): # must be first, because they move the stuff before the position). temp_rename = sorted(temp_rename, reverse=True, key=lambda x: (x.module_path, x.start_pos)) + buffers = set() for r in temp_rename: if r.in_builtin_module(): continue @@ -458,6 +459,8 @@ def rename(): if not result: return + buffers.add(vim.current.buffer.name) + vim.current.window.cursor = r.start_pos vim_command('normal! cw%s' % replace) @@ -466,7 +469,11 @@ def rename(): vim_command('{:d}wincmd w'.format(saved_win)) vim.current.window.cursor = cursor - echo_highlight('Jedi did %s renames!' % len(temp_rename)) + if len(buffers) > 1: + echo_highlight('Jedi did {:d} renames in {:d} buffers!'.format( + len(temp_rename), len(buffers))) + else: + echo_highlight('Jedi did {:d} renames!'.format(len(temp_rename))) @_check_jedi_availability(show_error=True) From afb84a837c8aa2d1f37124876f0fb49fb583ead0 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 2 May 2015 16:42:04 +0200 Subject: [PATCH 3/7] rename: save and restore view before/after changes --- jedi_vim.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jedi_vim.py b/jedi_vim.py index 88f6682..31015b5 100644 --- a/jedi_vim.py +++ b/jedi_vim.py @@ -461,14 +461,19 @@ def rename(): buffers.add(vim.current.buffer.name) + # Save view. + saved_view = vim_eval('winsaveview()') + vim.current.window.cursor = r.start_pos vim_command('normal! cw%s' % replace) + # Restore view. + vim_command('call winrestview(%s)' % PythonToVimStr(saved_view)) + # Restore previous tab and window. vim_command('tabnext {:d}'.format(saved_tab)) vim_command('{:d}wincmd w'.format(saved_win)) - vim.current.window.cursor = cursor if len(buffers) > 1: echo_highlight('Jedi did {:d} renames in {:d} buffers!'.format( len(temp_rename), len(buffers))) From bf281dabda414c6dabd58fd5d754c0ecef9f5d2a Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 2 May 2015 16:42:28 +0200 Subject: [PATCH 4/7] rename: fix _tabnew to go to the correct window --- jedi_vim.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jedi_vim.py b/jedi_vim.py index 31015b5..84436cd 100644 --- a/jedi_vim.py +++ b/jedi_vim.py @@ -577,6 +577,8 @@ def _tabnew(path, options=''): if buf_path == path: # tab exists, just switch to that tab vim_command('tabfirst | tabnext %i' % (tab_nr + 1)) + # Goto the buffer's window. + vim_command('exec bufwinnr(%i) . " wincmd w"' % (buf_nr + 1)) break else: continue From b9ba141069f2848f12121a014587561c03e29013 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 2 May 2015 16:42:36 +0200 Subject: [PATCH 5/7] rename: display error in case `new_buffer` should fail and continue Previously it would `return`, which would not restore the previous state. While I am not sure that it should continue, it should at least not return. --- jedi_vim.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jedi_vim.py b/jedi_vim.py index 84436cd..303080f 100644 --- a/jedi_vim.py +++ b/jedi_vim.py @@ -457,7 +457,8 @@ def rename(): if vim.current.buffer.name != r.module_path: result = new_buffer(r.module_path) if not result: - return + echo_highlight("Jedi-vim: failed to create buffer window for {}!".format(r.module_path)) + continue buffers.add(vim.current.buffer.name) From 154e2dbae3751224ae745fe5f2c02632a46d34fe Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 2 May 2015 18:46:50 +0200 Subject: [PATCH 6/7] rename: use original word's length for replacing Ref: https://github.com/davidhalter/jedi-vim/pull/403#discussion_r29548013 --- jedi_vim.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jedi_vim.py b/jedi_vim.py index 303080f..09f27a2 100644 --- a/jedi_vim.py +++ b/jedi_vim.py @@ -425,6 +425,7 @@ def rename(): vim_command('autocmd InsertLeave call jedi#rename(1)') vim_command('augroup END') + vim_eval("let s:jedi_replace_orig = expand('')") vim_command('normal! diw') vim_command(':startinsert') else: @@ -444,6 +445,7 @@ def rename(): if replace is None: echo_highlight('No rename possible, if no name is given.') else: + orig = vim_eval('s:jedi_replace_orig') temp_rename = goto(is_related_name=True, no_output=True) # sort the whole thing reverse (positions at the end of the line # must be first, because they move the stuff before the position). @@ -466,7 +468,7 @@ def rename(): saved_view = vim_eval('winsaveview()') vim.current.window.cursor = r.start_pos - vim_command('normal! cw%s' % replace) + vim_command('normal! c{:d}l{}'.format(len(orig), replace)) # Restore view. vim_command('call winrestview(%s)' % PythonToVimStr(saved_view)) From 4d67c1a6e331ddd9e7fdda29da2e428ecd3610a3 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 2 May 2015 18:51:08 +0200 Subject: [PATCH 7/7] rename: refactor into do_rename, add rename_visual This adds a visual mode map for renaming, which asks for the new name via input(). `rename` itself could be changed to use `input()`, too - but I've left it for now. --- autoload/jedi.vim | 4 ++ ftplugin/python/jedi.vim | 1 + jedi_vim.py | 90 +++++++++++++++++++++++----------------- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/autoload/jedi.vim b/autoload/jedi.vim index a2172bf..0d7ca21 100644 --- a/autoload/jedi.vim +++ b/autoload/jedi.vim @@ -179,6 +179,10 @@ function! jedi#rename(...) PythonJedi jedi_vim.rename() endfunction +function! jedi#rename_visual(...) + PythonJedi jedi_vim.rename_visual() +endfunction + function! jedi#completions(findstart, base) PythonJedi jedi_vim.completions() endfunction diff --git a/ftplugin/python/jedi.vim b/ftplugin/python/jedi.vim index 134fd91..9bbcf4b 100644 --- a/ftplugin/python/jedi.vim +++ b/ftplugin/python/jedi.vim @@ -19,6 +19,7 @@ if g:jedi#auto_initialization " rename if g:jedi#rename_command != '' execute "nnoremap ".g:jedi#rename_command." :call jedi#rename()" + execute "vnoremap ".g:jedi#rename_command." :call jedi#rename_visual()" endif " documentation/pydoc if g:jedi#documentation_command != '' diff --git a/jedi_vim.py b/jedi_vim.py index 09f27a2..d686085 100644 --- a/jedi_vim.py +++ b/jedi_vim.py @@ -425,63 +425,77 @@ def rename(): vim_command('autocmd InsertLeave call jedi#rename(1)') vim_command('augroup END') - vim_eval("let s:jedi_replace_orig = expand('')") + vim_command("let s:jedi_replace_orig = expand('')") vim_command('normal! diw') vim_command(':startinsert') else: # reset autocommand vim_command('autocmd! jedi_rename InsertLeave') - # Save original window / tab. - saved_tab = int(vim_eval('tabpagenr()')) - saved_win = int(vim_eval('winnr()')) - replace = vim_eval("expand('')") vim_command('normal! u') # undo new word cursor = vim.current.window.cursor vim_command('normal! u') # undo the space at the end vim.current.window.cursor = cursor - if replace is None: - echo_highlight('No rename possible, if no name is given.') - else: - orig = vim_eval('s:jedi_replace_orig') - temp_rename = goto(is_related_name=True, no_output=True) - # sort the whole thing reverse (positions at the end of the line - # must be first, because they move the stuff before the position). - temp_rename = sorted(temp_rename, reverse=True, - key=lambda x: (x.module_path, x.start_pos)) - buffers = set() - for r in temp_rename: - if r.in_builtin_module(): - continue + return do_rename(replace) - if vim.current.buffer.name != r.module_path: - result = new_buffer(r.module_path) - if not result: - echo_highlight("Jedi-vim: failed to create buffer window for {}!".format(r.module_path)) - continue - buffers.add(vim.current.buffer.name) +def rename_visual(): + replace = vim.eval('input("Rename to: ")') + orig = vim.eval('getline(".")[(getpos("\'<")[2]-1):getpos("\'>")[2]]') + do_rename(replace, orig) - # Save view. - saved_view = vim_eval('winsaveview()') - vim.current.window.cursor = r.start_pos - vim_command('normal! c{:d}l{}'.format(len(orig), replace)) +def do_rename(replace, orig = None): + if replace is None: + echo_highlight('No rename possible, if no name is given.') + return - # Restore view. - vim_command('call winrestview(%s)' % PythonToVimStr(saved_view)) + if orig is None: + orig = vim_eval('s:jedi_replace_orig') - # Restore previous tab and window. - vim_command('tabnext {:d}'.format(saved_tab)) - vim_command('{:d}wincmd w'.format(saved_win)) + # Save original window / tab. + saved_tab = int(vim_eval('tabpagenr()')) + saved_win = int(vim_eval('winnr()')) - if len(buffers) > 1: - echo_highlight('Jedi did {:d} renames in {:d} buffers!'.format( - len(temp_rename), len(buffers))) - else: - echo_highlight('Jedi did {:d} renames!'.format(len(temp_rename))) + temp_rename = goto(is_related_name=True, no_output=True) + # sort the whole thing reverse (positions at the end of the line + # must be first, because they move the stuff before the position). + temp_rename = sorted(temp_rename, reverse=True, + key=lambda x: (x.module_path, x.start_pos)) + buffers = set() + for r in temp_rename: + if r.in_builtin_module(): + continue + + if vim.current.buffer.name != r.module_path: + result = new_buffer(r.module_path) + if not result: + echo_highlight("Jedi-vim: failed to create buffer window for {}!".format(r.module_path)) + continue + + buffers.add(vim.current.buffer.name) + + # Save view. + saved_view = vim_eval('winsaveview()') + + # Replace original word. + vim.current.window.cursor = r.start_pos + vim_command('normal! c{:d}l{}'.format(len(orig), replace)) + + # Restore view. + vim_command('call winrestview(%s)' % PythonToVimStr(saved_view)) + + # Restore previous tab and window. + vim_command('tabnext {:d}'.format(saved_tab)) + vim_command('{:d}wincmd w'.format(saved_win)) + + if len(buffers) > 1: + echo_highlight('Jedi did {:d} renames in {:d} buffers!'.format( + len(temp_rename), len(buffers))) + else: + echo_highlight('Jedi did {:d} renames!'.format(len(temp_rename))) @_check_jedi_availability(show_error=True)