Recs.
Updated
Vim is a powerful, portable, keyboard based text editor. Being text-based, vim is lightning fast, with an incredible set of features developed over its multi decade existence.
SpecsUpdate
Pros
Pro Enables effective keyboard-driven editing due to its modal nature
Interaction with Vim is centered around several modes. Each mode has a different purpose and switching between them changes behaviour and keybindings. There are 12 modes in total (6 basic modes and 6 variations on basic modes) and 4 of them are used commonly.
Insert mode is for entering text. This mode most resembles traditional text entry in most editors.
Normal mode (the default) is entered by hitting ESC and converts all keybindings to center around movement within the file, search, pane selection, etc.
Command mode is entered by hitting ":" in Normal mode and allows you to execute vim commands and scripts similar in fashion to a shell.
Visual mode is for selecting lines, blocks, and characters of code.
Modes allow separating concerns between various tasks and reusing keys for different kinds of functionality. As a result, the workflow becomes more efficient.
Pro Ubiquity and portability
Vi/vim exists on almost all Unix-like platforms, it is the de-facto Unix editor, and is easily installed on Windows. All you need to make it work is a text-based connection, so it works well for remote machines with slow connections, or when you're too lazy to set up a VNC/Remote Desktop connection.
Pro Amazing extensibility
Vim uses a custom scripting language called VimL (or vimscript). It provides a rich scripting functionality to build upon the core of vim.
When combined with, for example, a plugin management system, it becomes easy to add support for syntax, debugging, build systems, git, and more.
Vim has thousands of plugins made by the community covering a wide range of languages, integrations and productivity enhancements.
Moreover, vim and neovim provide api with various popular programming language. This broadend its extensibility even further.
Pro Lightweight and fast
When compared to modern graphical editors like Atom and Brackets (which have underlying HTML5 engines, browsers, Node, etc.), Vim uses a sliver of the system's memory and it loads instantly, all the while delivering the same features. Vim is also faster than Emacs.
Pro Excellent performance
As it loads the whole file into RAM, replacing all string occurrences in 100 MB+ files is quick and easy. Every other editor has sort of died during that. It is extremely fast even for cold start. Vim is light-weight and very compact. In terminal, it only uses a small amount of memory and anytime you invoke Vim, it's extremely fast. It's immediate, so much so you can't even notice any time lag.
Pro Extremely portable
Vi/vim exists on almost all Unix-like platforms. It's the de-facto Unix editor and is easily installed on Windows. All you need to make it work is a text-based connection, so it works well for remote machines with slow connections, or when you're too lazy to set up a VNC/Remote Desktop connection.
Pro Has been supported for a long time and will be supported for many years to come
Pro Can never outgrow it
The fact that very few, if any, people claim to be a "Vim Master" is a testament to the breadth and depth of Vim. There is always something new to learn - a new, perhaps more efficient, way to use it. This prevents Vim from ever feeling stale. It's always fresh.
Pro Amazing productivity features
Vim's support of :s and :g commands helps users make complex changes to large files in seconds instead of hours.
Vim's keyset is mainly restricted to the alphanumeric keys and the escape key. This is an enduring relic of its teletype heritage, but has the effect of making most of Vim's functionality accessible without frequent awkward finger reaches.
Pro Useful undo features
Vim does not only offer unlimited undo levels, later releases support an undo tree. It eventually gives the editor VCS-like features. You can undo the current file to any point in the past, even if a change was already undone again. Another neat feature is persistent undo, which enables to undo changes after the file was closed and reopened again.
Pro Macros are highly predictable
Macros are sequences of instructions usually used to simplify common, repetitive tasks and increase productivity. Many text editors have programmable macros, but since vim is keyboard based, its programmed macros are usually far more predictable and easier to understand.
Pro Everything is mnemonic
No need to memorize different key combinations for things like deleting the text inside of a block or deleting the text inside of a pair of quotes. It's just a series of actions, or nouns and verbs, or however you prefer to think about it. If you want to delete, you select "d"; if you want it to happen inside something, you select "i"; and if you want the surrounding double-quotes, just select ". But if you were changing the text, or copying it, or anything else, you'd still use the same "i" and ". This makes it very easy to remember a large number of different extremely useful commands, without the effort it takes to remember all of the Emacs "magic incantations", for example.
Pro Has multiple distinct editing modes
Interaction with Vim is centered around several "modes", where purpose and keybindings differ in each.
Insert mode is for entering text. This mode most resembles traditional text entry in most editors.
Normal mode (the default) is entered by hitting ESC and converts all keybindings to center around movement within the file, search, pane selection, etc.
Command mode is entered by hitting ":" in Normal mode and allows you to execute Vim commands and scripts similar in fashion to a shell.
Visual mode is for selecting lines, blocks, and characters of code.
Those are the major modes, and several more exist depending on what one defines as a "mode" in Vim.
Pro Asynchronous I/O support
Since Vim 8, Vim can exchange characters with background processes asynchronously. This avoids the problem of the text editor getting stuck when a plugin that had to communicate with a server was running. Now plugins can send and receive data from external scripts without forcing Vim to freeze.
Pro Flexible feature-set
Vim allows users to include many features found in IDEs and competing editors, but does not force them all on the user. This not only helps keep it lighter in weight than a lot of other options, but it also helps ensure that some unused features will not get in the way.
Pro Productivity enhancing modal paradigm
As with all vi-like editors, Vim provides a modal paradigm for text editing and processing that provides a rich syntax and semantic model for composing succinct, powerful commands. While this requires some initial investment in learning how it works in order to take full advantage of its capabilities, it rewards the user well in the long run. This modal interface paradigm also lends itself surprisingly well to many other types of applications that can be controlled by vi-like keybindings, such as browsers, image viewers, media players, network clients (for email and other communication media), and window managers. Even shells (including zsh, tcsh, mksh, and bash, among others) come with vi-like keybinding features that can greatly enhance user comfort and efficiency when the user is familiar with the vi modal editing paradigm.
Pro Keyboard-based, mouse-free interface, and trackpad support
There's no need to reach for the mouse or the Ctrl/Alt buttons again. Everything is a mere key press or two away with almost 200 functions specifically for text editing. Vim does support the mouse, but it's designed so you don't have to use it for greater efficiency.
Versions of Vim, like gVim or MacVim, still allow you to use the mouse and familiar platform shortcuts. That can help ease the learning curve and you'll probably find you won't want to (or need to) use the mouse after a while.
Pro Donations and support to Vim.org helps children in Uganda through ICCF Holland
Cons
Con Poor feature discoverability
Though basic features like syntax checking, autocompletion, and file management are all available out of the box or with minimal configuration, this is not obvious to new users, who might get intimidated or assume they need to install complex plugins just so they can have this functionality. Other features new users might expect to find embedded in Vim, such as debugging, instead follow a UNIX-style model where they are called as external programs, the output of which might then be parsed by Vim so it can display results. Users not familiar with this paradigm will likely fault Vim for lacking those features as well.
Con Difficult learning curve
You'll spend a lot of time learning all the commands and modes supported in Vim. You'll then spend more time tuning settings to your needs. Although once it's tuned to your needs, you can take your .vimrc
to any machine you need and have the same experience across all your computers.
Con Poor package management out of the box
Out of the box package management in vim is (to put it lightly) bad. With the user being forced to download files and spread them out in folders inside their .vim
folder. But this can be easily fixed through the use of third-party package managers such as Vundle or Pathogen.
Update: Vim 8.0 has package management
Con Consume brain energy for editing that should be used for logic
Text editing in vim is awesome, but it requires thinking about combination of commands. In other editors, you don't have to think about how to delete this part of code. You just think about how to implement a feature, what is a good design for this code. Even after you get used to using vim, it still requires your brain for editing.
Con Difficult to write extensions for
Vim uses a custom scripting language, VimL, that is somewhat difficult to read and write. As part of data analysis on GitHub commit messages, vimL was found to have the highest percentage of commit messages with expressions of Anger. Almost double of that of the language that had the second highest precentage of expressions of Anger.
Con Doesn't play nice with the system cut/paste mechanisms
If compiled without -clipboard support (by default on MacOS). This can be worked around if you disable mouse for insert mode. You can then right-click your terminal and use paste like you would anywhere else in a terminal.
Con Poor support for external tooling
Many plugins depend on optional Python and Lua features, which may or may not be included in whatever binaries are available for your system. And without platform-specific hacks, it is difficult for plugins to operate in the background or use external tooling.
Con Requires Brain Mode Switching
When editing in vim, you have you use the vim keys; when editing in every other window on your PC, or in Word or Excel or other application, you need to use the standard system key combinations. Learning the Vim combinations can actually make you slower at everything else.
Recommendations
Comments
Flagged Pros + Cons
Pro VimL is a beautiful editor-centric langauge that is quintessential for heavy users
Vim is designed to edit plain text, and it is highly optimized to do that; however, sometimes one might want a little infrastructure to perform common routines. Surprisingly, VimL is an excellent candidate for this yet is perhaps one of the most under utilized aspects of vim.
Note that while the content herein is quite useful, many people prefer to forego creating and even installing plugins or not write any VimL so as to opt for a more minimal approach. They argue that if they ever need to be able to edit on someone else's computer or on an ssh session (etc), then it is useful, perhaps even more productive, to be extremely used to and familiar with nearly 100% vanilla vim. This may work for some people, but YOU, as the user, have the responsibility to choose what works best for YOU.
This PRO is also quite TL;DR, but having a quick read through just might pique your interest or get you over that little hump and make you just that much more productive in vim.
After one learns the basics of vim (operators, motions/text-objects, modes), there is still so much more to learn, but the beauty of vim is that once you can use vim, you already know a lot about VimL, since it is the language that runs within a vim session to be able to programmatically interact with the buffer and its contents as well as the vim session.
For example, when editing in code, one might want to add a semi-colon to the end of every line in a certain range and make this repeatable with the dot command. Those with a little vim experience might come up with one of the two following commands:
:'<,'>s/$/,/
:'<,'>norm! A,
Where first a range of lines is selected by pressing V
to enter visual mode (then maybe jjj
is typed to select an additional 3 lines below the first line, for example). Then, :
is typed to enter command mode. Vim will automagically put the '<,'>
which is the range that extends from the beginning to the end of the most recent visual selection. Finally, the commands that add a semi-colon at the end of the line are issued. These commands are applied to each line that was visually selected since a range is specified before each command.
If you understand either of these commands, then you are already quite familiar with VimL! This is because VimL is essentially the command-line or ex mode. Wrapping code like this in a function, then binding that to a command or a map, guarding against a few edge cases, and finally throwing that into a vim script or even just your vimrc can save a lot of time and be useful for years to come, since knowledge only builds on itself.
TUTORIAL
This tutorial will illustrate how to do exactly that which was just mentioned: create a command and map that call a function containing some VimL that will perform some useful--although in this case simple--task while also intelligently handling some edge cases. In this case, the example will build off of one of the simple commands from above in order to add a semi-colon but only to lines that aren't empty or only white space characters.
First, note that when vim is first launched, it loads vim files (all of which contain VimL) in a very particular order. Read more about that order in :help startup
.
For simplicity, one can put a vim script into ~/.vim/plugin/MyPlugin.vim (or ~/vimfiles/plugin/MyPlugin.vim on windows). There are a variety of other useful places to put such code (such as ~/.vim/autoload/ or ~/.vim/ftplugin/ or ~/.vim/indent/ or ~/.vim/after/ or ... etc, etc, etc), but the plugin directory gets loaded whenever vim is first starting up, and is always a safe place to put some functions and other functionality. It is important to be aware that this is loaded after the vimrc, however. Of course, one can source any vim file with :source path/to/MyFile.vim, and that stands for our plugin. To "reload" the file at any time, simply do :source ~/.vim/plugin/MyPlugin.vim
(or :source %
if you're editing the file in vim). Of course, the name doesn't have to be "MyPlugin"--one can name it whatever you want, but keep the ".vim" extension at the end.
The first step to creating the desired functionality is creating a function. This simply assigns a name to a bunch of "code", and in this case, the code is ex commands, or VimL! Here is what the function might look like:
function! s:AddSemicolon()
if (getline('.') !~# '^\s*$')
" if current line contains more than whitespace, add a ';' to end
normal! A;
endif
endfunction
The function
part at the beginning of the first line of the block creates a function (surprise!).
The exclamation mark following function
means that if this file is sourced again in the future, then the function should be re-evaluated and overwrite the old function. Otherwise, an error message appears, and the function remains unchanged.
Next, there is the name of the function: s:AddSemicolon()
. The name of the function is really just AddSemicolon
, but the prefixed s:
means that this function is only available to this script and this script only (unlike other programming languages, this is truly only accessible in this script, and can only be accessed via prefixing the function name--without the s:
prefix--with <sid>
, which stands for script id).
The empty parentheses indicate that this function takes no arguments (by the way, variables passed via the arguments list must be prefixed with a a:
; so, if function! Foo(bar)
is declared, then to access bar
, one really must use a:bar
).
Note that this function continues until the endfunction command is issued at the bottom of the block.
The contents of the function are quite simple yet worth covering:
getline('.')
returns the contents of current line. The results of that are checked with regex to make sure that the line is not just empty space. That is what getline('.') !~# '^\s*$'
does: if the current line where the cursor is only has spaces and/or tabs or is completely empty, then it is false (0); otherwise it is true (1) and the contents inside the if-block will be evaluated.
The line beginning with a double quote is a comment. Strangely enough, the line-wise comment character for VimL is one double quote (which is weird since it also denotes the start of a string).
Note the special, bash-like regex matching syntax of text !~ pattern
which is equivalent to !(text =~ pattern)
. The postfixed #
is to ensure that the text is matched exactly (it ignores case-insensitivity ... meaning that the match is case sensitive). Although this is completely unnecessary, many people almost always use it since it is good practice to do so. (Code responsibly!) :)
Finally, if the line is not empty, then normal! A;
will execute just that, and it will act as if the user has typed "A;" in order to go into insert mode at the end of the line and then typed a semi-colon, which is exactly the desired outcome. It is not possible to stay in insert mode after a :normal
command, so an <esc>
is not necessary.
Also, the !
that follows the command, normal
, is different than a !
following a function. When an exclamation mark follows a normal
command, it disregards any user mappings, which is often the desired effect when writing VimL. Read about this command at :help :normal
.
Here are the command and the normal-mode mapping that call the function:
command! -range -bar AddSemicolon <line1>,<line2>call <sid>AddSemicolon()
nnoremap <silent> <leader>; :call <sid>AddSemicolon()<cr>
The command
part creates a command (surpirse!).
After the above command is successfully created, typing :AddSemicolon
from normal mode and then pressing the Return
key will execute the function, since that's what it is made to do.
The exclamation mark in this instance serves the same purpose as for the function: if a command with this name already exists, silently overwrite it.
The -range
flag uses the current line as the range for this command unless it is otherwise specified just before your command. Read more about ranges with :help :range
and read more about the -range flag with :help :command-range
.
The second flag, -bar
allows us to place a '|' after this command so that we can chain multiple commands together with '|'. Read more about that at :help :command-bar
.
The next word is AddSemicolon
; since it follows command
and all of it's flags; this is the name of the command. It will now be possible to type :AddSemicolon
to execute the AddSemicolon()
function .
<line1>,<line2>
creates a range for this command to operate on, which you can read about again at :help :command-range
(then scroll down a little). This means it is possible to use something like vip:'<,'>AddSemicolon
(the '<,'>
gets added automatically : is typed from visual mode), and it will add a semi-colon to the end of all of the lines. One can also do something like 5:.,.+4AddSemicolon
to add semi-colons to this line and the following 4 lines (note that the range .,.+4
automatically gets inserted when you type 5: because vim is awesome :D)
The second line creates a normal mode mapping. The nnoremap
creates a mapping in normal mode that uses only all of the built-in mappings (it doesn't use any user-defined mappings, which contrasts the nmap
that does use user-defined mappings).
<silent>
doesn't echo anything when we run the mapping because it's distracting to me. If this is removed, it will spit out the contents of the map into the command-line area (in this case it will show call 123_AddSemicolon()
where 123
will be some random sequence of numeric chars representing the script id (<sid>
).
<leader>;
is what we will bind this mapping to. <leader>
by default is <bslash>
or the backslash key. Read about and how to change <leader> at :help mapleader
or :help <leader>
. A lot of people use ,
but that overwrites a useful built-in motion (:help ,
)
After indicating what keys should be mapped (in this case <leader>;
was mapped), the rest of the line consists of the expression that should be evaluated when these keys are pressed. (It is important to note that "<" is a very special character and will indicate the start of a special character [sequence]; if you want to insert a literal less-than character, use <lt>
). This is called the RHS (right-hand-side), while the keys that are mapped (<leader>;
) are the LHS (left-hand side).
:call <sid>AddSemicolon<cr>
, therefore, which will (a) open command mode with ':' (b) run <sid>AddSemicolon
(c) press Return
, since <cr>
is short for carriage return (if you don't put this, then you will be left in command mode.
Remember that <sid>
is the script id. In many cases, exposing a function only causes clutter, so <sid>
can be used to only expose the command and/or the map (both of which can access the script-wide variable with the <sid>
prefix as long as they reside in the same file).
This tutorial certainly does not baby anyone. The key take-away, it seems, is to RTFM in vim. Type :help
, press enter, and never stop reading. There are also plenty of online resources.
Also, this tutorial only explored some more simple topics. VimL is not the most efficient or straightforward programming language, but it can be very useful. Take advantage of it
CAVEAT
It can be a good waste of time, also, to learn VimL at work or even on your own time. Code responsibly! Do not learn VimL at the expense of being productive. Neither the author of this post nor slant nor any nyan cat will be held responsible for any VimL addictions or lost productivity.
Please sign here x_________________ and here x_________________
Thank you for signing your soul to The Beast: "VI VI VI" ~ Stallman
Pro Great productivity
Vim's keyset is mainly restricted to the alphanumeric keys and the escape key. This is an enduring relic of its teletype heritage, but has the effect of making most of Vim's functionality accessible without frequent awkward finger reaches.
Con Does not support multiple font-size
Though this doesn't matter if you only use vim for coding. But when you are using vim for writing an article or a TODO list, emacs-like font-size changing support could come in very handy. This feature is lacking in vim.