Best way to repeat a sequence of keystrokes/commands with a single keypress ?

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Best way to repeat a sequence of keystrokes/commands with a single keypress ?

Ivan Vecerina
Hi,
I sometimes want to repeat a sequence of operations
like I would repeat a single command.
For example, I can repeat with '.' something like:
 gI//<ESC>    {is a single operation '.' repeats all}
But I cannot as easily repeat:
 02r/    { '.' will repeat the 2r/ , but not the move to 0 }

[ Let's not focus on the example sequence I am using here,
  I do know that there are other ways to comment a line ]

The obvious choice to repeat multiple operations is to record
a macro (for example:  qq02r/q ), and replay it with @q.
Unfortunately, '.' after @q only replays the last action
within the macro, not the whole macro execution.
So I have to repeatedly type two awkward keys (@q) instead
of being able to use the dot command to repeat the whole
sequence of operations.
 [ I wonder why this behavior was chosen. Is there any
   way to have '.' repeat the whole macro instead ?    ]

Occasionally, I will create a temporary keyboard mapping,
only to be able to more easily repeat an edit sequence.


Am I missing an easier way ?


Thanks,
Ivan
--
http://ivan.vecerina.com/





 
____________________________________________________________________________________
Get your own web address.  
Have a HUGE year through Yahoo! Small Business.
http://smallbusiness.yahoo.com/domains/?p=BESTDEAL
Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

Tim Chase-2
> I sometimes want to repeat a sequence of operations
> like I would repeat a single command.
[cut]
> The obvious choice to repeat multiple operations is to record
> a macro (for example:  qq02r/q ), and replay it with @q.
> Unfortunately, '.' after @q only replays the last action
> within the macro, not the whole macro execution.
> So I have to repeatedly type two awkward keys (@q) instead
> of being able to use the dot command to repeat the whole
> sequence of operations.

Once you have run a macro once (with "@q"), you can re-run it
with "@@" which is considerably easier to type.

Additionally, if your macro moves you to the next point where
you'd issue the macro again, and you know you want to repeat it N
times, you can prefix the macro-execution with a count, such as

        23@q

will run the "q" macro 23 times.

You can read more if you need at

        :help @@

Alternatively, problems can often be rephrased in terms of an Ex
command that uses the ":%s" or ":g"/":v" to perform changes
across the entire file.  While you didn't want to focus on your
commenting example, one could do something like

        :g/foo/s!^!//

which would comment out every line containing "foo".  By changing
your thinking to exploit these commands, sometimes you can get
easy consistent changes without having to manually touch each bit
with a macro.  Knowing both macros and obscure corners of Ex, I
find I don't record macros all that often (maybe once every month
or so) but tend to use automated Ex commands to surgically alter
my text.

Hope this helps or at least gives you a couple new ideas,

-tim




Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

Jürgen Krämer
In reply to this post by Ivan Vecerina

Hi,

Ivan Vecerina wrote:

>
> I sometimes want to repeat a sequence of operations
> like I would repeat a single command.
> For example, I can repeat with '.' something like:
>  gI//<ESC>    {is a single operation '.' repeats all}
> But I cannot as easily repeat:
>  02r/    { '.' will repeat the 2r/ , but not the move to 0 }
>
> [ Let's not focus on the example sequence I am using here,
>   I do know that there are other ways to comment a line ]
>
> The obvious choice to repeat multiple operations is to record
> a macro (for example:  qq02r/q ), and replay it with @q.
> Unfortunately, '.' after @q only replays the last action
> within the macro, not the whole macro execution.
> So I have to repeatedly type two awkward keys (@q) instead
> of being able to use the dot command to repeat the whole
> sequence of operations.
>  [ I wonder why this behavior was chosen. Is there any
>    way to have '.' repeat the whole macro instead ?    ]

you can use @@ to repeat the execution of the last macro.

Regards,
Jürgen

--
Sometimes I think the surest sign that intelligent life exists elsewhere
in the universe is that none of it has tried to contact us.     (Calvin)
Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

Ivan Vecerina
In reply to this post by Ivan Vecerina
Thank you (and Jürgen too), @@ is an easy first step for me.

Next:

 

"Tim Chase" <[hidden email]> wrote in message news:[hidden email]...

