最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript refactoring in Vim - Stack Overflow

programmeradmin3浏览0评论

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

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

Share Improve this question edited Aug 30, 2011 at 15:09 Xavier T. 42.2k10 gold badges75 silver badges99 bronze badges asked Aug 30, 2011 at 14:23 Nick ZalutskiyNick Zalutskiy 15.4k7 gold badges54 silver badges50 bronze badges 2
  • I am not sure there is scope-aware solution for Javascript. But I'd like to be proven wrong. – Xavier T. Commented Aug 30, 2011 at 15:10
  • What refactoring do you want to perform exactly? Could you provide us with a before/after example? – romainl Commented Nov 6, 2011 at 10:53
Add a comment  | 

7 Answers 7

Reset to default 6

This is not limited to a certain block, but this how I would do it with plain Vim:

  1. Move cursor on top of arg1 and type *N
  2. Type ciw and insert replacement.
  3. Now you can use n and N 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.

发布评论

评论列表(0)

  1. 暂无评论