Neovim is fork of VI/VIM. It is brilliant, blazingly fast, highly configurable modal editor released in 2014. This repo helps you get started with using Neovim, giving you practical tips and providing necessary instructions to customise your IDE the way you want it.
Note: Vim/Neovim are called modal editors because their behavior changes depending on the working mode (Normal mode, Command mode, Visual mode, Visual Block mode etc)
Here's the history of editors for the last 50 years. If you look at VI/VIM, it was release more than 4 decades ago and still used widely. VIM uses "VimL" or VimScript as scripting language where as Neovim uses a light weight, simple language called Lua.
There are many IDEs like VSCode, Pycharm which just works out of the box then why Neovim? Some of the advantages are:-
- Faster Navigation by eliminating the need of a mouse
- Significantly improves your editing speed
- Macros to automate repetitive tasks
- Configure to your specific needs and preferences and stremline your workflow
- You can have custom keybindings mapped to your frequently used commands
- Enhance your productivity by providing features like split windows, quick search & replace and distraction-free mode too
This setup supports the following :
Python (Data Science & ML)
Rust
Lua
OCaml
Bash Scripting
HTML, CSS & JS
Notes, Blogs & Journaling
Here's the snapshot of my configuration.
neovim.mp4
- This is going to be challenging .. but what's the fun if it's easy
- You need to have lot of patience.. so take small steps
- Give yourself enough time to learn as it has a steep learning curve
- Finally, read..read...read lots of documentation
Before you go down this path, there are few things to keep in mind :
- Understand Vi/Vim history, motions and objects
- Learn Lua - A lightweight scripting language
- Get basic understanding of VimScript and Lua structure
- Understand relationship between Vim & NeoVim
os | command | config file location |
---|---|---|
mac | brew install neovim |
~/.config/nvim/ |
arch | sudo pacman -S neovim |
~/.config/nvim/ |
debian | sudo apt-get install neovim |
~/.config/nvim/ |
ubuntu | Need to build from source, check the section below | ~/.config/nvim/ |
If you follow sudo apt install neovim
, and run nvim --version
, it will point to 0.7 version.
The current version is 0.10
. Follow these steps for building neovim from source.
- You should either have
clang
orgcc
, if not available install usingsudo apt install clang
orsudo apt install gcc
- If you do not have CMake then install using
sudo apt install cmake
else you will have to install python3gsudo apt install python
and then runpip install cmake
- Next, install the following
sudo apt-get install ninja-build gettext cmake unzip curl build-essential
- Next, let us download the neovim source code
# clone the repository
git clone https://github.com/neovim/neovim
cd neovim
# set make
make CMAKE_BUILD_TYPE=RelWithDebInfo
# Fetch the stable branch (latest one)
git checkout stable
sudo make install
Some additional installations are required on your machine. LSP & DAP servers, linter and formatter can all be installed using Mason
plugin.
You can use pacman
or apt-get
if you are on other linux distributions.
tools | command | description |
---|---|---|
wezterm | brew install wezterm |
Excellent terminal written in rust and supports configuration in lua |
starship | brew install starship |
customizable shell, simpler than ohmyzsh |
fd | brew install fd |
Alternative to find command |
ripgrep | brew install ripgrep |
Real time grep |
lazygit | brew install lazygit |
amazing UI for git |
tmux | brew install tmux |
Terminal Multiplexer |
npm | brew install npm |
To install tsserver via Mason + Markdown |
python | brew install python |
Install python |
rust | brew install rust |
Rust compilers and toolchain |
yarn | brew install yarn |
For Markdown preview |
Check for installed fonts | brew search "font name" |
Check for fonts using brew |
Check for fonts | wezterm ls-fonts --list-system |
Check for fonts using wezterm |
Install Fonts | brew install --cask font-name |
Installing fonts |
For Ubuntu and other Linux systems, you need to install the nerd fonts or any fonts of your choice.
- Install fontconfig using
sudo apt install fontconfig
- Select the nerd font of your choice
- Download the zip file
- create a directory called "font" under
~/.local/share/fonts
- unzip font file and move it to the above fonts folder
- run the following command
fc-cache -fv
- Restart the terminal
To setup your IDE there are couple of ways. You either clone this repo or start configuring from scratch.
You need to clone this repo on your ~/.config directory. If this folder does not exist, create one.
> cd ~/.config
> git clone https://github.com/rvbug/neovim.git
> nvim
Once you open up neovim, lazy package manager will take over and start the entire installation process
If you already have your own personal neovim config, I would strongly suggest to do the following
# take backup of your existing config
> mv ~/.config/nvim ~/.config/nvim_backup
# you need to delete the folders as it might interfere with your setup
> cd ~/.local/share
> rm -rf nvim
This is how the folder structure looks like. All the folders should be under $HOME/.config/nvim
This is where nvim looks at everytime it starts so the lazy plugin manager is configured here.
This lock file helps you to configure neovim and the version quickly.
The best way to keep everything modularize is to split plugings into their own separate files and add it under this plugins directory. Lazy will automatically detect any changes on this folder and loads it.
Any/All plugin file should always return a table. Additional configuration/settings for that plugins should be inside a callback function.
See the sample setup for lua/plugins/themes.lua
. Same approach is used for most of the plugins unless specified differently in their documentation.
config = function()
is a call back function. Look at the themes.lua file where the plugin is called and then colorscheme is setup.
return {
"tiagovla/tokyodark.nvim",
:
:
config = function()
vim.cmd("colorscheme tokyodark")
end
}
This section will help you understand the structure of the neovim config.
Language Server Protocol
- LSP Config is the most challenging part of the configration. It uses open json rpc standard to communicate with IDE.
Autocompletion engine
- Uses 3rd party sources for completion, snippets, suggestions etc.
Lua is a very simple scripting language. It has one important data structure called table. Knowing how it works helps understand the structure of neovim packages and setup.
Look at the tree structure below. You will see ns
as a table with a global namespace.
It contains config
, functions
as sub table. "Language" is an option under global_ns.config table
ns = {}
--sub tables
ns.config = {
language = "Lua",
}
ns.functions = {
square = function(x) return x * x end
}
ns.message = "this is global variable"
-- dictionary
ns.external_data = {
key_one = "value_one",
key_two = 123
}
ns.coroutine = coroutine.create(function()
...
end)
-- Example usage:
print(ns.config.language)
print(ns.functions.square(5))
print(ns.message)
print(ns.external_data.key2)
command | description |
---|---|
:h or :help | shows all help options inside of neovim |
:h <command name> |
displays help for that command or function |
:option | displays all options available |
:h vim. | This is a neovim global table |
:InspectTree | Shows the AST for the languge opened in the buffer |
vim cmd | vim option | Nvim | Description |
---|---|---|---|
:set | vim.o is variable | vim.opt is table | difference between vim & lua |
:set nu | vim.o.number vim.cmd("set number") |
vim.opt.number vim.api.nvim_set_option('number', true) |
multiple ways to set number |
Here are the list of packages that is being used to get you started.
file name | Package | Type | Description |
---|---|---|---|
init.lua | lazy.nvim | Package Manager | Helps install other packages and extends your IDE |
themes.lua | tokyodark.nvim | Color Theme | It's personal choice. I use 'tokyodark' theme. |
nvim-tree.lua | nvim-tree | Packages | This is a file explorer tree package. It has dependency on nvim-web-devicons |
telescope.lua | telescope.nvim | Package | Fuzzy Finder |
treesitter | nvim-treesitter | Package | A parser generator tool, I have configured for Lua, JS, Rust, Python, HTML, CSS, Markdown. |
lualine.lua | lualine.nvim | Package | Status line theme and configuration |
autopairs.lua | autopairs | Package | Autocompletion of brackets |
gitsigns.lua | git-signs | Package | Git integration for buffers |
gitblame.lua | Git Blame | Package | Shows Git changes & owner |
comments.lua | comments | Package | smart block commenting |
floating-help.lua | Package | Floaing help | |
neorg.lua | neorg | Package | Emacs Org more equivalent for Neovim |
noice.lua | noice | Package | UI for commandline, popup and messages |
toggleterm.lua | toggle term | Package | terminal for neovim |
markdown.lua | Markdown | Package | Show Markdown preview (paused) |
render-markdown.lua | Markdown | Package | Work with inline Markdown file (new) |
quarto.lua | Quarto | Package | Support for Quarto files |
iron.lua | Iron | Package | Interactive REPL on neovim |
db.lua | vim-dadbod | DB | Plugin to interact with the DB |
db.lua | vim-dadbod-ui | DB UI | UI plugin for DB |
db.lua | vim-dadbod-completion | DB | Completion engine for DB |
completions.lua | cmp-path cmp-cmdline |
Package | helps in autocomplete on commandline |
lspconfig.lua | Mason | LSP Plugin | Allows to manage external tools like LSP & DAP servers, linters & formatters through its UI |
completions.lua | mason-tool-installer | LSP | Helps installing 3rd party tools |
completions.lua | nvim-cmp | LSP | A snippet engine which is used as a source and also for snippet "expansion" for nvim-cmp |
completions.lua | luasnip | LSP | used as a luasnip completion source for nvim-cmp, it supplies info to nvim-cmp to display and luasnip will expand it |
completions.lua | cmp.luasnip | LSP | used as a luasnip completion source for nvim-cmp, it supplies info to nvim-cmp to display and luasnip will expand it |
completions.lua | friendly-snippets | LSP | Collection of snippets for all programming languages loaded by luasnip |
completions.lua | cmp-nvim-lsp | LSP | A completion source for nvim-cmp to display whatever lsp is attached to the buffer |
completions.lua | none-ls | LSP | fork of null-ls, it helps in LSP diagnostics, code-actions and much more |
dap.lua | Debugging | DAP | Helps you to support programming language like python (for now) |
undotree.lua | Undo Tree | Package | Visualizes the undo history |
ai-assist.lua | Coding Assistant | AI | Using TabbyML/Codeium AI as your coding assistant. Experiemental phase |
obsidian.lua | Obsidian | Package | Obsidian Notes |
This is the basic configuration I use in keymaps.lua
.
Commands | Description |
---|---|
:set number |
show line numbers |
:set relativenumber |
show line number relative to the cursor |
:set tabstop=2 |
number of space for |
:set expandtab |
number of space for in insert mode |
:set shiftwidth |
number of space for (auto) indent |
vim.opt.ignorecase = true |
switch off case sensitive |
vim.opt.wrap = false |
set line wraps off |
vim.opt.splitbelow |
always split below by default |
vim.opt.splitright |
slipt wiondow to right by default |
:checkhealth |
check the status of your neovim, LSP, linters etc |
The keyboard shortcut for specific commands used in keymaps.lua
.
Command | Mapped to | Description |
---|---|---|
" " |
space is the leader Key | |
<leader>sv |
<C-w>v |
split window vertically |
<leader>sh |
<C-w>h |
split window horizontally |
<leader>sx |
<C-w>x |
close currrent window |
<leader>to |
:tabnew<cr> |
create new tab |
<leader>tx |
:tabclose<cr> |
close the current tab |
<leader>tn |
:tn<cr> |
move to the next tab |
<leader>tp |
:tp<cr> |
go to previous tab |
<c-n> |
:NvimTreeToggle |
Toggle File explorer |
<leader>tt |
:ToggleTerm<cr> |
toggle terminal |
<leader>ut |
:ToggleTree<cr> |
undo toggle tree |
<leader> zm |
:ZenMode |
Jump into Zen mode |
<leader> gf |
vim.lsp.buf.format |
Refresh the buffer` |
Command | Mapped to | Description |
---|---|---|
leader ss |
Live Server Start | HTML/CSS |
leader st |
Live Server Stop | HTML/CSS |
Command | Mapped to |
---|---|
leader mp |
Markdown Preview |
leader mt |
Markdown Toggle |
leader ms |
Markdown Preview stop |
Command | Mapped to | Description |
---|---|---|
leader or |
:OverseerRun |
Markdown Preview |
leader ot |
:OverseeToggle |
Markdown Preview |
Description: A nice Fuzzy finder package. It internally uses fd, ripgrep for finding files. As prequisties you have to install fd, ripgrep as mentioned on the "Other Prerequisities" section above.
keyboard mapping | mapped to | Description |
---|---|---|
<leader>ff |
:Telescope find_files<cr> |
find files |
<leader>fg |
:Telescope live_grep<cr> |
live grep |
<leader>fc |
:Telescope grep_string<cr> |
find string under cursor |
<leader>fb |
:Telescope buffers<cr> |
list all open buffers |
<leader>fh |
:Telescope help_tags<cr> |
list all help tags |
Description: Comments a line or block of code using the below keystrokes. Extremely helpful! You can find more shortcuts on their github repo
keystroke | action |
---|---|
gcc |
Toggles the current line using linewise comment |
gbc |
Toggles the current line using blockwise comment |
[count]gcc |
Toggles the number of line given as a prefix-count using linewise |
[count]gbc |
Toggles the number of line given as a prefix-count using blockwise |
Description: A completion engine plugin for neovim written in Lua.
keystroke | action |
---|---|
<C-b> |
Sroll backward |
<C-f> |
Sroll forward |
<C-Space> |
Completion |
Description: Parser generator tool and an incremental parsing library.
keystroke | action |
---|---|
<leader>gi |
Init selection |
<leader>ni |
node incremement |
<leader>nd |
node decrement |
<leader>si |
scope increment |
Description: Show help in a floating window
keystroke | action |
---|---|
<leader>f |
FloatingHelpToggle |
<leader>h |
FloatingHelp |
Description: By default, Neovim uses Netrw for file explorer. nvim-tree is a nice replacement for that.
keystroke | action |
---|---|
<leader>gb |
:GitBlameToggle |
To setup neovim for python and datascience, here are some of the steps to be followed
- In your virtual env , install neovim & debugpy along with other datascience/ML libraries
- Ensure you install pyright python LSP in your
lspconfig.lua
file
Neovim has extension to edit .md and .qmd files. For this to run following should be installed on your machine along with iron.nvim.
First you need to enable virtual env if you are working on any Data Science or ML project. Here's my Cookie-ml setup.
After you have enabled you need to install the following libraries
pip3 install Ipython
pip3 install quarto
Command | Mapped to | Description |
---|---|---|
leader qa |
:QuartoActivate |
Activate Quarto |
leader qp |
:QuartoPreview |
Preview works on .md & .qmd files |
leader qc |
:QuartoClosePreview |
Stop Preview |
Tmux is a terminal multiplexer which helps you create multiple terminals at once. You can have sessions with each having multiple windows. Once you install tmux, create a file like so. All the configurations are stored in the config file.
> cd $HOME
> touch .tmux.conf
Install tmux plugin manager to make tmux more powerful.
> git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
Now once you install any plugin <leaderkey> I
to install them.
My leader key is c-b
so the command to install additional plugins is c-b I
keystroke | action |
---|---|
c-b | Leader key |
c-b | create a new window |
c-b I | Install additional plugins using TPM |
Typically all IDEs support debugger to find and fix errors in your programs. DAP helps to abstract the way how IDE communicates with the debuger. This has been most challenging to set it up.
Every programming language needs an debugging adapter. For python you need to use debugpy
adapter. Here's how it should be installed.
> mkdir .virtualenvs
> cd .virtualenvs
> python -m venv debugpy
> debugpy/bin/python -m pip install debugpy
dappython.setup("~/.virtualenvs/debugpy/bin/python3")
-- add following lines if you use python3 instead of python
dappython.resolve_python = function()
return "/usr/bin/python3"
end
Note
: If you are working on data science or ML projects, do not activate your virtual environment before using DAP
keystroke | action |
---|---|
<leader>dt |
dap.toggle_breakpoint |
<leader>dc |
dap.continue |
<leader>1 |
step over |
<leader>2 |
step into |
<leader>3 |
dapui widgets hover |
<leader>4 |
dap launch server on port 8086 |
<leader>dr |
require"osv".run_this() |
Here are the steps for debugging python code
- Open python file
- Set breakpoints using
<leader>dt
- Start the debugger using
<leader>dc
Here are the steps for debugging lua code (incld. neovim)
- Open lua file and set breakpoints
- start the server using
require"osv".launch({port=8086})
- run the debugger using
require"osv".run_this()
and you are good to go
This configuration now supports two coding free version of coding assistant. This is still in the experiemental stage and I am still exploring multiple options.
Package | Description |
---|---|
Codeium | Extension but requires sign-up and Internet access |
TabbyML | Locally hosted and supports docker too |
# install using brew or your preferred package manager
$> brew install tabbyml/tabby/tabby
# to run the server on your local machine
$> tabby --serve --device metal --model TabbyML/StartCoder-1B
# install ocaml
$> bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)"
# initalize
$> ocaml init
# tool chain
$> opam install ocaml-lsp-server odoc ocamlformat utop
# finally run the following to update the current shell env
$> eval $(opam env --switch=default)
| Note: Motivation is from Viemu
Have a look my .dotfile repo if you want to setup and configure a new machine.
- DAP support for Rust
Neovim
Vim
Lua
Neovim Learning Path
Tmux
Wezterm
Neorg
What is DAP
DAP Adapter Installation Instructions
Learn Neovim the smart way
Learn Vim the smart way
Vim Galore
Comprehensive Vim Guide
Learn Vim Progressively
Vim Tutorials
Neovim Tutorials
Rust Setup on Neovim
Vim/Neovim Cheat sheet