- Lua 100%
| after/ftplugin | First commit | |
| img | First commit | |
| lsp | First commit | |
| lua | Added new colorscheme, J now joints line without moving | |
| snippets | First commit | |
| .luacheckrc | First commit | |
| init.lua | Removed module w/ manual commands to update plugins. | |
| keybindings.md | Updated keybinding documentation | |
| nvim-pack-lock.json | Added new colorscheme, J now joints line without moving | |
| README.md | updated section on how to update plugins manually | |
| stylua.toml | First commit | |
Summary
Introduction
This Neovim configuration was designed to create a highly customizable Integrated Development Environment (IDE).
This config adopts the new Neovim's native package management, which was introduced in version 0.12.
Running Neovim 0.12
To get the Neovim 0.12 you will need to compile from source the nightly branch.
If you just want to try out this config and want to keep your stable version of
Neovim, then copy the executable to some other place than your orignal (stable)
version.
For instance, install it in /opt/neovim12/bin/
git clone https://github.com/neovim/neovim
cd neovim
git checkout nightly
make CMAKE_BUILD_TYPE=RelWithDebInfo CMAKE_INSTALL_PREFIX=/opt/neovim12/
sudo make install
Next, copy this repo to you $HOME/.config/ folder.
Remember to use a folder name different from nvim, so you can preserve your own config.
git clone https://codeberg.org/selan/nvim-12 $HOME/.config/neoslim
Finally run the Neovim 0.12 passing the path to the config, or better still, create an alias:
alias nv="NVIM_APPNAME=neoslim /opt/neovim12/bin/nvim"
Where neoslim is the folder where this config lives
(e.g. $HOME/.config/neoslim), and you installed nvim in /opt/neovim12/bin.
Note
Adjuste your alias accordingly!
Now run nv file.cpp to test the config.
Features
Here some screenshots of the config in action with the
nigthfox colorscheme, nordfox
variation.
Some of the features displayed in this screenshots are:
- A file explorer and manipulator (
mini.files), with preview of files, similar tooil.nvim;
- A top bar that shows open buffers as tabs (
bufferline); - A temporary popup window at the bottom displaying keybindings as you type (
which-key);
- A statusbar located at the bottom of the screen (
mini.statusline); and, - The LSP + code completion in action (
blink).
Plugin management
In this config I don't use lazy.vim (or any other plugin manager), lspconfig
(for the configuration of the LSP engine), or mason-lspconfig (to set up
server configs based on the packages installed).
Note
There is nothing wrong with theses excellent plugins,
lazy.vim,lspconfig, ormason-lspconfig.
I moved away from them just to experiment with the Neovim's native way of managing plugins and setting up LSP servers.
All plugins will be stored in the vim-pack directory: $XDG_DATA_HOME/nvim/site/pack/core/opt.
They are all installed and managed with the command vim.pack.
Plugin update
To update the plugins, please read the instructions here.
The commands you will probably need are:
: checkhealth vim.pack: to check the current plugins' state.: lua vim.pack.update(): to get a list of all the updates that might be applied to the installed plugins.: lua vim.pack.del({'mason.nvim'}): to remove, for example, the pluginmason.nvim.
Folders organization
.
├── init.lua --> The entry point of the configuration
├── lsp --> LSP server configs
│ ├── bashls.lua --> LSP for bash script
│ ├── clangd.lua --> LSP for C/C++ language
│ ├── lua_ls.lua --> LSP for Lua language
│ ├── marksman.lua --> LSP for markdown files
│ ├── jdtls.lua --> LSP for Java language
│ ├── texlab.lua --> LSP for Latex language
│ ├── rnix.lua --> LSP for Nix language
│ └── rust_analyzer.lua --> LSP for rust language
├── lua
│ ├── config
│ │ ├── autocommands.lua --> Autocommands definitions
│ │ ├── enable_lsp.lua --> Manages which LSP servers to enable
│ │ ├── options.lua --> Neovim global options
│ │ └── plugin_updater.lua --> Functions and commands to update plugins
│ └── plugins
│ ├── colorschemes --> Folder with colorscheme plugins
│ ├── init.lua --> requires the plugins
│ ├── interface --> Folder with GUI-related plugins
│ ├── misc --> Folder with complementary plugins
│ ├── OFF --> Folder to store plugins you want to (temporarily) disable
│ └── programming --> Folder with programming workflow plugins
└── README.md
Plugin loading structure
I created a lua file for each plugin I want to add, with the following overall structure:
-- [1]: Add the package URL.
vim.pack.add({{src=plugin-URL}})
-- [2]: Define any local functions, if needed.
local function foo_bar(params)
-- function implemention
end
-- [3]: Setup the plugin.
require("package-name").setup({
-- configuration goes here
})
-- [4]: Define any related keybindings, if needed.
vim.keymap.set("n", "K", function() ... end, {desc="description"})
-- [5]: Set any options related to the plugin, if needed.
vim.o.something = value
-- [6]: Define autocommands, when required by the plugin
vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave", "TextChanged" }, {
group = package_autogroup,
callback = function()
-- some action goes here
end,
})
Plugins list
I tried to include the minimal list of plugins to get my programming workflow running. I have organized my plugins by 3 categories:
- interface: plugins that modify the GUI;
- programming: plugins that improves my programming experience; and,
- miscellaneous: plugins that improves my workflow but do not fit cleanly in the two previous categories.
- OFF: disabled plugins you might find useful.
I left in the OFF folder some plugins I had installed in previous iteration
of this config, in case you want to try those yourself.
The plugins I moved there I marked with (*).
Interface customization
These are plugins that modify the user interaction or improve the graphical user interface (GUI).
auto-session
-
Description: Automatically reopen the files and windows you had open. It's like you never left!
-
Source: rmagatti/auto-session
better-escape (*)
-
Description: Fast implementation of the popular mappings like
jkorjjto escape insert mode. -
Source: max397574/better-escape.nvim
If you want to remove this plugin and keep the same functionality, create the following keybindings:
-- Escape from Insertion into Normal mode.
vim.keymap.set("i", "jj", "<Esc>", { noremap = true, silent = true })
vim.keymap.set("i", "jk", "<Esc>", { noremap = true, silent = true })
-- If you are a fast typist, then set:
vim.opt.timeoutlen = 300
bufdelete
-
Description: Adds new commands to delete a buffer without messing up your window layout.
-
Source: famiu/bufdelete.nvim
If you want to remove this plugin, replace the command Bdelete by the native bdelete for the keybinding
<leader>c, which closes the current buffer.
This keybinding is defined in the which-key.lua file.
bufferline
-
Description: Creates and manages GUI tabs associated with open buffers.
-
Dependency: this plugins calls
Bdeletecommand to close a tab. This command is defined by thebufdeleteplugin. -
Source: akinsho/bufferline.nvim
devicons
-
Description: Provides Nerd Font icons (glyphs) for use by other plugins, such as pickers (
snacks) or autocomplete mechanisms (blink). -
Source: nvim-tree/nvim-web-devicons
mini
-
Description: Library of 40+ independent Lua modules improving Neovim (version 0.9 and higher) experience with minimal effort. Only the modules you select are downloaded.
-
Modules used:
mini-ai: extend and createa/itextobjects.mini-comment: comment lines.mini-files: navigate and manipulate file system.mini-icons: additional icon provider.mini-pairs: enable autopairs.mini-statusline: simple and functional statusline.mini-surround: surround objects actions.
-
Source: echasnovski/mini.nvim
snacks
-
Description: A collection of small plugins, similar to
mini. -
Modules used:
image: image viewer inside Neovim.input: bettervim.ui.input.notifier: prettyvim.notify.picker: collection of pickers for selecting items.quickfile: render file as quick as possible while loading plugins.rename: LSP-integrated file renaming with support for pluginmini-files.statuscolumn: pretty status column.
-
Source: folke/snacks.nvim
vim-tmux-navigatior
-
Description: When combined with a set of
tmuxkey bindings, the plugin will allow you to navigate seamlessly between vim andtmuxsplits using a consistent set of hotkeys. Requirestmuxv1.8 or higher. -
Source: christoomey/vim-tmux-navigator
If you don't use tmux then remove this plugin.
If you DO use tmux, you may want to checkout my tmux config.
which-key
-
Description: Helps you remember your keymaps, by showing available keybindings in a popup as you type.
-
Dependency:
mini-iconsanddevicons. -
Source: folke/which-key.nvim
Have a good memory? Then you don't need this plugin!!!
But, remember to move the keybindings set there to another file, say ./lua/config/mappings.lua.
Programming Workflow
The following plugins help to improve the way we interact with Neovim while programming.
For instance, they offer better autocomplete, listing of code components (classes,
methods, functions), code formatting and linting, display git-related indicators, etc.
aerial
-
Description: A code outline window for skimming and quick navigation of code components. This plugin requires a LSP server and a tree-sitter parser actives to work.
-
Dependency: LSP setup,
nvim-treesitteranddevicons. -
Source: stevearc/aerial.nvim
If you want to remove this plugin, create a new keybinding that call one of the snack's picker.
vim.keymap.set("n", "<leader>ls", function()
Snacks.picker.lsp_symbols({
layout = "sidebar",
-- make the picker start in normal mode, rather than insert mode.
on_show = function()
vim.cmd.stopinsert()
end,
})
end, { desc = "List [S]ymbols" })
blink
-
Description: A completion plugin with support for LSPs, cmdline, signature help, and snippets. It uses an optional custom fuzzy matcher for typo resistance. It provides extensibility via pluggable sources (LSP, buffer, snippets, etc), component based rendering and dynamic configuration. It replaces the native
nvimominicompletion mechanism (C-x C-o). -
Source: Saghen/blink.cmp
If you don't want to use this plugin, remember to activate the native nvim
ominicompletion mechanism (C-x C-o), so that you can have autocomplete
suggestions.
Change this autocommand inside lua.config.enable_lsp.lua.
vim.api.nvim_create_autocmd({ "LspAttach" }, {
callback = function(ev)
setup_keymaps(ev)
-- =========================================================================
-- Use the code below to activate omni-complete (C-X,C-O)
-- =========================================================================
local client = vim.lsp.get_client_by_id(ev.data.client_id)
if client and client:supports_method("textDocument/completion") then
-- Optional: trigger autocompletion on EVERY keypress. May be slow!
-- local chars = {}; for i = 32, 126 do table.insert(chars, string.char(i)) end
-- client.server_capabilities.completionProvider.triggerCharacters = chars
vim.lsp.completion.enable(true, client.id, ev.buf, {
autotrigger = true,
convert = function(item)
return { abbr = item.label:gsub('%b()', '') }
end,
})
end
-- =========================================================================
end,
colorizer
-
Description: A high-performance color highlighter for Neovim which has no external dependencies!
conform
-
Description:
Conformis a lightweight and powerful formatter plugin for Neovim that supports range formatting, embedded code blocks, and custom formatters. It hooks into the LSP handler and fixes bad-behaving LSP formatters.
If you remove this plugin, remember to set the formatting keybindings to call
the LSP formatting service with vim.lsp.buf.format().
gitsigns
-
Description:
gitsignsprovides fast git decorations. It offers signs for added, removed, and changed lines, asynchronous operations, navigation between hunks, stage and reset hunks, preview diffs, customizable settings, status bar integration, and more.
mason
-
Description: Portable package manager for Neovim that runs everywhere Neovim runs. Easily install and manage LSP servers, DAP servers, linters, and formatters.
This is an optional plugin you may skip, if installing external programs manually.
nvim-lint (*)
-
Description: An asynchronous linter plugin for Neovim (>= 0.9.5) complementary to the built-in Language Server Protocol support.
nvim-treesitter
-
Description: The goal of
nvim-treesitteris both to provide a simple and easy way to use the interface fortree-sitterin Neovim and to provide some basic functionality such as highlighting based on it, as well as indentation and incremental selection.Tree-sitteris a parser generator tool (external program) and an incremental parsing library. It can build a concrete syntax tree for a source file and efficiently update the syntax tree as the source file is edited.
nvim-ufo
-
Description: Improves Neovim's fold, making it look modern and keep high performance.
todo-comments
-
Description:
todo-commentsis a lua plugin for Neovim >= 0.8.0 to highlight and search for todo comments like TODO, HACK, BUG in your code base.
This is an optional plugin.
trouble (*)
-
Description: A pretty list for showing diagnostics, references, telescope results, quickfix and location lists to help you solve all the trouble your code is causing.
If you want to remove this plugin, create a new keybinding that call one of the
snack's picker.
vim.keymap.set("n", "<leader>le", function()
Snacks.picker.diagnostics_buffer({
layout = "sidebar",
on_show = function()
vim.cmd.stopinsert()
end,
})
end, { desc = "List [e]rros (diagnostics) of current buffer" })
vim.keymap.set("n", "<leader>lE", function()
Snacks.picker.diagnostics({
layout = "sidebar",
on_show = function()
vim.cmd.stopinsert()
end,
})
end, { desc = "List [E]rrors in all files" })
After invoking this picker, just press <C-q> to transfer the diagnostics to a
quickfix.
To navigate the components of a quickfix use ]q (next item) or [q (prev item).
Miscellaneous
These are plugins that add extra features to Neovim.
markdown-preview
-
Description: Preview Markdown files in your modern browser with synchronized scrolling and flexible configuration.
render-markdown (*)
-
Description: Plugin to improve viewing Markdown files inside Neovim.
-
Source: https://github.com/MeanderingProgrammer/render-markdown.nvim.
LSP setup
The LSP setup was done following the approach introduced in Neovim 0.11.
This means I am not using traditional external plugins related with LSP,
such as nvim-lspconfig or mason-lspconfig.
Next you will find the steps to setup LSP.
1. Install the servers you want
Make sure the LSP servers you need are installed and available in your system, as external stand-alone programs.
You may install your LSP server via the main package manager of your system (eg.
pacman, apt-install, etc.) or you may choose to install
mason, which is kind of a package manager
that runs inside Neovim.
If you have installed mason, then you may install the LSP servers of this config with:
:MasonInstall clangd
:MasonInstall jtdls
:MasonInstall prettier
:MasonInstall latexindent
:MasonInstall rust-analyzer
:MasonInstall stylua
:MasonInstall texlab
:MasonInstall rnix-lsp
2. Create the servers configuration
You need to provide a configuration for each server you want to enable.
In a nutshell, the server configuration controls how to establish the
connection between the LSP client (Neovim) and the LSP server (clangd, for
instance), and defines the exchange capabilities (of communication)
they support.
One way of providing LSP server configuration, described in the Neovim
documentation, is to create a
lsp folder anywhere in the
runtimepath.
Inside this folder we add a file for each server we want to configure.
You may copy the default configuration file directly from nvim-lspconfig
and modify it to suit your needs.
Note
The name of the LSP server configuration must match the server name you have installed. For instance, C++ LSP server is called
clangd, and the server configuration file must, therefore, be namedclandg.lua.
In my Neovim config I've setup seven LSP servers.
Here is how the lsp folder was organized:
├── lsp
│ ├── bashls.lua --> LSP for bash script
│ ├── clangd.lua --> LSP for C/C++ language
│ ├── jdtls.lua --> LSP for Java language
│ ├── rust_analyzer.lua --> LSP for rust language
│ ├── lua_ls.lua --> LSP for Lua language
│ ├── texlab.lua --> LSP for Latex language
│ ├── nixd.lua --> LSP for nix language
│ └── marksman.lua --> LSP for markdown files
3. Enable the servers
The last step is to enable the servers you've configured.
Here is a summary of all steps together:
- [recommended] Setup keybindings associated with native LSP vim commands.
- [optional] Configure the way diagnostics are displayed.
- [optional] Customize the behavior of any LSP handlers1 .
- [required] Enable the servers.
I did all these steps in the file lua.config.enable_lsp.lua.
That's it!
Your LSP configuration should be good to go.
Tip
To check whether the LSP server has been successfully assigned to the client, run the following command:
:checkhealth lspLook for the session
vim.lsp: Active Clients.
To learn more on how to setup LSP, access the excellent Neovim documentation on LSP.
Keybindings
You may have a look at some of the keybindings defined in this config here.
-
LSP handlers are functions that handle lsp-responses to requests made by Nvim to the server. ↩︎