vim word matching when moving

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

vim word matching when moving

Bahadir Balban
Hi,

I find the Q (recording) feature very handy. Using it I can move
around on function calls and for example add/remove an argument from
every occurence of a function.

For moving around, I am using the f command. e.g. in a function call:

function_call(arg1,arg2);

when cursor is at the begining of the file, I type, fa, to go to the
first occurence of 'a'

My questions:
1-) Is there a way to take this further, and match a whole word to go
forward to? For example f and a regular expression to match arg1 or
arg2. Could you give an example to this?

2) If I do, df} for example, I can delete everything on that line
until the '}', How could I do this for multiple lines, for example to
delete a whole structure, or function, or loop? Secondly, how can I
delete up to the second or third occurence of the char '}' ?

Thank you very much,
Bahadir
Reply | Threaded
Open this post in threaded view
|

Re: vim word matching when moving

Gareth Oakes-2
Hi there,

> For moving around, I am using the f command. e.g. in a function call:
>
> function_call(arg1,arg2);
>
> when cursor is at the begining of the file, I type, fa, to go to the
> first occurence of 'a'
>
> My questions:
> 1-) Is there a way to take this further, and match a whole word to go
> forward to? For example f and a regular expression to match arg1 or
> arg2. Could you give an example to this?

Maybe I'm missing something, but why don't you use the normal search
command?

/regex

For more help..
:help regex
:help /

> 2) If I do, df} for example, I can delete everything on that line
> until the '}', How could I do this for multiple lines, for example to
> delete a whole structure, or function, or loop? Secondly, how can I
> delete up to the second or third occurence of the char '}' ?

There's a bunch of movement commands to help you out here.  To get a
taster, put your cursor inside a block and go into normal mode (esc).
Now type "va}", without the quotes.  Replace the "v" in that command
with a "d" and you'll delete instead of select.  Or you could just as
easily type "d" straight after the "va}" to delete the selected area.

You can read more under..
:help motion

Cheers,
Gareth
Reply | Threaded
Open this post in threaded view
|

Re: vim word matching when moving

Tim Chase-2
In reply to this post by Bahadir Balban
> 1-) Is there a way to take this further, and match a whole word to go
> forward to? For example f and a regular expression to match arg1 or
> arg2. Could you give an example to this?

It sounds like you're just doing a regular search here, as done
with the "/" command.  This would allow you to subsequently use
n/N to find the next/previous instances of the regex.  Thus,
you'd just do

        /arg1regexp

and hit enter.  Is there something I'm missing?  The f/F/t/T
commands take a single character as their argument, so you can't
enter a regexp.

> 2) If I do, df} for example, I can delete everything on that line
> until the '}', How could I do this for multiple lines, for example to
> delete a whole structure, or function, or loop? Secondly, how can I
> delete up to the second or third occurence of the char '}' ?

Well, there are several ways.  One of which is to use the
associated text object.  If you're inside the {...} block, you can do

        di{

to delete the contents of those braces.  If you want to delete
the braces too, just change the "i" to an "a", as in

        da{

If you want to delete outer nested braces such as

        if (foo) {
                while (baz) {
                        baz = frob();
                }
        }

and you're on the "baz = frob()" line, you can do

        2di{

to delete the 2nd outer level (the if(foo) block), excluding the
braces (or again, "i"->"a" to do the braces too)

If your intent is to actually make changes, the "d" portion can
be changed to a "c" command to "change" the contents.  Thus, you
can do

        2ci{

to change the contents of the "if (foo)" block and just start
typing with the new contents.

Alternatively, if you just want to delete up to the Nth brace
from your current position, you can do (N=2 in this example)

        d2/}

This is an exclusive motion, meaning that the "}" character will
remain.  If you want to delete it in the same swoop, you can use

        d2/}/e

which includes through the end of the match.

More information can be found at

        :help search-offset
        :he objects
        :he text-objects
        :he a{
        :he i{
        :he ]}
        :he [{
        :he /

Hope these give you something to work with.

-tim





Reply | Threaded
Open this post in threaded view
|

Re: vim word matching when moving

Bahadir Balban
On 11/4/05, Tim Chase <[hidden email]> wrote:
> Hope these give you something to work with.
>
> -tim
>

Hi,

Thank you these were very useful. The reason I wanted to use motion
rather than /regex was that, I am recording a set of actions with Q,
and then repeating it on many functions. So my recordings are like, go
to the first argument, replace it with x, get back, go down 3 lines to
the next function, match the same argument ... etc. I guess I can also
do the same using /regex.

Thanks,
Bahadir
Reply | Threaded
Open this post in threaded view
|

Re: vim word matching when moving

Tim Chase-2
> Thank you these were very useful. The reason I wanted to use
> motion rather than /regex was that, I am recording a set of
> actions with Q, and then repeating it on many functions. So my
>  recordings are like, go to the first argument, replace it
> with x, get back, go down 3 lines to the next function, match
> the same argument ... etc. I guess I can also do the same
> using /regex.

It may be easier to use just a regular :global or :substitute
command.  The general format would be something like

        :g/regex_for_line/s/regex_for_arg/replacement/

If your args only fall on these function lines, then it can
easily be done in a single substitute pass, such as

        :%s/old_arg_regex/new_arg_regexp

Alternatively, you can use back references such as

        :%s/^\(function .\{-}\)arg_regex/\1replacement

Thus, if you had code of the form

        function foo(somearg) {
                dostuff
        }
        function bar(otherarg) {
                morestuff
        }

and you wanted to change "somearg" to "sSomearg" and "otherarg"
to "sOtherarg" you'd use

        :%s/^\(function .\{-}\)\(\a*arg\)/\1s\u\2

Or maybe that just muddies the waters for you :)

Just a few thoughts,

-tim





Reply | Threaded
Open this post in threaded view
|

Re: vim word matching when moving

Bahadir Balban
On 11/4/05, Tim Chase <[hidden email]> wrote:

> and you wanted to change "somearg" to "sSomearg" and "otherarg"
> to "sOtherarg" you'd use
>
>         :%s/^\(function .\{-}\)\(\a*arg\)/\1s\u\2
>
> Or maybe that just muddies the waters for you :)
>
> Just a few thoughts,
>
> -tim
>

I usually use sed to replace things, and just copy-paste replacement
one-liners I find on the web :) Need to read more on sed to understand
these. Is your example calling sed to do it, or is it a vim feature,
or a universal thing that both sed and vim supports?
Reply | Threaded
Open this post in threaded view
|

Re: vim word matching when moving

Tim Chase-2
> I usually use sed to replace things, and just copy-paste
> replacement one-liners I find on the web :) Need to read more
> on sed to understand these. Is your example calling sed to do
> it, or is it a vim feature, or a universal thing that both sed
> and vim supports?

Vim isn't calling sed in this case (though you can do that too).
  Both vim and sed support this feature.  They share common
ancestory (sorta[*]) to "ed" as vim traces a lineage somewhat like

        ed -> ex -> vi -> vim

while sed descends more directly

        ed -> sed

However, the "s/regexp/replacement/options" command is common to
them all.  The "regexp" portion has far more flexibility in vim
than in the others, but a strong knowledge of regexps can help
switch between them fairly uneventfully.

-tim

[*] I'm not sure if any code or libraries were shared between
them, but many of the ideas from one carried into its "ancestors".