nobe4
nobe4

Reputation: 2842

Javascript function expression reformatting with vim replace

Here is the reformatting I want to do :

// before
var name1 = function(){ /* stuff */ }
//after
function name1(){ /* stuff */ }

I used a vim replace command :

%s/var\.*\s*\(\w*\)\s*=\s*function/function \1

But I found it a little long for the task (matching a var, a word, a = and a function) ...

How would you do it a nicer way ?

Upvotes: 0

Views: 99

Answers (4)

Peter Rincker
Peter Rincker

Reputation: 45177

As @apsillers stated you can capture function to so you don't have to type it out in the replacement part of the substitute command. This yields this:

:%s/var\.*\s*\(\w*\)\s*=\s*\(function\)/\2 \1

However we can do a bit better by using \v or very magic to reduce the number of escapes. This yields:

:%s/\vvar.*\s*(\w*)\s*=\s*(function)/\2 \1

However we still have some issues:

  • Why match .* when a simple \s+ will do
  • \w* will also match an empty string which is invalid so use \w+

Now we have:

:%s/\vvar\s+(\w+)\s*=\s*(function)/\2 \1

As an alternative to using a substitution you may wan to use a macro or run a normal command. I prefer to use global, :g, and some normal commands via :norm:

:g/=\s*function/norm ^deye3dwe"0p

This command finds all lines that match =\s*function and execute a normal command. The normal command we run is ^deye3dwe"0p, which can be broken down like so:

  • ^ will start the the beginning of the line. If you do not care about indention remove the ^
  • de delete the word (var) and leaves the following space
  • ye will yank or copy the variable name with the prepended space
  • 3dw will delete 3 words which will leave us with on the f in function
  • Move to the end of function via e
  • "0p paste the freshly yanked variable name after function. We must use "0 register because the unnamed register will be clobbered by the 3dw

For more help see:

:h /\v
:h /\+
:h :g
:h :norm
:h "0

Upvotes: 1

LondonRob
LondonRob

Reputation: 79013

Here's the slickest I could get it in a macro:

0diw"fdt dtfw"fP

Here's the explanation:

  • 0 Go to the start of the line
  • diw delete "inside" the current word (i.e. not the following Space, we'll need it!)
  • "fdt into the f buffer (for "function" perhaps?!) delete to the next space
  • dtf delete up to the next f character
  • w jump to the next 'word' (which gets us to the open paren)
  • "fP 'put' from the f buffer before the cursor

Now a quick entry in your ~/.vimrc:

noremap <F4> 0diw"fdt dtfw"fP

and you're gold. (Or whatever shortcut key you want instead of F4.

Upvotes: 1

nobe4
nobe4

Reputation: 2842

@apsillers : putting function in a capture group and referring to it with \2

%s/var\.*\s*\(\w*\)\s*=\s*\(function\)/\2 \1

@Enermis : with a macro (assuming cursor is on the vof var) :

dwyef(i ^[pbbd0

Upvotes: 0

Ben
Ben

Reputation: 1143

I would also use the substitute command, but slightly differently: :%s/var\s\+\(\w*\)\s*=\s*\(function\)/\2 \1.

Upvotes: 1

Related Questions