: Alternatively, problems can often be rephrased in terms of an Ex
:
command that uses the ":%s" or ":g"/":v" to perform changes
: across the
entire file.

[...]

: By changing
: your thinking to exploit these commands, sometimes you
can get
: easy consistent changes without having to manually touch each
bit
: with a macro.

 

I admit that I am currently more of a visual "n.n.nn.nn." kind

of person. I should take some time to get into using Ex.

 

If I may seek further guidance with a concrete example:

 



While editing a file, I decide to rename "someIdentifier" to
"someIdentifier_" - I will need to append the underscore to
several (but usually not all) instances of the word.

Starting in normal mode at the first instance of "someIdentifier",

I would type:   *ea_<ESC>

But then I cannot use the "n.nn." routine to modify subsequent

identifiers -- because the '.' will not apply the change at

the end of the word.   (I would have to type "ne.nne.")

 

The same would happen if I want to rename "wonderfulFoo" to

"wonderfulBar".  I tend to type:   *fFceBar<ESC>

But then I cannot use "n.nn." to repeat (but maybe "n;.nn;.").

 

So: I like using the n-dot pair of commands, but I can only

    take advantage of it if I rewrite the whole identifier.

 

 

How would I use Ex or another approach to save me some typing

during the process described above (for example repeatedly

appending '_' to an identifier) ?


And can this trick still be easily applied if only some instances

of the identifiers are to be replaced ?

 

 

Thanks !

Ivan

 

 

[ wow... I'll be called a nuthead for asking such a question

  anywhere else on the net ... hopefully not here ;) ]






 
____________________________________________________________________________________
It's here! Your new message!  
Get new email alerts with the free Yahoo! Toolbar.
http://tools.search.yahoo.com/toolbar/features/mail/
Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

Ivan Vecerina
In reply to this post by Ivan Vecerina
[ again, trying to workaround messy newline conversions ]
Thank you (and Jürgen too), @@ is an easy first step for me.
Next:

"Tim Chase" <[hidden email]> wrote in message news:[hidden email]...
: Alternatively, problems can often be rephrased in terms of an
: Ex command that uses the ":%s" or ":g"/":v" to perform
: changes across the entire file.
[...]
: By changing
: your thinking to exploit these commands, sometimes you
: can get easy consistent changes without having to
: manually touch each bit with a macro.

 I admit that I am currently more of a visual "n.n.nn.nn." kind
of person. I should take some time to get into using Ex.

 If I may seek further guidance with a concrete example:

 While editing a file, I decide to rename "someIdentifier" to
"someIdentifier_" - I will need to append the underscore to
several (but usually not all) instances of the word.
Starting in normal mode at the first instance of "someIdentifier",
I would type:   *ea_<ESC>
But then I cannot use the "n.nn." routine to modify subsequent
identifiers -- because the '.' will not apply the change at
the end of the word.   (I would have to type "ne.nne.")

 The same would happen if I want to rename "wonderfulFoo" to
"wonderfulBar".  I tend to type:   *fFceBar<ESC>
But then I cannot use "n.nn." to repeat (but maybe "n;.nn;.").

So: I like using the n-dot pair of commands, but I can only
    take advantage of it if I rewrite the whole identifier.


How would I use Ex or another approach to save me some typing
during the process described above (for example repeatedly
appending '_' to an identifier) ?

And can this trick still be easily applied if only some instances
of the identifiers are to be replaced ?


Thanks !
Ivan

[ wow... I'll be called a nuthead for asking such a question
  anywhere else on the net ... hopefully not here ;) ]





 
____________________________________________________________________________________
Sucker-punch spam with award-winning protection.
Try the free Yahoo! Mail Beta.
http://advision.webevents.yahoo.com/mailbeta/features_spam.html
Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

Tim Chase-2
In reply to this post by Ivan Vecerina
 > Thank you (and Jürgen too), @@ is an easy first step for
 > me.

Glad to have some easy first steps to help you out.

 >> Alternatively, problems can often be rephrased in terms
 >> of an Ex command that uses the ":%s" or ":g"/":v" to
 >> perform changes across the entire file.
 >
 > [...]
 >
 >> By changing your thinking to exploit these commands,
 >> sometimes you can get easy consistent changes without
 >> having to manually touch each bit with a macro.
 >
 > I admit that I am currently more of a visual "n.n.nn.nn." kind
 > of person. I should take some time to get into using Ex.
 >
 > If I may seek further guidance with a concrete example:

