Javascript refactoring in Vim
I don't need anything super fancy, but some scope aware refactoring would be nice.
Refactoring something in function scope is one of the most common scenarios for me:
var funyfun = function(arg1, arg2) {
arg1 = ...arg2;
arg2....();
}
Is there a vim plugin that would allow me to refactor arg1, for ex, in the scope of that function or do I have to inv开发者_高级运维ent my own "select block, find, replace" shortcut.
For extra kudos, something that would "refactor on the fly" as I type, so I can see where changes are being made. Netbeans does an excellent job of this.
This is not limited to a certain block, but this how I would do it with plain Vim:
- Move cursor on top of
arg1
and type*N
- Type
ciw
and insert replacement. - Now you can use
n
andN
to navigate the occurrences and by pressing.
Vim will redo the replacement on the current match
Here's a shortcut for it:
" Simple word refactoring shortcut. Hit <Leader>r<new word> on a word to
" refactor it. Navigate to more matches with `n` and `N` and redo refactoring
" by hitting the dot key.
map <Leader>r *Nciw
Sound a bit like you only want renaming instead of refactoring. Full refactoring is tricky for Javascript, though some IDEs provide approximations. Since the question is about Vim specifically, and hacks aren't excluded, I'll just jump on the scope-aware aspect:
I've got a modified DoctorJS to generate scope-aware tags, with a Vim plugin for scope-aware navigation based on those tags (see blog post/screencast).
The hacky part comes in how navigation is implemented for Vim: I generate a search pattern that includes the scope of the variable and excludes all nested scopes for the same name. So, you could use that search pattern (function scoped_tags#FindTagInScope
) to implement renaming (only if all uses are in the same file, and it doesn't exclude comments and the like..). Or you could use the scoped navigation to jump through variable occurrences manually and use '.' to rename them..
A few JavaScript-aware commands for Vim are provided by tern_for_vim, such as :TernRename
for scope-aware renaming of variables, :TernDef
for jumping to the definition of the thing under the cursor, and so on. You will need to have nodejs and npm installed, make sure to read the installation instructions in the repo.
As a partial solution you can use Eclim with JSDT, which allows you to use power of Eclipse refactoring/debugging/auto-completion/plugins with Vim.
In my experience, it may be a bit slow on older machines, but it's worth giving it a try.
In addition to doing actual scope-aware refactoring and the like, consider :%s/varName/newNav/gc
. Per :help :s_c
, the c
flag passed to :s
enters a quick confirmation mode for find/replace operations that prompts you (y/n) on whether each match should be replaced or not.
you can do:
:.,/^}/ s/\<arg1\>/new_name/g
the .,/^}/
is a range that many Ex commands accept: from cursor line to next line starting with a closing brace.
Benoit and Epeli has some good points, however, I find it a bit tedious to write .,/^}/
before my substitute statement, and since it only modifies code from the cursor position to the next line starting with a }
, it depends on having the cursor position at the beginning of the function or block (and it will not work for an entire function with an if statement).
So instead I use visual mode in combination with textobjects. For instance, typing vi{
will select all the code inside the closest matching pair of {}
, va{
will include the {}
characters, and if you do this with visual line (vi{V
), you'll get the entire function declaration as well. Then you can just do a :s/\<arg1\>/new_name/g
to rename arg1
to new_name
, including function parameters.
精彩评论