Hacker News

Top stories

Live mirror
30 storiesupdated just nowView source snapshot
  1. Claude Code now reads AGENTS.md if there is no Claude.md(claude.com ↗)
    47comments
  2. Android 17 is the first since 3.x to add new APIs without releasing to the AOSP(grapheneos.social ↗)
    146comments
  3. Saving another 100TB of RAM(cloudflare.com ↗)
    22comments
  4. Cloudflare Quick Tunnels(cloudflare.com ↗)
    207comments
  5. Xcode 27.1 Beta Release Notes(developer.apple.com ↗)
    51comments
  6. Cache-to-Cache: Direct Semantic Communication Between LLMs (2025)(arxiv.org ↗)
    10comments
  7. Photon-Emission-Guided Laser Fault Injection Enables RP2350 Secure Debug(ledger.com ↗)
    39comments
  8. How to Write with an LLM(sockpuppet.org ↗)
    228comments
  9. Show HN: Cactus Needle 3: 8-29MB automation models can match DeepSeek V4 Flash(cactuscompute.com ↗)
    69comments
  10. OpenJev(openjev.com ↗)
    235comments
  11. The Implications of Linguistic Illegibility for LLM Security(arxiv.org ↗)
    12comments
  12. Our brain evolved from two primitive nervous systems that merged: Study(newscientist.com ↗)
    43comments
  13. C++26: Trivial infinite loops are no longer undefined behaviour(sandordargo.com ↗)
    151comments
  14. The first new cat species discovered in 100 years(nationalgeographic.com ↗)
    25comments
  15. Cyclomatic Complexity in C#(ndepend.com ↗)
    2comments
  16. Korea raises data breach fines to 10% of revenue(koreajoongangdaily.com ↗)
    49comments
  17. From Geometry to Algebra and Back Again: 4000 Years of Papers (2023) [video](youtube.com ↗)
    discuss
  18. I vibed a proof of Conway's conjecture(overreacted.io ↗)
    170comments
  19. How SpaceX streamlined the Raptor engine(construction-physics.com ↗)
    15comments
  20. Minimal Phone 2(minimalcompany.com ↗)
    127comments
  21. A search-and-inference database from scratch in pure Zig(antfly.io ↗)
    12comments
  22. Inside ZCode: Silently uploading your Git history to the cloud(ferstar.org ↗)
    87comments
  23. Border agents can search cellphones without a warrant or reasonable suspicion(lawandcrime.com ↗)
    108comments
  24. Warez: The Infrastructure and Aesthetics of Piracy (2021)(archive.org ↗)
    8comments
  25. Cekura (YC F24) Is Hiring(ycombinator.com ↗)
    discuss
  26. US Military had close call after using AI for hallucinated intelligence report(cnn.com ↗)
    247comments
  27. Show HN: Ax-check.com – Can agents use your product?(ax-check.com ↗)
    24comments
  28. North Korean nuclear test sets off years of earthquakes(science.org ↗)
    144comments
  29. Mathematicians Build Long-Awaited Graph Sandwich(quantamagazine.org ↗)
    15comments
  30. Show HN: Scry, programmable internet search w/ congestion pricing(scry.io ↗)
    16comments

Vim anti-patterns

333 pointsby 14y agoblog.sanctum.geek.nz
141 comments
14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

    set nrformats-=octal

to your .vimrc.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

Thanks, I always get frustrated doing full screen hops.

14y agoHN ↗

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!

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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)
14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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…

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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!

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

That, or subtracting ;)

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

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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

Thanks. This will improve my vim-fu tremendously.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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?

14y agoHN ↗

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?

14y agoHN ↗

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

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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

14y agoHN ↗

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)

14y agoHN ↗

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

14y agoHN ↗

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)

14y agoHN ↗

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

:)

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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?

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

how about remapping?

nnoremap <leader>d DO<esc>p

14y agoHN ↗

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

14y agoHN ↗

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

14y agoHN ↗

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?

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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.

14y agoHN ↗

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>
14y agoHN ↗

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.

14y agoHN ↗

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.