#+TITLE: Spacemacs Conventions

* Spacemacs conventions                                     :TOC_4_gh:noexport:
 - [[#code-guidelines][Code guidelines]]
   - [[#spacemacs-core-and-layer][Spacemacs core and layer]]
   - [[#all-layers][All layers]]
   - [[#use-package][Use-package]]
 - [[#key-bindings-conventions][Key bindings conventions]]
   - [[#reserved-prefix][Reserved prefix]]
     - [[#user-prefix][User prefix]]
     - [[#major-mode-prefix][Major mode prefix]]
     - [[#transient-state][Transient-state]]
   - [[#evilified-buffers][Evilified buffers]]
   - [[#navigation][Navigation]]
     - [[#n-and-n][n and N]]
     - [[#code-navigation][Code Navigation]]
     - [[#insert-state-buffers][=insert state= buffers]]
   - [[#confirm-and-abort][Confirm and Abort]]
   - [[#evaluation][Evaluation]]
   - [[#repls][REPLs]]
     - [[#send-code][Send code]]
     - [[#in-terminal][In terminal]]
   - [[#building-and-compilation][Building and Compilation]]
   - [[#debugging][Debugging]]
   - [[#plain-text-markup-languages][Plain Text Markup Languages]]
     - [[#headers][Headers]]
     - [[#insertion-of-common-elements][Insertion of common elements]]
     - [[#text-manipulation][Text manipulation]]
     - [[#movement-in-normal-mode][Movement in normal mode]]
     - [[#promotion-demotion-and-element-movement][Promotion, Demotion and element movement]]
     - [[#table-editing][Table editing]]
   - [[#tests][Tests]]
     - [[#all-languages][All languages]]
     - [[#language-specific][Language specific]]
   - [[#toggles][Toggles]]
   - [[#refactoring][Refactoring]]
   - [[#code-formatting][Code Formatting]]
   - [[#help-or-documentation][Help or Documentation]]
 - [[#writing-documentation][Writing documentation]]
   - [[#spacing-in-documentation][Spacing in documentation]]

* Code guidelines
** Spacemacs core and layer
Function names follow these conventions:
  - =spacemacs/xxx= is an interactive function called =xxx=
  - =spacemacs//xxx= is a private function called =xxx= (implementation details)
  - =spacemacs|xxx= is a /macro/ called =xxx=

Variables follow these conventions:
  - =spacemacs-xxx= is a variable
  - =spacemacs--xxx= is a private variable (implementation details)

** All layers
A package is initialized in a function with name =<layer>/init-xxx= where:
  - =<layer>= is the layer name
  - =xxx= is the package name

** Use-package
- Always use =progn= when a code block requires multiple lines for =:init= or
  =:config= keywords.
- If there is only one line of code then try to keep =:init= or =:config=
  keywords on the same line.
- Don't nest multiple =use-package= calls unless you have a very good reason
  to do it.

* Key bindings conventions
** Reserved prefix
*** User prefix
~SPC o~ and ~SPC m o~ must not be used by any layer. They are reserved for the
user.

*** Major mode prefix
~SPC m~ is reserved for the current major mode. Three keys bindings are not an
issue (ie. ~SPC m h d~) since ~SPC m~ can be accessed via ~​,​~.

*** Transient-state
Whenever possible a transient-state should be enabled with ~M-SPC~ and ~s-M-SPC~. We
need the latter bindings on OS X since ~M-SPC~ is used by the OS for spotlight.

For instance transient-states dedicated to special buffers like =helm= or =ido=
buffers are good candidates to be put on ~M-SPC~ and ~s-M-SPC~.

It is recommended to add ~q~ to leave the transient-state.

** Evilified buffers
/Evilifying/ a buffer is to set the =evilified state= as the default
state for the major mode of the buffer.

The =evilified state= is derived from the =emacs state= and modify the
map to:
- add ~hjkl~ navigation
- add scrolling feature on ~C-f~, ~C-b~, ~C-d~ and ~C-u~
- ~G~ and ~gg~ to go to the end and beginning of the buffer
- add incremental search with ~/~, ~n~ and ~N~
- enabling =evil-ex= on ~:~
- add =visual state= and =visual line state= on ~v~ and ~V~
- add yank on ~y~ _in visual state only_
- activate evil-leader key on ~SPC~

Setting the =evilified state= to a mode is done by calling the macro
=spacemacs|evilify-map=.

/Evilification/ rebinds shadowed key bindings according to the following
rules:
- alphabetic key bindings: ~x~ -> ~X~ -> ~C-x~ -> ~C-X~
- ~SPC~ -> ~​'​~
- ~/~ -> ~\~
- ~:~ -> ~|~
- ~C-g~ cannot be shadowed

If a key binding cannot be remapped then it is ignored and a warning message
is displayed in =*Messages*=.

** Navigation
*** n and N
To be consistent with the Vim way, ~n~ and ~N~ are favored over Emacs ~n~ and
~p~.

Ideally a transient-state should be provided to smooth the navigation
experience. A transient-state allows to repeat key bindings without entering
each time the prefix commands. More info on transient-states in the
[[file:DOCUMENTATION.org::Transient-states][documentation]].

*** Code Navigation
The prefix for going to something is ~SPC m g~.

| Key     | Description                                     |
|---------+-------------------------------------------------|
| ~m g a~ | go to alternate file (i.e. =.h <--> .cpp=)      |
| ~m g b~ | go back to previous location (before last jump) |
| ~m g g~ | go to things under point                        |
| ~m g G~ | go to things under point in other window        |
| ~m g t~ | go to corresponding test file if any            |

*** =insert state= buffers
Navigation in buffers like =Helm= and =ido= which are in =insert state=
should be performed with ~C-j~ and ~C-k~ bindings for vertical movements.

| Key   | Description |
|-------+-------------|
| ~C-j~ | go down     |
| ~C-k~ | go up       |

** Confirm and Abort
Confirming and aborting actions which are bound to ~C-c C-c~ and ~C-c C-k~
in raw Emacs are mirrored in Spacemacs to:

| Key                     | Description               |
|-------------------------+---------------------------|
| ~SPC m ​,​~ and ~SPC m c~ | Valid/Confirm the message |
| ~SPC m a~ and ~SPC m k~ | Abort/Discard the message |

Some example of these modes are =magit= commit messages, =message-mode= for
mails or =org-mode= notes.

** Evaluation
Live evaluation of code is under the prefix ~SPC m e~.

| Key     | Description                                   |
|---------+-----------------------------------------------|
| ~m e $~ | put point at the end of the line and evaluate |
| ~m e b~ | evaluate buffer                               |
| ~m e e~ | evaluate last expression                      |
| ~m e f~ | evaluate function                             |
| ~m e l~ | evaluate line                                 |
| ~m e r~ | evaluate region                               |

** REPLs
*** Send code
A lot of languages can interact with a REPL. To help keeping a
consistent behavior between those languages the following conventions
should be followed:
  - ~SPC m s~ is the prefix for sending code. This allows fast interaction with
    the REPL whenever it is possible
  - lower case key bindings keep the focus on the current buffer
  - upper case key bindings move the focus to the REPL buffer

| Key     | Description                                                  |
|---------+--------------------------------------------------------------|
| ~m s b~ | send buffer                                                  |
| ~m s B~ | send buffer and switch to REPL                               |
| ~m s d~ | first key to send buffer and switch to REPL to debug (step)  |
| ~m s D~ | second key to send buffer and switch to REPL to debug (step) |
| ~m s f~ | send function                                                |
| ~m s F~ | send function and switch to REPL                             |
| ~m s i~ | start/switch to REPL inferior process                        |
| ~m s l~ | send line                                                    |
| ~m s L~ | send line and switch to REPL                                 |
| ~m s r~ | send region                                                  |
| ~m s R~ | send region and switch to REPL                               |

Note: we don't distinguish between the file and the buffer.

*** In terminal
History navigation in shells or REPLs buffers should be bound as well to
~C-j~ and ~C-k~.

    | Key   | Description                |
    |-------+----------------------------|
    | ~C-j~ | next item in history       |
    | ~C-k~ | previous item in  history  |
    | ~C-l~ | clear screen               |
    | ~C-r~ | search backward in history |

** Building and Compilation
The base prefix for major mode specific compilation is ~SPC m c~.

    | Key Binding | Description       |
    |-------------+-------------------|
    | ~m c b~     | compile buffer    |
    | ~m c c~     | compile           |
    | ~m c r~     | clean and compile |

Note: we don't distinguish between the file and the buffer. We can
implement an auto-save of the buffer before compiling the buffer.

** Debugging
The base prefix for debugging commands is ~SPC d~.

| Key Binding | Description             |
|-------------+-------------------------|
| ~m d a~     | abandon current process |
| ~m d b~     | toggle a breakpoint     |
| ~m d B~     | clear all breakpoints   |
| ~m d c~     | continue                |
| ~m d d~     | start debug session     |
| ~m d i~     | inspect value at point  |
| ~m d l~     | local variables         |
| ~m d n~     | next                    |
| ~m d r~     | run                     |
| ~m d s~     | step                    |

Notes:
  - Ideally a transient-state for breakpoint navigation should be provided.
  - If there is no toggle breakpoint function, then it should be implemented at
    the spacemacs level and ideally the function should be proposed as a patch
    upstream (major mode repository).

** Plain Text Markup Languages
For layers supporting markup languages please follow the following
keybindings whenever applicable.

*** Headers
All header functionality should be grouped under ~SPC m h~

| Key Binding | Description                                      |
|-------------+--------------------------------------------------|
| ~m h i~     | Insert a header                                  |
| ~m h I~     | Insert a header alternative method (if existing) |
| ~m h 1..10~ | Insert a header of level 1..10 (if possible)     |

*** Insertion of common elements
Insertion of common elements like links or footnotes should be grouped
under ~SPC m i~

| Key Binding | Description      |
|-------------+------------------|
| ~m i f~     | Insert footnote  |
| ~m i i~     | Insert image     |
| ~m i l~     | Insert link      |
| ~m i u~     | Insert url       |
| ~m i w~     | Insert wiki-link |

*** Text manipulation
Manipulation of text regions should be grouped under ~SPC m x~

| Key Binding | Description                   |
|-------------+-------------------------------|
| ~m x b~     | Make region bold              |
| ~m x c~     | Make region code              |
| ~m x i~     | Make region italic            |
| ~m x q~     | Quote a region                |
| ~m x r~     | Remove formatting from region |
| ~m x s~     | Make region strike-through    |
| ~m x u~     | Make region underlined        |
| ~m x v~     | Make region verbose           |

*** Movement in normal mode
In normal mode Vim style movement should be enabled with these keybindings:

| Key Binding | Description                            |
|-------------+----------------------------------------|
| ~g h~       | Move up one level in headings          |
| ~g j~       | Move to next heading on same level     |
| ~g k~       | Move to previous heading on same level |
| ~g l~       | Move down one level in headings        |

*** Promotion, Demotion and element movement
Promotion, demotion and movement of headings or list elements (whatever is
possible) should be enabled with the following keys in any mode

| Key Binding | Description                  |
|-------------+------------------------------|
| ~M-h~       | Promote heading by one level |
| ~M-j~       | Move element down            |
| ~M-k~       | Move element up              |
| ~M-l~       | Demote heading by one level  |

*** Table editing
If table specific commands are available the they are grouped under the
~SPC m t~ group.

** Tests
A lot of languages have their own test frameworks. These frameworks
share common actions that we can unite under the same key bindings:
 - ~SPC m t~ is the prefix for test execution.
 - ~SPC m t X~ is used to execute ~SPC m t x~ but in debug mode (if supported).

*** All languages

| Key     | Description                                                  |
|---------+--------------------------------------------------------------|
| ~m t a~ | execute all the tests of the current project                 |
| ~m t A~ | execute all the tests of the current project in debug        |
| ~m t b~ | execute all the tests of the current buffer                  |
| ~m t B~ | execute all the tests of the current buffer in debug         |
| ~m t t~ | execute the current test (thing at point, function)          |
| ~m t T~ | execute the current test in debug (thing at point, function) |

Note: we don't distinguish between the file and the buffer. We can
implement an auto-save of the buffer before executing the tests of
buffer.

*** Language specific

| Key     | Description                                      |
|---------+--------------------------------------------------|
| ~m t m~ | execute the tests of the current module          |
| ~m t M~ | execute the tests of the current module in debug |
| ~m t s~ | execute the tests of the current suite           |
| ~m t S~ | execute the tests of the current suite in debug  |

Note that there are overlaps, depending on the language we will choose
one or more bindings for the same thing

** Toggles
- Global toggles are under ~SPC t~, ~SPC T~ and ~SPC C-t~
- Major mode toggles are only under ~SPC m T~

** Refactoring
Refactoring prefix is ~SPC m r~.

** Code Formatting
Major-mode code formatting is under prefix ~SPC m =~.

| Key Binding | Description              |
|-------------+--------------------------|
| ~m = =~     | format thing under point |
| ~m = b~     | format current buffer    |
| ~m = f~     | format current function  |

** Help or Documentation
The base prefix for help commands is ~SPC h~. Documentation is considered
as an help command.

| Key     | Description                        |
|---------+------------------------------------|
| ~m h h~ | documentation of thing under point |
| ~m h r~ | documentation of selected region   |

* Writing documentation
Spacemacs provides an example layer =README.org= file in
=~/.emacs.d/core/templates/README.org.template=.

** Spacing in documentation
- Spacemacs tries to keep the documentation consistent between all layers by
  providing some rules for spacing:
  - After each header, you should not add an empty line
    - *Exception*: If the first item under the header is a table, add an empty
      line after it
  - At the end of each header node, there should be an empty line
  - Note: Many layer =READMEs= do not follow this convention yet. Please fix
    them if you can.

- To keep things readable only mention the prefix ~SPC~ when documenting
  key bindings, you don't need to mention ~M-m~.
