Clean Vim

Videos

I wanted to show how one can use quite clean Vim to work efficiently. It requires to know only a few key aspects and some mentality shift but it took me almost 10 years to come to those conclusions. There is very little such content on the internet - besides this 9 years old classic: How to Do 90% of What Plugins Do (With Just Vim) .

I typically write articles here but some things sell better on a video. I don't record often so the quality of the video and presentation itself is questionable but I think it gets the point across.

The talk

Transcript
Hi.

I would like to show how to use Vim Text Editor with little to non configuration.
The internet is full of videos and tutorials on how to add more to it
- more configuration and more plugins
- how to change it's functionalities and behaviour
but there are little to no examples of how can it be used efficiently in it's
original form.

Just so you know:
this is not an introduction to the Vim Text Editor,
nor a tutorial on how to use it.

I've been using Vim for software development of bigger and bigger projects for
more than 10 years now.  But I've been programming for almost twice as long
just not in Vim.  Before I used all kind of IDEs and different text editors:
Visual Studio, NetBeans, InteliiJ, Android Studio, QtCreator, PowerShell ISE,
Sublime Text, Atom, Visual Studio Code and more.  Naturally when I begun using
Vim I already had certain expectations as to what it should provide and how it
should work.  After years I've realized that those expectations prevented me
from mastering the tool.

Also I worked in more than one language and technology on all major operating
systems (windows, linux and mac - on many different versions).  And I used Vim
on all of them.  So what you will see can be applied anywhere.

Let's take a look at the graph of how the number of lines in my vimrc file
changed over the years of using it.

When I started I just copied someone's configuration which had approximately 50
lines and I kept adding to it.  At some point I actually understood what those
lines did so I was able to do a small cleanup but at the same time I started
adding plugins.

Over the years I had a couple of cycles of cleanup but in general my vimrc file
grew to about 500 lines of code.  And that was not accumulation of a wasted or
unused features.  I actually relied on all of those 500 lines for my daily
work.  And that was my personal config.  The one I used for work was much large
- about 700 lines.

But a big shift happen half a year ago.  Frustrated with the need to maintain
large configuration between my work laptop's NeoVim and personal laptop's Vim
I started to challenge every line of my configuration.  The fact that one was
in Lua on Mac and other in VimScript on Linux only motivated me more.
Also my brother's tiny Emacs config was an additional inspiration.

It took me just one day to figure out that almost everything I had a special
plugin or shortcut for already was doable in default Vim.  Hence my
configuration dropped from 500 lines to just 20.  It doubled since then to
about 50 lines but those new lines are mostly a convenience shortcuts -
not new fancy features.

So in the last half a year I've been practicing using quite clean vim for my
regular daily work without experiencing any loss in productivity.  On the
contrary.  With the cleaner setup I'm more focused and calmer.

So let's start with removing everything from my vimrc and launching a new
instance of vim.  I'm using graphical vim but it does not matter.  After years
on Windows I just prefer it and it cause less issues with terminal shortcuts in
terminal buffers in vim - which I do use a lot.

I will disable the GUI elements.
I'm not using them and they are just taking up space.

Let's start with opening files and managing buffers.
The thing that every new vim user starts with is installing a NerdTree plugin
to have a tree view of the project file structure.  After years of detox from
IDE's I no longer find that useful at all.  Ofc default vim has the file
explorer build in - which if you really want can be used to mimic the NerdTree
plugin functionalities and behaviour.  You can toggle the tree view and  have
it just like in an IDE.

When we start to learn programming we work on small projects and in those
the tree view works.  But on real life big commercial codebases they are very
slow and you will click yourself to death trying to navigate around and open
files.

So most people use fuzzy finders instead - and I did too - CtrlP and fzf to be
exact.  Until I encountered a project big enough that fuzzy finders were either
too slow, would completely hang or there were so many similarly named files
that the results of fuzzy finding were useless.

