Editor Wars: The Revenge of Vim


Rarely on these pages have I read such a fluff piece! Al Williams’ coverage of Emacs versus Vim was an affront to the type of in-depth coverage our Hackaday readers deserve. While attempting to be “impartial” he gave a seven-sentence summary of Vim, the Ultimate Editor. Seven sentences! Steam is pouring out of my ears like Yosemite Sam.

yosemite+samAl, like a lot of you out there, thinks that he “knows how to use vi”. I’m here to tell you that he doesn’t. And unless you’ve spent the last few years alone in a cave high in the Himalayas, with only food, drink, a laptop, and Vim Golf, you probably don’t either. Heck, I don’t consider myself a Vim master, but I’m going to write this overwrought essay praising it (using Vim, naturally).

The reason I’m writing this is not to perpetuate the vi-versus-Emacs war. That idea is silly anyway, and was probably invented by Emacs folks to steal some of vi’s limelight. You see, vi-versus-Emacs is a red herring. Vi and Vim are so strange, so different from any other editor you might use, that it makes Emacs look simply boring in comparison: it’s just a normal editor with decent extensibility (if you can stand Lisp), horrible key combinations that may or may not cause carpal tunnel syndrome, and code bloat that rivals Microsoft Word. If you’re comfortable using Pico or Nano or Joe or Notepad++ or Gedit or Kate, or anything else for that matter, you can be comfortable using Emacs in a month or so. It’s really just another editor. Yawn.

Vi is something else. It’s a programming language for editing text that’s disguised as an editor. If you try to use it like a normal text editor, you will suffer. If you approach your text editing chores like factoring code into functions, you’re starting to understand Vi.

Modes and Movements

vim-shortcutsAs Al pointed out, vi and Vim (henceforth Vim, because it’s got some neat extras that I really miss in plain-old vi) use the concept of modes. There’s “insert mode” where you type text. In a normal editor, you’re always in insert mode. When editing in Vim, most of your time is spent in “normal mode” where your keystrokes are like commands, moving the cursor around, cutting, pasting, finding, replacing, crafting macros, changing one HTML tag to another, and generally editing. This distinction between typing and editing is central to Vim’s philosophy, and they’re fundamentally different activities.

When you start up Vim, it tells you to type :help and work through a tutorial telling you how to move the cursor around. You should go do that — that’s what it’s there for. It’s not going to make you a master, but you’re going to learn the basics. Do not go around saying that you “know how to use Vim” at this point. You’ll just look silly. You will know how to move the cursor around, cut and paste, and enter and edit text. In short, you’ll be editing like a monkey you would in Emacs.

Programming Text Editing

The real secret of Vim is that normal-mode usage is a language somewhere between a human language and a programming language. It’s got verbs, adjectives, and nouns (or functions, modifiers, and objects). Your job is to figure out how to express your text editing desires in terms of these, mostly single character, commands.

Let’s take c, the command that “changes” some text. By itself it does nothing — it needs an object. But if you type caw (“change a word”), the word under your cursor gets deleted and Vim enters insert mode, waiting for you to type the word’s replacement and hit Escape to go back to normal mode. If you want to change a whole sentence, cas deletes it and you’re typing anew. Want to change all arguments of a C function inside parentheses? ci) “changes inside parentheses”. (ca) deletes the entire thing, parentheses and all.) Numbers fit in as well. If you want to change the next five words, c5w does what you want. The syntax is modular and extensible. In this sense, it’s easy to learn.

the-shining-3_7-movie-clip-all-work-and-no-play-1980-hd-4lq_mju4qhwmp4-shot0001Cute trick. But here’s the punchline: .. Period repeats the last editing action as a whole unit. So if you just changed a word to “Hackaday” and returned to normal mode, cawHackaday<Esc>, and you have the cursor over another word, typing . turns it into “Hackaday” as well. Tossing a movement command into the mix, w will move the cursor to the start of the next word. Now, alternating . and w will change every word in your document to “Hackaday”. Using only two keys. Think about how much more efficiently Jack Nicholson could have appeared crazy in “The Shining” if he had Vim and the . command.

