top | item 19794558

Intermediate Vim

280 points| signa11 | 7 years ago |dn.ht | reply

126 comments

order
[+] jnurmine|7 years ago|reply
Maybe you can cover macros since they are conceptually very simple and very powerful.

They may seem a bit complex but are quite simple. Basically you just record your editing movements and play it back.

How macros work: press q x to record and q to end. Then repeat with @ x, where x is the name of the macro you want to use (you can have several macros). Anything you do will be played back. That's it... Conceptually simple.

A nice trick is to record a macro for a single line and place the cursor on the start of the next line at the end of the recording. This way it's possible to operate upon large blocks of text in a similar way by just repeating the macro. The key then is to use generic movements like "go to the beginning of line" (^), "go to the end of line" ($), "skip word" (w), etc.

As a silly toy example, if you have a list of strings in a text file, you can turn it into a list of quotes with (from the top of my head):

  qx<Home>i"<Esc>$i<Right>",<Down><Home><Esc>q
(Record macro, go to beginning of line, insert mode, write a quote, exit insert mode, go to end of line, insert mode, move right, write a quote and a comma, move down to next line, move to the beginning of line, exit insert mode, end macro recording)

Then to process 100 lines, you'd do:

100@x

That turns these:

  alpha
  bravo
  charlie
  delta
  ...
into

  "alpha",
  "bravo",
  "charlie",
  "delta",
  ...
If you have hundreds of lines of that you'll start to appreciate the easy automation.

I use macros to do drive-by mass-edits without resorting to sed, scripting, regular expressions etc. since the cognitive load of those is higher for me.

Edit: formatting

[+] n8henrie|7 years ago|reply
My favorite newish-to-me macro trick is to use "recursive macros" -- macros that call themselves at the end, eg `qa[do something]@aq`. The idea (at least for me so far) is to record a line-wise action that goes to the next line before calling itself and will fail on the first non-matching line. For example, if you need to put some text after the first `0`, using commands like `t` or `f` to get there will fail if there is no `0`, but `/` will go to the next `0` on any line.

A macro like this will just keep calling itself until it fails, which is nice for files with thousands of lines and you want to make a change that is not conducive to a regex.

As a tip that took me a while to figure out, you can search within a visual selection using `\%V`, which may make it easier to reliably go to a specific part of the current line (compared to t or f like I mention above).

Also wanted to point out that iVim for iOS is pretty good, for those rare cases you want to do some text processing on the move that makes you miss Vim: https://itunes.apple.com/us/app/ivim/id1266544660?mt=8

A decent post on recursive macros: https://jovicailic.org/2018/06/recursive-macros-in-vim/

[+] isostatic|7 years ago|reply
I've used vim for a couple of decades, but never pushed to many advanced features. For your example above I'd do :%s/^/"/ and :%s/$/",/

Unless I use a feature regularly I find it's a higher cognative load. I use bash, sed and perl regexps on a near daily basis. Macros are very rare.

[+] brianpgordon|7 years ago|reply
For that example I would open the document in Sublime Text, select all, and split selection into lines so that I have an independent caret on every line. Then I'd just type the quote at the beginning and end of each line - the home/end keys will put each caret at the beginning or end of its respective line.
[+] weavie|7 years ago|reply
I was going to say that one annoying thing about these macros is you can't press . to repeat the last macro. It is annoying having to count out 143 lines and then do 143@x or what I tend to do is do it in batches of say 20 until I get to the end..

But this has prompted me to look this up and it turns out that you can use @@ to do this. This will make my life a lot easier, I can just smash <Shift 2> until all my lines are updated.

