To Master Vim, Use It Like Language
danielmiessler.com
danielmiessler.com
Mastering Vim means going beyond vanilla movements and learning all of Vim's nasty warts to replace good GUI features. It means learning the wonky, dead Vimscript language. It means knowing how to use the arcane arglist. It means knowing how to go into insert-normal mode, and when to use the expression register. It means knowing everything about very magic search, and why default search is poorly designed. These are all randomly chosen examples, because mastering Vim involves mentally juggling a very large playbook of oddball features to complete editing tasks.
The main resources to help you master Vim are the book "Practical Vim" by Drew Neil, and if you're ever in the unfortunate position of needing to write or edit a Vim plugin, "Learn Vimscript the Hard Way" is invaluable http://learnvimscriptthehardway.stevelosh.com/
Vim - precision editing at the speed of thought
The irony in your comment is that I recommend Drew's book in the primer, and Drew has recommended this primer as well.
Maybe they're both good ways to learn Vim.
For one thing, not all of the things you said must be mastered, vim is plenty big enough to support various ways of working. E.g. I never use the arglist.
For another, from a pedagogical perspective, there's different levels of "mastery", and there's nothing worse we can do to scare off people trying to learn a new editor than to tell them "oh, no, to be considered a real master you need to put in months of learning".
* find/replace/regexes
* registers and macros
* vim settings (spell, list, highlight, number, wrap)
* the plugin ecosystem
* editing multiple files simultaneously (splits, buffers, moving between them)
* folds
Anyone else want to chime in with stuff I've either forgotten or don't know I don't know?
Tag files would be another good one.
So while I agree with you in that they aren't a part of my typical workflow, they are a piece of vim that I'm glad I familiarized myself with.
Everyone uses tag files, in some sense, when they use :help :)
How to enable it: use "set foldmethod=syntax" (with C++) or "set foldmethod=indent" (with JS, where "syntax" doesn't work for me). Also, I use "set foldminlines=0" so that 1-line paragraphs get closed as well (it looks more consistent).
How to use it: close all folds "zM" (I remember it because the M is shaped like it's all folded on itself). Open all folds "zR". Open one fold "zo", close one fold "zc". Open one fold recursively "zO", close one fold recursively "zC".
By the way, I almost never use manual folds, so "zf" is almost useless to me.
FWIW, I map <Space> to za, so that I can unfold/refold quickly. I also map - to zx to quickly fold up a file I may have drilled some holes in.
Vimcasts (http://vimcasts.org/) has some good tutorials. Vimgolf (http://vimgolf.com/) also has some good exercises.
https://github.com/rking/ag.vim https://github.com/kien/ctrlp.vim
Save me so much time opening files and finding matches+open-at-match
HN thread: https://news.ycombinator.com/item?id=2911930
For example - '%' matches parentheses and braces. So if you want to delete a block of code, you could go to the opening (or closing) brace, and do "d%". If you wanted to indent only that block of code, you'd do "=%". In this context, ":help motion.txt" makes for a good read.
Apart from this, I'd also recommend listing down things about your current workflow that you find irritating, and trying to find solutions for them in vim.
For instance - I wanted to be able to browse through cscope matches in a regular vim buffer than the ridiculous less-like interface that's the default. I found quickfix, which solved my problem neatly. I then wanted to open each match in a vertical split, rather than in the same window - I ended up writing a little bit of vimscript and a keybinding for this.
Sometimes, when going through a gazillion cscope matches, I find it convenient to hide stuff that isn't relevant - I use (manual) folds for this purpose.
then, code in vim. at every pain point ask "is there some faster/easier way to do this?" sometimes you'll find something that seems great, then never use it again. other times, you'll relieve a recurring pain point and at the same time incorporate expanded facility with vim. after awhile, you'll pretty naturally start messing with vimscript as well.
in other words, i think videos and tutorials of "look at how powerful vim is in this situation!" can only go so far, at least until you've really expanded your horizons through practical use and need.
edit: the earlier advice in responses to you (some of which i basically just repeated) is good too. mine could be distilled into a sentence: "learn vim by coding in it, but allowing time for 'how could i do this better?'" on the one hand, just do your normal work. on the other hand, don't stay satisfied with being "good enough" at vim to do your normal work. that's where the learning curve is, and after you do that artificial thing (overdoing "can i make this easier?") it quickly becomes natural.
exactly why I use Vim this way. On DEC VT-100 terminals this was the only way you could work and I must say I sometimes cheat and add the necessary bash commands to make it work on my console.
Step 1: Start using it in your work.
Step 2: Find out something that bothers you. E.g., something you miss from another editor, or some kind of movement that you make a lot and would really love to automate.
Step 2': Very important for Step 2 - you have to really hate doing anything repetitive or annoying. With time you'll get a feel for what is easy to find a solution for.
Step 3: Figure out how to solve that specific problem.
Later on, you may do what other people say and look around for videos of other people using vim, look at plugins, etc. I only started doing that after I got much "better" at vim.
Just a quick example: I was editing a lot of css files, which always have lines like:
.some-rule { sometext: 234px; }
And every time, I'd want to change the number (e.g. change 234px to 200px).
If I used the "standard" vim toolset, I could just jump to the number 2, then do "change word", but then I'd have to retype the "px" every single time, and this annoyed me. Now, there are plenty of ways of dealing with this problem, but I knew about something called text objects, and decided to investigate the idea further, and soon found a plugin that makes numbers a text object.
The end result is that I now have mappings to "jump to the first number in the line" and to "change a number", so my flow is much simpler.
This is a small annoyance thing, but let me investigate the whole topic of text objects, creating custom mappings, etc. And, it solved an actual problem I had.
Oh, and mappings/macros are awesome in cases were you want solve specific problems in less moves. I use macros to test out my ideas. I sometimes then make them a mapping. That isn't often, but when I do that, it's because they are general and needed enough.
Shameless plug: I wrote a plugin (https://github.com/unblevable/quick-scope) that facilitates the use of "f" and family that even beginners can take advantage of.
I like using yap and dap to copy/move paragraphs around when I'm editing markdown text.
Of course it's not Vim's fault that the standards established by vi were not taken up by the early GUI systems, but I wish there was a better way to deal with this problem than a figurative grizzled old console cowboy going "suck it up, n00b, it builds character." I'm aware that people have made command sets that make Vim and the *nix console in general more GUI-standards-friendly, but these are never presented to actual CLI newbies, so by the time you're aware of them you've done half the work already...
Cream[0] is a configuration for Vim that makes it work in a way more familiar to people used to Word and other traditional Windows GUI programs.
Using two keystrokes instead of ESC to leave insert mode is definitely a personal preference and not necessarily more efficient or comfortable.
Also, while in insert mode, using ctrl-h for backspace and ctrl-w for delete word are really nice.
In any case, I prefer ^[ to ^C, and hopefully you will too!
Edit now that I have actually looked at the article: Yes, you can map it to Control but for me it's an awkward place to put a modifier. What if you want to do Ctrl-A? Ctrl-C? At least the way I type, I'm better off using the one in the corner.
* When I tap Caps, it's `<esc>`
* When I hold Caps OR hit it in combination with any other key, it's `<ctrl>`
It really feels like the best of both worlds. I primarily develop on OSX, so I use https://pqrs.org/osx/karabiner/ to handle the remapping.* I have to quickly explain something on my colleagues machine. * A colleague wants to show me something on my machine.
The `<esc>` is, I daresay, one of the most ingrained keys when operating a computer. When you keep mistyping it, levels of stress will go up.
The efficiency doesn't come from the fact that it's not as far to reach. The efficiency comes from the fact that you don't have to find home row with your left hand again and can continue your command sequence immediately.
Bill Joy, regarding vi: "It's like one of those pinatas--things that have candy inside but has layer after layer of paper mache on top. It doesn't really have a unified concept. I think if I were going to go back--I wouldn't go back, but start over again."
Hunter S. Thompson, on an unrelated topic: "That was the fatal flaw [...] the desperate assumption that somebody--or at least some force--is tending the Light at the end of the tunnel."
I think vim is a useful tool. It's available on most systems and is powerful. But trying to grok it and appreciate its UI isn't really something I want to do.
The time lost in that 10% is totally worth the cost of the time saved in the 90%.
And since everyone uses their text editors differently, it's not practical to move any one individual's personal configuration choice into vim core.
A few additional things that have saved me keystrokes...
replace mode (R)
insert normal mode (<c-o>)
paste from a register in insert mode (<c-r>reg)
expression register (=)
clipboard and active selection registers (+, * respectively)
command ranges (e.g. 10,+5s/foo/bar/g)
miscellaneous commands (:global, :argdo, :normal, etc...)
This article is so logically laid out I think anyone could get to at least Level 3 with the article and a few hours diligent practice. Level 4 would then beckon....
When I became a serious sed - and then ed - user, I became a much better (faster, more productive) vi/vim user when I didn't need to be in visual mode all the time.
http://code.tutsplus.com/tutorials/vim-essential-plugin-easy...
Been a while since I used emacs, ctrl-everything is an emacs idiom [0] and a pinky killer. I guess the best bit is it's configurable. Really like this tute Daniel, found a nice add for my .vimrc already.
I don't agree that it should be the only thing one uses for all development/writing tasks.
Yes, vim is ubiquitous. However, no one uses vim without high levels of customization. So i think there is a bigger dependency issue here.
Also, I've seen millennials struggling to cope with vim - it's like handing a cassette to a person who's grown up with an iPod.
As long as the work gets done, an editor does not matter.
This time around I've been keeping a list of the stuff I miss from my usual workflow. Here's two of the most maddening:
1. Searching for literal text. Is there a way to avoid having to manually escape special characters?
2. Maintaining cursor position when scrolling. Maybe I want to go look at another part of the file and come back. How can I scroll without it moving my cursor?
As far as I can tell, I'm SOL on both counts.
2. C-e and C-y as long as the cursor position doesn't move out of the visible area
If you want to go back and forth, you can set two marks.
Put "set nomagic" in your .vimrc. This makes e.g. "." match a literal period/full-stop rather than any character. To get the special behaviour, escape the character: e.g., in nomagic mode, "\." matches any single character.
If you only want this behaviour occasionally, putting "\M" at the start of your search will invoke it for that search only: e.g. "/\Mfull.stops.only" will match "full.stops.only" but not "full-stops:only".
Even in nomagic mode, a few characters are treated specially, e.g. "$" for end of line. To suppress even these, start your search "\V": e.g., "/\V$1000". N.B., you can't make this behaviour permanent in your .vimrc: you can only invoke it search by search.
If you want the full gory details for all of the above, try ":help pattern" in Vim.
Edit: spelling
Vi(m) is a model, not an implementation. I wish people would stop handicapping themselves with very bad implementations. Intellij, Visual Studio (Resharper) understands the languages your working in. Let the machine do what it does best and aid you in the language while you concentrate on domain.
I think you are talking about modal editing, vi is an application, vim is another application.
The point I was trying to make (which irked somebody) is that the modal vi keybindings in modern IDEs is more important than Vi(m) itself.
Also, Minority Report.
That said, of course I use a web browser for 99% of my Internet actions. But being able to Alt-Tab into the terminal and run wget to quickly pull down a list of files may feel like 1970s-era, but it's still a powerful technique today, and for as long as users need to do things beyond what designers intended them to.
Text-interfaces work well because they restrict input to precise parameters, however as interfaces become "smarter" and are able to capture the meaning of imprecise interfaces such as hand gestures and interpret them precisely without requiring the user to deliver them with robotic precision, interfaces will become more expressive, we will be able to work more naturally in the domain in which we think, which is, these physical three dimensions.
If you've ever watched a mathematics professor write on the chalk board you'll know what I mean. So expressive. So much conveyed with so few markings. And yet, very sloppy. But still. Reading it off the board, those symbols just feel so much better in your head than any words would.
No, vim is an editor, not a model (whatever that means) and definitely not an IDE. These are very different things.
I use vim to edit all sorts of text (including for instance this text box, using It'sAllText[1] ). Why would I use an IDE for that ? That'd be silly now, wouldn't it ? ...and at least for me, once I got used to using vim, I didn't see how the IDE could better '...aid you in the launguage ...' than vim itself.
[1] https://addons.mozilla.org/en-US/firefox/addon/its-all-text/
Great post.
I'm not really a fan of what passes as IDEs, either, but I generally am not attached to any particular editor and hop around them.
(The right answer to vi vs. emacs is, of course, Acme.)
Even if you agree with vim's approach to modal editing and object motions, there is plenty bad to be said about it in light of some of the tools we have available to us today. But humble origins do not always lead on to humble ends. There is no use in calling a book bad and giving as your reason that it was once pulp. It would be just as unhelpful to call the Lisps of today slow, and to use as your crutch the old adage that "LISP programmers know the value of everything and the cost of nothing."[1] As GP said, "There's been some progress since the 1970s."
[1] https://en.wikiquote.org/wiki/Alan_Perlis#Epigrams_on_Progra...
Incidentally, there is nothing inherently wrong with 1970's user interfaces. My car still has a steering wheel just like cars did in the 1970's. And there is a reason for that. Because it works really well.
First, efficiency of bandwidth over an ssh connection. You might think, "Oh but there is tons of bandwidth on the internet today". However, I actually use vim to pair program with people in the UK while I'm in Japan. Vi commands can easily deal with variable latency and still give good performance because you are almost always in command mode. Instead of arrowing down to some character, I simply tell the editor where I want it to go using a language with a grammar. I have very happily coded all day with 300+ ms latency in Vim. For me this is a killer feature that is painful with any other input system. (vi is even better at this because it reduces the number of repaints to a bare minimum).
The second feature is very much related to the first - the use of a grammar for describing what you want the editor to do. With most editors, you press a key and it does something small and specific. With vi/vim you describe things that you want the editor to do with sentences.
This is a great example of the difference between ease of use and ease of learning. vi/vim is very difficult to learn well (or at least it takes a lot of time and practice). But it is arguably much easier to use once you have that learning. It's like the difference between "Pick up glass. Drink beer." and "Move hand. Move hand. Move hand. Grab glass. Lift glass. Move hand. Move hand. Move hand. Tilt glass. Drink beer".
Sure, it's not for everyone, but it's clearly not reasonable to say that the state of the art has improved in these respects. I can think of no other editor that even attempts to solve these problems. If you know of some, I'd be happy to learn of them.
One thing I used to do is visit http://www.vimgolf.com/ and compete with the best solutions there. Aside from a higher usage of meta characters (which is a modal vs. quasimodal thing, rather than a sentence vs. select thing), my editor of choice (Sublime Text) rarely lost out.
There is the caveat that some things that are great for golfing are relatively useless elsewhere (eg. numeric modifiers) and vice-versa (command panel: trim trailing spaces). I miss the later in vim much more than I miss the former in typical editors... although I still hacked it into Sublime anyway.
Probably my example was a bit poor. I wasn't trying necessarily make the argument that Vim is more keystroke efficient than other editors. I used Emacs for 20 years before I switched to Vim and I was quite efficient with it. I was more trying to convey the idea that the way of thinking was different. Instead of concentrating on the immediate motion of the cursor, I'm concentrating on the structure of the document.
Lately I've been thinking it would be nice if someone were to think a bit more about extending the state of the art in modal editors. Vim was a nice extension of vi, but the grammar is still pretty crufty in a lot of places. It would be cool to rethink it from scratch, I think.
In what way does the multiple selection model not concentrate equally on the structure of the document? It's true that vim has a larger vocabulary than a typical editor, but its grammar is actually weaker. For example, I know of no way to combine two arbitrary motions.
Consider the case where you want to delete all strings containing the word die, where the string grammar is non-trivial. In a selection-based language you can
* select-all-"die", manually checking that they're inside strings
* select-enclosing-block
* delete
If one had a language-aware string token finder (and, frankly, a token-aware editor would be amazing - maybe I should edit Sublime to do that...), one could even
* select-all-string-tokens
* select-all-"die" inside selection
* select-enclosing-block
* delete
This is a very structural approach. I don't know a neat way of doing this with vim. (I'd be happy to learn I'm wrong!) There are other examples, like where one wants to work on some collection of things in lockstep and vim's inability to hold state through selections between commands results in a difficult workflow. The multiple selection model remains semantically unperturbed.
I would very much be interested in a modal editor that doesn't just try to copy vim - working on multiple selections with a large vocabulary and syntax-awareness would be wonderful. I also find some things, like temporarily restricting actions to a subset of selections, needlessly hard in Sublime. There's a lot that can be done!
Speaking of token aware editing, smalltalk had an AST aware "editor" called a "refactoring browser". It could even infer the type of a variable by running tests and seeing what type the variable held in the running code. This is where you can get some crazy utility happening with automatic refactoring. Unfortunately most languages these days are needlessly complicated to parse (ahem... ruby).
I am toying with the idea of writing an Evil like mode in Emacs that gives the utility of vim, but without some of the cruft from vi. I think Emacs is a good platform to do it in since it gives you a lot for free (especially a nice lisp interpreter to implement features in ;-) ). However, I have far too many things on the go as it stands :-(