That doesn’t sound useful, but think about how many times you refactor code by changing all functions named “foo()” to “getFooInstantanceMethod()”. Of course there’s a “normal” search and replace functionality in Vim, but most of the time you don’t actually need it. Why? Because /foo searches for “foo” andcaw will then change the word under the cursor. And the search, being a movement, is repeatable with ;. Alternating ; and . becomes the same as a search and replace, only both the search and replace parts are (nearly) arbitrary editing actions. Instead of typing “y” and “n” to change or not change each match, you just hit ; until you get where you want to be, and then type ..

There’s so much to say on this topic that it’s the classic off-topic question at StackOverflow. The point of Vim is that text writing (in insert mode) is just typing and there’s not much that the editor can do for you there. Text editing, on the other hand (in normal mode), often consists of repetitive actions. Vim is built around treating these actions as single units and making it easy to repeat them and link them together. If you’re a programmer, this sounds a lot like the activity that we call programming — breaking a big task down into functions and running them. If you understand coding, you can learn to understand Vim.

Visual and Command Modes

There are actually a few more modes that you’ll want to know on your path to Vim mastery. Visual mode lets you select a region of text first and then apply a command to it second. It’s useful for one-offs, but visual-mode selections are hard to translate into generalizable functions, so I don’t use it as much as I used to when I was learning. There are some useful plugins that make good use of visual mode, however.

Command mode is where the real Vim heads geek out. It’s essentially ed, the ancient line editor. :17,25d deletes lines 17 through 25 without moving the cursor. :-3t. copies the line three above the current one. :v/foobar/s/thang/thing/g changes “thang” to “thing” in all lines of the document that don’t contain “foobar”. This is also where you can use all that regular expression juju you’ve got stored in your grey matter.

On the other hand, simple things like global search and replace, and deleting or copying whole lines are also simple on the command line. %s/one/two/gc changes all occurrences of “one” to “two”, with confirmation — your standard search and replace. (% specifies the whole document. You can use line-number ranges here too.) And of course there’s :e which opens a file for editing, and :wq which saves the current file and quits. You don’t need to know much of the command line mode commands, but a few are fantastically useful.

Registers and Macros

After a while, you’ll want to understand the registers. Vim stores text (or commands) in registers — like variables in a programming language. You can cut and paste into or out of the registers, and the first ten of them are essentially a cut buffer. The registers make a great place to store text that you’re cutting out now, but not sure that you want to throw away yet. "zdi} will delete all the code inside function brackets but save it in register “z”. You can paste it back at any time with "zp. Want to paste that thing you deleted five deletions ago? Type :reg to see all the registers and their values.

You can also record and play back series of Vim commands into the registers like macros; Vim commands are mostly just letters, after all. q starts and ends a macro recording, so qw will record a macro into register “w”. You can play it back later with @w. Macros are, of course, as powerful as the person writing them. (And yes, the registers plus the text buffer is Turing complete. Don’t go overboard.) I only use a few macros, but those that I do use, I use all the time.

