- 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.NeovimNvim 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 moduleKover 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