Managing layers to use with SpaceNeovim.
Name | Description |
---|---|
+core/behavior | Core functionality for SpaceNeovim |
+core/sensible | Sensible default settings |
+completion/asyncomplete | Auto-completion with asyncomplete |
+completion/coc | Auto-completion with coc.nvim |
+completion/deoplete | Auto-completion with deoplete |
+completion/ncm2 | Auto-completion with NCM2 |
+completion/snippets | Snippet support |
+checkers/ale | Syntax checking with Ale |
+checkers/neomake | Syntax checking with Neomake |
+checkers/syntastic | Syntax checking with Syntastic |
+docs/dash | Browse offline documentation with Dash |
+docs/zeal | Browse offline documentation with Zeal |
+gui/ide | An opinionated setup with VimR/Oni |
+nav/buffers | Common buffer functionality |
+nav/comments | Manipulating comments |
+nav/files | Common file operations |
+nav/fuzzy | Fuzzy search for files, buffers and methods |
+nav/fzf | Fuzzy search using FZF |
+nav/jump | Easy navigation inside files |
+nav/navigation | Easy navigation on screen |
+nav/quit | Common quit functionality |
+nav/start-screen | Add start screen when opening Neovim |
+nav/text | Common text operations |
+nav/tmux | Navigate between VIM and TMUX panes |
+nav/windows | Common window functionality |
+scm/git | Git and fugitive support |
+specs/testing | Run tests directly from the editor |
+tools/format | Format files |
+tools/language-server | Language server support |
+tools/multicursor | Support for multiple cursors |
+tools/terminal | Defaults and keybindings for the terminal |
+ui/airline | Replace the status bar with airline |
+ui/dynamic-cursor | Dynamically change the cursor depending on the mode |
+ui/toggles | Toggles for common components |
Language layers
Name | Description |
---|---|
+lang/-example | A template for creating new language layers |
+lang/elm | Support for Elm |
+lang/fsharp | Support for F# |
+lang/go | Support for Go |
+lang/haskell | Support for Haskell |
+lang/java | Support for Java |
+lang/javascript | Support for JavaScript |
+lang/php | Support for PHP |
+lang/purescript | Support for PureScript |
+lang/python | Support for python |
+lang/ruby | Support for Ruby |
+lang/rust | Support for Rust |
+lang/vim | Support for VimL |
A layer consists of, as minimum:
- a
README.md
describing the layer (configuration, keybindings etc), - either a
config.vim
, adding the layer key bindings, or - a
packages.vim
, adding the packages that needs to be installed - optionally, if a
func.vim
is present, it is loaded first (define commands and helper functions in this to keep things clean)
These files are grouped under a +category/layer-name
directory hierarchy. As an example, the layer buffers
is located under the group +nav
(short for navigation).
A layer is only ever run if it is enabled, so there is no need to check for it. However, if you want to check if another layer is enabled, before doing anything, it can be done with,
if SpaceNeovimIsLayerEnabled('+checkers/neomake')
" Make specific configuration for neomake here...
endif
This can especially be useful in the +lang
layers, to add information to checkers and completions.
The API available to layers are (<arg>
are required, [arg]
are optional), for keybindings,
Command | Arguments | Description | Example |
---|---|---|---|
SpBind | <map> , <binding> , <name> , <value> , <isCmd> |
Map a key to a specific mapping type, with a description and command to execute. The <isCmd> argument adds <CR> on the end if 1 and nothing if 0 . |
SpBind 'tmap', 'wj', 'window-down', 'wincmd j', 1 |
SpMap | <binding> , <name> , <value> , [isCmd] |
Map a key with map /noremap , with a description and command to execute. <isCmd> defaults to 1 (i.e. adds <CR> ). |
SpMap 'wk', 'window-up', 'wincmd k' |
SpMap | <binding> , <name> , <value> , [isCmd] |
Map a key with nmap /nnoremap , with a description and command to execute. <isCmd> defaults to 1 (i.e. adds <CR> ). |
SpMap 'wk', 'window-up', 'wincmd k' |
SpVMap | <binding> , <name> , <value> , [isCmd] |
Map a key with vmap /vnoremap , with a description and command to execute. <isCmd> defaults to 1 (i.e. adds <CR> ). |
SpVMap 'wk', 'window-up', 'wincmd k' |
SpFileTypeBind | <filetype> , <map> , <binding> , <name> , <value> , <isCmd> |
Map a key, only shown under a specific filetype, to a specific mapping type, with a description and command to execute. The <isCmd> argument adds <CR> on the end if 1 and nothing if 0 . |
SpBind 'tmap', 'wj', 'window-down', 'wincmd j', 1 |
SpFileTypeMap | <filetype> , <binding> , <name> , <value> , [isCmd] |
Map a key with map /noremap , only shown under a specific filetype, with a description and command to execute. <isCmd> defaults to 1 (i.e. adds <CR> ). |
SpFileTypeMap 'haskell', 'mgt', 'show-type-at', 'GhcModType' |
SpFileTypeNMap | <filetype> , <binding> , <name> , <value> , [isCmd] |
Map a key with nmap /nnoremap , only shown under a specific filetype, with a description and command to execute. <isCmd> defaults to 1 (i.e. adds <CR> ). |
SpFileTypeNMap 'haskell', 'mgt', 'show-type-at', 'GhcModType' |
And the API for various helper functions,
Command | Arguments | Description | Example |
---|---|---|---|
SpAddPlugin | <PluginName> , [Configuration] |
Adds a plugin to load with vim-plug optionally with a vim-plug configuration. |
SpAddPlugin 'Shougo/vimproc.vim', { 'for': 'haskell', 'do' : 'make' } |
SpSpaceIndent | <filetype> , <indentation> |
Set the amount of spaces a certain filetype is indented. | SpSpaceIndent 'haskell', 2 |
SpTabsIndent | <filetype> , <indentation> |
Set the amount of tabs a certain filetype is indented. | SpTabsIndent 'go', 8 |
SpLoadFunc | <path-to-script> , <file-name> |
Load (source) a file into Vim. | SpLoadFunc expand('<sfile>:p') 'other-file.vim' ' for loading 'other-file.vim' in the layer directory |
To add a keybinding, first make sure that the vim-leader-guide grouping exists with
" Top level grouping (i.e. SPC e)
let g:lmap.e = get(g:lmap, 'e', { 'name': 'errors' })
" Deeper level Grouping under SPC e m
let g:lmap.e.m = get(g:lmap.e, 'm', { 'name': 'more' })
NOTE: It is important to use get()
to avoid overwriting the mapping if it exists in another layer already.
ANOTHER NOTE: if you are adding a new language, you don't have to add the grouping, since let g:lmap.m = { 'name': 'major-mode-cmd' }
already exists.
The e
in g:lmap.e
denotes the key that the group is under. Then add your keybinding by using SpBind
or the shorter SpMap
/SpMap
,
SpBind 'map', 'eC', 'neomake-check-file', 'Neomake', 1
" Is equivalent to,
SpMap 'eC', 'neomake-check-file', 'Neomake'
SpBind 'nmap', 'eC', 'neomake-check-file', 'Neomake', 0
" Is equivalent to (default value is `1`, so we explicitly say `0` to not automatically add `<CR>` behind),
SpMap 'eC', 'neomake-check-file', 'Neomake', 0
which puts the keybinding at SPC e l
. Note that the first e
in el
is necessary to put it under the e
grouping.
For more check out the +nav/buffers
layer for an example of usage, and keybinding-helpers.vim
for the helper functions.
This time we use SpAddPlugin
to add the plugin and its vim-plug configuration,
SpAddPlugin 'neomake/neomake'
SpAddPlugin 'Shougo/vimproc.vim', { 'for': 'haskell', 'do' : 'make' }
which will add the package 'neomake/neomake' to be installed with the configuration {}
(default value), and 'Shougo/vimproc.vim' with the more complex configuration { 'for': 'haskell', 'do' : 'make' }
. The configuration can be used for post-installation commands or to lazy-load the plugin (e.g. only loading a language plugin when that language filetype is active).
To keep the files a bit more clean, your functions should reside in separate files, such as func.vim
. If func.vim
is found in your layer, it is automaticaly included as the first item. To easily include other files, use,
" Load `func.vim` in the current layer directory
SpLoadFunc expand('<sfile>:p')
" Load `other-file.vim` in current layer directory
SpLoadFunc expand('<sfile>:p'), 'other-file.vim'
The expand('<sfile>:p')
bit is to include the path of the current layer that is calling the SpLoadFunc
function. If no second argument is given it defaults to func.vim
, since that is the normal convention.
For more check out the +nav/files
layer for an example of usage, and helpers.vim
for the helper functions.
Most of adding a new language layer is just like adding a normal layer, except for keybindings and groupings, as described below.
Adding a language keybinding is a bit different, since we only want it shown when the language is actually active. All language keybindings should be under SPC m
, and if you use the helper functions, that's also where they'll go.
It consist of two combined steps:
- Add your groupings
- Add your mappings
Step 1. and step 2. is done using au FileType MYFILETYPE
, for example, a snippet of the haskell
keybindings,
au FileType haskell let g:lmap.m = { "name": "major-mode-cmd",
\"c": ["GhcModCheckAndLintAsync", "ghcmod/check"],
\"r": { "name": "haskell/refactor"
\, "b": ["call ApplyAllSuggestion()", "hlint/refactor-buffer"]
\, "r": ["all ApplyOneSuggestion()", "hlint/refactor-at-point"]
\ },
\"h": { "name": "haskell/documentation"
\, "h": ["SpaceNeovimHaskellHoogle", "search-hoogle"]
\, "t": ["GhcModType", "ghcmod/type-at"]
\, "i": ["GhcModInfo", "ghcmod/info"]
\ },
\}
We simply construct a new dictionary mapping for g:lmap.m
which is only valid under our filetype, and contains the commands we want to bind. A "name": "haskell/grouping"
defines a simple grouping and a ["GhcModCheckAndLintAsync", "ghcmod/check"]
defines a command and description respectively.
Note: The reason it's defined under a filetype in this tedious way, is so that we get unique mappings for each filetype and that the change happens automatically.
For more check out the +lang/haskell
layer for an example of usage, and bindings.vim
for the helper functions.
It is recommended to add the following to .git/hooks/pre-commit
,
# Get the current dir
startDir=$(pwd)
# Get the project root
rootDir=$(git rev-parse --show-toplevel)
cd $rootDir
# Run vint
vint auto-layers.vim keybinding-helpers.vim helpers.vim