For instance, here’s a macro I use a million times a day. I write Hackaday posts in Markdown and then compile them into HTML for posting. A link in Markdown looks like this: [link text](https://www.example.com). S]f]a(<Esc>"+pa)<Esc> surrounds the currently selected text in a “[]” pair, finds the closing “]”, adds an open parenthesis, leaves insert mode, pastes the contents of the clipboard, adds a closing parenthesis, and goes back to normal mode. (Yeah, that took me a while to get working.) But now, I copy a link in the browser, select text and type @l in Vim, and I’ve got a Markdown link to that website.

Plugins

Like any editor worth its bits, Vim is also incredibly extensible, and if there’s any feature that can’t be macroed, one can always write a plugin for it. In my opinion, Vimscript is even more unpleasant to write in than Lisp, so I leave extension writing to other folks. Someone’s written a module already for nearly everything you’d want anyway. But don’t go hog-wild with plugins in the beginning. You’ve already got your work cut out for you just learning Vim.

When you do succumb to install a bunch of plugins, my advice is to add them one at a time and use it until you understand each intimitely. Here’s what I run, in a reasonable order to install and learn them: vim-sensible, vim-airline, vim-abolish, ctrlp.vim, UltiSnips, vim-surround, vim-easy-align.

The Best Vim Commands

If you already use Vim, but don’t use the following commands to their fullest, you’re not living right.

  • I and A insert and append text to the front of the line or the end, respectively.
  •  m and “` set marks and jump back to them. This is invaluable for leaping around a long document with ease.
  • g; goes back to the location of the last edit. This is “pick up where I left off before going somewhere else”. It’s gold. But that’s not all — it keeps track of your edit history so that you can go back five edits ago. And g, moves you back forward in the edit history.
  • CTRL-] jumps to the location of the definition of the function under the cursor, and CTRL-t gets you back. Go as deep as you want — hitting CTRL-t until it doesn’t work anymore will get you back where you started. (You’ll need a tags file to make this work.) This is fully 1/2 of the value of an IDE like Eclipse for me, built in, with less screen clutter.
  • The other half of an IDE is tab-completion of long variable or function names. This is done in Vim with CTRL-n and CTRL-p to scroll up and down the possible list. If you are using a tags file, or if you have the file with the other definitions open in Vim, it will complete the name for you.
  • gg=G jumps to the top of the document (gg) and auto-indents it (=) until the end of the document (G). This makes all your open and close braces line up, and makes it very easy to spot the one that you forgot.
  • u undoes the last command. CTRL-r redoes. :earlier 2m reverts to the state that it was two minutes ago. If you end up undoing, editing, and then want to undo some previous changes, you can. g+ and g- will step up and down the undo tree. It gets complicated.
  • / and f, the search commands, are vital as a motion in a compound command. df, deletes everything up to the first comma. d/foo lets you delete until the first (interactive) match on “foo”. This can replace many other movements if you’re so inclined.
  • :r reads in a file. :! runs a command in the shell. :r! pastes the output of a command into your document. :r!ls whatever* is often faster than typing in a filename. I’m not going to get started on how UNIXy the ability to run your text through arbitrary shell scripts is.

Vi Everywhere!

Once you get used to Vim’s movement commands, you’re pretty much spoiled forever. You can of course use the mouse, but when you get good, you’ll only do so rarely. It’s so much faster to keep your hands on the keys. Most every hardcore Vim user remaps the Escape key (which returns to normal mode) to something convenient. Mine is where Caps Lock used to be, right under my left pinkie. (I actually multiplex it with Control using xcape.) Yeah, that’s extreme, but it’s so much better than what people do to avoid getting carpal tunnel from Emacs which was designed to work on a keyboard that doesn’t really exist anymore.

If you use Bash shell on a Unix, set -o vi will make readline behave almost like vi. Your browser can be Vimmified: Vimperator and Pentadactyl for Firefox or cVim, vimium, and ViChrome for Chrome should do the trick. If you want to go all-out, qutebrowser is the best native Vim-style browser out there at the moment, and it’s going to get much better soon.

Search “vi keybindings” and you’ll find that they’re supported in everything from Visual Studio to Eclipse to Emacs. Why does Emacs have a Vi-emulation mode, but Vim doesn’t have an Emacs emulation mode? Think about that for a while, and you’ll realize that the editor wars have been won.

Getting used to Vim takes a while. Getting really good takes a programmer’s mindset and some active practice. I used Emacs from 1994 to 2011 for code, my dissertation, overheads for classes I taught, and academic papers. Since 2011, I’ve used Vim for yet more code, a book, e-mail, and all my writing for Hackaday. I can still improve, and I add new tricks to my repertoire monthly despite five years of using it for six to eight hours per day. Vim is deep, like anything that’s really worth diving into, but it’s rewarding because there’s always more. Don’t believe anyone who tells you that they “know” Vim. :wq.

Resources

There’s really too much to say about Vim. Here’s a short list of great resources:



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *