Hacker News new | past | comments | ask | show | jobs | submit login
Vim anti-patterns (sanctum.geek.nz)
333 points by mcrittenden on Feb 7, 2012 | hide | past | web | favorite | 142 comments



Of all the "Vim tricks" article I came across, this one is my favorite so far.

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!


'gg' and 'G' in command mode will send you to the beginning and the ending of the file.

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.


45G does the same thing as :45, so the people using gg and G can also remain consistent with their muscle memory.


The beautiful thing about muscle memory is you can have two similar concepts map to completely different keys and your muscles will handle it just fine. I happily use gg/G/:# without mental overhead.


And for completeness, so does 45gg.


I like the idea of :1 and :$, but how do you get it to work in conjuction with selections (visual mode)?

If I want to select the entire contents of the file, hitting "v" then ":1" seems not to work.


The reason for that difference between ctrl-d and ctrl-f is that one moves the cursor half a page (or 'scroll') and the other scrolls the screen one page.


> I never bothered installing plugins and spent all my time instead learning

This wisdom should be shared with everyone learning vi/vim, since this leads directly to the largest payoff.


If you don't use plugins, you are really missing out.

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'm also a fan of Pathogen (and tpope's stuff in general), but now I would recommend Vundle. It's like Ruby's Bundler for Vim. The difference is that you define the bundles (plugins) you want to use right in your .vimrc. With :BundleInstall/:BundleUpdate clones/updates these plugins.

https://github.com/gmarik/vundle


I'm not really sold on vundle (or other plugins like it). I don't really like the automation it provides. I'd much rather just install stuff by hand in to ~/.vim/bundle and do my own updates. That way I have maximum control and full knowledge of what's going on in the install process.


How long have you been using vim?


Decades.


I dunno, Command-T was a pretty big boon to my productivity (https://github.com/wincent/Command-T).


I don't mean to say that you shouldn't find and use plugins, because there are some really great ones that answer real needs.

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.


I disagree to some extant. I've been a power use for more than a decade and some of the default ways of doing things are just wrong. It is true though that people are reluctant to learn about what vim itself already provides - more people should use the fantastic help system (once you know the basics) rather than rely on blog posts for everything, too.


The general idea is that if your productivity relies on external plugins, it will drop very low as soon as you have to use someone else's machine, or when you have to work with lots of various systems where setting up your environment isn't an option.


I think it's more that everyone is taking the bus to Abilene. Can you explain the first point a bit more? On the second point, you can always :e scp if you need to.

I've never maintained my own .vimrc, or know what plugins I have installed or not, btw.


There are some extremely powerful and useful plugins, CommandT for example, that shouldn't be miss.


In case you missed it, this one will teach you much more than just a few commands... It's all about combining commands or producing 'sentences' as the author calls it:

http://yanpritzker.com/2011/12/16/learn-to-speak-vim-verbs-n...



There's an option to configure how keyword completion works when ctrl-p or ctrl-n is used: 'complete'. Vim can scan the current buffer, other windows, other buffers, dictionaries, spell checking, thesaurus, included files, tags.


a useful one is 'markers'. I use it a lot when jumping from place to place.

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.


> Example: :ma <-- sets a marker at the current cursor location named 'a'

You don't even need the leading colon, just ma while in normal-mode.


Ok, I'm going to get a little blasphemous here, but I retain functionality of the arrow keys because they allow me to move the cursor while in INSERT mode. I find that ESC + [hjkl] + I to be slower than just using the arrow keys since the distance to escape vs arrows keys is about the same for the respective fingers (minus the cost of exiting and re-entering INSERT mode). I am sometimes told I should remap ESC to facilitate the use of hjkl, but the benefits seem dubious since I rarely have a need to move one or two spaces/lines outside of INSERT mode (instead, opting to traverse my code via line number, [], g/G, w/b, A/I, or marks).

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.


You really shouldn't be moving in insert mode. The only thing you should be doing in insert mode is typing new text (or erasing a few characters immediately before the cursor that you mistyped while still in insert mode).

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.


I find this needlessly strict. Personally I map arrow keys to more useful things in normal mode (tab switching for left/right), but I leave them in insert mode not because I have a bad habit of using them, but because on the occasions that I instinctively use them (eg. I often type pairs of braces and then back-arrow) they are not a crutch preventing me from using some more efficient normal mode ops. I am extremely fluent in hjklwWeEbBfFtT, and I correctly use the atomicity of insert mode, so it would just be dogma if I remapped arrow keys in insert mode.

Also btw, Control-h,j,k,l I have mapped to switch windows.


"But you should really try to wean yourself off the bad habit of moving in insert mode."

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.


I have seven years of professional avg personal daily use of vim and never bothered to leave the arrows. I don't move so often in insert mode, I just prefer my hands the be far from each other. Ijkl maniacs should stop repeating the same refrain over and over...

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)


"I have seven years of professional avg personal daily use of vim and never bothered to leave the arrows."

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.


Arrow keys are fine in insert mode but it sounds like you might be spending too much time in insert mode rather than considering normal to be the default mode. Do you use arrows in normal mode too?


>I rarely have a need to move one or two spaces/lines outside of INSERT mode (instead, opting to traverse my code via line number, [], g/G, w/b, A/I, or marks).


if you're hopping out of insert mode to do a single navigation command, why not use the insert mode's ^O mapping?

(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)


This isn't an issue if you've mapped ESC to jk or something similar.


<j><k><k><i>

OR

<up>

I prefer a single key to four, even if I have to move my hand off the home-row.


How often is it that you want to perform this move (edit the character immediately above the cursor, but not in block mode)? If you're moving horizontally by a single space, you have backspace and delete for single-character moves (which are an edge case). If you're intending to add new content in a new line, why not <Esc>O?


I just started learning vim. It would be great if someone made a game for learning that taught some simple commands—something along the lines of, "Perform the needed operation(s) in the fewest number of keystrokes possible." For instance, add an attribute to an html tag with your cursor at a certain starting point on the line. Then have a leaderboard of the shortest key-combos used, with comments.

I'll bet more experienced vimers could learn something from this, too.



Thanks! That's definitely getting there. It would be even better if I could do it in the browser, with simpler challenges to start out. Maybe a few intro tutorials or the like.


Here's my advice. Instead of trying to learn all of these tips at once, bookmark the page (or leave it open), and try to use one of the tips at a time for at least a week. If you focus on one at a time, you'll get a much better feel for when the command is actually saving you time/thought. Also, they'll stick more permanently in memory/muscle memory.


Don't try to learn everything at once.

$ 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.


Another great way to learn new vim tricks is to simply hang out on #vim on freenode.

I've learned a lot that way, and still do every day.


One other major feature I would mention: text-objects

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


And to complement them, the surround.vim plugin: http://www.vim.org/scripts/script.php?script_id=1697


