Thursday, December 26, 2013

Re: Macros in Vim

On 25/12/13 20:24, DwigtArmyOfChampions wrote:
> So many tutorials tell me how to record a macro and how to run it. But nowhere does it say what I'm supposed to do with them. I don't understand what kinds of commands usually get recorded in macros? What are some examples of really good, efficient, time-saving macros?
>
The difference between macros and mappings is not always obvious, even
from the help (":help macro" is a synonym to ":help mapping" and ":help
key-mapping") so first, a little bit of terminology (explaining how _I_
use those two terms) then I'll try to explain both of them.

By "macro" I mean something that you record by doing it, and (before
doing it, in fact) assign to a register. It may be remembered in the
viminfo, together with other registers; or you may use a macro for a
short time (even less than a session) then never again.

By "mapping" I mean something that you record, but not by doing it, and
assign to a key or sequence of keys. A good place to store general-use
mappings is in your vimrc; specific filetype-dependent mappings can also
be defined buffer-locally by a filetype-plugin. Throwaway mappings are
possible but rare.


I. MAPPINGS
===========

Mappings are, in my experience, the most used, so I'll talk about them
first. There are two main categories of them, with a number of subtypes:

Mappings for used in Normal and Visual modes (in all cases, {lhs} means
left-hand side, {rhs} means right-hand side, and each of them must be
replaced by one or more keystrokes, represented either by a character or
by a <> symbolic name):

:map {lhs} {rhs}
and subtypes
:nmap {lhs} {rhs} (Normal only)
:vmap {lhs} {rhs} (Visual and Select)
:xmap {lhs} {rhs} (Visual only)
:smap {lhs} {rhs} (Select only)
:omap {lhs} {rhs} (Operator-pending)

Mappings for use in Insert and Command-line modes:
:map! {lhs} {rhs}
and subtypes
:imap {lhs} {rhs} (Insert only)
:cmap {lhs} {rhs} (Command-line only)

In all the above ex-command names, replace "map" by "noremap" if you
want to FORBID reinterpretation of the {rhs} for further mappings after
running the mapping.

Before the {lhs} you can also use one or more of the options <buffer>
<script> <expr> etc. shown under ":help map-arguments". For example,
<expr> will treat the {rhs} as an arithmetic expression, and use the
_result_ of evaluating (computing) the expression. The computation is
done at runtime, after you hit the {lhs} key or key sequence to trigger
the mapping. Or <buffer> means that the mapping will only apply to the
buffer (the editfile) which was current when the mapping was defined.
Etcetera.

In addition to the quickfix mappings already shown by Shlomi Fish (which
I assign to <F2> and <S-F2> as the {lhs} but of course which {lhs} to
use is a matter of choice), here are a few more, copied from my vimrc:

:map <F3> :wa|wv<CR>
:imap <F3> <C-O>:wa|wv<CR>

to save my work (all edit buffers and the viminfo) by hitting F3 in any
mode other than Command-line mode. This will give a warning if there are
any modified unnamed buffers.

:map <F11> <C-W>w
:map <S-F11> <C-W>W
:imap <F11> <C-O><C-W>w
:imap <S-F11> <C-O><C-W>W

to go to the next split-window (right or below the current one) with
F11, to the previous one (left or above) with Shift-F11, and to a
specific window by number (number 1 being at top left) with either of
them preceded by a count. This will also work in any mode other than
Command-line mode.


II. MACROS
==========

Macros are sequences of keys that you record by doing them, maybe
because you have no precise idea beforehand about which exact keys you
will need to hit in what order to arrive at the desired result. They are
also usually less permanent than mappings. Be forewarned that any
lapses, erase-and-corrects, etc. that you do while recording will be
_part_ of the recording, and will be done again every time you repeat
the macro.

Each macro is recorded in a register, so each of them _occupies_ one
register which cannot be used for anything else at the same time. Since
there are only 26 "letter" registers usable for that kind of job, you
should be sparing in assigning them. For throwaway macros, which I use
for some repetitive task and then never again (these are the kind of
macros I use most often), I reserve register q, because that way I know
that anything started by qq and ended by q is a macro (not including the
starting qq and ending q) and that I mustn't use register q for a yank,
delete or put. Also, a macro (unlike a mapping) always starts in Normal
mode, and even though it is possible to go back and forth between Normal
and Insert mode in a macro, you normally cannot insert a q by means of a
macro, so IMHO it is better to keep them for tasks done entirely in
Normal mode, where you won't use the q key except to start or stop a
macro -- and maybe as a register name, which is another reason to
reserve register q for the macro itself.

To "play" the macro I hit @ followed by the register letter: thus, in
the case mentioned, @q — if I wanted to repeat it _again_ as many times
as possible until Vim errors out, I would type 999@@ immediately after
the @q . There are other variations (less useful IMHO), see ":help
complex-repeat".

Sometimes I want a few macros to "persist" for a longer time, then I
first check ":reg" to see which registers are still available (holding
something that I can afford to discard, or unlisted which means not yet
holding anything) and then I decide on which ones to use. These macros
will still probably have been recorded by doing them, and of no use to
anyone but me, so listing them here wouldn't serve any purpose. The few
ones I have now aren't human-readable anyway when I list them by :reg


Best regards,
Tony.
--
There was a young lady from Spain
Who got sick as she rode on a train;
Not once, but again,
And again, and again,
And again, and again, and again.

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments: