e3b6464649
* [core][keybinng] improve minor mode binding This commit added add a new function defun spacemacs/declare-prefix-for-minor-mode and improved spacemacs/set-leader-keys-for-minor-mode. `which-key` package recently introduced a new api which-key-add-keymap-based-replacements which improves perfomance and allows prefix and namings to be stored directly in keymap. This is a great improvement. With this new api we now make change to spacemacs/declare-prefix-for-minor-mode to manage prefix also. For example: (spacemacs/set-leader-keys-for-minor-mode 'lsp-mode "=" "format" "=b" #'lsp-format-buffer) Before we had to use another api to bind prefix spacemacs/declare-prefix-for-mode which only works on major-mode. As lsp-mode is a minor mode this api causes a lot of problems to which-key performance. An example is https://github.com/syl20bnr/spacemacs/issues/12455 which led to my hack in https://github.com/syl20bnr/spacemacs/pull/12474. The improved spacemacs/set-leader-keys-for-minor-mode will take care of both prefix and key naming for the minor mode. This will allows us to have a better set up for dynamic minor modes such as lsp-mode, tide-mode etc. Also another api is created to make prefix for minor mode: spacemacs/declare-prefix-for-minor-mode. Usage: (spacemacs/declare-prefix-for-minor-mode 'tide-mode "E" "errors")" * [tide] improve prefix * [lsp] improve prefix |
||
---|---|---|
.. | ||
img | ||
config.el | ||
funcs.el | ||
layers.el | ||
packages.el | ||
README.org |
JavaScript layer
Description
This layer adds support for the JavaScript language using js2-mode.
Features:
- Multiple backends support: Tern and LSP
- Smart code folding
- Refactoring: done using js2-refactor.
- Auto-completion and documentation
- Browser based REPL available via skewer-mode and livid-mode
- Server based REPL with nodejs-repl
- Formatting with web-beautify or prettier
- Interactive debugger using dap-mode
- Display Flow & Typescript type information
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.
Error checking / linting
To activate error checking / linting using flycheck, install on your system one of the available linters
such as ESLint
, JSHint
or StandardJS
:
$ npm install -g eslint
# or
$ npm install -g jshint
# or
$ npm install -g standard
If you install these in non-standard locations, add the following to your
dotspacemacs/user-init
function:
(add-to-list 'exec-path "/path/to/node/bins" t)
Finally, you will want to turn off js2-mode warnings, since they might be in conflict with the linter you are using via flycheck:
(javascript :variables js2-mode-show-strict-warnings nil)
web-beautify
See web-beautify layer documentation.
prettier
See prettier layer documentation.
import-js
See import-js layer documentation.
Install ImportJS
on your system:
$ npm install -g import-js
To enable it, set the layer variable javascript-import-tool
:
(javascript :variables javascript-import-tool 'import-js)
Choosing a backend
To choose a default backend set the layer variable javascript-backend
:
(javascript :variables javascript-backend 'tern)
Alternatively the lsp
backend will be automatically chosen if the layer lsp
is used and you did not specify any value for javascript-backend
.
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:
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
((js2-mode (javascript-backend . lsp)))
When lsp
is set as the backend, but you don't want to use lsp as the linter,
set the variable javascript-lsp-linter
to nil
.
(javascript :variables
javascript-backend 'lsp
javascript-lsp-linter nil)
Choosing a formatter
To choose a formatter, set the layer variable javascript-fmt-tool
:
(javascript :variables javascript-fmt-tool 'web-beautify)
The formatter can be chosen on a per project basis using directory local
variables (files named .dir-locals.el
at the root of a project). For example
to use the prettier
formatter:
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
((js2-mode (javascript-fmt-tool . prettier)))
Note: you can easily add a directory local variable with SPC f v d
.
You can choose formatting tool:
(setq-default dotspacemacs-configuration-layers '(
(javascript :variables
javascript-fmt-tool 'prettier)))
Default is ’web-beautify
.
Format buffer before saving
(javascript :variables javascript-fmt-on-save t)
Backends
Tern
See tern layer documentation.
Tide
See tide layer documentation.
Language Server Protocol
To use an LSP server with JavaScript, add it as a javascript-backend
to your
~/.spacemacs
.
(setq-default dotspacemacs-configuration-layers
'((javascript :variables
javascript-backend 'lsp)))
TypeScript
You have to install typescript-language-server
(recommended) or
javascript-typescript-langserver
language server packages via
npm i -g typescript typescript-language-server
or
npm i -g typescript javascript-typescript-langserver
Flow
You have to install flow-bin
.
npm i -g flow-bin
Or, if you'd rather use a locally-installed flow-bin
from your project's
node_modules directory, see the node-add-modules-path setting.
Debugger (dap integration)
To install the debug adapter you may run M-x dap-firefox-setup
or
M-x dap-chrome-setup
if you are using Linux or download it manually from
Firefox Debug Adapter or Chrome Debug Adapter and adjust
dap-firefox-debug-path
or dap-chrome-debug-path
. For usage instructions
refer to dap-mode readme.
Configuration
Indentation
To change how js2-mode indents code, set the variable js2-basic-offset
, as
such:
(setq-default js2-basic-offset 2)
or when adding the javascript
configuration layer:
(javascript :variables js2-basic-offset 2)
Similarly, to change how js-mode indents JSON files, set the variable
js-indent-level
, as such:
(setq-default js-indent-level 2)
or when adding the javascript
configuration layer:
(javascript :variables js-indent-level 2)
REPL
Browser based REPL
To use the browser based REPL set the javascript-repl
variable as shown below:
(setq-default dotspacemacs-configuration-layers
'((javascript :variables javascript-repl `skewer)))
In addition 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 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).
Server based REPL
To use the server based REPL set the javascript-repl
variable as shown below:
(setq-default dotspacemacs-configuration-layers
'((javascript :variables javascript-repl `nodejs)))
In addition install nodejs and make sure that node
is in the path.
Node
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 introduces a security risk:
(setq-default dotspacemacs-configuration-layers
'((javascript :variables node-add-modules-path t)))
Node Externs
If you want js2-mode
to presume node
variables are defined by the host
system (for completion purposes i.a.) set the js2-include-node-exters
variable to t
in the javascript
config section:
(setq-default dotspacemacs-configuration-layers
'((javascript :variables js2-include-node-externs t)))
Flow/Typescript
Enable the lsp backend to view type information, jump to declarations, and more.
js2-mode is sometimes confused by the type syntax, so you may wish to disable their parse warnings:
(javascript :variables javascript-backend 'lsp
js2-mode-show-strict-warnings nil
js2-mode-show-parse-errors nil)
Key bindings
js2-mode
Key binding | Description |
---|---|
SPC m w |
toggle js2-mode warnings and errors |
% |
jump between blockswith 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 |
Importing (import-js)
Key binding | Description |
---|---|
SPC m i i |
Import the module for the variable under the cursor |
SPC m i f |
Import any missing modules and remove any modules that are not used |
SPC m g i |
Go to the module of the variable under cursor |
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 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 |
Browser based 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 T l |
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 |
Server based REPL (nodejs-repl)
Key binding | Description |
---|---|
SPC m s i |
Switch to NodeJS REPL if one has been started, otherwise start one |
SPC m s e |
Send last expression to NodeJS REPL |
SPC m s E |
Send last expression to NodeJS REPL and switch to REPL |
SPC m s b |
Send current buffer to NodeJS REPL |
SPC m s B |
Send current buffer to NodeJS REPL and switch to REPL |
SPC m s l |
Send current line to NodeJS REPL |
SPC m s L |
Send current line to NodeJS REPL and switch to REPL |
SPC m s r |
Send active region to NodeJS REPL |
SPC m s R |
Send active region to NodeJS REPL and switch to REPL |
SPC m s s |
switch to REPL |
debugger (dap mode)
Using the dap
layer you'll get access to all the DAP key bindings, see the
complete list of key bindings on the dap layer description.