L, M, and H are also very useful for vertical movement. My general procedure for navigating (when I don't have anything particular to find), from general to specific, is: Ctrl-f/Ctrl-b, L/M/H, j/k).


I like CTRL-U/CTRL-D for scroll up/down by half a screen, as opposed to a full screen.


Thanks, I always get frustrated doing full screen hops.


The Escape key on modern keyboards is a lot further from home row than it was on Bill Joy’s keyboard back when he designed vi. Hitting Escape is usually unnecessary; Ctrl+[ is a lot closer, and more comfortable.

That's not an "anti-pattern," that's an opinion. I think C-[ is uncomfortable as hell.


I have caps setup as a third ctrl key. So at least for me Ctrl-[ is super easy to hit, as is every other ctrl based modifier.

I greatly prefer this setup. I never used Caps before and now I have a useful key in a useful position.


It depends on the keyboard layout, though. To write [ I need to type Right Alt + 8.


Many of the tips involving keys like {[^$ look cool, but are impossible to hit fast on a non-US keyboard.


I highly suggests switching to QWERTY while coding in Vim. You should be already familiar with it and it only takes a few days to be really at ease with it. We don't need characters from our languages in our code (at least most of the time).


Sometimes you can hit ctrl-<key where [ is on US layout>, but I forget if/when it works that way.


Same here. ctrl-3 works also, for some reason.


It's probably more comfortable than reaching an unremapped modern PC Escape key, though. And if you do light remapping, making Caps a Control instead (as in the Mac's Keyboard control panel) makes ^[ even easier.

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.)


I have jj mapped to Esc in insert mode. If you type it quickly, the two j characters vanish and you escape out of insert mode. If you type them slowly you get two j characters in your text. I rarely need two j's in my text, of course, so it's a good escape key sequence, but pick whatever you want. I chose jj because it keeps me on home row.


Sometimes my muscle memory winds up telling me it needs. That's how I wound up mapping both jj and ;l to Esc. The first gets used when I've finished an insertion and am about to pause to think (it feels more emphatic) while the second gets used when I'm in flow and know exactly what I'm going to do next.

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!


Speaking of chording, there's a pretty cool vim plugin called "arpeggio", that will allow you to map chords:

http://www.vim.org/scripts/script.php?script_id=2425


Ick, that makes for lag if you just type 'j'.


Hopefully you type fast enough that by the time your brain noticed any lag on the "j", you are already a few letters down the line.

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.


It's just an ugly way to do a mapping. I used to have some mappings like these in my rc, but I removed them in favor of similar ones that backtrack instead. If the author wants "jj" to be <ESC>, it can be done without the lag: You just check the previous character on 'j' and then take action accordingly.


Can you show us the script you use to make this happen? Sounds interesting.


jk is faster :)


I've used vim for so long that I don't find hitting the escape key to be a bother -- in fact, I don't even notice it at all anymore. It's the same with hitting :

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.


Given how common the escape key is in Vim, I swapped caps-lock and escape, which IMO is vastly more comfortable than C-anything.


For me hitting the ordinary control key is even more comfortable than hitting the caps-lock key. That's because to hit the caps-lock key I have to lift my little finger and move it to the left, while to hit the control key I only have to press down with the part of my palm that's directly below my little finger (and directly above the control key).


Since I learned Vim with the normal Escape key location and find it easier to hit than the normal Ctrl keys, I turn caps into another Ctrl. Plus, everything has Ctrl key shortcuts.


I prefer ctrl-c even if people flip their shit about this half the time.


On the contrary I find it quite pleasant, but it all relies on the having Caps Lock bound to Control.


I've thought for a while that Vim could analyze how a user edits and spot repeated use of inefficienct techniques like these -- and then suggest the more efficient alternatives to the user. Implementing this could make a nice project.


These kind of articles always have a few new things in them, even of most of it is familiar -- I guess everyone just has a slightly slightly different set of indispensable tricks.

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.


I've tried relative numbers a few times in Vim, but always found it hard to adjust. But recently Jeff Kreeftmeijer wrote up a way to get the best of both worlds[1]: relative numbers in command mode and absolute numbers in insert mode or if Vim loses focus. Just another option to consider.

[1] http://jeffkreeftmeijer.com/2012/relative-line-numbers-in-vi...


That's a good hack. Personally I just have F4 mapped to toggle between relative and absolute, but relative is the default. I rarely care about specific line numbers because if I'm looking at a stack trace for something I just jump directly with :#


If you train yourself, you can get good at guessing the line numbers, plus is makes you feel godly when you correctly dd the 17 lines you want.


That, or subtracting ;)

I swear the entire UI of Vim is made to make the user feel like a ninja.


I'm fairly sure the GP meant "dd", not "add".


Ah, I meant subtracting the current line number from the target line number to get the number of lines to jump, instead of just guessing.


Got it. I think we ironically tend to underestimate our ability to estimate. I normally :set nonumber, and like secoif, I've impressed myself on numerous occasions with how well I'm able to estimate line counts and character counts. Give it a try -- you're likely to impress yourself too.


Correct.


I need to do more of this. At the moment I'm relying on visual mode way too much (i.e. select what I like, then delete it).


After around 5 years of using vim, I'm at the point now where everything in this article and comment thread is already in muscle memory. My only advice would be similar to whats in other comments:

* 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.


I've used vim for coming on 15 years now, so I feel that I may qualify as 'experienced'. My biggest productivity gain was giving up on endless customization after I had reached a certain proficiency (e.g., everything in the original article is rather basic vim usage) and comfortable workflow for specific development purposes (e.g. when switching to a new language, I spend some time setting vim up to solve the most glaring pain points and once it feels comfortable, I stop customizing). All the mucking about with various baroque plugins and ever-more-marginal keystroke-saving key mappings costs a lot more time than what can be gained from it. For example, I used to have a bunch of mappings that would insert documentation blocks in various forms. Just misremembering the mapping once a day causes enough workflow disruption to undo any gains from having them in the first place. Nowadays I just type comments / docblocks by hand. It's a few more keystrokes, but a lot more natural and flexible.

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.


I've only been using vim full-time for a year and a half, but I'm slowly ramping up on things like window and buffer management. Probably my favorite life-changing trick is the quick macro:

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.


Nice! I think I might add that to my .vimrc. The only thing I'd add about macros is that I generally use them for multi-line transformations (i.e. they usually end with `j`). This means you can record your macro and the run `n@q` where n=the number of lines you want to run it for and q=the register where your macro lives. This is useful for annoying, repetitive syntax transformation tasks.


Ah, I never have done a count on a macro before, but I do much the same thing with the @q bind. I have my key repeat rate set to maximum, so I can just hold down space and it flies down the lines.


I see you're using Command-T, but for anyone else, these remaps will list all buffers using F1 and quickly jump to b1..b9 using \1 .. \9, and toggle between alt buffers using \\, all in normal mode. Super handy and quick.

  " 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>


Some tips:

* 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


Here's a good tip I picked up recently when working with numbers:

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.


I've been using those more and more recently and have noticed a couple interesting things to be aware of. First, Vim interprets a dash character immediately preceding the number as a negative sign. (In playing around a bit I suspect this behavior is slightly influenced by the syntax rules for the particular filetype you're working with.) The effect of this is to flip the behavior of CTRL-A and CTRL-X. Secondly, if the first digit of the number is '0', Vim will behave as if the number is octal, so incrementing "07" once will result in "010". Similarly, a prefix of "0x" or "0X" will cause a number to be treated as hex.


To avoid the "07" -> "010" problem you can add

    set nrformats-=octal
to your .vimrc.


You can prepend a count to that too, to increment/decrement by a fixed amount.

This gets scary useful when you use tpope's speeddating plugin.


Just be aware if you are in a screen session, ctrl-a ctrl-x chord will lock the screen. It bit me only an hour ago.


Okay, here's one that I've been stuck with. What does Ctrl-Z do in vim, and how do I "undo" it? I always have to kill -9 the vim process, and it sucks cleaning up where I was.


tl;dr: type `fg`.

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.


That's an anti-pattern too. You should use one of the many ways of loading up multiple files in one vim session. I don't know what the best is, because I'm an emacs user, but I know there are many options.

Losing access all your editing state when you move to a new file is silly, regardless of editor.


It goes beyond just editing multiple files. I'm a huge fan of tabs in vim so I do a lot of :tabnew filename (which has autocompletion by the way) and mapped \tp and \tn to :tabprevious and:tabnext. I sometimes just open in a new file buffer like emacs does, no tabs and no window splits but when I'm done with the file I go back to the other one.

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.)


Ctrl-Z to actually suspend vi is fine. (Quick shell commands can be done in vi of course, but sometimes when you need a shell, you really need a shell.) It was the recursive opening of vi I was saying is a bad idea.


Why not gt and gT? All the commiting/greping/chmoding/building stuff can be done from within Vim. You don't really need to get out of it unless you want to launch a curses program or an interactive SSH session. Eck, even in such cases I think it's way better to have multiple terminal windows or panes.


It's mostly habit for me not using gt and gT. I only learned :tabnext and :tabprev when I learned of tabs at some point, and the mappings followed shortly after. I have a lot of other \whatever bindings too. (Such as \gt that's mapped to :tab split<CR>:exec("tag ".expand("<cword>"))<CR>)

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.


Vim's tabs are horrible if you insist on using it like other apps' tabs but they are really useful exactly for that kind of situation: just open a new tab with your "stuff from a different context". From there, switching from tab (context) to tab (context) is pretty easy with gt and gT. No inductive stack to corrupt, no complex mental projections…


and if you've gone so far down the hole you're completely lost, 'jobs' is a useful way (in most shells, I think?) to figure out where you are.


Others have already answered the gist of your problem, so I'm just going to add the following:

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).


It backgrounds the running process. Type 'fg' to bring it back to the foreground. This isn't actually a vim thing, it's a shell thing


Normally Ctrl-Z will pause a process and it will be kept as a background job. Type 'jobs' in your prompt to see running jobs.

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.


It's amazing how many articles like this there are, and how I always seem to learn something new.


zt, zz and zb are great too. They redraw the screen so that the line the cursor is currently on becomes the top, middle, or bottom line of the window.


Other "z" commands (these are the ones I always get mixed up):

    :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)