[+] y7|7 years ago|reply
I also use a lot of macros. I just learned that macro registers are the same as regular registers, so you can actually paste the contents of a macro and examine it or save it to a file (e.g. "xp after recording your macro).
[+] snarfy|7 years ago|reply
I use the . (dot) command a lot out of habit. It executes the last command. If the last command was a macro execution, dot doesn't execute the macro - it executes the last command of the macro. Is there a way to fix this?

edit I see someone else answered this - use @@ instead of .

[+] mundacho|7 years ago|reply
Another simpler way (even simpler than macros) that works great for simple mass editing is visual blocks. In normal mode, press Ctrl + V and you get to select a literal block of text (not like visual mode, where the text is sequential). Then you can for example, do a "c" to change the selected text in each of the rows that your block covers. This is especially practical to remove a column. Just select the column, press d and voilà.
[+] contras1970|7 years ago|reply
this is somewhat shorter:

    qq0i"<Esc>A",<Esc>jq@@
i agree this example is silly. i'd do something like

    :%s/.*/"&",/
[+] A2017U1|7 years ago|reply
This is really neat, thanks for rundown. Its easy to get far too comfortable with ad-hoc sed commands when there's far better solutions out there.
[+] asadjb|7 years ago|reply
I feel composing commands is where the real power of Vi(m) comes from. This can be really helpful to someone just starting out with Vim.

I got a boost in my Vim productivity after reading a similar StackOverflow answer a couple of years ago. It's a nice read for people familiar with Vim, and another good resource for new users.

"Your problem with Vim is that you don't grok vi." https://stackoverflow.com/a/1220118

[+] ryannevius|7 years ago|reply
I'm not sure I'd call any of this "intermediate" Vim. Most of it appears in vimtutor, and the rest in the "basic editing" portion of the reference manual.
[+] hyperpallium|7 years ago|reply
Vim: difficult to learn, difficult to master.

Most of it is "intemediate".

[+] campbellmorgan|7 years ago|reply
For anybody who's found more IDE-y activities a bit beyond the current generation of VIM plugins (looking at you Typescript), the Vim plugins for VsCode and Visual Studio are actually surprisingly good and I find myself at least as productive as I do in Vim.

I imagine it might be quite a good starting point for somebody who's used to VsCode productivity but wanted to get into vim without going full vim!

[+] diehunde|7 years ago|reply
The problem I have with those plugins is that I use a lot of split buffers not just for editing but also for exploring directories using :Explore for example. Some IDEs+vim plugins support horizontal splits but then when you have to jump between different modes such as explorer or console they use different shortcuts.

Nevertheless, I think that VIM support for IDEs has improved a lot these past years. VSCode and Jet brains have done an awesome work integrating it to their software.

[+] dhotson|7 years ago|reply
Hey all, I'm the author. Feedback is welcome! :)

The reason I wrote this is because I've been pair programming quite a bit lately and also mentoring some new vim users—so I wrote this little guide to help vim beginners level up their skills a bit.

What I noticed is that a lot of vim beginners find composing commands and text-objects to be kind of mind blowing.. and even more experienced vim users mentioned that these were the things that made them have that "aha" moment and convinced them to learn more.

[+] jhoh|7 years ago|reply
Great article! The features you showed were some of the ones I've had my first "Oh, now I get why vim is so great"-moments and that really boost your productivity.

> Tip: Generally after you’ve inserted some text, you want to return to command mode so that you’re ready to enter your next command. I’d recommend pressing esc any time you’ve finished typing.

Totally agree with this. What really helped me with getting this into my muscle memory was remapping Capslock to ESC which seems to be what many (most?) vim users do.

[+] timrichard|7 years ago|reply
Nice checklist...

I'm not quite convinced about this as general advice :

> If you’re like me and never learned to touch type properly, just use the arrow keys, it’s fine, don’t worry about it.

When I decided to go all-in on Vim keys some time ago (trying to find plugins for everything), it didn't take long to transition to hjkl. I think it's easier and more convenient to stay near the home row rather than moving my hand over for the arrows. I don't strictly touch type either.

[+] jakecopp|7 years ago|reply
I think the concerns others have mentioned about the title/content level are valid, but even though I knew most of the commands I enjoyed reading this! I quite liked your writing style and page design.
[+] chapium|7 years ago|reply
Visual mode is a good next step after getting comfortable with b,w,e,h,j,k,l navigation.
[+] mxschumacher|7 years ago|reply
instead of "52gg" I prefer ":52"
[+] dmortin|7 years ago|reply
> I've been pair programming quite a bit lately

Does it mean both party have to use the same editor? I wouldn't participate in a pair programmnig like that.

Pair programming is best when everyone can use one's favorite editor. When there is a pair switch there is also an editor switch if the other party prefers a different editor.

[+] jaequery|7 years ago|reply
“If you’re like me and never learned to touch type properly, just use the arrow keys, it’s fine, don’t worry about it.”

Are touch typists rare these days? I feel like people these days forego even learning to type properly. I dont understand why they refuse to just learn it, it is such an essential skill to have.

[+] KhoomeiK|7 years ago|reply
TIL I'm an intermediate user of Vim! /s

I think this is pretty basic in terms of general vim commands. Navigation and insertion are all basic use cases that beginners should know. That said, the section about composing commands was really interesting!

[+] cranium|7 years ago|reply
One thing I miss on Vim I have on Spacemacs with the Evil layer is the "a" object (for "argument"). With it I can delete/change an argument of a function in a flash.

Example (cursor on the last arg):

  importAntigravity(usePython, crashTheUniverse)
  <type daa for "delete an arg">
  importAntigravity(usePython)
[+] url00|7 years ago|reply
This does that in Vim: https://github.com/wellle/targets.vim

I use it all the time! The only reason I don't use Spacemacs is the startup time/GUI lag, but if it works for you keep at it!

[+] declank|7 years ago|reply
I use Emacs/Evil for hobby programming and vi for quick edits on servers. Wish I had this guide years ago. Incredibly helpful. :)
[+] tebs1200|7 years ago|reply
A well written guide for introducing some of the power of Vim to a new user.