Of course :)

 > While editing a file, I decide to rename "someIdentifier" to
 > "someIdentifier_" - I will need to append the underscore to
 > several (but usually not all) instances of the word.

The typical way to do this would be something like

   :%s/\<someIdentifier\>/&_/g

If you want confirmation, you can use

   :%s/\<someIdentifier\>/&_/gc

which will prompt you for each instance of "someIdentifier"
that it finds, and append an underscore if you answer "y" to
the question.

The "\<" and "\>" ensure that there are word-boundaries (as
defined by your 'iskeyword' setting) which prevent it from
finding and replacing things like "wholesomeIdentifier" and
"someIdentifier2"

The ampersand in the replacement stands for "whatever it was
that I found, drop it here in the replacement".  This is
shorthand for

   :%s/\<someIdentifier\>/someIdentifier_/g

 > The same would happen if I want to rename "wonderfulFoo" to
 >
 > "wonderfulBar".  I tend to type:   *fFceBar<ESC>

Similarly, one would do something like

   :%s/\<wonderfulFoo\>/wonderfulBar/g

(again with the "c"onfirmation flag if you want to confirm
each replacement)

You can read about ":s"ubstitute commands and the various
flags at

   :help :s
   :help :s_flags

This is a jet-fuel-powered version of search-and-replace
that one finds in most editors.  The {pattern} portion has
an incredible degree of complexity for finding precisely the
match you intend, including context, repetitions, and the
like.  Far too much erudition can be found at

   :help pattern

There are also tricks that can be done in the replacement
portion as well:

   :help sub-replace-special


It's prob. more than you want/need at the moment, but after
tapping the power of vim's search&replace, it bugs me to use
s&r in any other app.

 > But then I cannot use "n.nn." to repeat (but maybe "n;.nn;.").
 > How would I use Ex or another approach to save me some typing
 > during the process described above (for example repeatedly
 > appending '_' to an identifier) ?

If you have trouble with the above, you can do some
transitional work as long as you don't mind a little mental
arithmetic.  For you first example, you can use the regular
search command as you normally do:

   /someIdentifier

but append

   /someIdentifier/e

which will drop your cursor at the end of the match (where
you can use "a_" followed by <esc> to append the underscore)
rather than at the beginning of it.  This will allow you to
use your "n.nn.n.nn." method, as it will put you in the
right place.  For your second example, you have to do a
little tweaking, as you want to be 3 characters from the
end, you have to use

   /someIdentifier/e-2

(curses on those silly fence-post issues) followed by
"ceBar" followed by <esc> to "c"hange to the "e"nd of the
word.  This too is repeatable with your "n.nn.n.n." pattern.
This is because the "n" and "N" operators remember the
offset as well, so they position you at the right place.

To read more on this, you can hit the help at

   :help search-offset

 > And can this trick still be easily applied if only some instances
 > of the identifiers are to be replaced ?

If you can identify them by certain factors, then vim can
handle them.

If, for instance, you only wanted to do the above
search&replace on lines containing "function" at the
beginning of the line, you could use

   :g/^function/s/\<wonderfulFoo\>/wonderfulBar/g

Things can get crazy-complex when you start building these,
but the expressive power allows you the freedom to make
surgically precise strikes on your text, for things like
"replace every instance of 'footnoteN' where N is an
arbitrary positive integer, with 3 added to N, but only from
the 314th line of my file through the end of text as
determined by the last line containing the word 'APPENDIX'
from the end of the file" (avert your eyes if you're easily
daunted)

:314,$?APPENDIX?s/footnote\zs\(\d\+\)/\=submatch(0)+3/g

from which you can discern the basic skeleton:

   :{range}s/{pattern}/{replacement}/{flags}

where
   range = 314,$?APPENDIX?
   pattern = footnote\zs\(\d\+\)
   replacement= \=submatch(0)+3
   flags = g

(pedant's note: if APPENDIX falls on the last line, it won't
find it)

 > [ wow... I'll be called a nuthead for asking such a question
 > anywhere else on the net ... hopefully not here ;) ]