Some simple mnemonics might help you out.

  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.


Yeah, I like the fold commands, which I barley discovered a few weeks ago. I typically do "set foldmethod=indent" then pres "zr" multiple times until I'm at the fold level I want. Then I can just do "zo" on the parts of code I'm interested in.


there's also

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'.


I'm a big fan of Ctrl-e and Ctrl-y which, despite being in the "one line at a time" category, are really useful for changing the context of the cursor a little bit without changing the cursor's line. I've even gone as far as to remap those to J and K.


thanks! I knew zz 'centers the screen'. you made it a lot clearer ;p


Mm... Agree with those.

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

:)


Re using the Caps key mapped to Esc. Many people are commenting they never use the Caps Lock key. I'm puzzled since I use it all the time. Do you not capitalise your constants or globals? Or maybe you don't write much C or C++; I'm not sure what the standards are for ruby etc.

Autocomplete helps, but life without a CapsLock would be awkward for me.


I also find it strange that so few people use caps lock, but among all my programmer associates, I am the only one that does. That said, I hit Esc way more often than Caps Lock, so I've swapped those two keys.


This article only touches on the "c" noun. There are quite a few handy things which you can do with it, such as delete all the text between quotes and put you insert mode (ci").

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.


I'm guilty of some of these anti-patterns (like for example the arrow keys) but honestly I feel incredibly fast and productive when using ViM. I'm afraid to drastically tweak my workflow at this point because I don't think the optimization will be worth it.

Overall it feels like good advice but it's just not my cup of tea.


Cars? I'd have to learn to drive? What's wrong with my horse I already know how to ride?


haha, I see what you mean and it does sound like I have a bad attitude. But I feel like the overall gain I'd get from this isn't worth the time I'll spend retraining my muscle memory.

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.


Wow, it's almost like you studied a video of me coding to write that post.

Thanks. This will improve my vim-fu tremendously.


Question for wiser vim users than myself: If I delete (say, a line comment) with `D`, how do I paste it as a line of its own without macro trickery involving `o<esc>p`? Is that possible?


You mean that you deleted it with dd? Can you show a before and after of what you're trying to accomplish, because it's very likely possible. I'm just not sure what you're trying to do.


say I have a line here ( | being my cursor)

    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.


To break a single line into two lines on a whitespace boundary, one pattern I find myself using often is moving the cursor to the whitespace and hitting 'r<return>'.

(The 'r' command replaces the character under the cursor with the next key typed, without going into insert mode.)


Oh that's a nice trick, I'll remember that one. As an avid user of J I've been wanting its inverse.


Isn't J the inverse?


how about remapping?

nnoremap <leader>d DO<esc>p


well you can do O ctrl-r " <esc> and it will paste it and leave you back in normal mode but that is kinda an anti-pattern. maybe it's time for a remapped keybinding?

try:

nnoremap <leader>p o<esc>p

is it really a requirement to not have a macro/keybinding?


I like :sh and ctrl-d to bounce back and forth...


Why not ^Z and ^D?

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.


> The benefits of getting to grips with Vim are immense ...

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.


>Many people don't realize this, but Vim arose from vi, which in turn arose from "ed".

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.


> So what if it "arose" from previous software?

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.


Actually Vim has 6 basic modes, but none of them are "delete" or "move the cursor".

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.


It is all about effeciency. I find when I am not using vim I am less effecient. I like the seemingly minimal, ultra complex features of vim. I can count on some form of it being installed on most *nix machines. I can customize it to my liking...what can I say...I love it. To me, it is as modern as any editor.


> It is all about effeciency. I find when I am not using vim I am less effecient. [emphasis added]

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.


I've never heard anyone say that they liked Vi because it was cutting edge technology. You sound quite sour about it.


I've never understood this obsession with editing efficiency among programmers. When coding I spend about 90% of my time thinking about what to type. A good IDE that really understands the structure of my code without twenty flaky plugins is worth much more to me than saving some keystrokes.


Typing efficiency I'm "meh" on; don't get in my way, but I'm not too worried about it. I've tried tons of autocomplete of every kind and tend to just turn it all off. Navigational efficiency is very important, though. If I want to look at a bit of code, fractions of a second count if I'm going to stay in flow.

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.


I think it depends somewhat on the language. For Ruby I prefer Emacs and don't see much benefit in autocomplete. But for Objective-C & Cocoa, which is admittedly a somewhat extreme case, autocompletion is a godsend.

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.


I don't. I do my thinking in the code because I can edit fast enough to keep up. I test out ideas as they come to me, delete them, refine them in the code itself rather than think up abstractions and then translate them into code in a second step.


[deleted]


My remarks were about a lineage of programs that still contain truly crippling features, in order to meet the needs of an environment that has long since disappeared. Mathematics doesn't have this problem.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: