Transform Your Neovim into a IDE: A Step-by-Step Guide
Updates:
- 2024-04-04. Use lazy.nvim rather than packer.nvim 🤗
- If you have configured your Neovim followed my post previously, you may check this commit to see how to migrate from
packer.nvim
tolazy.nvim
. Remember to run:checkhealth lazy
after the migration as we also need to remove some outdated files ofpacker.nvim
.
- If you have configured your Neovim followed my post previously, you may check this commit to see how to migrate from
Further reading
- How to set up Neovim for a new programming langauge and get more control over code formatting, please refer to the next post
Version info
I use a Macbook pro-2020 Intel Edition with macOS 13.2. This is my Nvim
edition:
|
|
Why Neovim
After using Vim
for one year, I find myself having trouble in configure ~/.vimrc
. The syntax of Vimscript is not my liking, leading me to switch Neovim(Nvim)
. Rather than migrating my old ~/.vimrc
. I decided to start from scratch and take this opportunity to re-evaluate my previous Vim configuration. I aim to replace my plugins with the latest SOTA(State-of-the-art) alternatives. It’s been some time since I last edited my ~/.vimrc
In my opinion, it’s essential to understand the meaning behind each option and statement in the configuration file. That’s the approach I took in this post. My goal is to make the configuration files self-contained and easily understandable. To achieve this, I aim to provide clear explanations for each setting and include comments to enhance readability.
💡 Please note that I may have missed some options. However, as a reminder, you can always access the help docs in the
Nvim
by typing:h <name>
to get more information
💡 This post assumes that you have a basic understanding of Vim
The basics
Lua
In my Nvim
configuration, I will use the Lua programming language as much as possible. Thus, it’s recommended that the reader familiarize themselves with Lua. Take a look at Learn Lua in Y minutes
Configurations files paths
The configuration directory for Nvim
is located at ~/.config/nvim
. On Linux/Mac, Nvim
will read ~/.config/nvim/init.lua
when it starts up. Theoretically, we can put everything inside this single file. It’s a bad practice though. To keep things organized, I prefer to break it down into smaller, more manageable parts.
If you follow this post to configure your Nvim
, your ~/.config/nvim
should look like this⬇️
|
|
The explanations
init.lua
is the entry point. We will “import” other*.lua
files ininit.lua
colorscheme.lua
for the themekeymaps.lua
for key mappingslsp.lua
for the LSP supportoptions.lua
for some global optionsplugins.lua
for third-party plugins
- Put the configurations of third-party plugins in this
config
folder. For example,nvim-cmp.lua
for thenvim-cmp
plugin lua
folder. When we callrequire
to import a module in Lua, it will search this folder.- Replace the path separator
/
with.
, and remove the suffix -.lua
. That’s how you get the parameter ofrequire
- For example, to import
nvim-cmp.lua
, you should writerequire('config.nvim-cmp')
- Replace the path separator
Options
We mainly use these: vim.g
, vim.opt
, and vim.cmd
. I made a cheatsheet below:
In Vim |
In Nvim |
Note |
---|---|---|
let g:foo = bar |
vim.g.foo = bar |
|
set foo = bar |
vim.opt.foo = bar |
set foo = vim.opt.foo = true |
some_vimscript |
vim.cmd(some_vimscript) |
key mappings
The syntax of key binding in Nvim
:
|
|
For a detailed explanation, please refer to :h vim.keymap.set
Configure Nvim from scratch
Now we can configure Nvim
step by step :)
Install Neovim
I am a Mac user, so I use Homebrew to install Nvim
1
|
|
After completing the installation, If the ~/.config/nvim/
directory doesn’t exist, you should create the folder and init.lua
file
|
|
💡 Please note that after making any modifications to the
*.lua
files, you need to restart theNvim
to see the changes take effect. I will assume that you restart yourNvim
after each section
Options configuration
The features:
- Use the system’s clipboard
- Use the mouse in
Nvim
- Tab and whitespace
- UI configuration
- Smart search
Create ~/.config/nvim/lua/options.lua
file and edit:
|
|
Then edit the init.lua
file, use require
to import options.lua
file
|
|
Key mappings configuration
The features:
- Use
<C-h/j/k/l>
to move the cursor among windows - Use
Ctrl
+ arrow keys to resize windows - In select mode, we can use
Tab
orShift-Tab
to change the indentation repeatedly
Create ~/.config/nvim/lua/keymaps.lua
and edit:
|
|
Edit init.lua
and import keymaps.lua
|
|
💡
...
means that I omit other lines(in order to save the length of the post)
Install package manager
A powerful Nvim
should be augmented with third-party plugins. I have selected lazy.nvim as my plugin manager, which has several amazing features including:
- 🧪 Correct sequencing of dependencies
- 🔒 Lockfile
lazy-lock.json
to keep track of installed plugins - …
Create ~/.config/nvim/lua/plugins.lua
and paste the following code. At the moment, I haven’t added any third-party packages. The template code will bootstrap lazy.nvim
for us.
|
|
💡 The syntax of adding a third-party plugin in
lazy.nvim
is adding specification in the...
ofrequire("lazy").setup({})
.
Again, import plugins.lua
in init.lua
|
|
If you see a black window with no content when opening Nvim
, just wait for a moment as lazy.nvim
is in the process of installing itself☕️. After the Dashboard appears, you may type :Lazy
to check if it works correctly.
:q
to quit the floating window of lazy.nvim
.Colorscheme
My favorite theme - monokai.nvim. Add this plugin in plugins.lua
|
|
Save the changes and wait for lazy.nvim
to finish installing. Create ~/.config/nvim/lua/colorscheme.lua
and edit:
|
|
The pcall
here refers to a protected call in Lua, which will return a boolean value to indicate its successful execution(a similar approach can be found in Go with the use of err
). By using pcall
instead of vim.cmd('colorscheme monokai_pro')
, we can avoid some annoying error messages in case the colorscheme is not installed2
Again, import colorscheme.lua
in init.lua
|
|
Auto-completion
It can be quite complicated to configure auto-completion manually, which is why we use some fantastic plugins to ease the burden. Now I will discuss a simpler solution I have found.
First, use this plugin nvim-cmp, which can manage many completion sources for us. It can also let us customize the completion menu etc.
Create ~/.config/nvim/lua/config/nvim-cmp.lua
and edit
|
|
Then we modify plugins.lua
file to add the plugins needed:
|
|
Explanations:
cmp.setup
function accepts a Lua table, which defines some options for customization. You will find that plenty of plugins follow this API design. It’s a common practice.LuaSnip
is a code snippet engine. Thenvim-cmp
says that we should pick a code snippet engine at least. Just ignore this if you don’t need this- We can use
config = function() ... end
inlazy.nvim
to specify the code to run after the plugin is loaded. I set it to load thenvim-cmp.lua
file - The
nvim-cmp
is the main plugin we care about. All other plugins begin withcmp-
is the completion sources helper used bynvim-cmp
. Thelspkind.nvim
will make it more beautiful :)
Key mappings in nvim-cmp
Use mapping = ...
. The syntax is ['<key-binding>'] = cmp.mapping.xxx,
. Different cmp.mapping.xxx
options can be found in the manual. If you want to set a different key-binding, just change the [...]
My key mappings:
- Use
<C-k/j>
or “/ ” to move among completion items - Use
<C-b/f>
to scroll among the doc of completion item - Use
<CR>
to confirm completion
Completion menu in nvim-cmp
Use formatting = ...
:
- Use
fields
to specify the appearance of each completion item - Use
format = function(...)
to set the text for each completion source. You can specify completion sources insources = ...
🎙️ You can use basic completion now ~
LSP
To turn Nvim
into an IDE, it is necessary to rely on LSP3. It is cumbersome to install and configure LSP one by one manually, as different LSPs have different installation steps, and it is inconvenient for future management. That’s where tools like mason.nvim and mason-lspconfig.nvim come in to make our lives easier 🤗
Modify the plugins.lua
file:
|
|
Create a ~/.config/nvim/lua/lsp.lua
file to manage it. Let’s configure mason
and mason-lspconfig
first
|
|
💡 Add whatever LSP you like in the
ensure_installed
, the complete list can be found in server_configurations. I use the two programming languagespython/rust
, and because we use Lua to configureNvim
, we also addedlua_ls
here
After configuring the mason-lspconfig
, we can now configure nvim-lspconfig
now. Because the configuration code is relatively long, I only show the configurations for pylsp
. The latest file can be found here.
💡 Each LSP may have its options to configure, check the corresponding GitHub repo to get more info, or you can just set
on_attach = on_attach
.
Add the following code to the nvim/lua/lsp.lua
file
|
|
The key-binding here is quite similar to what we did in nvim-cmp
. Refer to the manual as you wish.
Append a line in init.lua
|
|
Once you’ve restarted Nvim
, take a look at the status bar below. You should notice Mason is busy installing the specified LSPs (Keep in mind that Nvim should not be closed during this process). To track the installation progress, enter :Mason
in Nvim
. While you wait, you can type g?
to get additional information about the Mason plugin.
Now we have a lightweight IDE🎉🎉🎉
Wrap-up
With this configuration, we successfully turned Nvim
into a lightweight IDE, which supports code highlighting, code completion, syntax checking, and other functionalities. It is completely open source and free 🤗.
I realized that even after trying different code editors and IDEs, I always found myself searching for Vim support. So I chose to turn Nvim
into an IDE and host the configuration files on my martinlwx/dotfiles. In this way, I can easily clone my configuration files to any new machine and have a consistent programming experience across machines.
Polishing tools requires effort and time. To understand the purpose of each option, I had to search for various materials. However, despite the challenges, I firmly believe that it’s worth it. Understanding your tools allows you to further extend and customize them. This article aims to present a simple and straightforward configuration, but there are still many beautification and customization things that can be done, including many excellent third-party plug-ins that have not been mentioned yet. The exploration and discovery are left to the readers