- Neo-vim configuration
- Package Manager
- Structuring Your Plugins
- LSP
- Linters & Formatters
- Autocompletion & Snippets
- Debuggers
- Packages
- Commands
Neo-vim configuration from scratch.
# MacOS
brew install neovim
# Windows
winget install Neovim.Neovim
Nvim supports using init.vim
or init.lua
as the configuration file, but not both at the same time.
The runtimepath
of nvim expects this file to be in ~/.config/nvim/init.lua
in Mac or Linux and for Windows in ~/AppData/Local/nvim/init.lua
.
The standard directories can be further configured by the $NVIM_APPNAME
environment variable. This variable controls the sub-directory that Nvim will read from (and auto-create) in each of the base directories. For example, setting $NVIM_APPNAME
to "foo" before starting will cause Nvim to look for configuration files in $XDG_CONFIG_HOME/foo
instead of $XDG_CONFIG_HOME/nvim
. $NVIM_APPNAME
must be a name, such as "foo", or a relative path, such as "foo/bar".
set expandtab
set tabstop=2
set softtabstop=2
set shiftwidth=2
:source %
source this file. This is for sourcing vimscript file.
To set vim scripts and configurations in lua file we need meta-accessors
to expose lower level vim commands in lua runtime. vim.cmd
function takes the vim commands and converts it for lua. Thus the previous commands should be-
vim.cmd("set expandtab")
vim.cmd("set tabstop=2")
vim.cmd("set softtabstop=2")
vim.cmd("set shiftwidth=2")
- packer.nvim
- lazy.nvim
Instructions at GitHub. You can add the following Lua code to your init.lua to bootstrap lazy.nvim:
-- install and/or check for lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-- declare variables for the next command
local plugins = {}
local opts = {}
-- load lazy.nvim and key bindings
require("lazy").setup(plugins, opts)
Get catppuccin.
{ "catppuccin/nvim", name = "catppuccin", priority = 1000 }
-- add it to local plugins tuple
local plugins = {
{ "catppuccin/nvim", name = "catppuccin", priority = 1000 }
}
This installs the plugin but doesn't enable it.
To enable most packages we need require
and setup
function. The setup
function imports all the package functionality in lua runtime for neovim to execute it. So add the following after requiring lazy-
require("lazy").setup(plugins, opts)
require("catppuccin").setup()
vim.cmd.colorscheme "catppuccin"
For fuzzy finding files and grep through project. link.
Add to local plugins
local plugins = {
{ "catppuccin/nvim", name = "catppuccin", priority = 1000 },
{
'nvim-telescope/telescope.nvim', tag = '0.1.5',
dependencies = { 'nvim-lua/plenary.nvim' }
}
}
Now to initialize it add the following after require lazy-
require("lazy").setup(plugins, opts)
local builtin = require("telescope.builtin")
vim.keymap.set('n', '<C-p>', builtin.find_files, {})
vim.keymap.set('n', '<leader>fg', builtin.live_grep, {})
find_files
is the function withing telescope.builtin
which is loaded by require
. This allows us to fuzzy find files in our project.
Tool for generating abstract syntax tree. Used for code highlighting, indenting etc. TSUpdate
updates treesitter itself. Add to local plugin.
local plugins = {
{ "catppuccin/nvim", name = "catppuccin", priority = 1000 },
{
'nvim-telescope/telescope.nvim', tag = '0.1.5',
dependencies = { 'nvim-lua/plenary.nvim' }
},
{"nvim-treesitter/nvim-treesitter", build = ":TSUpdate"}
}
Then require nvim-treesitter.configs
and assign it to a local variable, eg. config. then config.setup
local config = require("nvim-treesitter.configs")
config.setup({
ensure_installed = {"lua", "javascript"},
highlight = { enable = true },
indent = { enable = true },
})
File explorer tree. There is neo-tree and nvim-tree. Add neo-tree to local plugins
local plugins = {
{ "catppuccin/nvim", name = "catppuccin", priority = 1000 },
{
'nvim-telescope/telescope.nvim', tag = '0.1.5',
dependencies = { 'nvim-lua/plenary.nvim' }
},
{"nvim-treesitter/nvim-treesitter", build = ":TSUpdate"},
{
"nvim-neo-tree/neo-tree.nvim",
branch = "v3.x",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons",
"MunifTanjim/nui.nvim",
}
}
}
Then add key mapping vim.keymap.set('n', '<C-n>', ':Neotree filesystem reveal left<CR>')
Every spec file under the "plugins" directory will be loaded automatically by lazy.nvim
. To split plugin specs in multiple files, create lua/plugins.lua
which will return
(instead of local plugins =
) all plugins list. All plugin specific setup
could be placed in separate files inside plugins folder, it is not needed to add require
calls in your main plugin file anymore.
Now require("lazy").setup("plugins")
in ~/.config/nvim/init.lua
will use the list from ~/.config/nvim/lua/plugins.lua
. Any lua file in ~/.config/nvim/lua/plugins/*.lua
will be automatically merged in the main plugin spec.
nvim/
├── init.lua
├── lua/
├── plugins.lua
├── plugins/
├── telescope.lua
├── neo-tree.lua etc. ├
~/.config/nvim
├── lua
│ ├── config
│ │ ├── autocmds.lua
│ │ ├── keymaps.lua
│ │ ├── lazy.lua
│ │ └── options.lua
│ └── plugins
│ ├── spec1.lua
│ ├── **
│ └── spec2.lua
└── init.lua
For plugin specific setups we can move those to the plugins/*.lua
with plugin spec config
. config
is executed when the plugin loads. The default implementation will automatically run require(MAIN).setup(opts)
.
Move the plugin setup commands within config = function() ... end
.
Put require("plugin").setup()
inside config function.
return {
"catppuccin/nvim",
config = function()
vim.cmd.colorscheme "catppuccin"
end
}
To move remaining vim settings from init.lua
to a new file we can just require("file-name")
. It should be placed in the lua
folder like nvim/lua/file-name.lua
.
Create lualine.lua
in plugins folder. return
the following also add config
if required.
return{
'nvim-lualine/lualine.nvim',
dependencies = { 'nvim-tree/nvim-web-devicons' },
config = function
require('lualine').setup({
options = {
theme = 'dracula'
}
})
end
}
Language Server Protocol. Allows communication between text editors and language servers in the local machine. Provides language intelligence features like go to definition, code actions, quick fixes, hover documentation etc.
mason
is the LSP manager plugin.
mason-lspconfig
closes some gaps that exist between mason.nvim
and lspconfig
. mason-lspcofig
provides ensure_installed
property.
nvim-lspconfig
sets up communication between neovim and language servers. Also provides key bindings.
return {
"williamboman/mason.nvim",
"williamboman/mason-lspconfig.nvim",
"neovim/nvim-lspconfig",
}
-- full lsp-config.lua with setups and configuration
return {
{
"williamboman/mason.nvim",
config = function()
require("mason").setup()
end
},
{
"williamboman/mason-lspconfig.nvim",
config = function()
require("mason-lspconfig").setup({
ensure_installed = { "lua-ls" }
})
end
},
{
"neovim/nvim-lspconfig",
config = function()
local lspconfig = require("lspconfig")
lspconfig.lua_ls.setup({})
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, {})
vim.keymap.set('n', 'K', vim.lsp.buf.hover, {})
vim.keymap.set({ 'n', 'v' }, '<leader>ca', vim.lsp.buf.code_action, {})
end
}
}
It sets vim.ui.select
to telescope. That means for example that neovim core stuff can fill the telescope picker. Example would be lua vim.lsp.buf.code_action()
.
Usually linters are CLI tools, null-ls
plugin brings these functionality to neovim LSP. It is archived now so use none-ls
.
null_ls.builtins.formatting.stylua,
this integrates stylua functionalities with LSP. We need to install stylua
from mason > Formatter
. Install each linter and formatter for all languages (python [black, isort], javascript [eslint_d, prettier] etc) you want to use.
alpha is a fast and fully programmable greeter for neovim. startify
theme gives the latest files you used in the dashboard.
nvim-cmp
- completion engineLuaSnip
- snippet enginecmp_luasnip
- completion source for nvim-cmpFriendly Snippets
- Snippets collection for a set of different programming languages.cmp-nvim-lsp
- nvim-cmp source for neovim's built-in language server client.
If you're using LuaSnip make sure to use require("luasnip.loaders.from_vscode").lazy_load()
, and add friendly-snippets
as a dependency for LuaSnip, otherwise snippets might not be detected. If you don't use lazy_load()
you might notice a slower startup-time.
Debug adapter protocol (DAP). Two plugins nvim-dap
and nvim-dap-ui
. Features - breakpoints, step over function, step into function, variable tracing.
Also install language specific Debug Adapter.
- Catppuccin
- Telescope
- Treesitter
- Neotree
- Lualine
- Mason
- mason-lspconfig.nvim
- nvim-lspconfig
- telescope-ui-select.nvim
- none-ls.nvim
- Dashboard alpha-nvim
- nvim-cmp completion engine
- LuaSnip snippet engine
- cmp_luasnip completion source for nvim-cmp
- Friendly Snippets
- cmp-nvim-lsp
- nvim-dap
- nvim-dap-ui
- Record macro -
qq
, to stopq
- Paste macro -
@q
\
- search:source %
source this file.:Lazy
- lazy GUI:Telescope find_files<cr>
to see if telescope.nvim is installed correctly.Ctrl p
- find files by telescope<leader>fg
- Live Grep:TSUpdate
- update parsers:TSInstall
- install parsers:Neotree
- Press ? in the Neo-tree window to view the list of mappings.Ctrl n
- reveal file tree:LspInfo
- by nvim-lspconfig, shows LSPs connected to current buffer:h vim.lsp.buf
- help doc showing all available functions in vim.lsp.buf moduleK
over a function - display documentation of that functionCtrl x o
- LSP builtin omni func<leader>gf
- formatting withvim.lsp.buf.format
<Leader>dt
- debugging toggle breakpoint<Leader>dc
- debugging continue