The vim-list is yet one more of Vim's amazing assets.  It's
a friendly bunch, and rather on-topic (barring
semi-off-topic discussions about moving the tips/scripts bit
of vim.org to a wiki).  I've been a regular user of Vim for
nearly 7 years, and still regularly learn things sipping at
the list's firehose.

Hope this helps,

-tim





Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

A.J.Mechelynck
In reply to this post by Ivan Vecerina
Ivan Vecerina wrote:
[...]
> While editing a file, I decide to rename "someIdentifier" to
> "someIdentifier_" - I will need to append the underscore to
> several (but usually not all) instances of the word.
[...]

Here's how I would do that:

Let's assume your current directory (as shown by ":pwd") is the top directory
of the project in question, and that you want to check all *.pro, *.cpp, *.c
and *.h files in that directory and below.

        :args ./**/*.pro ./**/*.cpp ./**/*.[ch]
        :argdo 1,$s/\<someIdentifier\>/\0_/gc | update

The first line sets the argument list to the project files.

The second line runs a common set of commands on all the files in the argument
list, as follows:

        1,$       from first to last line of the file
        s/        substitute what?
        \<        begin-of-word (zero-length)
        someIdentifier
        \>        end-of-word (zero-length)
        /         replace by what?
        \0        the whole matched string
        _         plus an underscore
        /         start of replace flags
        g         everywhere (not only first time) in the line
        c         with "confirmation" prompt
        | update  then write the file if modified

The confirmation prompt takes care of your "...(but usually not all)..."
restriction by showing you each possible replace in turn, asking for a yes/no
decision. The ":update" command saves each file (if modified) before examining
the next, and is not needed if at least one of 'autowrite' and 'autowriteall'
is on (which is not the default).


Best regards,
Tony.
--
Sex is one of the nine reasons for reincarnation ... the other eight
are unimportant.
                -- Henry Miller
Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

A.J.Mechelynck
In reply to this post by Tim Chase-2
Tim Chase wrote:
[...]

> You can read about ":s"ubstitute commands and the various
> flags at
>
>   :help :s
>   :help :s_flags
>
> This is a jet-fuel-powered version of search-and-replace
> that one finds in most editors.  The {pattern} portion has
> an incredible degree of complexity for finding precisely the
> match you intend, including context, repetitions, and the
> like.  Far too much erudition can be found at
>
>   :help pattern

far too much indeed, but there is a nice summary at

        :help pattern-overview

>
> There are also tricks that can be done in the replacement
> portion as well:
>
>   :help sub-replace-special
>
>
> It's prob. more than you want/need at the moment, but after
> tapping the power of vim's search&replace, it bugs me to use
> s&r in any other app.
[...]


Best regards,
Tony.
--
There was a young man of St. John's
Who wanted to bugger the swans.
        But the loyal hall porter
        Said, "Pray take my daughter!
Those birds are reserved for the dons."
Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

Ivan Vecerina
In reply to this post by Ivan Vecerina
"Tim Chase" <[hidden email]> wrote in message news:[hidden email]...
: > While editing a file, I decide to rename "someIdentifier" to
: > "someIdentifier_" - I will need to append the underscore to
: > several (but usually not all) instances of the word.
:
: The typical way to do this would be something like
:
:   :%s/\<someIdentifier\>/&_/g
:
: If you want confirmation, you can use
:
:   :%s/\<someIdentifier\>/&_/gc

Ok. So a possible shortcut to type this could be:
   *:%s/<C-R>//&_/gc
Then: yn to accept/reject substitutions.

: > The same would happen if I want to rename "wonderfulFoo" to
: >
: > "wonderfulBar".  I tend to type:   *fFceBar<ESC>
:
: Similarly, one would do something like
:
:   :%s/\<wonderfulFoo\>/wonderfulBar/g

Makes sense.
Yet I liked the alternative:

: [...]  For your second example, you have to do a
: little tweaking, as you want to be 3 characters from the
: end, you have to use
:
:   /someIdentifier/e-2

Nice!  Damn, I remember reading about this flag,
but I failed to think of using it !
So here, the "find + replace end of word" can be
typed as:   */<C-R>//e-2<CR>ceBar<ESC>
Then: n.n to accept/reject substitutions.