Then I discovered vim's starstar and CTRL-D shortcut.
When opening a file with the :Edit command you can at any point press CTRL-D to
get a preview of possible results.  Press TAB to autocomplete to one of them
and cycle through.  This turns the vim's command line in an interactive file
explorer.  You can used single star to match anything in the directory or
double star to search recursively.  If at any point Vim would take too long to
show you the list of possible files you can cancel the action with CTRL-C and
provide more precise path.

This is slightly slower than a fuzzy finder but it's WAY more precise.  Thanks
to the fact that you can narrow down the search path it works very well on huge
codebases.  It's great not only for searching for files but also for just
exploring the directories structure.

There is one useful thing that the build in Vim's file explorer gives you tho.
The gx shortcut - which will try to open the path under the cursor in the
default program.  I mostly use that for web URLs.

If you cycle through two or four the same files often then you can mark them.
Press m and any CAPITAL letter to mark the file.  Later you can jump to it by
pressing apostrophe and the selected letter.  You can see you marks with :marks
command.  This gives you similar functionality as the popular harpoon plugin.

After opening a bunch of files you will want to switch between them.
CTRL-O and CTRL-I are your friends for quick back and forth but typically you
want to go to a specific file by name.  fuzzy finders do that but I found that
build-in :b command is more than enough.  Again use CTRL-D to see the possible
results.  Combine that with a star and you can efficiently search and narrow
down the list of already opened files quickly and with ease.

Those two commands are the most often used ones so I do have shortcuts for
them.  With that and the knowledge about starstar, CTRL-D and TAB completion
I have no need for fuzzy finder plugins and this workflow is efficient on the
codebase of any size.

On the topic of shortcuts or mappings.  I used to have a lot of them.  One of
the pains of using the vim is the amount of typing it requires.  Doing
everything by keyboard has a lot of advantages (like being able to record your
actions with a macro) but it will wear you down on the longer sessions.
Emacse's CTRL based shortcuts look crazy to us but they DO require less effort
to type than the vim commands.  Turns out vim has a lot of these kind of
shortcuts too.

The CTRl-W shortcut is mainly for managing windows and splits.  But turns out
that there are CTR-W shortcuts for other stuff like: making a new file, opening
and switching between tabs, closing current file.

The other problem that people solve with custom shortcuts is the constant need
to press the Escape key.  To go back from INSERT mode to NORMAL mode people do
crazy stuff like mapping 'jk' keys sequence or long press of a space to act as
Escape.  They don't know that the simple CTRL-C does exactly that already.  It
took me just 10 years to find that in the help files and now I'm retraining my
muscle memory.  It works in both INSERT mode and COMMAND mode.

Let's change the topic to compiling / building projects.

A lot of space in my old vimrc configuration was taken up with shortcuts and
functions that automated that.  I always knew that Vim has a :make command
for that purpose.  But I hated the way it works.  It relies on the makeprg
setting.  Basically the :make command will run whatever command is set in
the makeprg and append to that any additional parameter.

If all of you compilation / build commands are the same then that's fine.  But
I work with many different technologies at the same time and having to
constantly change the makeprg setting was not productive.  There is also an
issue of having to wait for the command to finish but we will address that in
a minute.  Of course you can run any command you want with the :! command but
that will not populate the quickfix window with the compiler's output and you
won't be able to jump between errors.

I realized tho that what I can do is to set the makeprg to be an empty string.
That way I can run ANY command with the :make as if I would use Bang command
but it will populate the quickfix window.  With that trick I use :make to run
not only building commands but also grep to search through entire projects.

Vim does have dedicated :grep command with it's own grepprg setting but I don't
really have to use them since :make can do both now.  And the default make
errorformat - which determines which output lines are errors and allows you to
jump between the files - is better than the default grepformat.  And that's
important because your operating system's grep is not enough to work with huge
codebases.  Other reason is that normally Windows does not have grep but findstr
command which has a different output format.

