#+TITLE: HTML layer

#+TAGS: dsl|layer|markup|programming

[[file:img/html.png]]

* Table of Contents                     :TOC_5_gh:noexport:
- [[#description][Description]]
  - [[#features][Features:]]
- [[#install][Install]]
  - [[#lsp][LSP]]
  - [[#web-beautify][web-beautify]]
  - [[#prettier][prettier]]
  - [[#choosing-a-formatter][Choosing a formatter]]
  - [[#activate-leex-support][Activate leex support]]
- [[#backends][Backends]]
  - [[#language-server-protocol][Language Server Protocol]]
- [[#live-display-in-browser][Live display in browser]]
- [[#key-bindings][Key bindings]]
  - [[#web-mode][Web mode]]
  - [[#cssscss][CSS/SCSS]]

* Description
This layer adds support for editing HTML and CSS.

** Features:
- Editing HTML and CSS file using [[http://web-mode.org/][web-mode]]
- Support for Sass/Scss and Less files
- Generate HTML and CSS coding using [[https://github.com/smihica/emmet-mode][emmet-mode]]
- Tags navigation on key ~%~ using [[https://github.com/redguardtoo/evil-matchit][evil-matchit]]
- Support for editing Slim and Pug templates using [[https://github.com/slim-template/emacs-slim][slim-mode]] and [[https://github.com/hlissner/emacs-pug-mode][pug-mode]]
- See the effects of typed HTML using [[https://github.com/skeeto/impatient-mode][impatient-mode]]
- imenu support for CSS and Sass through [[https://github.com/hlissner/emacs-counsel-css][counsel-css]]
- 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 =html= to the existing =dotspacemacs-configuration-layers= list in this
file.

SCSS linting requires SCSS-Lint version >= 0.43.0. You can get it from GitHub:

#+BEGIN_SRC command-line
  gem install scss_lint_reporter_checkstyle
  gem install scss_lint
#+END_SRC

** LSP
To enable LSP, set the layer variables below to =t=:
- =css-enable-lsp=
- =less-enable-lsp=
- =scss-enable-lsp=
- =html-enable-lsp=

** 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 formatter
To choose a formatter, set the layer variable =web-fmt-tool=:

#+BEGIN_SRC elisp
  (html :variables web-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")

  ((html-mode (web-fmt-tool . prettier)))
#+END_SRC

*Note:* you can easily add a directory local variable with ~SPC f v d~.

** Activate leex support
To activate support for ~.leex~ files set below config variable to a
non-nil value.

#+BEGIN_SRC elisp
  (html :variables html-enable-leex-support t)
#+END_SRC

* Backends
** Language Server Protocol
For css files, you have to install =vscode-css-languageserver-bin=

#+BEGIN_SRC sh
  npm i -g vscode-css-languageserver-bin
#+END_SRC

For html files, you will need to install =vscode-html-languageserver-bin=

#+BEGIN_SRC sh
  npm install -g vscode-html-languageserver-bin
#+END_SRC

Don't forget to set the corresponding layer variables mentioned above to =t=

* Live display in browser
Use ~SPC m I~ to enable impatient mode, opening a live view of a HTML file in
your browser. You may wish to enable impatient mode in referenced CSS or JS
files, too.

When the underlying file is an HTML file, ~SPC m I~ automatically opens the page
in the browser. For other buffers, a list of available views can be found on
[[http://localhost:8080/imp]].

For more information visit the [[https://github.com/skeeto/impatient-mode/blob/master/README.md][help page on GitHub.]]

* Key bindings
** Web mode

| Key binding | Description                                               |
|-------------+-----------------------------------------------------------|
| ~SPC m g p~ | quickly navigate CSS rules using =helm=                   |
| ~SPC m e h~ | highlight DOM errors                                      |
| ~SPC m I~   | open live view in browser                                 |
| ~SPC m g b~ | go to the beginning of current element                    |
| ~SPC m g c~ | go to the first child element                             |
| ~SPC m g p~ | go to the parent element                                  |
| ~SPC m g s~ | go to next sibling                                        |
| ~SPC m h p~ | show xpath of the current element                         |
| ~SPC m r c~ | clone the current element                                 |
| ~SPC m r d~ | delete the current element (does not delete the children) |
| ~SPC m r r~ | rename current element                                    |
| ~SPC m r w~ | wrap current element                                      |
| ~SPC m z~   | fold/unfold current element                               |
| ~%~         | evil-matchit key binding to jump to closing tag           |
| ~C-return~  | emmet-expand snippet                                      |

A transient-state is also defined, start it with ~SPC m .~ or ~, .~

| Key binding | Description                                                    |
|-------------+----------------------------------------------------------------|
| ~?~         | Toggle full help                                               |
| ~c~         | clone current element                                          |
| ~d~         | delete (vanish) current element (does not delete the children) |
| ~D~         | delete current element and children                            |
| ~j~         | next element                                                   |
| ~J~ / ~gj~  | next sibling element                                           |
| ~h~         | parent element                                                 |
| ~k~         | previous element                                               |
| ~K~ / ~gk~  | previous sibling element                                       |
| ~l~         | first child element                                            |
| ~p~         | show xpath of current element                                  |
| ~q~         | leave the transient-state                                      |
| ~r~         | rename current element                                         |
| ~w~         | wrap current element                                           |

** CSS/SCSS

| Key binding | Description                      |
|-------------+----------------------------------|
| ~SPC m g h~ | quickly navigate CSS rules       |
| ~SPC m z c~ | fold css statement to one line   |
| ~SPC m z o~ | unfold css statement to one line |