[ snipped: examples of the power of :s/.../ ]

I like the simplicity/predictability of "n.", especially when reworking a function/small block within a larger file.
But I am not petrified by regular expressions either -- I have been doing some perl programming (though I really am a C++ veteran).
After 8 months of vimming (I started with http://www.viemu.com/), it is time for me to get more fluent with Ex commands.

Just let me first enjoy the /../e trick for a couple of weeks...

: Hope this helps,

It did !  Thanks a lot.

[ Thank you Tony as well for the additional references and advice for multi-file substitutions. ]


Kind regards,
Ivan


--
http://ivan.vecerina.com/





 
____________________________________________________________________________________
TV dinner still cooling?
Check out "Tonight's Picks" on Yahoo! TV.
http://tv.yahoo.com/
Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

Tim Chase-2
 > Ok. So a possible shortcut to type this could be:
 >    *:%s/<C-R>//&_/gc
 > Then: yn to accept/reject substitutions.

Definitely, if that's good with your workflow.  I find
it disturbing to jump to another location (triggered by
the initial "*") so I tend not to use it, but your way
is certainly parsimonious with the keystokes :)  I've
been known to use

   :%s/\<<C-R><C-W>\>/&_/gc

where ^R followed by ^W pulls in the word under the
cursor.  However, if I already have used */# to search
forward/backward, and I know it's in my search
register, I do exactly as you describe.

Sometimes, having the "\<" and "\>" aren't that
important, so it just becomes

   :%s/<c-r><c-w>/&_/gc

The nice thing about vim is that there are a number
ways to do things, and you can use whatever suits you
at the time.

 >>   :%s/\<wonderfulFoo\>/wonderfulBar/g
 >
 > Makes sense.
 > Yet I liked the alternative:
 >
 >> [...]  For your second example, you have to do a
 >> little tweaking, as you want to be 3 characters from
 >> the end, you have to use
 >>
 >>   /someIdentifier/e-2
 >
 > Nice!  Damn, I remember reading about this flag,
 > but I failed to think of using it !
 > So here, the "find + replace end of word" can be
 > typed as:   */<C-R>//e-2<CR>ceBar<ESC>
 > Then: n.n to accept/reject substitutions.

While I occasionally use the "/e" modifier, I rarely
use the "/e{offset}" modifier because it requires too
much thought on my part...but again, the limitation
is my wetware, not my software :)

 > I like the simplicity/predictability of "n.",
 > especially when reworking a function/small block
 > within a larger file.  But I am not petrified by
 > regular expressions either -- I have been doing some
 > perl programming (though I really am a C++ veteran).

Heh, if you can handle Perl, Vim's regexps are a walk
in the park. :)

If you're already comfortable with regexps, it's just
coming to the realization of "Hmmm...a good regexp here
would save me a lot of time", and learning to recognize
those times.

 > After 8 months of vimming (I started with
 > http://www.viemu.com/), it is time for me to get more
 > fluent with Ex commands.

like opening a tool-chest, seeing a power-drill, and
not knowing what it's for, so you stick with your
manual screw-driver.  beware the dark side ;)

Sorry for the long ramble on :s stuff in my previous
post...just showing a little of what Ex can do. :)

 > Just let me first enjoy the /../e trick for a couple
 > of weeks...

As mentioned above...use what works best for you and
your workflow.  Some folks work best with macros, some
[myself included] use Ex commands, and some use
whatever they know or works for them.  You don't seem
daunted by trying new things, so experiment away! :)

-tim





Reply | Threaded
Open this post in threaded view
|

Re: Best way to repeat a sequence of keystrokes/commands with a single keypress ?

Karl Guertin
I flip between ex commands and macros for semi-automated file
conversion and most of what I'd say has been covered, but I'll toss in
a personal quirk from my .vimrc.

By default, both ` and ' do approximately the same thing in that they
jump to a mark (' is a linewise `, it positions the cursor at ^ in the
destination line). Since I don't find ' to be particularly useful, I
remap it to @a and record my macros to "a (qa...q):

  "executes the macro in register a
  nnoremap ' @a

  "repeats the macro in register a for the entire visual selection
  xnoremap ' :normal @a<CR>

I find this to be convenient and it provided an easy way to
record/execute macros when I was learning vim.