Vim anti-patterns
blog.sanctum.geek.nz
blog.sanctum.geek.nz
I have been a vim power user for a little over 2 years now. I never bothered installing plugins and spent all my time instead learning ... the exact same commands described in the article. Now I type fast, I mean real fast.
A couple more tips I find useful:
- 'gg' and 'G' in command mode will send you to the beginning and the ending of the file.
- 'Ctrl-N' and 'Ctrl-P' in insert mode will auto-complete (suggestions only come from existing words in opened buffers, for more you'd probably need plugins).
All the other tips are _spot on_! I especially like the first one about moving vertically one line at a time. It takes some time getting used to, but the fact that you can repeat the 'jump' or jump back to your previous position. Believe me, you'll fly :)
My new set of advice for blazing fast typing:
1. Learn to touch type. The rest is meaningless without this.
2. Repeat 'vimtutor' religiously for 10-15 days.
3. Read this post and apply every tip until it's hard-written in your fingers' muscle memory.
4. ... voila!
http://yanpritzker.com/2011/12/16/learn-to-speak-vim-verbs-n...
This wisdom should be shared with everyone learning vi/vim, since this leads directly to the largest payoff.
I've never maintained my own .vimrc, or know what plugins I have installed or not, btw.
But it seems that a lot of people new to vim get distracted by plugins, tweaking their config, et al, when they could be learning the "vi way" to get their actual code editing productivity.
Check out PreciseJump and EasyMotion:
http://www.vim.org/scripts/script.php?script_id=3437
http://www.vim.org/scripts/script.php?script_id=3526
(watch the animated gif demos on those pages and be amazed!)
MRU is really useful for navigating the most recently opened files:
http://www.vim.org/scripts/script.php?script_id=521
xptemplate is an awesome, very advanced snippet plugin:
http://www.vim.org/scripts/script.php?script_id=2611
NerdCommenter, for easy commenting/uncommenting blocks of code:
http://www.vim.org/scripts/script.php?script_id=1218
And, of course, before you install any plugin, you should do yourself a favor and install and use Pathogen, or something like it:
http://www.vim.org/scripts/script.php?script_id=2332
For me, these are some of the most essential plugins that I use every day. Some other good ones are tabular, renumber, stripansi, matchit, and surround.
I've always used ':1' for the beginning and ':$' for the end. To me, the benefit of this is that I always use the same mechanism to go to a particular line of a file. (I often do, say, ':45' if an error is reported at line 45.)
For moving up and down large distances, I also prefer ctrl+u for up and ctrl+d for down. There is a minor difference: ctrl+f will put the last line at the top of the screen, filling the rest with the tilde-abyss. That always bothers me.
If I want to select the entire contents of the file, hitting "v" then ":1" seems not to work.
Example: :ma <-- sets a marker at the current cursor location named 'a'
later on, you can go back to this exact place by typing "a (that is quote followed by letter 'a' - the marker you named.
Note that you can have as many markers as you want.
You don't even need the leading colon, just ma while in normal-mode.
tl;dr - arrow keys vs hjkl makes little productivity difference to an experienced vim user (unless of course, you've baked hjkl into your workflow, but remember that the reverse is true as well)
edit: I also find it productive to have one mental model for cursor movement as well as selecting splits or tmux panes.
OR
<up>
I prefer a single key to four, even if I have to move my hand off the home-row.
Once you're outside of insert mode, you have a ton of options for moving around very quickly and efficiently. You are crippling yourself by using the arrow keys to move character by character or line by line instead of going out of insert mode, not to mention the time you waste moving your entire hand to the arrow keys and back.
That said, if you really feel you absolutely must move in insert mode, may I suggest mapping:
control-h
control-j
control-k
control-l
to move while in insert mode, instead of using the arrow keys. That way your hands can remain on the home row, and you'll continue to use the familiar keys to move around. (As for hitting the control key itself, I like to do that with the part of my palm that's right below my little finger, so I don't have to move my fingers from the home row -- it also makes for virtually no finger strain, compared to using your fingers to hit it).But you should really try to wean yourself off the bad habit of moving in insert mode.
Also btw, Control-h,j,k,l I have mapped to switch windows.
That's just dogmatism for the sake of it. There are certainly cases where it takes less finger movement to use arrow key movement (either by character or by word) in insert mode than it would take with switching to normal mode and doing hjkl movement.
My favorite tricks: o in select mode, ctrl-y in insert mode.
Still looking for a good commenter for python (NERD commenter don't work for me)
There are also two-finger, hunt-and-peck typists who've been typing for 30 years.
Just because you've been doing something one way for a long time doesn't mean it's a good idea.
(in insert mode)
^O t x
(still in insert mode, and the cursor has navigated to right before the next 'x' character) ^O 4 4 G
(still in insert mode, now on line 44)I'll bet more experienced vimers could learn something from this, too.
You might also be interested in http://stackoverflow.com/questions/2588481/are-there-any-kat...
$ vimtutor is great. Do it a few times until you don't need to read it. It's not really game-y but it's quite challenging when you come from TextMate world.
Also there is a site called http://openvim.com that works more or less like what you describe. I hate it, though. I can't bear the tone and the forced jokes and it's nowhere near as well thought out as $vimtutor.
Others have pointed at vimgolf.
One of the cool things about Vim is that you always learn new tricks.
I've learned a lot that way, and still do every day.
text-objects are basically things Vim knows about that you can operate on with the "verbs" of vim (d/c/y etc). So, for example, if you're inside quotes, you can yank everything inside the quotes with yi" (to include the quotes, you use ya"), regardless of where the cursor is inside the quotes.
For more information see :h text-objects
That's not an "anti-pattern," that's an opinion. I think C-[ is uncomfortable as hell.
I greatly prefer this setup. I never used Caps before and now I have a useful key in a useful position.
If you're really down with keyboard remapping, though, go for putting the Escape key somewhere closer. I learned a Sun keyboard in grad school, which put Esc where PCs have backquote/tilde, and I've remapped every keyboard I use regularly to this arrangement. (I also swap backslash and backspace for roughly the same reason.)
If you are too dependent on visual feedback while typing, you'll have a difficult time typing fast in any environment.
That said, I don't think I'd ever try remapping escape. I have long fingers though.
I once read a thread discussing the topic of Esc replacements and was astounded to learn that some people had reinvented chording: they mapped all the permutations of h,j, and k into Esc replacements and then simply banged all three at the same time to exit!
It would take much more effort for me to retrain myself to use control-[ or some other key than to keep using escape.
On the other hand, if I was just starting out, I might consider remapping jj or jk to escape.
I've already mapped the space bar to : but I keep forgetting to use it. It's all muscle memory at this point, and a bother to retrain it.
The most most useful Vim trick I've seen recently is "set relativenumber". This makes Vim show line numbers relative to the current line. This is awesome, because it lets you easily jump to any line you can see. eg. you can get to a line marked "9" above the cursor by pressing "9k".
It can be slightly tricky to get used to if you're used to absolute numbers (have to use gg more), but for me it's worth it.
[1] http://jeffkreeftmeijer.com/2012/relative-line-numbers-in-vi...
I swear the entire UI of Vim is made to make the user feel like a ninja.
* Learn to touch-type
* Learn new features slowly, giving each of them time to find their place in your workflow.
My questions for other vim power users:
* What _epic_ custom mappings do you have? Steve Losh's <Leader>ev for editing .vimrc and <Leader>sv for sourcing completely changed how I use and customize vim... are the any others with that level of impact?
* How have you mapped control of buffers/windows/tabs? Command-T buffer mode takes care of open buffers, and the default window/tab control mappings seem good enough for me, but I'm wondering if there's a nicer way for this interaction to work. Currently I've got arrow keys mapped to moving tab focus, but it feels like their might be a better way here.
* Are there any fun and creative ways you've integrated with the shell/plugins? Here are some examples I've got:
<Leader>r :!rake
<Leader>rs :!rake spec
<Leader>rl :!rake spec (test near this line)
<Leader>gs :GStatus (fugitives 'git status')
<Leader>gb :GBlame (fugutives 'git blame')
* What's a nice way to do find in project? Both vimgrep and :Ggrep are OK, but I find it weird that I'm taken out of the editor for both of those... Ideally I'd like the results to open up in a buffer which I can then browse through in some nice way.
nnoremap <Space> @q
It dramatically lowers the mental barrier to macro use (at least when you're starting out with macros). Where I use to use ragex search and replace I now instinctively go for macros, and I'm getting good at choosing the most robust commands for the situation. The pattern of qq => /foo => cwbar => Esc => Space-Space-Space is incredible. It's so infinitely superior to regex search and replace, and the fact that you can paste the macro and modify it as text is the cherry on top.
Also, staying as close as possible to the default settings makes it a lot easier to move to other environments and/or upgrade. Although now that I have my .vimrc in my Dropbox it doesn't matter as much as it used to.
" Buffers ***
nnoremap <F1> :ls<CR>
nnoremap \1 :b 1<CR>
nnoremap \2 :b 2<CR>
nnoremap \3 :b 3<CR>
nnoremap \4 :b 4<CR>
nnoremap \5 :b 5<CR>
nnoremap \6 :b 6<CR>
nnoremap \7 :b 7<CR>
nnoremap \8 :b 8<CR>
nnoremap \9 :b 9<CR>
nnoremap \\ :b #<CR>* remap jj to ESC: imap jj <Esc>
* align on "=>" with (Tabular plugin): nmap <Leader>t> :Tabularize /=>\zs<CR>
* for project-wide search (and replace), I recommend EasyGrep plugin ([1] see options)
[1] https://github.com/sohooo/vimfiles/blob/master/vimrc#L384
Increment a number on or after the cursor with Ctrl-A and decrement with Ctrl-X in normal mode. Saves a few keystrokes over having to replace or enter insert mode.
This gets scary useful when you use tpope's speeddating plugin.
set nrformats-=octal
to your .vimrc.If there is only one a '%' will bring to foreground the last job, otherwise you can do 'fg x' where 'x' is the job number.
One nice thing about this setup is you can "stack" processes in the shell.
Say you're working on file_x, but file_x depends on header_file_y and file_z. file_x makes sense on its own, so you don't want to split a new pane; you just want to leave your workspace as it is and come back to it later.
Hit ctrl-z, and fire up vim with the new stuff you want. When you're done, quit the current vim session and come back to your old context with `fg`.
The key observation is this stacks inductively, so you cant tumble down the dependency rabbit hole and always come back to the context you were at originally. This feature alone has made it impossible to ever leave console vi.
It really came in handy in my Operating Systems class where I could fly around the codebase an order or magnitude faster than everyone else.
If you really need to go back to a particular context %[num] lets you go back to the nth suspended process, but this will corrupt your stack of processes, so `fg` won't be in a clean order.
Losing access all your editing state when you move to a new file is silly, regardless of editor.
But I also use ctrl+z frequently, even more when I'm editing over ssh. Usually because I want to do something outside of the editor window not directly related to editing. Or it might be related to editing, it depends, I just want a shell. I may even have forgotten which file contains what I want to edit, so I might back out to a shell and use a find|xargs grep or ack command. Basically any time gedit users open the terminal for something in the middle of editing, I just ctrl+z (or open a new shell tab, but as mentioned ctrl+z is joy on ssh where a new tab means a new connection).
So I use ctrl+z. Also :!bash is stupid, but :r!cmd should be on the page. (It pastes the output of cmd into the file.)
And yeah, you can do every shell action in vim with things like :make and so on and :! when a nice wrapper isn't pre-made, but at that point it starts to feels a little too emacs-y for me in a lot of places and again, frequently I ctrl+z for things orthogonal to what I was working on. Sometimes I do use those wrappers, of course, but it's unnatural in many cases and I think it's of questionable utility compared to mastering the command line normally or compared to other vim features. Linux is my IDE, vim is my editor. I like to have them work together instead of one dominating the other.
That's not a feature of vi(m), that's a part of some shells (bash, zsh). You can suspend any programming running in a shell with ^Z. In addition to getting it back to run in the foreground with 'fg', you could also put it in the background with 'bg' (which is equivalent to starting a program with '&' at the end), or detach it from the shell process with 'disown' to make it a distinct process instead of a child of the shell process (which means it will keep running when you close the shell, which is often useful).
I use vim a lot and I'd add these as things in vim I found to be major productivity sinks too:
- using tabs
Simply too finiky. Create windows using :split and :vsplit. Swap between them using control-W h/j/k/l or :winc h/j/k/l Also:
CTRL-W =, CTRL-W N-, CTRL-W N+, CTRL-W N<, CTRL-W N>
Especially useful on large visual terminals where you can have multiple files open all at once and swap between them without touching the mouse.
- cwBLAH . . . . .
agh. Use :%s/blah/BLAH/g
:)
:setlocal spell spelllang=en_us - turn on spell check
z= - bring up list of suggestions
zg - add word to dict
zug - undo add to word
zw - mark as wrong
zuw - undo wrong
:help fold
zf<motion> - create fold (common motions '%', 'a{', 'a(' )
zo - open fold
zA - open folds recursively
zc - close fold
zd - forget fold
zj - move to next fold
zk - move to prev fold (up)zR - Open all folds
zM - Close all folds
zO - Open all folds under the cursor recursively
zC - Close all folds under the cursor recursively
zX - Undo manually opened and closed folds: re-apply 'foldlevel'.
zg g = Good word, add to personal dict
zug Undo Good word.
zw obviously, Wrong word.
...
zo Open
zA open All
zc Close
zj uses the same movement as the j key
zk ditto
Once you have the mnemonics sorted, sometimes you find you can remember the others because they are the ones "left out" of those with mnemonics, like zd doesn't have a mnemonic, so the command left over is "forget fold", so zd is that one. After a while, muscle memory takes over.Autocomplete helps, but life without a CapsLock would be awkward for me.
I recommend that anyone who doesn't use this give it a try, as it saves a few keystrokes.
PS. I guess the "i" subject is useful too for operating "inside" specific characters.
Overall it feels like good advice but it's just not my cup of tea.
Or in other terms, I don't think I'm going from horse to car.
Perhaps I should experiment for a month and see if it does actually make a difference.
Thanks. This will improve my vim-fu tremendously.
callFunction(); |// HEY THIS IS A REALLY LONG COMMENT
From there, I hit D, which is the same as d$. I want to then paste it so I have something like // HEY THIS IS A REALLY LONG COMMENT
callFunction();
But I want to do that without entering insert mode.nnoremap <leader>d DO<esc>p
(The 'r' command replaces the character under the cursor with the next key typed, without going into insert mode.)
try:
nnoremap <leader>p o<esc>p
is it really a requirement to not have a macro/keybinding?
I just recently learned to use ^D to exit a shell. It's amazing how many times in my life I've typed out exit^M -- or worse, exot^H^Hit^M -- when all I needed was ^D.
Edit: I now realize that you can't pair ^Z and ^D. It's either ^Z and fg, or :sh and ^D.
This may be true, but IMHO it can't compare to dumping Vim and choosing an editor that more efficiently exploits modern computers and their interfaces.
Many people don't realize this, but Vim arose from vi, which in turn arose from "ed". This family of editors contains a command infrastructure meant to avoid the waste of paper on a teletype terminal (ed's original display device).
And how do I know this? I used ed, and an early version of vi, years ago during my NASA engineering days in the 1970s, while designing part of the Space Shuttle. All those separate vi modes -- insert, delete, move the cursor, and others -- originated in ed, at a time when it was a priority to assist the operator while typing blind, before wasting another 11 inches of paper just to see how it all turned out. The first version of vi was screen oriented, but it carried over the original separate modes, and kept them separate.
When I wrote the first version of Apple Writer (http://en.wikipedia.org/wiki/Apple_Writer) in 1979, people had a hard time adjusting to an editor that allowed you to insert, delete and move the cursor without changing modes. It seemed a rather simple idea to me, but at the time, among vi users, it was met with shock and disbelief.
And here we are, over 30 years later, and people are still learning vi/Vim, as though it represents cutting edge technology.
I think we should hold a wake for vi/Vim, and maybe we should invite Fortran to the party.
So what if it "arose" from previous software? Should we hold a wake for the UNIX model? Everything as a file? Come on, it's 2012! I'll spare you a list of popular software that still employs metaphors from the 70s and just say that vim != ed. The robust plugin system alone allows vim to be pretty much anything you want, and I can't think of any features from any modern IDE that vim doesn't support.
You're missing the point that Vim still has the infrastructure of the original program -- it still has three separate modes: insert, delete and move the cursor, just as its distant predecessor did. This has no purpose except to agree with tradition.
And the purpose of modal editing in the modern day is that, when editing and not just composing, you don't have to spend your day holding down various combinations of modifier keys.
That was great. Someone searching the Web for remarks about efficiency will certainly miss your bons mots.
On this basis I must conclude that Vim doesn't have an integrated spell-checker.
This is very much personal opinion, but what I found with autocomplete is the time I'm typing the code I'm also using to think about it. Even on those surprisingly rare occasions where I manage to set up autocomplete that is both fast and accurate, it still didn't speed me up much. If I'm thinking so far ahead of my typing that I'm actually frustrated about the typing, that is typically an absolutely enormous code smell that something is very wrong, and I need to address the redundancy immediately.
But autocomplete is only one feature among many I appreciate in a good IDE. I'd also hate to give up a good visual debugger with integrated breakpoints, direct links from compile errors, etc. I know you can hack a lot of this together in Vim or Emacs but after 15 years of doing just that I don't miss it when I'm using IntelliJ or XCode.