简体   繁体   中英

vim macro until pattern is matched

I have an array of states that no one is going to have to modify often, so I want to remove the white space.

I tried the following keystrokes as there are some whitespace characters between the commas in the array and the endlines:

q a /, ENTER FORWARD v /\\n ENTER d

Unfortunately, whomever formatted this neglected to place any whitespace after 'Montana', so when I run the macro 51@a , it breaks after 27 iterations.

How can I have a macro only run a pattern if \\s is matched, or better yet, how can I run a macro until it recognizes ); (end of array).

EDIT: Here is an example. Note the two white space characters after all entries except keys MT , NE , NV and NH .

$state_list = array('AL'=>"Alabama",  
        'AK'=>"Alaska",  
        'AZ'=>"Arizona",  
        'AR'=>"Arkansas",  
        'CA'=>"California",  
        'CO'=>"Colorado",  
        'CT'=>"Connecticut",  
        'DE'=>"Delaware",  
        'DC'=>"District Of Columbia",  
        'FL'=>"Florida",  
        'GA'=>"Georgia",  
        'HI'=>"Hawaii",  
        'ID'=>"Idaho",  
        'IL'=>"Illinois",  
        'IN'=>"Indiana",  
        'IA'=>"Iowa",  
        'KS'=>"Kansas",  
        'KY'=>"Kentucky",  
        'LA'=>"Louisiana",  
        'ME'=>"Maine",  
        'MD'=>"Maryland",  
        'MA'=>"Massachusetts",  
        'MI'=>"Michigan",  
        'MN'=>"Minnesota",  
        'MS'=>"Mississippi",  
        'MO'=>"Missouri",  
        'MT'=>"Montana",
        'NE'=>"Nebraska",
        'NV'=>"Nevada",
        'NH'=>"New Hampshire",
        'NJ'=>"New Jersey",
        'NM'=>"New Mexico",
        'NY'=>"New York",
        'NC'=>"North Carolina",
        'ND'=>"North Dakota",
        'OH'=>"Ohio",  
        'OK'=>"Oklahoma",  
        'OR'=>"Oregon",  
        'PA'=>"Pennsylvania",  
        'RI'=>"Rhode Island",  
        'SC'=>"South Carolina",  
        'SD'=>"South Dakota",
        'TN'=>"Tennessee",  
        'TX'=>"Texas",  
        'UT'=>"Utah",  
        'VT'=>"Vermont",  
        'VA'=>"Virginia",  
        'WA'=>"Washington",  
        'WV'=>"West Virginia",  
        'WI'=>"Wisconsin",  
        'WY'=>"Wyoming"
);

To:

$state_list=array('AL'=>"Alabama",'AK'=>"Alaska",'AZ'=>"Arizona",'AR'=>"Arkansas",'CA'=>"California",'CO'=>"Colorado",'CT'=>"Connecticut",'DE'=>"Delaware",'DC'=>"District Of Columbia",'FL'=>"Florida",'GA'=>"Georgia",'HI'=>"Hawaii",'ID'=>"Idaho",'IL'=>"Illinois",'IN'=>"Indiana",'IA'=>"Iowa",'KS'=>"Kansas",'KY'=>"Kentucky",'LA'=>"Louisiana",'ME'=>"Maine",'MD'=>"Maryland",'MA'=>"Massachusetts",'MI'=>"Michigan",'MN'=>"Minnesota",'MS'=>"Mississippi",'MO'=>"Missouri",'MT'=>"Montana",'NE'=>"Nebraska",'NV'=>"Nevada",'NH'=>"New Hampshire",'NJ'=>"New Jersey",'NM'=>"New Mexico",'NY'=>"New York",'NC'=>"North Carolina",'ND'=>"North Dakota",'OH'=>"Ohio",'OK'=>"Oklahoma",'OR'=>"Oregon",'PA'=>"Pennsylvania",'RI'=>"Rhode Island",'SC'=>"South Carolina",'SD'=>"South Dakota",'TN'=>"Tennessee",'TX'=>"Texas",'UT'=>"Utah",'VT'=>"Vermont",'VA'=>"Virginia",'WA'=>"Washington",'WV'=>"West Virginia",'WI'=>"Wisconsin",'WY'=>"Wyoming");

EDIT:

Just googled vim macro until pattern matched, and came across my own question. I have a better example now:

    namespace A{
            class a{}
            class a{}
    }
    namespace B{
            class b{}
            class b{}
            class b{}
    }

Needs to become:

    namespace A{
            class Aa{}
            class Aa{}
    }
    namespace B{
            class Bb{}
            class Bb{}
            class Bb{}
    }

This cannot be solved with the previously accepted answer.

Honestly the easiest answer would be to join the lines.

If you visual select the entire region and just press J (or feed the range to :join ) all of the lines will end up on one line. (There may be excess whitespace in-between elements but thats easier to fix then trying to write the macro).

If you then want to remove the excess whitespace you could run

:s/,\s\+/,/g

on the joined line.

Take a look at :h J and :h :join

First of all, you can easily remove all trailing whitespace with one command:

:%s/\s\+$//e

That will work on every line of the file. If you want to do it only on this fragment of code, you can specify different range (instead of %, which is whole file). For example, you can pass line numbers (1 to 51):

:1,51s/\s\+$//e

or first visually select, and then run command removing whitespace (you have to be on the first line starting this sequence):

V/)<CR>:s/\s\+$//e

If you really want to use macro, you can slightly tweak (and simplify) your macro:

qa0f,lDq

and then run it on every line at once by first of all visually selecting all of them (again, start on line you want, I won't put gg here because it might be just part of the file):

V/)<CR>:normal @q

This will play the macro over every selected line, up to the line with ) .

I hope it helps :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM