Setting up Emacs

as a Javascript

editing

environment for

Fun or Profit

I’ve been doing a lot of Javascript lately, which has naturally led to a whole lot of trips down the .emacs rabbit-hole

So, here are the steps you need to turn OOTB Emacs into the perfect environment for working on Javascript:

Auto-completion

Fizzing!



First up, you’re going to want decent auto-completion, so install the straightforwardly named auto-complete-mode. Due to some mode-name aliasing that goes on in the Emacs23 javascript mode, You’ll need to make sure it can find the relevant Javascript dictionary so

cd path/to/auto-complete/dict
ln -s javascript-mode js-mode

and then add to your .emacs:

(add-to-list 'load-path "~/path-to/auto-complete")
; Load the default configuration
(require 'auto-complete-config)
; Make sure we can find the dictionaries
(add-to-list 'ac-dictionary-directories "~/emacs/auto-complete/dict")
; Use dictionaries by default
(setq-default ac-sources (add-to-list 'ac-sources 'ac-source-dictionary))
(global-auto-complete-mode t)
; Start auto-completion after 2 characters of a word
(setq ac-auto-start 2)
; case sensitivity is important when finding matches
(setq ac-ignore-case nil)

You now have auto-completion for all variable names in all open Javascript buffers, as well as for standard syntax words (setTimeout, parseInt, onFocus etc).

Snippeting

Not content with that, we’ll also want some kind of intelligent snippet package right – how many times do you really want to type all those semicolons and curly braces? Once is good for me.

The excellent Yasnippet provides this (check out the youtube demo if you’ve not come across it before)

Once you’ve got that downloaded and installed, you’ll want some Javascript snippets to load in, the ones I use, for standard Javascript and jQuery can be downloaded from here, and then the directory provided by that tarfile needs to go in yasnippet/snippets/text-mode

So for our .emacs:

(add-to-list 'load-path "~/path/to/yasnippet")
;; Load the library
(require 'yasnippet)
(yas/initialize)
;; Load the snippet files themselves
(yas/load-directory "~/path/to/yasnippet/snippets/text-mode")
;; Let's have snippets in the auto-complete dropdown
(add-to-list 'ac-sources 'ac-source-yasnippet)

Syntax Checking

Whoops...

One of the problems with Javascript programming is that the feedback loop for syntax errors is *slow* – if you’re working with the web you have to wait for a whole pageload. So we’ll want on-the-fly error checking.

Kevin Turner originally wrote Lintnode, which runs a lighthweight node.js server that passes your file to Douglas Crockford’s JSLint to integrate with Flymake – the Emacs solution for on-the-fly syntax checking. The fork I’m currently maintaining at Github contains some enhancements such as automatic initialization and JSLint options passed from Emacs that the original has yet to merge in. Given that JSLint frequently complains about things that you might like it to er, not complain about, the ability to change the options with the lintnode-jslint-excludes variable makes this far more useable.

So:

Install node.js and npm (The package manager for node)

Get lintnode and the dependencies

git clone https://github.com/davidmiller/lintnode.git
cd lintnode
npm install express connect-form haml underscore

Then we need this in our .emacs:

(add-to-list 'load-path "~/path/to/lintnode")
(require 'flymake-jslint)
;; Make sure we can find the lintnode executable
(setq lintnode-location "~/path/to/lintnode")
;; JSLint can be... opinionated
(setq lintnode-jslint-excludes (list 'nomen 'undef 'plusplus 'onevar 'white))
;; Start the server when we first open a js file and start checking
(add-hook 'js-mode-hook
          (lambda ()
            (lintnode-hook)))

Syntax errors will now be given a red background without having to leave the comfort of Emacs.

Even better, if we install the Flymake Cursor package, we get the error message in the minibuffer when the cursor is on a line with an error.

Easy Mistake!

Get the source from http://www.emacswiki.org/emacs/flymake-cursor.el and then add to your .emacs:

(add-to-list 'load-path "~/emacs/minor-modes")
;; Nice Flymake minibuffer messages
(require 'flymake-cursor)

Edit:

As Jesse and Magnar point out in the comments, it’s probably a better idea to not exclude ‘undef from the jslint errors, but rather to declare global variables at the top of your .js file

 /*global $ */

This way you can let jslint know about other libraries you are using, but still get the checks for undefined variables in your own code.

Code folding

Underscore outline

Especially if you’re dealing with large projects, the ability to hide portions of code can be great for maintaining focus. Emacs comes with this built in, but you have to enable it, so returning to our .emacs:

(add-hook 'js-mode-hook
          (lambda ()
            ;; Scan the file for nested code blocks
            (imenu-add-menubar-index)
            ;; Activate the folding mode
            (hs-minor-mode t)))

This means that when your cursor is in the function…

var Foo = 42;
addFoo = function(num){
    // Let's add the meaning of life to
    // our `num` - it'll be fun!
    var meaningful;
    meaningful = num + Foo;
};

… and you M-x hs-hide-block, the function turns into:

Var Foo = 42;
addFoo = function(num){...};

To my taste the default keybinding of C-c @ C-h to hide blocks is somewhat perverse, so I’d recommend this in your .emacs:

;; Show-hide
(global-set-key (kbd "") 'hs-show-block)
(global-set-key (kbd "") 'hs-show-all)
(global-set-key (kbd "") 'hs-hide-block)
(global-set-key (kbd "") 'hs-hide-all)

YMMV.

Javascript Console

Having a REPL for the language you’re working with close to hand is basically required for me to enjoy working with it. Now that we’ve installed node.js, though, we can have us a Javascript console inside Emacs with js-comint

Once you’ve grabbed the file, your .emacs should have:

(add-to-list 'load-path "~/path/to/js-comint")
(require 'js-comint)
;; Use node as our repl
(setq inferior-js-program-command "node")
 
(setq inferior-js-mode-hook
      (lambda ()
        ;; We like nice colors
        (ansi-color-for-comint-mode-on)
        ;; Deal with some prompt nonsense
        (add-to-list 'comint-preoutput-filter-functions
                     (lambda (output)
                       (replace-regexp-in-string ".*1G\.\.\..*5G" "..."
                     (replace-regexp-in-string ".*1G.*3G" ">" output))))

You can then run a Javascript REPL with M-x run-js and also send portions of files by selecting them and then running M-x send-region. Neat.

By way of conclusion

There are a few other tweaks that make my Javascripting just that little bit nicer, but they’re more personal Emacs setup than anything specific to Javascript. So, there you have it, the perfect Javascript editing environment.

Love regards etc

Tags: , , , , , , , ,

52 Responses to “Setting up Emacs as a Javascript editing environment for Fun or Profit”

  1. Thanks for this. That setup for js-comint is going to be particularly handy.

  2. Tom Davey says:

    Wow, awesome. What a great tutorial. You are a graceful and lucid writer.

    Curious: why not use Yegge’s js2-mode or the older Javascript major modes?

    Thanks again for this,
    Tom Davey

    • david miller says:

      @Tom js2 has some great features, but I tend to use Emacs 23′s built in js-mode (The natural successor to the old espresso-mode)…
      js2 never really got indentation right. only thing that’s even usable is the bouncing indentation setup, which overrides TAB & means that I can’t then use default Yasnippet keys for expansion…
      It’s also really, really big for an editing mode – not sure I really want a recursive-descent parser running every 3 seconds when I’m editing a js file on a remote server over ssh :)
      I keep meaning to pull a bunch of the better smallish features out of it and bind them with hooks but haven’t gotten around to it

  3. bob says:

    Pleased with myself – finally set up most everything :)
    Thanks for the guide.

    One thing though…

    If I’m wrapping a script in jquery’s “$(document).ready()” then lintnode, understandably, flags the error:
    “$.” is not defined.
    Fair enough… $ really hasn’t been defined yet.

    Is there a way that we can lintnode or flymake to not flag the error?

    • david miller says:

      Yeah, that can come up a lot – if you’re using this version of lintnode then you can pass the –exclude option to turn off specific JSLint warnings [1] – so you’d want –exclude undef.

      You can set these from within Emacs – I use this in my ~/.emacs

      (setq lintnode-jslint-excludes (list ‘nomen ‘undef ‘plusplus ‘onevar ‘white))

      [1] http://www.jslint.com/lint.html#options

    • Jesse Proulx says:

      At the top of your JS files you can add a comment that JSLint will read for option switches and variables declared outside of your script, like so:

      /*jslint browser: true */
      /*global $,console */

      • david miller says:

        @jesse
        @Magnar

        I didn’t know about the /*global */ directive – thanks!

        Edited the post to suggest this :)

        • Uri says:

          Both jslint and jshint support rc files you can keep in your projects, and thus avoid adding these indicators in source files. e.g. .jslintrc or .jshintrc

  4. thorarinn says:

    Pardon my ignorance, but I can’t seem to get the syntax-checking part to work properly: I’ve set up node as well as your fork of Lintnode, using the same settings in my .emacs, but when I run flymake-start-syntax-check on my js files, it’s all red. I’m using jQuery, but shouldn’t that be ok if I exclude undef in the .emacs setup like you did?

    This seems like such a cool addition to my js dev setup that I really want to make it click :)

  5. thorarinn says:

    … and thanks a lot for the guide!

  6. tortuga says:

    Great blog!
    Really thanks for sharing this post! : )
    You make me set up a great emacs js env. in few minutes!

    a small note: You didn’t yank your latest “))”
    to close your (setq inferior-js-mode-hook
    and > has replaced the >

    Bye and still thanks,

  7. Jesse Proulx says:

    An alternative to lintnode is to run a standalone version of V8, like so: https://github.com/valeryz/jslint-v8

    This removes the overhead of running a node server application just for syntax checking, but still has the speed of the node.js internal engine.

  8. Murph says:

    Are you not bothered by the way js-mode indents inlined var declarations? eg

    var foo = {},
    bar = ”,
    baz,
    bat;

    Kinda sucks… and not only that, but even if you manually space the variables, the syntax highlighting doesn’t recognize them.

    I found a bug report on the emacs list for this issue from April, but nothing else. I’m new to emacs and have no idea how to fix it, other than to switch to the modified js2-mode, which I don’t want to do.

    Great guide, though. I tried getting js-comint working with Node yesterday and failed. It was invoking the REPL but not sending the region. Going to follow the guide step by step and see if I can fix it. Thanks

    • Murph says:

      So following up myself, when I set up the Node REPL, I get some functionality but it continues to be buggy. If I write a function and highlight it and run M-x js-send-region, I get ‘…’ printed from Node. Likewise if I place the pointer after that function and do M-x js-send-last-sexp. Does anyone else have these problems?

      • Murph says:

        Testing it some more, it seems like js-send-region only works for me if the region is one line. Otherwise it seems the region does not get read into the Node REPL and the REPL prints out ‘…’ . Would love a fix; being able to use inferior shells is one of the major reasons I’m trying to switch to Emacs.

        • GraemeA says:

          I’ve been looking at this – my impression is that some multiline functions work Ok with js-send-region, but it seems that blank lines confuse it.

          Also, embedded tab character in the region causes problems.

          I’m working on overriding comint-input-sender to strip out the problematic characters (this seems to be the approved way of altering input to comint) – no success yet.

    • david miller says:

      >> other than to switch to the modified js2-mode, which I don’t want to do.
      Quite :)

      Was planning on looking into modifying indent behaviour to fix a bug in another project of mine, once I’ve figured out how that works, I may see if I can pull some of those indentation/highlighting bits out as a mode-hook.

  9. Luca Lenardi says:

    Hi! And first of all thanks a lot for this wonderful (and useful) post.

    Just an open question: did you came up with something for in-emacs documentation? It could be something like pylookup for the emacs python environment. Probably the point is getting the documentation in the correct format. Any idea?

  10. Jan Gloser says:

    Thanks a lot, man.

  11. basementdad says:

    Hi, in your $.get and $.post snippets are errors. They contain a “}” too much before the semicolon. Except that, thanks for the snippets. Awesome stuff.

    • david miller says:

      Thanks for the heads-up – in practice I tend not to use $.get & $.post very often – updated the tarball to fix that though

  12. Srinivas Y says:

    how did you resolve the tab conflict in both autocomplete and yasnippet.

    autocomplete works fine but snippet doesn’t work. am i missing something here. When i type fun and hit tab it auto-completes to function rather than expanding the snippet.

    btw thanks for the superb article…helped me setting up my emacs.

  13. wvxvw says:

    Something quick. This might be new feature, but you would want to update it, probably. I was following your explanation and found that I also must provide some values to lintnode-jslint-set otherwise node server will not launch from flymake-jslint.

  14. [...] Setting up Emacs as a Javascript editing environment for Fun or Profit « Deadpan Sincerity [...]

  15. Marius says:

    Thanks for a great article!

    I wondered about one thing: Have you managed to combine comint and js-mode, to get auto-completion (and syntax highlighting) in the interpreter?

  16. Fantastic web page. Many helpful tips here. I am submitting the idea to a few pals ans as well revealing around delicious. And definitely, thank you on your hard work!

  17. [...] todo esto tendremos Emacs listo para programar JavaScript. Por cierto, en esta web encontré gran parte de la información necesaria para escribir este [...]

  18. ari says:

    Thanks for the fantastic article. I’ve been able to get some of it working but have run into some trouble getting flymake up.

    After following your directions, I try to visit a .js file and get the following:

    File mode specification error: (file-error “Searching for program” “no such file or directory” “node”)

    If I add the .nvm directory where node lives to my load-path I then get the following error:

    Flymake: Configuration error has occurred while running (curl –form source=<pendingAccounts.test_flymake.js –form filename=pendingAccounts.test_flymake.js –proxy http://127.0.0.1:3003/jslint). Flymake will be switched OFF.

    (where pendingAccounts.test.js is the name of the file I'm trying to visit).

    For what it's worth, for the next moth or so we'll still be on node 0.6.21

    I've started tracking this down (in pauses at work – it'll take a bit) but I wanted to post where I'm at in case it helps someone or if the solution is known.

    And thanks again! Viva emacs!

  19. ari says:

    Oh snap. I think it has to do with the ancient version of node we’re using here at the ol’ office: 0.6.21

    I’ma give up for a while and let the browser tell me when I typo.. We’re supposed to upgrade soon.

  20. kuchnia says:

    magnificent put up, very informative. I wonder why the other specialists of
    this sector don’t realize this. You must continue your writing.
    I’m confident, you have a great readers’ base already!

  21. Article Source: Daniels is a master trout angler and author, living and trout fishing in the
    Mountain West – the heart of trophy trout country.

    To keep your campsite free from them, here are good tips to follow:.

    Scenes like this early morning scape may be welcoming to several individuals who seek the relaxation of one of the world’s oldest sports: fishing.

  22. endado says:

    You understand therefore significantly in the case of this topic, produced me in my view consider it from a lot of numerous angles. Its like women and men don’t seem to be involved unless it is something to do with Girl gaga! Your own stuffs outstanding. All the time care for it up!

  23. Tɦe brand is high bbay led light… Donald high bay led lights.

  24. This dust can enter the house with the air and cause illness and aggravate any dust related allergies.
    Household products such as vegetable oil and castile soap can be combined
    with vinegar to clean wood decks naturally as
    well. your family, especially children, your friends, your pets and yourself.

    Feel free to surf to my webpage – certified Long Island Stair installer [taylorschg.Soup.io]

  25. Kiyoko says:

    I see a lot of interesting posts on your page.
    You have to spend a lot of time writing, i know how to save
    you a lot of work, there is a tool that creates unique, google
    friendly posts in couple of minutes, just search in google – laranita’s free
    content source

  26. I loved as much as you’ll receive carried out right here.
    The sketch is tasteful, your authored material stylish. nonetheless, you command get got an nervousness over that you wish
    be delivering the following. unwell unquestionably come more
    formerly again since exactly the same nearly a lot often inside case you shield this hike.

    Check out my homepage … oklejanie samochodów

  27. endado says:

    Hello there, You have performed an excellent job. I will definitely digg it and in my opinion suggest to my friends. I’m confident they will be benefited from this web site.

  28. I have been exploring for a little for any high quality articles or
    weblog posts in this kind of area . Exploring in Yahoo I eventually stumbled upon this website.
    Reading this info So i’m glad to exhibit that I’ve an incredibly just right uncanny feeling I found out just what I needed.

    I such a lot definitely will make certain to do not omit this site
    and provides it a look regularly.

  29. Led high bay warehouse lighting

    Setting up Emacs as a Javascript editing environment for Fun or Profit « Deadpan Sincerity

  30. Johnk684 says:

    Very informative blog post.Really thank you! Keep writing. agegefdebcee

  31. Simply want to say your article is as astonishing.
    The clearness on your put up is simply great and i can assume
    you are knowledgeable on this subject. Fine together with your permission allow me to seize your RSS feed
    to stay updated with impending post. Thank you a
    million and please carry on the enjoyable work.

  32. Uggs On Sale says:

    On Sale Ugg Boots lakers season will begin in September and last to October.

  33. I am regular reader, how are you everybody? This piece of writing posted
    at this web page is actually fastidious.

    Look at my page: foggy window repair arlington

  34. This design is spectacular! You definitely know how to keep a readerr entertained.
    Between your wit and your videos, I was almkst
    moved to start my own blog (well, almost…HaHa!) Fantastic job.
    I really loced what you had to say, and more than that, hhow you presented it.
    Too cool!

Leave a Reply