Unlike other language development, JavaScript, for me, has two components, a front-end, browser-based interface, as well as a back-end, server-side interface through Node.
I like the extras found in Steve Yegge’s js2-mode.
(use-package js2-mode
:ensure t
:init
(setq js-basic-indent 2)
(setq-default js2-basic-indent 2
js2-basic-offset 2
js2-auto-indent-p t
js2-cleanup-whitespace t
js2-enter-indents-newline t
js2-indent-on-enter-key t
js2-global-externs (list "window" "module" "require" "buster" "sinon" "assert" "refute" "setTimeout" "clearTimeout" "setInterval" "clearInterval" "location" "__dirname" "console" "JSON" "jQuery" "$"))
(add-hook 'js2-mode-hook
(lambda ()
(push '("function" . ?ƒ) prettify-symbols-alist)))
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode)))Color defined variables with color-identifiers-mode:
(use-package color-identifiers-mode
:ensure t
:init
(add-hook 'js2-mode-hook 'color-identifiers-mode))While editing JavaScript is baked into Emacs, it is quite important
to have flycheck validate the source based on jshint, and eslint.
Let’s prefer eslint:
(add-hook 'js2-mode-hook
(lambda () (flycheck-select-checker "javascript-eslint")))Now load and edit a JavaScript file, like jshint-code-test.js.
The Tern project is a JavaScript analyzer that can be used to improve the JavaScript integration with editors like Emacs.
(use-package tern
:ensure t
:init (add-hook 'js2-mode-hook (lambda () (tern-mode t)))
:config
(use-package company-tern
:ensure t
:init (add-to-list 'company-backends 'company-tern)))The following additional keys are bound:
M-.- Jump to the definition of the thing under the cursor.
- M-,
- Brings you back to last place you were when you pressed
M-.. C-c C-r- Rename the variable under the cursor.
C-c C-c- Find the type of the thing under the cursor.
C-c C-d- Find docs of the thing under the cursor. Press again to open the associated URL (if any).
The js2-refactor mode should start with C-c . and then a two-letter
mnemonic shortcut.
efisextract-function: Extracts the marked expressions out into a new named function.emisextract-method: Extracts the marked expressions out into a new named method in an object literal.ipisintroduce-parameter: Changes the marked expression to a parameter in a local function.lpislocalize-parameter: Changes a parameter to a local var in a local function.eoisexpand-object: Converts a one line object literal to multiline.coiscontract-object: Converts a multiline object literal to one line.euisexpand-function: Converts a one line function to multiline (expecting semicolons as statement delimiters).cuiscontract-function: Converts a multiline function to one line (expecting semicolons as statement delimiters).eaisexpand-array: Converts a one line array to multiline.caiscontract-array: Converts a multiline array to one line.wiiswrap-buffer-in-iife: Wraps the entire buffer in an immediately invoked function expressionigisinject-global-in-iife: Creates a shortcut for a marked global by injecting it in the wrapping immediately invoked function expressionagisadd-to-globals-annotation: Creates a/*global */annotation if it is missing, and adds the var at point to it.evisextract-var: Takes a marked expression and replaces it with a var.ivisinline-var: Replaces all instances of a variable with its initial value.rvisrename-var: Renames the variable on point and all occurrences in its lexical scope.vtisvar-to-this: Changes localvar ato bethis.ainstead.aoisarguments-to-object: Replaces arguments to a function call with an object literal of named arguments. Requires yasnippets.3iisternary-to-if: Converts ternary operator to if-statement.svissplit-var-declaration: Splits avarwith multiple vars declared, into severalvarstatements.uwisunwrap: Replaces the parent statement with the selected region.
(use-package js2-refactor
:ensure t
:init (add-hook 'js2-mode-hook 'js2-refactor-mode)
:config (js2r-add-keybindings-with-prefix "C-c ."))I also configure Skewer for my HTML and CSS files, we need to do the same for JavaScript:
(use-package skewer-mode
:ensure t
:init (add-hook 'js2-mode-hook 'skewer-mode))Kick things off with run-skewer, and then:
- C-x C-e
- `skewer-eval-last-expression’
- C-M-x
- `skewer-eval-defun’
- C-c C-k
- `skewer-load-buffer’
Using the coffee-mode for CoffeeScript file.
(use-package coffee-mode
:ensure t
:init
(setq-default coffee-tab-width 2))Need to remember the following keybindings:
Return- Insert newline and indent line
C-c C-<, backtab- Indent line or region to left
C-c C->- Indent line or region to right
A-r, C-c C-k- Compile buffer to JavaScript
A-R- Compile content of region to JavaScript
A-M-r, C-c C-z- Run CoffeeScript REPL
C-c C-l- Send this line to REPL buffer
C-c C-r- Send content of region to REPL buffer
C-c C-b- Send content of buffer to REPL buffer
C-c C-o C-s- Enable coffee-cos-mode
(use-package ob-coffee
:ensure t)Make sure that we can simply require this library.
(provide 'init-javascript)Before you can build this on a new system, make sure that you put
the cursor over any of these properties, and hit: C-c C-c