By now you have used enough `vim` to see it's tremendous text editing potential.
Out of the box it works very well, but with some additional configuration and a few plugins installed it get's even better.
We'll go over all basic aspects of tweaking your `~/.vimrc` file from some welcome changes, some aesthetic to a complete IDE.
For IDE features we'll focus on `python3` and `bash` but I'll leave some links to point you in the right direction for other languages.
The point of this chapter is not to race towards the end but to understand what every step adds to your working comfort.
I highly advise to take the changes to your vimrc *slowly* and see if you actually *like* the change.
If you don't like a feature you don't have to use it, but it's still good to be aware of where you can take vim for future reference.
## Which vim to install
A simple `sudo apt install vim` installs a *basic* version of vim but when you're on a server and need to do some scripting it's a better idea to install `vim-nox`.
What's the difference?
We can get some information about both packages via `sudo apt-cache show vim vim-nox`.
Classic vim will give you the following description:
```
Description-en: Vi IMproved - enhanced vi editor
Vim is an almost compatible version of the UNIX editor Vi.
.
Many new features have been added: multi level undo, syntax
highlighting, command line history, on-line help, filename
completion, block operations, folding, Unicode support, etc.
.
This package contains a version of vim compiled with a rather
standard set of features. This package does not provide a GUI
version of Vim. See the other vim-* packages if you need more
(or less).
```
And vim-nox the following:
```
Description-en: Vi IMproved - enhanced vi editor - with scripting languages support
Vim is an almost compatible version of the UNIX editor Vi.
.
Many new features have been added: multi level undo, syntax
highlighting, command line history, on-line help, filename
completion, block operations, folding, Unicode support, etc.
.
This package contains a version of vim compiled with support for
scripting with Lua, Perl, Python 3, Ruby, and Tcl but no GUI.
```
I would *always* install vim-nox but this is personal preference.
Some people like the graphical versions of vim, or `gvim`, but I'm not a fan.
Maybe try the vim-gtk package to see if you like it.
Do keep in mind that the program you'll invoke is **always**`vim` no matter which version you install!
For graphical vim you'll invoke `gvim`.
**From here on out I expect a vim-nox installed!**
## Basic improvements
You'll probably always want to include the following in your vimrc.
You can [download](./assets/vimrc_basic) the file if you want to try it out but do take the time to read the comments.
" don't make vim vi compatible (if not set you miss out on a lot of features!)
" you'll see this option set in most configuration files found online
set nocompatible
" enable filetype recognition plus indent and plugin (pretty much mandatory)
filetype plugin indent on
" enable syntax highlighting
syntax on
" backspace can be a tricky thing and this setting makes it work a lot better
set backspace=indent,eol,start
" when tab completing on the expert line you don't want to miss out on EDIT vs
" edit or nerdtree vs NERDTree and this setting ignores case completely
set ignorecase
" highlight your search patterns (very handy when building regexes)
set hlsearch
" highlight the search pattern as-you-go (tremendously helpful when
" constructing regexes)
set incsearch
" always show a status line at the bottom of your vim which shows some basic
" information about the file, which line you're at etc
set laststatus=2
" show files in statusbar when opening via expert mode
set wildmenu
" also show all possible expert mode commands in the statusline
set wildmode=full
" reverse numbering (in the sideline) so you don't have to manually count how
" many lines you have to yank
set rnu
" it's also nice to still have your absolute line number in the sideline
set nu
" can do copy paste from the clipboard
set clipboard=unnamedplus
```
You can test out the vim configuration above by downloading it to your home directory and telling vim explicitly you want *that* vimrc by invoking `vim -u ~/vimrc_basic test.py` where `test.py` is just an example.
Each setting has some information about what it does but vim comes with built-in help.
You can invoke this help by pressing `:help laststatus`.
## Getting help
![vim help](./assets/vim_01.png)
Now, what has happened here?
Vim opened it's own documentation in a new *horizontal split* and moved the cursor there.
At first this is very intimidating but there are just a few command you need to know to manage this situation perfectly.
Don't worry about messing up the documentation, it's opened in read only mode.
* you can read the documentation by pressing `j` to go down and `k` to go up
* to navigate splits you use `CRTL-w j` to go down, `CRTL-w k` to go up, `CTRL-w l` to to right and `CRTL-w h` to go left
* to close the documentation you need to be *inside* the documentation split and press `:close` which means it will close the split you're in (if your cursor is on the **other** split you can use `:only` which does the opposite)
The `CTRL-w` affair is a shortcut to vim's window navigation.
You can read up a bit more in the manual at `:help window` but below is the gist of it.
It might sound a bit confusing at the start but think of `tmux` and it's *panes, splits and windows* and it might make some more sense.
```
Summary:
A buffer is the in-memory text of a file.
A window is a viewport on a buffer.
A tab page is a collection of windows.
A window is a viewport onto a buffer. You can use multiple windows on one
buffer, or several windows on different buffers.
A buffer is a file loaded into memory for editing. The original file remains
unchanged until you write the buffer to the file.
A buffer can be in one of three states:
*active-buffer*
active: The buffer is displayed in a window. If there is a file for this
buffer, it has been read into the buffer. The buffer may have been
modified since then and thus be different from the file.
*hidden-buffer*
hidden: The buffer is not displayed. If there is a file for this buffer, it
has been read into the buffer. Otherwise it's the same as an active
buffer, you just can't see it.
*inactive-buffer*
inactive: The buffer is not displayed and does not contain anything. Options
for the buffer are remembered if the file was once loaded. It can
contain marks from the |viminfo| file. But the buffer doesn't
contain text.
```
If you actually read the documentation you must have noticed you can make tabs, as in firefox tabs, in vim!
I tend to mostly use buffers, based on [this](https://stackoverflow.com/questions/26708822/why-do-vim-experts-prefer-buffers-over-tabs) philosophy but you do you.
As for window navigation I add the following to my vimrc but you will probably not like it too much.
This remaps the arrow keys, which you should **not** be using for navigation text anyway, to window navigation.
If the `nnoremap` makes no sense try `:help mapping`.
## Switching quickly from config file to config file
A lot of information about vim online is geared towards programmers and not system administrators but I have a trick for you that will probably help you quite a bit when modifying configuration files.
You have to get comfortable with opening and navigating buffers first so a quick rundown on the basics.
To do this exercise properly first prepare the following files by executing the commands below.
We already have syntax highlighting via the `set syntax=on` feature but we can also have autocomplete for quite a lot of scripting languages out of the box.
This is one of the main reasons we install vim-nox and not vim!
The shortcut to achieve it is a double whammy `<c-x><c-o>` which triggers omnicomplete.
Have a look at `:help omnifunc` to learn more about it but first, a hands on example.
1. Open the python file we made before with `vim -u ~/vimrc_basic ~/python_test.py`
2. Navigate to the end of the file, go into **insert** mode and type `datetime.`
3. Remain in insert mode after the `.` and hit `<c-x><c-o>`
4. Stay calm and read on.
![autocomplete](./assets/vim_02.png)
The screenshot above is probably very much like what you're confronted with.
The *dropdown* menu is a context aware autocomplete menu meaning these are all functions, methods, classes or variables belonging to this module.
The horizontal split window at the top shows the documentation of the menu item you have selected.
You can navigate this list either with the *arrows* or with `<c-n>` to go down and `<c-p>` to go up.
I personally don't like the documentation jumping up and down on my screen so you can add the following to remove it all together.
Now to be able to view the documentation we'll need to install some plugins.
I have not found a clean way of hiding the preview window *and* adding a shortcut to show documentation.
There is a lot of online debate on which plugins to use, which autocomplete engine is the best, if you even need anything beyond vanilla vim, etc.
From here on out I'll just list my current personal preferences.
I've done quite a bit of tweaking an testing over the years and this list can be a shortcut for you to not having to debug as much.
For me, autocomplete is essential.
I don't really understand *how* you can learn how to code without.
This being said, I use autocomplete for all sorts of things ranging from email to code and configuration files.
The modern way of doing autocomplete is to do it *asynchronous* meaning vim won't freeze when it's waiting on a list of possible candidates.
I'm a pretty big fan of the [Language Server Protocol](https://en.wikipedia.org/wiki/Language_Server_Protocol) and the world seems to agree it's the way to go.
For vim I use the following plugins as a bare minimum.
* [asyncomplete.vim](https://github.com/prabirshrestha/asyncomplete.vim) to offer async completion
* [vim-lsp](https://github.com/prabirshrestha/vim-lsp) which is a LSP client written in vimscript
This might seem like a lot but they are all pretty neat plugins that work super well together.
With this installed vim becomes a language server client and a client is nothing without a server.
You can see a list of suppored servers [here](https://github.com/mattn/vim-lsp-settings) and mattn/vim-lsp-settings makes it super easy to install one.
In order for it all to work, for python and bash, you should do a systemwide installation of python3-pip, python3-venv and npm with the following command.
```bash
sudo apt install -y python3-pip python3-venv npm
```
For python just install the above mentioned plugins and open up a python file.
You'll be prompted to install [pyls](https://github.com/palantir/python-language-server) which is a very good language server.
Type `:LspInstallServer pyls-all`, wait for it to finish and you're good to go!
It might take some time to get everything initialized properly the first time you launch it, but that's quite normal.
For bash you'll need the npm package installed.
If that's the case you just open up a script and you'll be prompted to install the server.
Type `:LspInstallServer bash-language-server`, wait a bit and you're good to go!