What I use instead of grep on huge codebases is the git grep.  The version
control system does not have to read the file tree to search through the files.
It can do it in it's own cache and it's almost instantaneous.  I encourage You
to learn how to use it as in many use cases it can replace the slow and heavy
LSP functionalities.

You can easily repeat previous commands by typing a part of them and pressing
UP arrow.  You can also press CTRL-F in the command window to turn it into
a regular buffer that you can search through, edit and execute commands by
pressing ENTER.  I bet you didn't know that.  But it makes vim commands more
powerfull than those of Visual Studio Code or other modern editor because here
you can search through your previous commands and edit them with ease.
CTRL-F is very usefull.  Make sure to read about it in :help c_CTRl-F

When it comes to long running commands there are two options.

In newer Vim versions there is a builtin terminal.  Use :term command to open
a new terminal window.  This is not a dummy terminal but a fully functional one
at the level of xterm.  You can even run vim in here.  It's main advantage is
that you can start up any command and have it running on the side while you
edit your files.  You can even close this window and have it running in the
background.  Depending on the vim version every terminal buffer will have
a prefix before it's name which will make it easy to find all you terminal
buffers.  NeoVim uses term: as a prefix, regular vim has just a Bang but that's
enough.  The second advantage is that you can escape into the normal mode in
the terminal.  The shortcut for that is cumbersome and different on different
operating systems and vim versions so I've mapped it to ESC key.  Now you can
scroll, search and copy anything in here.  I often use gx command to open up an
URL from the terminal.  I read man pages like that and search through the logs.
It has it's quirks but it's way better then regular terminal and I used vim to
run all my terminal for more than two years now.

But it's not a fire and forget system.  Also jumping to errors from this
terminal is not that straight forward as in the quickfix window.  Ideally we
would like to run :make asynchronously.  Unfortunately as far as I know in the
default vim we can not do that.  Since it's 8th version Vim has a facilities
to run asynchronous jobs but it has to be integrated via a vimscript.
So that's one of two things that I use plugin for and it's called AsyncRun.

I don't use any plugin manager - just copy pasted it's files and now I can run
any command with :AsyncRun as with :make but it will run in the background.
I can stop it with :AsyncStop.  Preview output in quickfix window and jump
between errors if any were reported.

The other plugin I use is for LSP.  But I won't talk about that.
If you are using NeoVim it's build in anyway.  The only reason I have to rely
on it sometimes is the messy codebase at work.  I worked on huge codebases
before with just a grep so I know that the issue is not the scale of the project.

Besides not having  configuration and plugins maitenance burden I like how this
workflow allows me to work as effieciently from a tiny vim window as on a big
screen.  This made some part of my work easier when I have to see other windows
(browser, documents, chat) while I programm or search for something through the
codebase.

And that's it.

The main idea is to master the default vim's :edit and :buffers commands which
combined with :make and :terminal give you a complete system to do your work.
There are also way more sohrtcuts then you think and the one you need is
probably already there.  We tend to focus on vim-motions when learning vim and
many of us never learn the rest of the editor which forces us to have a ton of
configuration to make it like other IDEs.  But with a few ideas shifts we won't
need any of that.

Vim is a well though peace of software.  It's idea of how to do things is time
tested so we can learn a few things from it.

Thank you for listening.
Bye

The showcase

I apologize for the terrible sound quality in this one.
Unfortunately that's the best I can do with my current hardware.

Erratum

What I failed to mention in both videos is that when you remove all my personal settings all that's left is just:

set wildignorecase         " ignore case in file paths search :e **/*/
set makeprg=""             " empty so that any command can be run with :make
set hidden                 " dont ask to save unasved changes when closing window
tnoremap <Esc> <C-\><C-n>  " escape from terminal
noremap <C-p> :e 
noremap <C-l> :b 

As one can see You don't have to manage huge configurations and multiple plugins in order to effeciently use Vim. That's all you need and everything else is in the fingers.

reddit discussion