One thing I'd suggest for the author, based on a quote from the article - "Invest your time to learn new skills" - Try and invest some time to learn touch typing.

I worked as a developer for years thinking that it wasn't worth the effort, but after taking a couple of weeks to learn, I never looked back. My productivity, particularly with Vim has jumped leaps and bounds.

[+] kaitari|7 years ago|reply
After years of using Vim, I recently learned that I could use `Ctrl+C` instead of `ESC` to get back to command mode. Mind blown.
[+] alanning|7 years ago|reply
Interesting! I didn't know about `CTRL+C`.

You may like to also try `CTRL+[`. It's the telnet escape character and seems to be a general substitute for ESC on OSX, Windows, and I think Linux too. I find it pretty quick since my hands can work together.

Another handy tip I ran across was to remap CAPS LOCK to CTRL. Quite nice for both Vim and Emacs users once you get used to it.

[+] simplicio|7 years ago|reply
Alt+Movement is what I usually use, since it's easy to hit on my keyboard, and lets you combine dropping out of insert mode and a movement command to move you towards where you want to be for whatever you want to do next.

If you don't want to move, you can just hit Alt+l as the "default" escape.

[+] ludsan|7 years ago|reply
I use that all the time except for the case where I'm doing a visual block insert when the control-c doesn't do what an escape does.
[+] cheunste|7 years ago|reply
Holy crap really?!?

Man, that'll definitely save my pinky from cramping up every so often.

[+] gfiorav|7 years ago|reply
Funny, after two years on Vim, I just discovered Esc
[+] Ice_cream_suit|7 years ago|reply
Disappointingly elementary.

Even I, an Emacs user who occasionally uses vi am familiar the material in this.

Can anybody suggest any real intermediate vi material?

[+] LocalPCGuy|7 years ago|reply
Beginner vim is being able to exit vim successfully, knowing how to hit i to insert text, and how to save your file. Just because you are familiar with it doesn't mean it isn't intermediate, it just means you are already intermediate.
[+] knolax|7 years ago|reply
As a Vim user one of my gripes when first using Vim was how cumbersome the built in help files were. I guess that's why there are so many "vim cheatsheets" out there, the built in documentation is a pain to use.
[+] lenkite|7 years ago|reply
One thing I always wished VIM had was the generalized ability to repeat the last navigation command with "," and ";". I mean if I use "[m" to go to the previous method, then I want to be able to repeat that with ",". Never understood why ",' and ";" are only for "f" and "F"
[+] opan|7 years ago|reply
The balloon comparison is strange. I would've just said that adding shift to a shortcut often reverses it... / for search and ? for search backwards, alt-tab to switch windows, alt-shift-tab to go the other way, ctrl-tab to go to next tab in Firefox, ctrl-shift-tab for backwards. It's incredibly common.
[+] isostatic|7 years ago|reply
The defaults in vim 8 in debian and ubuntu really changed the way vim worked, it was horrendous

As far as I'm concerned, the following is an non-negotiable requirement for vimrc.

  source /usr/share/vim/vim80/defaults.vim
  set noincsearch
  set scrolloff=0
  set mouse=
[+] jermy|7 years ago|reply
Just to extend this - if you're often using different users (or need to otherwise deploy via a configuration manager), I've found out that a good way of having system-wide options on Debian is /etc/vim/vimrc.local with something like:

   " Workaround stupid defaults.vim behaviour
   if filereadable("/usr/share/vim/vim80/defaults.vim")
      source /usr/share/vim/vim80/defaults.vim
   endif
   let g:skip_defaults_vim = 1
 
   " Disable stupid seeking to last position
   autocmd! vimStartup BufRead
 
   " Disable stupid mouse support
   set mouse=
[+] johannkokos|7 years ago|reply
I learned a new one recently. zt redraw so that current line is at top, zb redraw so that current line is at bottom, zz redraw so that current line is at the center.

If you are on twitter, you might want to follow MasteringVim. You'll learn one trick every day.