Ethan
Ethan

Reputation: 60089

How can I format JS code in Vim?

I have this bit of JavaScript...

 15   $('.ajax_edit_address').each(function() {
 16     $(this).ajaxForm({
 17       target: $(this).parents('table.address').find('tr.address_header').children(':first'),
 18       success: function(response) {
 19         $('input, select, textarea', '.ajax_edit_address').removeClass('updating');
 20       }
 21     });
 22   });

That's formatted the way I like it. But let's say I had just finished typing something and I wanted to tidy it up. So I run the Vim code formatter on it...

=7j

The result is...

 15   $('.ajax_edit_address').each(function() {
 16       $(this).ajaxForm({
 17 target: $(this).parents('table.address').find('tr.address_header').children(':first'),
 18 success: function(response) {
 19 $('input, select, textarea', '.ajax_edit_address').removeClass('updating');
 20 }     
 21 }); 
 22       });

Vim seems to have trouble with functions as method arguments.

Here is what I think is the relevant part of my .vimrc...

:set cindent shiftwidth=2

" indent depends on filetype
:filetype indent on

:filetype plugin on

Is there something else that needs to be installed or configured to format JS code?

Upvotes: 26

Views: 30220

Answers (7)

Pierz
Pierz

Reputation: 8118

If you've got js-beautify installed (it's available for Python: pip install jsbeautifier, or Node: npm -g install js-beautify) then you can just run it directly from vim - to reformat the current file:

:%!js-beautify

Upvotes: 13

ton
ton

Reputation: 4577

Another alternative that do not need to configure anything inside vim is to run the format command manually at save like:

:w !js-beautify --stdin >%

After saving in this way the vim editor will ask you to reload the current file content:

W12: Warning: File "src/static/js/main.js" has changed and the buffer was changed in Vim as well
See ":help W12" for more info.
[O]K, (L)oad File: 

This works like the :w sudo tee % command used to save a file that you modified without privilege.

The command uses the standard input(STDIN) and write it to a variable file descriptor % used as source of current file.

PS: of course you need to install the js-beautify.

pip install jsbeautifier

Upvotes: 1

Pierre-Antoine LaFayette
Pierre-Antoine LaFayette

Reputation: 24402

The biggest issue seems to be the cindent doesn't recognize this type of syntax:

test({
  var b = 2;
});

It will turn it into this:

test({
    var b = 2;
    });

If you handle that case I'd imagine the indent wouldn't be so awful for the jQuery syntax. But this would require you writing a custom javascript indent file. Also, you'd have to edit the html indent file to not use cindent for script tags with javascript content.

I don't think anyone has successfully created a jquery/prototype compatible indent file for javascript. The existing javascript indent scripts are all flawed.

Upvotes: 2

Nick Zalutskiy
Nick Zalutskiy

Reputation: 15430

There is a far simpler solution that requires no vim plugins.

Install js-beautify to your system python:

pip install jsbeautifier

Then add this to your .vimrc:

autocmd FileType javascript setlocal equalprg=js-beautify\ --stdin

That's it.

Run :help equalprg to see why this works.

Upvotes: 15

the blizz
the blizz

Reputation: 330

I'd recommend the CLI version of einars/jsbeautify, which you can find here: https://github.com/einars/js-beautify. It's the offline version of www.jsbeautifier.org.

Use this plugin https://github.com/Chiel92/vim-autoformat to run the formatter on your current buffer with one button press.

Upvotes: 8

Jichao
Jichao

Reputation: 41795

VIM plugin Jsbeautify could handle jQuery correctly. It's the vim plugin version of the online Jsbeautify.

Upvotes: 23

jamessan
jamessan

Reputation: 42657

Unfortunately, 'cindent' just isn't going to do the job since it's is very much tied to C syntax. Since all the default indent script for javascript does is turn on 'cindent', that's not much help. It even says so in the script!

" Maintainer: None! Wanna improve this?

I don't do anything other than really basic javascript so I've never bothered trying to find anything better. From a quick look on vim.org, this script looks like it may be worth a shot. It's newer, so it probably takes into account the more complex javascript that's used now days.

Upvotes: 0

Related Questions