241 lines
12 KiB
Org Mode
241 lines
12 KiB
Org Mode
#+TITLE: JavaScript layer
|
||
|
||
[[file:img/javascript.png]]
|
||
|
||
* Table of Contents :TOC_4_gh:noexport:
|
||
- [[#description][Description]]
|
||
- [[#features][Features:]]
|
||
- [[#install][Install]]
|
||
- [[#web-beautify][web-beautify]]
|
||
- [[#prettier][prettier]]
|
||
- [[#choosing-a-backend][Choosing a backend]]
|
||
- [[#choosing-a-formatter][Choosing a formatter]]
|
||
- [[#backends][Backends]]
|
||
- [[#tern][Tern]]
|
||
- [[#language-server-protocol][Language Server Protocol]]
|
||
- [[#configuration][Configuration]]
|
||
- [[#indentation][Indentation]]
|
||
- [[#repl][REPL]]
|
||
- [[#node-modules][Node Modules]]
|
||
- [[#key-bindings][Key Bindings]]
|
||
- [[#js2-mode][js2-mode]]
|
||
- [[#folding-js2-mode][Folding (js2-mode)]]
|
||
- [[#refactoring-js2-refactor][Refactoring (js2-refactor)]]
|
||
- [[#documentation-js-doc][Documentation (js-doc)]]
|
||
- [[#repl-skewer-mode][REPL (skewer-mode)]]
|
||
|
||
* Description
|
||
This layer adds support for the JavaScript language using [[https://github.com/mooz/js2-mode][js2-mode]].
|
||
|
||
** Features:
|
||
- Multiple backends support: Tern and LSP
|
||
- Smart code folding
|
||
- Refactoring: done using [[https://github.com/magnars/js2-refactor.el][js2-refactor]].
|
||
- Auto-completion and documentation
|
||
- REPL available via [[https://github.com/skeeto/skewer-mode][skewer-mode]] and [[https://github.com/pandeiro/livid-mode][livid-mode]]
|
||
- Formatting with [[https://github.com/yasuyk/web-beautify][web-beautify]]
|
||
|
||
* Install
|
||
To use this configuration layer, add it to your =~/.spacemacs=. You will need to
|
||
add =javascript= to the existing =dotspacemacs-configuration-layers= list in
|
||
this file.
|
||
|
||
To activate error checking using flycheck, install one of the [[http://www.flycheck.org/en/latest/languages.html#javascript][available linters]]
|
||
such as =ESLint= or =JSHint=:
|
||
|
||
#+BEGIN_SRC sh
|
||
$ npm install -g eslint
|
||
# or
|
||
$ npm install -g jshint
|
||
#+END_SRC
|
||
|
||
If you install these in non-standard locations, then add the following to your =dotspacemacs/user-init= function:
|
||
|
||
#+BEGIN_SRC elisp
|
||
(add-to-list 'exec-path "/path/to/node/bins" t)
|
||
#+END_SRC
|
||
|
||
** web-beautify
|
||
See [[file:../../+tools/web-beautify/README.org][web-beautify layer]] documentation.
|
||
|
||
** prettier
|
||
See [[file:../../+tools/prettier/README.org][prettier layer]] documentation.
|
||
|
||
** Choosing a backend
|
||
To choose a default backend set the layer variable =javascript-backend=:
|
||
|
||
#+BEGIN_SRC elisp
|
||
(javascript :variables javascript-backend 'tern)
|
||
#+END_SRC
|
||
|
||
Backend can be chosen on a per project basis using directory local variables
|
||
(files named =.dir-locals.el= at the root of a project), an example to use the
|
||
=lsp= backend:
|
||
|
||
#+BEGIN_SRC elisp
|
||
;;; Directory Local Variables
|
||
;;; For more information see (info "(emacs) Directory Variables")
|
||
|
||
((js2-mode (javascript-backend . lsp)))
|
||
#+END_SRC
|
||
|
||
** Choosing a formatter
|
||
To choose a formatter, set the layer variable =javascript-fmt-tool=:
|
||
|
||
#+BEGIN_SRC elisp
|
||
(javascript :variables javascript-fmt-tool 'web-beautify)
|
||
#+END_SRC
|
||
|
||
Formatter can be chosen on a per project basis using directory local variables
|
||
(files named =.dir-locals.el= at the root of a project), an example to use the
|
||
=prettier= formatter:
|
||
|
||
#+BEGIN_SRC elisp
|
||
;;; Directory Local Variables
|
||
;;; For more information see (info "(emacs) Directory Variables")
|
||
|
||
((js2-mode (javascript-fmt-tool . prettier)))
|
||
#+END_SRC
|
||
|
||
*Note:* you can easily add a directory local variable with ~SPC f v d~.
|
||
|
||
* Backends
|
||
** Tern
|
||
See [[file:../../+tools/tern/README.org][tern layer]] documentation.
|
||
|
||
** Language Server Protocol
|
||
You just have to install javascript and typescript language server packages:
|
||
|
||
#+BEGIN_SRC sh
|
||
npm i -g typescript javascript-typescript-langserver
|
||
#+END_SRC
|
||
|
||
* Configuration
|
||
** Indentation
|
||
To change how js2-mode indents code, set the variable =js2-basic-offset=, as
|
||
such:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default js2-basic-offset 2)
|
||
#+END_SRC
|
||
|
||
or when adding the =javascript= configuration layer:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(javascript :variables js2-basic-offset 2)
|
||
#+END_SRC
|
||
|
||
Similarly, to change how js-mode indents JSON files, set the variable
|
||
=js-indent-level=, as such:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default js-indent-level 2)
|
||
#+END_SRC
|
||
|
||
or when adding the =javascript= configuration layer:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(javascript :variables js-indent-level 2)
|
||
#+END_SRC
|
||
|
||
** REPL
|
||
To use the available JS repl, you need a running httpd server and a page loaded
|
||
with skewer. If a blank page serves your needs, just use the run-skewer command
|
||
in your javascript buffer. If you want to inject it in your own page, follow
|
||
[[https://github.com/skeeto/skewer-mode#skewering-with-cors][these instructions]] (install the Greasemonkey script and then click the triangle
|
||
in the top-right corner - if it turns green, you’re good to go).
|
||
|
||
** Node Modules
|
||
If you would like =node_modules/.bin= to be automatically added to the buffer
|
||
local =exec_path=, e.g. to support project local eslint installations, set the
|
||
=node-add-modules-path= variable in the =javascript= config section. Note that
|
||
doing this [[https://stackoverflow.com/questions/9679932#comment33532258_9683472][introduces a security risk]]:
|
||
|
||
#+BEGIN_SRC elisp
|
||
(setq-default dotspacemacs-configuration-layers
|
||
'((javascript :variables node-add-modules-path t)))
|
||
#+END_SRC
|
||
|
||
* Key Bindings
|
||
** js2-mode
|
||
|
||
| Key Binding | Description |
|
||
|-------------+--------------------------------------|
|
||
| ~SPC m w~ | toggle js2-mode warnings and errors |
|
||
| ~%~ | jump between blockswith [[https://github.com/redguardtoo/evil-matchit][evil-matchit]] |
|
||
|
||
** Folding (js2-mode)
|
||
|
||
| Key Binding | Description |
|
||
|-------------+--------------------------|
|
||
| ~SPC m z c~ | hide element |
|
||
| ~SPC m z o~ | show element |
|
||
| ~SPC m z r~ | show all element |
|
||
| ~SPC m z e~ | toggle hide/show element |
|
||
| ~SPC m z F~ | toggle hide functions |
|
||
| ~SPC m z C~ | toggle hide comments |
|
||
|
||
** Refactoring (js2-refactor)
|
||
Bindings should match the plain emacs assignments.
|
||
|
||
| Key Binding | Description |
|
||
|---------------+----------------------------------------------------------------------------------------------------------------|
|
||
| ~SPC m k~ | deletes to the end of the line, but does not cross semantic boundaries |
|
||
| ~SPC m r 3 i~ | converts ternary operator to if-statement |
|
||
| ~SPC m r a g~ | creates a =/* global */= annotation if it is missing, and adds var to point to it |
|
||
| ~SPC m r a o~ | replaces arguments to a function call with an object literal of named arguments |
|
||
| ~SPC m r b a~ | moves the last child out of current function, if-statement, for-loop or while-loop |
|
||
| ~SPC m r c a~ | converts a multiline array to one line |
|
||
| ~SPC m r c o~ | converts a multiline object literal to one line |
|
||
| ~SPC m r c u~ | converts a multiline function to one line (expecting semicolons as statement delimiters) |
|
||
| ~SPC m r e a~ | converts a one line array to multiline |
|
||
| ~SPC m r e f~ | extracts the marked expressions into a new named function |
|
||
| ~SPC m r e m~ | extracts the marked expressions out into a new method in an object literal |
|
||
| ~SPC m r e o~ | converts a one line object literal to multiline |
|
||
| ~SPC m r e u~ | converts a one line function to multiline (expecting semicolons as statement delimiters) |
|
||
| ~SPC m r e v~ | takes a marked expression and replaces it with a var |
|
||
| ~SPC m r i g~ | creates a shortcut for a marked global by injecting it in the wrapping immediately invoked function expression |
|
||
| ~SPC m r i p~ | changes the marked expression to a parameter in a local function |
|
||
| ~SPC m r i v~ | replaces all instances of a variable with its initial value |
|
||
| ~SPC m r l p~ | changes a parameter to a local var in a local function |
|
||
| ~SPC m r l t~ | adds a console.log statement for what is at point (or region) |
|
||
| ~SPC m r r v~ | renames the variable on point and all occurrences in its lexical scope |
|
||
| ~SPC m r s l~ | moves the next statement into current function, if-statement, for-loop, while-loop |
|
||
| ~SPC m r s s~ | splits a =String= |
|
||
| ~SPC m r s v~ | splits a =var= with multiple vars declared into several =var= statements |
|
||
| ~SPC m r t f~ | toggle between function declaration and function expression |
|
||
| ~SPC m r u w~ | replaces the parent statement with the selected region |
|
||
| ~SPC m r v t~ | changes local =var a= to be =this.a= instead |
|
||
| ~SPC m r w i~ | wraps the entire buffer in an immediately invoked function expression |
|
||
| ~SPC m r w l~ | wraps the region in a for-loop |
|
||
| ~SPC m x m j~ | move line down, while keeping commas correctly placed |
|
||
| ~SPC m x m k~ | move line up, while keeping commas correctly placed |
|
||
|
||
*** Documentation (js-doc)
|
||
You can check more [[https://github.com/mooz/js-doc/][here]]
|
||
|
||
| Key Binding | Description |
|
||
|---------------+---------------------------------------|
|
||
| ~SPC m r d b~ | insert JSDoc comment for current file |
|
||
| ~SPC m r d f~ | insert JSDoc comment for function |
|
||
| ~SPC m r d t~ | insert tag to comment |
|
||
| ~SPC m r d h~ | show list of available jsdoc tags |
|
||
|
||
** REPL (skewer-mode)
|
||
|
||
| Key Binding | Description |
|
||
|-------------+------------------------------------------------------------------|
|
||
| ~SPC m e e~ | evaluates the last expression |
|
||
| ~SPC m e E~ | evaluates and inserts the result of the last expression at point |
|
||
|
||
| Key Binding | Description |
|
||
|-------------+------------------------------------------------------------------------------------|
|
||
| ~SPC m s a~ | Toggle live evaluation of whole buffer in REPL on buffer changes |
|
||
| ~SPC m s b~ | send current buffer contents to the skewer REPL |
|
||
| ~SPC m s B~ | send current buffer contents to the skewer REPL and switch to it in insert state |
|
||
| ~SPC m s f~ | send current function at point to the skewer REPL |
|
||
| ~SPC m s F~ | send current function at point to the skewer REPL and switch to it in insert state |
|
||
| ~SPC m s i~ | starts/switch to the skewer REPL |
|
||
| ~SPC m s r~ | send current region to the skewer REPL |
|
||
| ~SPC m s R~ | send current region to the skewer REPL and switch to it in insert state |
|
||
| ~SPC m s s~ | switch to REPL |
|