Today we will introduce you how to configure Go development environment under Vim. If you are interested, you may want to give it a try.
System Dependencies
Before we start, we need a handy terminal emulation software. There are many such programs, but make sure to choose one that supports utf-8 encoding and 24-bit true color. Here I recommend.
- linux platform st
- macos platform iTerm2
- window platform Windows Terminal
There are also cross-platform terminal emulation software, such as Alacritty, which have some problems on different platforms, so beginners should not bother with them.
Everything in this article relies on a UNIX environment, windows users should install Windows Subsystem for Linux. This distribution has new software versions and is especially suitable for developers.
To lower the threshold of command line operation, I recommend using On My Zsh. Oh My Zsh provides mainly detailed command completion functions, which are very convenient.
Other software that needs to be installed are
- git version control
- tmux terminal reuse
- fzf fuzzy matching for file travel
- ripgrep file content search, much faster than grep
- go language compiler
Finally, NeoVim is installed.
Basic Configuration
NeoVim’s default configuration file is ~/.config/nvim/init.vim
.
Vim is compatible with vi by default, which is difficult to use, but NeoVim gives up compatibility with vi and enables many configuration items. So there are not many configurations that need to be changed.
I personally recommend adding the following configuration.
This is all you need for the basic configuration. vim opens the file with the cursor on the first line by default. If you want to automatically jump to the last exit position, you need to add the following configuration.
It would take quite a bit of talking to make sense of how this configuration works. Let’s not get hung up on it. Let’s start by installing a few plugins.
Plugin Management
Vim has a lot of plugins for managing plugins. But I don’t recommend them, because you can easily manage them with git.
First, let’s go to the ~/.config/nvim
directory and run git init
.
Then we create the plugins directory by running mkdir -p pack/vendor/start
. The name of the vendor directory can be whatever you want, but the pack/*/start
three-level directory structure cannot be changed, it is specified by vim.
All plugins just need to be placed in the pack/*/start/
directory and they will work.
If we want to add a plugin we can.
|
|
If you want to update the plugin you can.
|
|
If you want to remove the plugin you can.
|
|
To be clear, this is a git submodule operation. Here we install the required plugins.
Theme plugins
First of all, we need to install a theme that looks a little bit better. I especially recommend tender, which is a theme that supports 24-bit true color and has a cooler tone.
|
|
Then you need to add the following configuration to open the theme
File plug-in
Viewing the directory structure
The IDE interface displays a file manager on the left side, and Vim can achieve a similar effect with plugins. I recommend using the venerable NERDTree plugin.
|
|
Once installed, you can open the file manager with :NERDTreeToggle
. If you want NERDTree to locate the current file, you can execute the :NERDTreeFind
command.
NERDTree supports many configurations, which can be viewed via :h NERDTree
. It is recommended to add the following configuration.
Considering that NERDTree is more commonly used, we can set two shortcut keys
nnoremap
indicates that the shortcut key is set in Normal mode. <leader>
defaults to \
, and generally user-defined shortcut keys start with <leader>
to prevent them from affecting the default key position. The final <cr>
indicates a carriage return. So when we press \e
in Normal mode, Vim will automatically simulate typing :NERDTreeToggle
for us and then pressing enter. This is no different than typing the command and executing it ourselves.
NERDTree itself also supports writing extensions. The only extension I recommend here is nerdtree-git-plugin, which displays the status of git changes in NERDTree.
|
|
nerdtree-git-plugin requires no additional configuration.
Search for file paths
If you’re not familiar with the project structure, start with NERDTree, but if you are, using NERDTree is a bit unwieldy. This is the time to use fzf as a big tool. I wrote a fzf.vim myself, which is pure and recommended for everyone.
|
|
fzf.vim needs a shortcut key of its own. I suggest using ctrl-p
.
|
|
Mapping the ctrl key combination requires the use of pointed brackets, c for ctrl, otherwise it is no different from normal mapping.
This way, pressing ctrl-p
in Normal mode opens a search window. Then you can keep typing characters to filter the search results, and finally press enter to open the corresponding file.
Search file contents
fzf.vim can only search file paths. If you want to search the contents of a file, you need to use the ripgrep command. I have also written my own plugin called ag.vim.
|
|
ag.vim uses the ag command by default. If you use ripgrep, you need to add the following line to configure it.
|
|
If we want to search for the keyword fzf
, then we can execute :Ag fzf
. Regular expressions are supported, such as :Ag a[0-9]+
.
Recently used files
The last requirement is to record a list of recently opened files. I wrote a plugin mru.vim for this as well.
|
|
Again, you need to set a shortcut key, I use ctrl-u
:)
|
|
Once installed, mru.vim will automatically keep a list of recently used files, and will sort and de-duplicate them according to when they were used. Just press ctrl-u
to open the file list. The cursor will stop at the last used file. You can open the last used file by pressing enter. You can also move the cursor and select other files.
The above are the main plug-ins related to file operations, which basically cover the common file operations.
Git
For beginners, you should in principle use the command line to work with git. But I found a plugin that shows the status of file changes in real time that I must recommend, called gitsigns.
gitsigns can display the change status of a file in real time on the far left side of the window, very fast. gitsigns is developed in lua and can only be run under NeoVim.
Because it is written in lua, the way it is loaded and configured is very different from traditional plugins. We start by creating a vim.lua file in the directory where init.vim is located. This file can be named whatever you want, but not init.lua, and then we add a command to init.vim that loads the lua configuration
|
|
The configuration of the lua plugin is written to the vim.lua file. gitsigns also requires little additional configuration, just add a line that says
|
|
Note that the require
syntax of lua is used here. You can import files without spaces, and it’s an expression with a return value, so you can call the setup()
method directly on the return value.
There are many git-related plugins, but they are not recommended for beginners. You should wait until you are familiar with the git command before tinkering with it.
Syntax highlighting
Vim implements syntax highlighting by default using keywords and regular expressions. But this approach is slow and not smart enough.
NeoVim supports syntax highlighting and code folding using TreeSitter. TreeSitter does syntax analysis of the code, and incrementally, allowing for more fine-grained syntax coloring.
Installation is also very simple.
|
|
After restarting NeoVim, run :TSInstall
to install the required languages.
|
|
If you need to update, then you can execute :TSUpdate
.
Then we add the following code to vim.lua.
The syntax here is rather odd, but common. In lua, both arrays and dictionaries are represented by {}
. Arrays are {1,2}
and dictionaries are {a=1,b=2}
, which can be defined in nested sets. And lua allows parentheses to be omitted when calling functions. That means setup({a=1})
can be abbreviated to setup{a=1}
and print("abc")
can be abbreviated to print "abc"
.
We also need to make vim use treesitter to do code folding by adding the following configuration to init.vim.
Then restart NeoVim and you’ll see the highlighting and collapsing effects.
Complementary jumps
The most important thing about writing code is the auto-completion and smart jump features. This is a bit tricky to configure.
In the old days, every IDE would implement a set of code completion and jumping features. Later, Microsoft released the language server protocol (lsp), which aims to abstract out the code completion and jumping features and provide the services to the public using a standard interface.
It was first used in vs code, but now more and more tools are starting to support lsp. NeoVim has a built-in lsp function.
The Go language also maintains its own official language server, called gopls, which we install first:
|
|
Because configuring lsp is relatively cumbersome, each language needs to be configured separately. To make it easier to use, NeoVim maintains an official configuration collection for each language, which is distributed as a plugin. So we also need to install this configuration.
|
|
Finally, you need to enable complement and jump support for the Go language by adding the following code to vim.lua.
|
|
Note that gopls is only supported for projects with go.mod added. Open a Go file, run :LspInfo
, and you should see Configured servers list: gopls
.
Find a function at random, press gd
and it should jump to the corresponding function definition, return to it and press ctrl-t
. NeoVim will start the gopls program the first time you use it, so there will be a slight delay. Subsequent use will be quick.
Switch to insert mode, type fmt.
and press ctrl-x ctrl-o
and you should see a pop-up completion window.
For other functions, please try it yourself according to the comments in the configuration.
This solution is by far the cleanest and fastest solution. However, there are two minor flaws in this solution.
- Can’t automatically import the newly referenced package name
- No automatic code formatting
How can I put up with this? After a bit of tinkering, we found a solution.
We need to create a ftplugin
folder in the init.vim directory, and then create a new go.vim file in it, with the following contents.
|
|
Vim automatically executes the vim scripts in the plugin
directory. This is not the case for the ftplugin
directory. The ft prefix in the name is a shortened version of the file type, and the files in it are named with their extensions. For example, go.vim is only executed when the go source file is opened.
With the above configuration, NeoVim will automatically format the code and import the used package names when it exits.
Auto-completion
After the previous completion plugin is configured, you need to press ctrl-x ctrl-o
in insert mode to trigger the completion. It is not as convenient as IDE. Can you support auto-trigger? Yes, but you need to install a new plugin. Here I recommend using cmp, also developed by lua, which is very fast.
You need to install six related plugins in one go.
|
|
Then add the following code to vim.lua.
|
|
So far you have done all the configuration work, enjoy it as much as you can.
One thing to note, however, is that the first time you use the lsp-related features, NeoVim will start gopls, and there will be a delay of a few seconds. After that, it will be very fast.
Summary
This article provides Go developers with a complete configuration manual, which implements most of the IDE features with minimal cost. Based on the configuration in this article, it should be easy to do your daily Go development work under NeoVim. I myself believe in the KISS principle, use only the necessary plugins and add only the necessary configuration. After you get started, you should focus on the basics of Vim, and then toss around plugins and configurations when you become proficient!