4 ms·
Last week I forced myself to pull a bunch of names out of HTML for a dropdown listbox using a vim macro. I could've used a regular expression but I wanted to l
by dpritchett 16y ago
Last week I forced myself to pull a bunch of names out of HTML for a dropdown listbox using a vim macro. I could've used a regular expression but I wanted to learn vim macros. Here's what I did. No guarantees that this is the right way to do it or that it's better than emacs.
q0 (start recording a macro to store in buffer 0)
df" (delete everything from cursor through the next quote character)
f( (jump to the next open paren)
d$ (delete everything from cursor to end of line)
j (cursor down one line)
0 (skip to beginning of line)
q (finish recording macro)
50@0 (execute macro 0 fifty times)
That turned a bunch of lines that looked like
<option value="My Full Name (domain\account)">My Full Name (domain/account)</option>
into lines that just looked like
My Full Name
To reiterate, I typed q0df"f(d$j0q50@0 and my problem was solved with little thought.
- Xurinos 16y agoTwo helpful mods to your macro: (1) After the f(, you probably want h to move the cursor left onto the space before the (. (2) Instead of d$, just use D. Alternative for both those comments: Replace d$ with Dx More than one way to do it anyway... I would have spammed "qq" instead of "q0" to save finger space, but you might have already been using your q register for all I know. The other nice thing about vim macros is that since they are stored in vim registers, they can be accessed and manipulated. Make a one-keystroke mistake in your macro? Paste it to your buffer, edit it, and copy it back into the register. Now you can use it again. Example: "0p => df"f(d$j0q Modify to be df"f(Dxj0q and highlight and "0y For the readers, " accesses a register, y = yank, p = paste. Emacs defines "yank" the opposite way of vim: it means to yank from the clipboard and paste to your buffer. In vim, it means to yank it out of your buffer and put it into your clipboard (another register, as it happens, along with special registers that understand different levels of your OS's clipboards).
- dpritchett 16y agoThanks for the tips. I wrote my first vim macro last week so obviously there's a lot more for me to pick up!
- nuclear_eclipse 16y ago> After the f(, you probably want h to move the cursor left onto the space before the (. Or just use t( to automatically move to the preceding space. ;) The best part about Vim is that you can ask 50 people about shotcuts and get 50 distinct answers, and each person can learn something new from each other. :)
- Xurinos 16y agoGood catch! So true. I forgot about this point, a concept I do not see a lot of in emacs: vim has a number of similar functions that differ purely by where the cursor ends up. The f vs t is one such distinction. Another is navigation of words by first letter or last letter (w vs e). Not often mentioned is the variations of block highlighting, where I can quickly (two or three letters) highlight my block and choose whether or not to include the beginning and end of block. For example, when I am in the middle of a sexp, vi( highlights everything inside the parentheses, and va( includes the parentheses. For {}s, just use vi{ and va{. And there are more options like these for saving keystrokes that, thanks to generally consistent policies, are the same for multiple commands -- cw (change the next word), dw (delete the next word), vw (highlight the next word), etc.
- kroger 16y ago"To reiterate, I typed q0df"f(d$j0q50@0 and my problem was solved with little thought." Cool. The same thing can be accomplished in emacs with something like: C-x ( M-z C-s ( C-b C-k C-u 50 C-x e It's 19 characters against yours 16. And it can be reduced if you use F3 and F4, like someone noted. And, naturally, you can also edit emacs macros
- dpritchett 16y agoThanks for the comparison. I took a few tips on Vim macros yesterday and shortened mine: qqdf"t(D+@qq@q qq opens a macro in register q df" deletes through the first " t( jumps to the character before the next ( D deletes to end of line + jumps to the beginning of the next line @q recursively calls macro q q@q stops recording macro q, calls it once
- Xurinos 16y agoThis post is actually wrong on many accounts. For example, you'll find that M-Z followed by C-s is followed by immediate disappointment. It also does not save the macro or even do what the vim macro does (going to the beginning of the next line before starting the macro), which would cause it to fail catastrophically. The real sequence (based on this one) is this: C-x ( M-z " C-s ( C-b C-b C-k Home Down C-x ) C-u 50 C-x e I did two "C-b"s. I did that as more of a way to get out of the search mode quickly and lead into the next move. The first C-b could be an enter. The second C-b could be a left arrow, saving a keystroke but taking you off the main keyboard; however, I thought it would be nice to hold down the ctrl the whole time and just double-tap the b, so I will be keeping that in mind for keystroke count. Not that this is a problem in emacs... after all, you are having to hold down ctrl or meta throughout most of the process here, so you have to make stretches. If we count holding down the ctrl and meta keys as characters/keystrokes (and we also need to count the shift key), we have a total of 29 keystrokes. I would not personally use the C-u combo, though, for numbers. I just held down Meta. That reduces your keystrokes to 28. And it is 27 if you use enter and left arrow instead of C-b C-b... the fingering is more awkward and arguably slower, but it will work (as opposed to the other NOT working) if you are not in highlight search mode. I gave all the shortcuts I knew about (not retyping ctrl in silly places, etc), but all those shift keys and finger switches add up. With vim, you will find that you do a lot less of this song and dance with modifiers. His improved/correct vim macro, btw, is qqdf"t(Dj0q50@q which has a total count of 18, counting smart use of the shift key. The finger stretches are a lot shorter and the feel more natural. Try both combos as listed (I am using a 28 keystroker for feel), and you should see what I mean. qqdf"t(Dj0q50@q C-x ( M-z " C-s ( C-b C-b C-k Home Down C-x ) M-5 M-0 C-x e In other words, there is additional value over just number of keystrokes. Note... if 50 was the wrong guess at the number of lines, he does not have to type @q or @0 again to recall the last macro used. He can just type @@. This makes life much easier in an uncertain wall of text. Edit: Parbo's suggestion of using function keys (which looks like only one macro can be used at a time) brings the emacs count down a little at the expense of flying to the top of your keyboard: -6 keystrokes, leaving us with about 22. Try that for feel as well: qqdf"t(Dj0q50@q F3 M-z " C-s ( C-b C-b C-k Home Down F4 M-5 M-0 C-x e