How to Turn Vim Into a Lightweight IDE
Build your own editor to facilitate programming with Vim
Introduction
The Vim text editor is often used as a tool for editing configuration files on a Linux system. For this purpose, Vim does the job exceptionally well by providing unique features such as buffers, macros and bookmarking to name a few.
As well as a text editor, Vim also ships with a built-in scripting language called Vim script. This powerful feature allows developers to extend the functionality of Vim by writing plug-ins that accomplish specific tasks, such as code completion and interacting with the file system. This means that it is possible to install and configure any number of plug-ins to extend Vim’s functionality and literally build the perfect editor, specifically for you.
This article will demonstrate how to turn Vim into a lightweight IDE by installing and configuring a range of useful plug-ins. We will adopt a step-by-step approach where you will quickly learn the work flow (or process) of building your own editor with Vim.
Task Overview
The Vim text editor is very customizable even without the use of plug-ins. It is therefore a good idea to initially tweak some of Vim’s fundamental behavior. With this in mind, we will complete a few tasks before installing any plug-ins:
- Install the Vundle plug-in manager.
- Modify some Vim settings for correct tabbing behavior, searching, and terminal functionality.
- Install some color schemes from the awesome-vim-colorschemes repository.
At this point, we will take a look at installing and configuring these plug-ins:
- vim-polyglot: Provides language packs and indentation.
- auto-pairs: Pair completion when typing brackets, parenthesis, quotes, etc.
- NERDTree: An integrated file system explorer.
- tagbar: A panel that displays a source file’s tags.
- ctrlsf.vim: Enables asynchronously searching the file system.
- fswitch: For switching between header and implementation files.
- vim-protodef: For pulling function prototypes into implementation files.
Many Vim plug-ins come with sensible configurations and should work adequately out-of-the-box. Excellent documentation normally accompanies a plug-in as well, which is usually accessed via Vim’s :help
command.
Browsing through plug-in documentation is definitely a worthwhile endeavor because you might find a cool feature or setting that you didn’t know about before.
Getting the Final Configuration File
I have created a GitHub repository containing the final .vimrc
file that we will be putting together in this article. Feel free to refer to it at any point if you get stuck or would like installation instructions for using it on your own system.
You can also download the final Vim configuration file using curl on the command line:
$ curl -L https://raw.githubusercontent.com/danebulat/vim-config/master/light-ide/vimrc > vimrc
Installing a Vim Plug-in Manager
A Vim plug-in manager is a script that is able to automatically download, install and remove plug-ins by simply reading your .vimrc
file. A plug-in manager will download plug-ins into separate directories and enable them every time we launch Vim.
Since our IDE will require many plug-ins — which may also have external dependencies — we will opt to install the Vundle plug-in manager. Vundle is installed by firstly cloning its Git repository into your ~/.vim/bundle
directory:
$ mkdir -p ~/.vim/bundle
$ cd ~/.vim/bundle
$ git clone https://github.com/VundleVim/Vundle.vim.git Vundle.vim
Then open your .vimrc
file and add the following boilerplate code:
set nocompatible
filetype off" Set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim" Download plug-ins to the ~/.vim/plugged/ directory
call vundle#begin('~/.vim/plugged')" Let Vundle manage Vundle
Plugin 'VundleVim/Vundle.vim'call vundle#end()
filetype plugin indent on
Now, whenever we want to install a new plug-in that is hosted on GitHub, we specify it using the format Plugin '<github_account>/<repository_name>'
between the call vundle#begin(..)
and call vundle#end()
lines. Also take note that repositories will be downloaded into the ~/.vim/plugged/
directory on the file system.
Let’s now open Vim and run the :PluginInstall
command to enable Vundle:
$ vim ~/.vimrc
# In Vim
:PluginInstall
A side panel will open after running :PluginInstall
showing the installation progress. When the Vim status line displays a Done
message, feel free to close the panel by pressing q
.
In order to remove a plug-in, simply comment out the corresponding Plugin
line and run the :PluginClean
command in Vim. The associated repository will then be removed from your file system.
Modifying Some Vim Settings
This section will go through modifying some basic Vim settings to make the editor feel more modern and natural to use.
Open up .vimrc
and add some code to enable line numbers and syntax highlighting:
set nu " Enable line numbers
syntax on " Enable syntax highlighting
Vim will now look for a corresponding syntax/<language>.vim
file when it opens up a particular source file. For example, if we open a file called main.cpp
, Vim will attempt to load a syntax/cpp.vim
file to render C++ syntax correctly. Because we will be installing language packs via a plug-in very shortly, it's not important to know about which syntax schemes your Vim installation supports - we just need to make sure syntax
is turned on.
Let’s also fix Vim’s tabbing behavior by modifying some settings:
" How many columns of whitespace a \t is worth
set tabstop=4 " How many columns of whitespace a "level of indentation" is worth
set shiftwidth=4 " Use spaces when tabbing
set expandtab
The expandtab
setting guarantees that our source code files will always use space characters instead of the tab (\t
) character. Encoding tabs as space characters in source files is recommended for a range of programming languages such as Python. We also make sure that tabs take up four columns of white space via the shifttab
and tabstop
settings.
Moving forward, Vim’s search function is triggered when the forward slash key is pressed in normal mode. Let’s tweak its behavior to make text searching in source files more intuitive:
set incsearch " Enable incremental search
set hlsearch " Enable highlight search
The incsearch
setting will automatically update matches in a source file as you type a search query. The hlsearch
setting turns on highlighting to provide some visual feedback when typing a search term. Run the :noh
command to hide any highlighted text in the editor.
Lastly, let’s configure how the built-in terminal is opened when the :term
command is run:
set termwinsize=12x0 " Set terminal size
set splitbelow " Always split below
set mouse=a " Enable mouse drag on window splits
We provide a sensible default height of twelve rows for the terminal window, and instruct Vim to always open it below the current active window. Mouse functionality is also enabled on the last line, which allows us to resize a window by clicking and dragging on a split.
Plug-in Installations
Language Packs for Syntax Highlighting
The vim-polyglot plug-in provides correct syntax highlighting and indentation for over 50 languages. When a file is open in Vim, the plug-in will load a corresponding script for that particular file type and apply the correct language settings.
Let’s add the Polyglot repository to the plug-in list in .vimrc
and install it on the command line:
Plugin 'sheerun/vim-polyglot'
# Install on command line
$ vim +PluginInstall +qall
Because language packs are loaded on demand, your Vim startup time will not be affected by having many installed on your system. Moreover, we can inspect the storage requirement for the language packs with the du
utility:
$ du -hcs ~/.vim/plugged/vim-polyglot
# Output
23M .vim/plugged/vim-polyglot/
23M total
Our IDE now supports syntax highlighting and indentation for over 50 languages. Feel free to open some source files of various languages to check out this new behavior.
Color Schemes
Although Vim ships with some interesting color schemes, it would be nice to install our own collection. It is possible to preview Vim’s installed color schemes with the :color <scheme-name>
command. I recommend tabbing through the scheme names after typing :color
.
If you are not satisfied with the defaults, there is a plethora of excellent color schemes online available for download. A great resource for discovering new color schemes for Vim is the awesome-vim-colorschemes repository, which lists a huge collection of color scheme projects. I encourage you to spend some time looking through the list and choosing your favorites. My configuration will include the following color schemes:
- archery: A color scheme inspired by Arch Linux colors.
- iceberg: Dark blue color scheme.
- nord: An arctic, north-bluish clean and elegant theme.
- scheakur: A professional light/dark color scheme.
- vim-hybrid-material: Material color scheme based on w0ng/vim-hybrid.
- vim-solarized8: An optimized solarized theme.
Add the Git repositories of your chosen color schemes to .vimrc
and run the necessary installation command on the command line:
Plugin 'cocopon/iceberg.vim'
Plugin 'arcticicestudio/nord-vim'
Plugin 'Badacadabra/vim-archery'
Plugin 'kristijanhusak/vim-hybrid-material'
Plugin 'scheakur/vim-scheakur'
Plugin 'lifepillar/vim-solarized'
# Install on command line
$ vim +PluginInstall +qall
From here, I recommend previewing the installed color schemes before deciding on which one to load by default. Open up a source file with plenty of code in order to get a good feel for each of the new color schemes:
$ vim test.cpp
: color <TAB>
At this point we can append a couple of lines to .vimrc
to automatically load a color scheme when launching Vim:
set background=dark " dark or light
colorscheme scheakur " Your favorite color scheme's name
Set the background
variable to either dark
or light
depending on the style of your default color scheme. Run the :set background=light
and :set background=dark
commands in Vim If you're unsure about which one to use.
Pair Completion
The Auto Pairs plug-in provides automatic pair completion when we input characters such as brackets, parenthesis and quotes. It also provides some formatting functionality, such as when you press the Enter
key after typing an initial pair character.
Let’s add the auto-pairs repository to the plug-in list in .vimrc
and install it on the command line:
Plugin 'jiangmiao/auto-pairs'
# Install on command line
$ vim +PluginInstall +qall
Pair completion is useful when working with programming languages such as C and C++, but it often gets in the way when editing basic configuration files that don’t require pair completion. It would be nice to quickly toggle pair completion on and off via a key mapping. The auto-pairs plug-in provides a variable specifically for this, which we can set in .vimrc
:
let g:AutoPairsShortcutToggle = '<C-P>'
Pair completion is now toggled whenever we press Ctrl+P
in normal mode. I encourage you to read the auto-pairs GitHub page to find out more about what this useful plug-in can do.
File System Explorer
The NERDTree plugin is a powerful file system explorer. It provides functionality for browsing the filesystem, opening files for reading or editing, and performing file operations. NERDTree is a feature-rich plug-in and includes many configuration settings, key mappings, as well as an API for adding new features.
This section will introduce the NERDTree plug-in by detailing the installation process and going through some key features so you can start using it effectively. I also encourage you to check out the excellent documentation by running the :help nerdtree
command within Vim after completing this tutorial.
Let’s add the NERDTree repository to the plug-in list in .vimr
and install it on the command line:
Plugin 'preservim/nerdtree'
# Install on command line
$ vim +PluginInstall +qall
From here you can run the :NERDTree
command in Vim to open up a new tree. The panel can be closed either by pressing the q
key or running the :NERDTreeClose
command.
The j
and k
keys may be used for moving up and down the tree, and you can search for specific nodes (files and directories) with the forward slash key (/
) as usual. NERDTree also defines key mappings to navigate and interact with the tree - the most useful of which are detailed in this table:
Have a play with these key mappings to get used to navigating the tree. Take note that the NERDTree panel must be in focus for the mappings to work.
Let’s also take a look at some important commands for opening and closing the NERDTree panel and modifying the tree root:
The root represents the outermost directory of the tree hierarchy. You will likely change roots when switching between projects that you wish to work on at any given moment.
NERDTree also supports the creation of bookmarks which can be used for navigating to projects and important locations on your file system efficiently. For example, you could create a bookmark for every project on your system — enabling you to jump from project-to-project and work on the corresponding project files efficiently. Providing a tree is in focus, these commands allow you to work with bookmarks:
Let’s go ahead and override some configuration variables provided by NERDTree in .vimrc
to tweak its behavior and appearance:
let NERDTreeShowBookmarks = 1 " Show the bookmarks table
let NERDTreeShowHidden = 1 " Show hidden files
let NERDTreeShowLineNumbers = 0 " Hide line numbers
let NERDTreeMinimalMenu = 1 " Use the minimal menu (m)
let NERDTreeWinPos = “left” " Panel opens on the left side
let NERDTreeWinSize = 31 " Set panel width to 31 columns
Let’s also set up a mapping that will toggle the NERDTree panel when the F2
key is pressed:
nmap <F2> :NERDTreeToggle<CR>
Moving forward, I recommend refining your configuration and adding more key mappings as you continue to use NERDTree and its many commands.
Source File Outliner
The tagbar plugin provides a way to browse the tags of the currently opened file. What this means is that we can immediately see the structure of the file by viewing its tags which convey class, variable and function identifiers. Key mappings are also provided that allow you to navigate an outline and jump to the corresponding location in the source file.
The tagbar GitHub page reveals that it depends on the Exuberant Ctags program (>= 5.5), which is often wrapped in a package called ctags
. This package needs to be installed via your operating system’s package manager to make the tagbar plug-in usable with Vim. For example, ctags
can be installed on Arch Linux via pacman:
$ sudo pacman -S ctags
# Check Exuberant Ctags or Universal Ctags is installed
$ ctags --version
With all dependencies taken care of, add the tagbar repository to the plug-in list in .vimrc
and install it on the command line:
Plugin 'preservim/tagbar'
# Install on command line
$ vim +PluginInstall +qall
The plug-in exposes some useful variables that we can modify to improve our workflow in the editor. The following code shows some overridden tagbar settings in our Vim configuration file:
" Focus the panel when opening it
let g:tagbar_autofocus = 1" Highlight the active tag
let g:tagbar_autoshowtag = 1" Make panel vertical and place on the right
let g:tagbar_position = 'botright vertical'" Mapping to open and close the panel
nmap <F8> :TagbarToggle<CR>
Setting the g:tagbar_autofocus
variable to 1
focuses the tagbar panel upon opening it. Additionally, setting the g:tagbar_autoshowtag
to 1
means that the correct symbol is highlighted in the tagbar panel as the cursor is moved within the corresponding source file. A mapping to the :TagbarToggle<CR>
command is also defined which allows us to open the sidebar by simply pressing the F8
key.
The panel’s cursor can be controlled with the standard Vim navigation keys (h
, j
, k
, l
) as well as some additional mappings defined by the plug-in. The most important mappings are presented here:
The tagbar documentation details its complete command set and configuration options. Run the :help tagbar
command in Vim to open it up.
Searching Files
CtrlFS is a powerful plug-in that searches for files on the file system asynchronously. Search strings can be based on the current word being hovered over by the cursor, a selection in visual mode, an arbitrary search term we type ourselves, and even a regular expression.
After performing a search, we are able to quickly preview the resulting files in a pop-up or load them into the current window for editing.
The CtrlSF Github page states that your system needs to have a code-searching tool installed such as ack
or ag
in order for the plug-in to work. Therefore, make sure you install one of these tools via your operating system's package manager. For example, you can install the ack
package on Arch Linux via pacman:
sudo pacman -S ack
After installing necessary dependencies, add the CtrlFS repository to the plug-in list in .vimrc
and install it on the command line:
Plugin 'dyng/ctrlsf.vim'
# Install on command line
$ vim +PluginInstall +qall
The upcoming configuration specifies how important features of the plug-in behave. I recommend copying this code and tweaking the values after using the tool a few times:
" Use the ack tool as the backend
let g:ctrlsf_backend = 'ack'" Auto close the results panel when opening a file
let g:ctrlsf_auto_close = { "normal":0, "compact":0 }" Immediately switch focus to the search window
let g:ctrlsf_auto_focus = { "at":"start" }" Don't open the preview window automatically
let g:ctrlsf_auto_preview = 0" Use the smart case sensitivity search scheme
let g:ctrlsf_case_sensitive = 'smart'" Normal mode, not compact mode
let g:ctrlsf_default_view = 'normal'" Use absoulte search by default
let g:ctrlsf_regex_pattern = 0;" Position of the search window
let g:ctrlsf_position = 'right'" Width or height of search window
let g:ctrlsf_winsize = '46'" Search from the current working directory
let g:ctrlsf_default_root = 'cwd'
It is also strongly recommended that you set up some mappings that enable you to search quickly:
" (Ctrl+F) Open search prompt (Normal Mode)
nmap <C-F>f <Plug>CtrlSFPrompt " (Ctrl-F + f) Open search prompt with selection (Visual Mode)
xmap <C-F>f <Plug>CtrlSFVwordPath" (Ctrl-F + F) Perform search with selection (Visual Mode)
xmap <C-F>F <Plug>CtrlSFVwordExec" (Ctrl-F + n) Open search prompt with current word (Normal Mode)
nmap <C-F>n <Plug>CtrlSFCwordPath" (Ctrl-F + o )Open CtrlSF window (Normal Mode)
nnoremap <C-F>o :CtrlSFOpen<CR>" (Ctrl-F + t) Toggle CtrlSF window (Normal Mode)
nnoremap <C-F>t :CtrlSFToggle<CR>" (Ctrl-F + t) Toggle CtrlSF window (Insert Mode)
inoremap <C-F>t <Esc>:CtrlSFToggle<CR>
The mappings all follow the convention of initially pressing Ctrl+F
followed by a unique letter to perform an operation with CtrlSF. Go ahead and test out the mappings above, and refer to the following table to navigate the results panel:
To wrap up our discussion on the CtrlSF plug-in, its full documentation can be opened in Vim by running the :help ctrlsf-options
command.
Switching Between .h and .cpp Files
The next plug-in we will take a look at is called FSwitch and provides functionality for quickly switching between a header and implementation file. The plug-in makes it possible to configure the type of companion files, as well as the search paths that are utilized to find them.
Firstly add the FSwitch repository to the plug-in list in .vimrc
and install it on the command line:
Plugin 'derekwyatt/vim-fswitch'
# Install on command line
$ vim +PluginInstall +qall
Let’s now jump back into .vimrc
and append this code:
au! BufEnter *.cpp let b:fswitchdst = 'hpp,h'
au! BufEnter *.h let b:fswitchdst = 'cpp,c'These lines specify that:
These lines specify that:
- When the loaded buffer is a
.cpp
file, the companion is of typehpp
orh
. - When the loaded buffer is a
.h
file, the companion is of typecpp
orc
.
The configuration specifies that companion files must have the same name — meaning that only the file type may be different so the connection can be made.
Let’s also define a mapping that splits the active window vertically and loads the companion file on the right side of the split. This responsibility is given to Ctrl+Z
with the line:
nmap <C-Z> :vsplit <bar> :wincmd l <bar> :FSRight<CR>
FSwitch allows companion files to be placed in separate ./include/
and ./src/
directories relative to the project's root. If you need the plug-in to search other directories in your project, check out the documentation by running :help fswitch
in Vim.
Pulling Prototypes Into Implementation Files
The vim-protodef plug-in can pull in function prototypes from a C++ header (.h
) file into a corresponding implementation (.cpp
) file. Let's try this out by firstly updating .vimrc
and installing the plug-in:
Plugin 'derekwyatt/vim-protodef'
# Install on command line
$ vim +PluginInstall +qall
By default, the plug-in provides two mappings to pull in the prototypes:
" Pull in prototypes
nmap <buffer> <silent> <leader> ,PP" Pull in prototypes without namespace definition"
nmap <buffer> <silent> <leader> ,PN
The leader key is in fact the backward slash (\
) key — meaning that your prototypes will be copied into your implementation file by pressing the \ + PP
or \ + PN
key combinations. Feel free to adjust these values and consult the documentation for more configuration options by running :help protodef
.
In Conclusion
At this point we have a boilerplate configuration with several essential IDE features including syntax highlighting for over 50 languages, a file system explorer, file searching, and an integrated terminal. If you are a developer who prefers to write code in a minimal environment, this setup may be adequate.
The following list describes some other Vim plug-ins that you could install to create a more feature-rich environment:
- indentLine: Displays indentation levels with vertical lines.
- vim-fugitive: A Git wrapper.
- vim-gitgutter: Show a Git diff in the gutter.
- vim-move: Move lines and selections up and down.
- YouCompleteMe: A powerful code-completion engine.
From here, I encourage you to read more plug-in documentation and continue to iteratively build upon your IDE. The Vim Awesome website is also a great resource for discovering new plug-ins.
Related Articles
Other articles I have written that focus on Vim: