The goal of this project is to have a fast Neovim startup, provide mappings that can be easily memorised, interact with the Lua API, and make programming fun.
This setup is mostly customised to for Go (Golang) development. But there are a few other LSP servers setup as well.
This project supports Neovim version 0.7
or later.
- Besides in a few places that Neovim doesn't provide an API in Lua, most configuration is done in Lua.
- It loads really fast! With over 90 plugins, it takes 12ms to
20ms on average to load up. (benchmarked with the
StartupTime
benchmark tool). - LSP, Treesitter, and FZF are setup to work together. Completion
- with nvim-cmp plugin is setup. It is optimised to handle very large
- files. There are some handy textobjects such as backticks and
- indents. You can add the current location of the cursor or make
- notes on the current location in the quickfix/local lists with repeatable mappings.
- You can manipulate quickfix/local lists. It comes with integration with
- git and gist. Has a lot of useful feedback in the gutter. Statusline is
- configures with feline. It is set to give a lot of useful information about the buffer.
- Prettier quickfix buffer and quickfix tools. The theme is setup with Lua to
- take advantage of its performance.
Just clone this project:
$ git clone https://github.com/arsham/shark.git ~/.config/nvim
Once you start Neovim
, it will install the package manager and installs the
listed plugins.
You need to run the InstallDependencies
command to install some dependencies.
Run TSUpdate
to satisfy treesitter dependencies, and finally run
LspInstallInfo
and install the LSP servers you need. Some dependencies can't
be installed with this tool (yet), therefore you need to install them manually.
The command will let you know what you need to install in the notification.
You can check the health of your installation by running the checkhealth
command.
Some default mappings/commands are augmented to centre the buffer after the execution.
Some mappings/commands are obvious, but I've left them here as a reminder. Some are left out either because they are not used too often, or they are defined after writing this document and I've forgot to document.
I would recommend you have a look at the code to see what is available to you.
This list might change at any time depending on if there is a better replacement or the requirement changes.
Click to view the plugin list
Some plugins are not listed here. You can find the complete list in the plugins.lua file.
In most mappings we are following this theme, unless there is an uncomfortable situation or messes with a community-driven or Vim's very well known mapping:
Part of mapping | Description |
---|---|
b | Buffer |
q | Quickfix list mappings |
w | Local list mappings (because it's beside q) |
d | LSP Diagnostics |
g | Go to, Jump to, run something that goes to or jumps to |
m | Match highlighting, marks |
f | File, Find |
y | Yank |
a | All, or disabling certain constraints |
] | Jumps to the next item |
[ | Jumps to the previous item |
h | Hunk |
z | Folds, language/spelling |
i | Indent |
The leader
key is space
!
Click to view the mappings
Mapping | Description |
---|---|
<Ctrl-Shift-p> |
Show Control panel (commands) |
<Ctrl-w>b |
Delete current Buffer |
<leader>kk |
Toggles Neovim tree |
<leader><leader> |
Toggles Neovim tree |
<leader>kf |
Finds current file in the Neovim tree |
<Alt-j> |
Shifts line(s) down one line and format |
[count]<Alt-k> |
Shifts line(s) up one line and format |
<Alt-,> |
Adds , at the end of current line without moving (repeatable) |
<S-Alt-,> |
Removes , from the end of current line without moving (repeatable) |
<Alt-.> |
Adds . at the end of current line without moving (repeatable) |
<S-Alt-,> |
Removes . from the end of current line without moving (repeatable) |
<Alt-;> |
Adds ; at the end of current line without moving (repeatable) |
<S-Alt-,> |
Removes ; from the end of current line without moving (repeatable) |
<Alt-{> |
Adds curly brackets at the end of line into insert mode (repeatable) |
[count]]<space> |
Inserts [count] empty lines after (repeatable) |
[count][<space> |
Inserts [count] empty lines before (repeatable) |
]i |
Jump down along the indents |
[i |
Jump up along the indents |
<leader>gw |
Greps for current Word in buffer. Populates the locallist |
<leader>sp |
Toggles Spelling on current buffer |
<leader>sf |
Auto fixes previous misspelled word |
cn |
Initiate a cgn on current word |
g. |
Use last change (anything) as the initiate a cgn on current word |
z= |
Show spell recommendations |
g= |
Re-indents the hole buffer |
]c |
(gitsigns) Next hunk |
[c |
(gitsigns) Previous hunk |
<leader>gg |
Fugitive git buffer |
<leader>hb |
(gitsigns) Blame line |
<leader>hs |
(gitsigns) Stage hunk |
<leader>hl |
(gitsigns) Stage line |
<leader>hu |
(gitsigns) Unstage hunk |
<leader>hr |
(gitsigns) Reset hunk |
<leader>hR |
(gitsigns) Reset buffer |
<leader>hp |
(gitsigns) Preview hunk |
<leader>hh |
Opens the help for current word |
<Alt-Left> |
Reduce vertical size |
<Alt-Right> |
Increase vertical size |
<Alt-Up> |
Reduce horizontal size |
<Alt-Down> |
Increase horizontal size |
<Esc><Esc> |
Clear hlsearch |
<leader>1 |
Diff get from LOCAL (left) |
<leader>2 |
Diff get from BASE (middle) |
<leader>3 |
Diff get from REMOTE (right) |
[V]@<reg> |
Execute a macro over range of selected lines |
<leader>zm |
Set folding method to Manual |
<leader>ze |
Set folding method to Expression |
<leader>zi |
Set folding method to Indent |
<leader>zm |
Set folding method to Marker |
<leader>zs |
Set folding method to Syntax |
There are more specialised mappings provided, keep reading please!
Click to view the text objects
Text Object | Description |
---|---|
H |
To the beginning of line |
L |
To the end of line |
ii |
In Indentation |
i` |
In backtick pairs (multi-line) |
a` |
Around backtick pairs (multi-line) |
an |
Around Next pairs (current lint) |
in |
In Next pairs (current line) |
il |
In line |
al |
Around line |
iN |
In Numeric value (can be float too) |
ih |
In Hunk |
af |
Around Function |
if |
In Function |
am |
Around call |
im |
In call |
ab |
Around Block |
ib |
In Block |
ah |
Around Hunk (git changes) |
ih |
In Hkunk (git changes) |
au |
Around Unit |
iu |
In Unit |
aa |
Around Argument |
ia |
In Argument |
az |
Around folds |
iz |
In folds |
There are sets of i* and a* text objects, where *
can be any of:
_ . : , ; | / \ * + - #
There are a few tools for interacting with quickfix and local lists.
Following mappings can be used for either cases, all you need to do it to
substitute w
for q
or vice versa. Generally q is for quickfix list
and w is for local list. I chose w because it's beside q and it
makes it easy to think about these two types of lists.
<leader>qq
, <leader>ww
, <leader>qn
and <leader>wn
are repeatable with
.!
After adding an item to the list, an indicator in the statusline will show you how many items you have in a list.
Click to view mappings for lists
Mapping | Description |
---|---|
<leader>cc |
Close both quickfix and local list windows |
<leader>qq |
Add current line and column to the quickfix list. |
<leader>qn |
Add current line and column with your note to the quickfix list. |
<leader>qo |
Open the quickfix list. |
<leader>qd |
Drop the quickfix list. |
<leader>qc |
Close the quickfix list. |
]q |
Go to the next item in the quickfix list and centre. |
[q |
Go to the previous item in the quickfix list and centre. |
<leader>wq |
Add current line and column to the locallist. |
<leader>wn |
Add current line and column with your note to the locallist. |
<leader>wo |
Open the locallist. |
<leader>wd |
Drop the locallist. |
<leader>wc |
Close the locallist. |
]w |
Go to the next item in the locallist and centre. |
[w |
Go to the previous item in the locallist and centre. |
Click to view commands for lists
Command | Description |
---|---|
Clearquickfix |
Clear the quickfix list. |
Clearloclist |
Clear the local list of current buffer. |
Additional to nvim-bqf bindings,
you can do <count>dd
in the quickfix/local list buffers to delete <count>
rows from quickfix/local list buffer.
You can highlight words with random colours.
<leader>ma
and <leader>me
are repeatable with .!
Click to view the mappings
Note that all these mappings are bound to the current window.
Mapping | Description |
---|---|
<leader>ma |
Add current word as a sub-pattern to the highlights. |
<leader>me |
Add an exact match on current term. |
<leader>mp |
Add an match by asking for a pattern. |
<leader>ml |
Add current line |
<leader>md |
Delete Matches with fzf search. |
<leader>mc |
Clear all matched patterns on current window. |
Click to view the mappings
Most actions can apply to multiple selected items if possible.
Mapping | Description |
---|---|
<Ctrl-p> |
File list in current folder. |
<Alt-p> |
File list in home folder. |
<Ctrl-b> |
Buffer list. |
<Alt-b> |
Delete buffers from the buffer list. |
<Ctrl-/> |
Search in lines on current buffer. |
<Alt-/> |
Search in lines of all open buffers. |
<leader>@ |
Search in ctags or LSP symbols (see below). |
<leader>: |
Commands |
<leader>ff |
Find in contents of all files in current folder. |
<leader>fF |
Like <leader>ff , but you can filter filenames too |
<leader>fa |
Find All disabling .gitignore handling. |
<leader>fA |
Like <leader>fA , but you can filter filenames too |
<leader>fi |
Incrementally Find. |
<leader>rg |
Search (rg) with current word. |
<leader>fG |
Like <leader>fG , but you can filter filenames too |
<leader>ra |
Search (rg) disabling .gitignore handling. |
<leader>fA |
Like <leader>fA , but you can filter filenames too |
<leader>ri |
Incrementally search (rg) with current word. |
<leader>fh |
File History |
<leader>fl |
File locate (requires mlocate) |
<leader>gf |
GFiles |
<leader>mm |
Marks |
<Ctrl-x><Ctrl-k> |
Search in dictionaries (requires words-insane) |
<Ctrl-x><Ctrl-f> |
Search in files |
<Ctrl-x><Ctrl-l> |
Search in lines |
Yank Mappings | Description |
---|---|
<leader>yh |
List Yank History) |
<leader>y |
Yank to the + register (external clipboard) |
<leader>p |
Paste from the + register |
<leader>P |
Paste from the + register (before/above) |
(v) p |
Paste on selected text without changing "reg |
If you keep hitting <Ctrl-/>
the preview window will change width. With
Shift-/
you can show and hide the preview window.
When you invoke <leader>yh
you will be presented with a history of the
yanked items. Upon choosing one, the item will be set to the unnamed
register and you use p from there.
When a file is selected, additional to what fzf provides out of the box, you can invoke one of these secondary actions:
Mapping | Description |
---|---|
alt-/ |
To search in the lines. |
alt-@ |
To search in ctags or lsp symbols. |
alt-: |
To go to a specific line. |
alt-q |
Add items to the quickfix list. |
Note that if a LSP
server is not attached to the buffer, it will fall back to
ctags
.
Sometimes when you list files and sink
with @, the LSP
might not be
ready yet, therefore it falls back to ctags
immediately. In this case you can
cancel, which will land you to the file, and you can invoke <leader>@
for
LSP symbols.
There are a few added commands to what fzf provides.
Click to view the commands
Command | Description |
---|---|
Reload | Reload one or more lua config files |
ArgAdd | Select and add files to the args list |
ArgDelete | Select and delete files from the args list |
GGrep | Run git grep |
Marks | Show marks with preview |
MarksDelete | Delete marks |
Worktree | (Also WT) switches between git worktrees |
Todo | List todo/fixme lines |
When a LSP server is attached to a buffer, a series of mappings will be defined for that buffer based on the server's capabilities. When possible, fzf will take over the results of the LSP mappings results.
Please note that I have remapped <Ctrl-n>
and <Ctrl-p>
with <Ctrl-j>
and
<Ctrl-k>
in completion menu in order to move up and down.
Click to view the mappings
Mapping | Description |
---|---|
gd |
Go to Definition |
gD |
Go to Declaration |
<leader>df |
Show function definition in popup |
<leader>gi |
Go to Implementation |
gr |
Show References |
<leader>@ |
Document Symbols |
<leader>gc |
Show Callers (incoming calls) |
H |
Hover popup |
<Alt-h> |
(insert mode) Show Hover popup |
K |
Show Signature help |
<Alt-l> |
(insert mode) Show Signature help |
<Ctrl-l> |
(insert/select mode) next snippet choice |
<Ctrl-h> |
(insert/select mode) previous snippet choice |
<Tab> |
(insert mode) Next completion item |
<Shift-Tab> |
(insert mode) Previous completion item |
<Ctrl-j> |
(insert mode) Next completion item |
<Ctrl-k> |
(insert mode) Previous completion item |
<Alt-n> |
(insert mode) Next completion source |
<Alt-p> |
(insert mode) Previous completion source |
<leader>dd |
Show line Diagnostics |
<leader>dq |
Fill the Quicklist with Diagnostics |
<leader>dw |
Fill the local list with Diagnostics |
]d |
Go to next diagnostic issue |
[d |
Go to previous diagnostic issue |
<leader>i |
Organise imports |
<leader>gq |
Format the buffer with LSP |
<leader>dr |
Restart the LSP server (see below) |
<leader>ca |
Code Actions (also in visual mode) |
<leader>cr |
Code lens Run |
]f |
Jumps to the start of next function |
[f |
Jumps to the start of previous function |
]b |
Jumps to the start of next block |
[b |
Jumps to the start of previous block |
<leader>.f |
Swap function to next |
<leader>,f |
Swap function to previous |
<Alt-n> |
Initiate node selection |
<CR> |
After selection is initiated, increment selection |
<BS> |
After selection is initiated, decrease selection |
<Alt-n> |
After selection is initiated, increment selection on scope |
- The
<leader>@
binding will use theLSP
symbols if is attached to the buffer, orctags
otherwise. - Invoke
<leader>df
twice to enter the flowing window.q
exits.
Please see the code for all available mappings.
LSP defines its own set of commands, however I have added a few interesting additions.
Click to view the commands
Command | Description |
---|---|
RestartLsp |
Restart LSP with a delay. |
Rename |
Rename a symbol |
CodeAction |
Also works on a visually selected text. |
WorkspaceSymbols |
|
DocumentSymbol |
|
Callees |
|
Callers |
|
CodeLensRefresh |
|
CodeLensRun |
|
Diagnostics |
|
DiagnosticsAll |
|
Definition |
|
TypeDefinition |
|
Implementation |
|
References |
|
ListWorkspace |
|
Test |
Find a test with the name of current function |
Log |
Show LSP logs |
The RestartLsp
fixes an issue when the LspRestart
does not have any
effects.
The following list of commands do not fit into any specific categories.
Click to view the commands
Command | Description |
---|---|
InstallDependencies |
Install required dependencies |
WatchLuaFileChanges |
Watch for changes in current file and reload |
CC |
Close all floating windows |
Scratch |
Create a scratch buffer |
Filename |
View the filename |
YankFilename |
Yank the filename to " register |
YankFilenameC |
Yank the filename to + register |
YankFilepath |
Yank the file path to " register |
YankFilepathC |
Yank the file path to + register |
MergeConflict |
Search for merge conflicts |
JsonDiff |
Diff json files after formatting them |
Tmux |
Start a tmux project (using tmuxp) |
[count]Lorem |
Insert (count) line(s) Lorem Ipsum text |
After running InstallDependencies
you will be notified to install some
programs.
I never was a fan of snippets, until I discovered the LuaSnip plugin and it changed my mind. Here is a demo of a couple of snippets shipped with this setup:
Click to view advance snippets demo
Queryrows snippet creates a useful code in Go that uses the Retry library for querying postgres.
Ife snippet is an improvement over a snippet by tjdevries that tries to work better with return values.
These are commands you can use in Lua land. Assign the required module to a variable and re-use.
local quick = require('arshlib.quick')
Executes a normal command. For example:
quick.normal('n', 'y2k')
See :h feedkeys()
for values of the mode.
Create highlight
groups:
quick.highlight("LspReferenceRead", {ctermbg=180, guibg='#43464F', style='bold'})
These functions will call your function/command and then centres the buffer:
quick.call_and_centre(function() print("Yolo!") end)
quick.cmd_and_centre("SomeCommand")
This launches a popup buffer for the input:
require("arshlib.util").user_input{
prompt = "Message: ",
on_submit = function(value)
print("Thank you for your note: " .. value)
end,
}
Unpacks and prints tables. This function is injected into the global scope.
dump({name = "Arsham"})
You will notice not everything is where they should be. For example there is a
lua/mappings.lua
file that contains a lot of mappings, but there are a few
more in plugin settings and lsp folder. The same goes for the commands.
The reason for this is because I wanted to make sure if I disable a plugin, none of its associated mappings or commands are loaded.