Practical Vim< /a> vit Practical Vim< /a> Note that the styling for a Visual selection is the... development I thought I knew Vim, but Practical" name="description"/>
Tải bản đầy đủ - 0 (trang)
Tip 69. Act Upon a Collection of Files

Tip 69. Act Upon a Collection of Files

Tải bản đầy đủ - 0trang

Chapter 11. Macros



• 170



macros/ruby_module/animal.rb

# ...[end of copyright notice]

class Animal

# implementation

end



We’ll wrap the class in a module to end up with this:

# ...[end of copyright notice]

module Rank

class Animal

# implementation...

end

end



Preparation

Source these lines of configuration to reproduce the examples in this tip:

macros/rc.vim

set nocompatible

filetype plugin indent on

set hidden

if has("autocmd")

autocmd FileType ruby setlocal ts=2 sts=2 sw=2 expandtab

endif



The ‘hidden’ option is discussed in more depth in Enable the ‘hidden’ Setting

Before Running ‘:argdo’ or ‘:bufdo’, on page 84.

If you’d like to follow along, consult Section 3, Downloading the Examples,

on page xxii. The directory code/macros/ruby_module contains the set of files that

we’ll be working with.



Build a List of Target Files

Let’s stake out the terrain by building a list of the files that we want to act

upon. We’ll keep track of them using the argument list (for more details, see

Tip 37, on page 80):









:cd code/macros/ruby_module

:args *.rb



Running :args without arguments reveals the contents of the list:









:args

[animal.rb] banker.rb frog.rb person.rb



We can navigate through this list of files using the :first, :last, :prev, and :next

commands.



www.it-ebooks.info



report erratum • discuss



Act Upon a Collection of Files



• 171



Record a Unit of Work

Before we begin, let’s make sure we’re at the start of the arguments list:







:first



Now let’s record a macro that performs the necessary work:

Keystrokes



Buffer Contents



qa



# ...[end of copyright notice]

class Animal

# implementation...

end



gg /class



# ...[end of copyright notice]

class Animal

# implementation...

end



O module Rank



# ...[end of copyright notice]

module Rank

class Animal

# implementation...

end



j>G



# ...[end of copyright notice]

module Rank

class Animal

# implementation...

end



Go end



# ...[end of copyright notice]

module Rank

class Animal

# implementation...

end

end



q



# ...[end of copyright notice]

module Rank

class Animal

# implementation...

end

end



Each of these files begins with a copyright notice, so we have to take care to

properly normalize the cursor position. Pressing gg places the cursor at the

start of the file, and /class jumps forwards to the first occurrence of the

word “class.” Having made these preparatory steps, we can now proceed to

make the changes.

We use the O command to open a new line above the cursor, inserting the

new text. Then we advance our cursor to the next line, where we use the >G



www.it-ebooks.info



report erratum • discuss



Chapter 11. Macros



• 172



command to indent each line up to the end of the file. Finally, we jump to the

end of the file by pressing G and then using the o command to create a new

line below the cursor, inserting the end keyword there.

If you’re following along with your editor, try to resist the urge to save your

changes to the file by running :w. We’ll see why in a moment.



Execute the Macro in Parallel

The :argdo command allows us to execute an Ex command once for each buffer

in the argument list (see :h :argdo ). But if we were to run :argdo normal @a right

now, there would be side effects.

Think about it. Running :argdo normal @a executes the macro that we just

recorded in all of the buffers in the argument list, including the first one: the

one that we changed as we recorded the macro. As a result, the first buffer

gets wrapped in a module twice over.

To prevent this, we’ll revert all of the changes we just made to the first buffer

in the argument list by running :edit! (see :h :edit! ):







:edit!



If you had already written the changes to a file, then :edit! won’t work. In this

case, you could just use the u command repeatedly until the file looked as it

did when you opened it.

Now we can go ahead and execute the macro in all of the buffers in the

argument list:







:argdo normal @a



This technique takes a bit of setup, but that one command does a lot of work

for us. Now let’s see how we could adapt this macro to run in series.



Execute the Macro in Series

Our macro performs a single unit of work on a single buffer. If we want to

make it act upon multiple buffers, we could append a final step that advances

to the next buffer in the list. (See Table 18, Executing the Macro in Series, on

page 173.)

While we could run 3@a to execute the macro on each of the remaining files

in the buffer list, there’s no need to be so precise about it. When we reach

the last buffer in the argument list, the :next command fails and the macro

aborts. So, rather than specifying an exact count, we only have to ensure that

we provide a number that’s large enough: 22 will do, and it’s easy to type.



www.it-ebooks.info



report erratum • discuss



Act Upon a Collection of Files



Keystrokes



Buffer Contents



qA



module Rank

class Animal

# implementation...

end

end



:next



class Banker

# implementation...

end



q



class Banker

# implementation...

end



22@a



class Banker

# implementation...

end



• 173



Table 18—Executing the Macro in Series



Save Changes to All Files

We’ve changed four files, but we haven’t saved any of them yet. We could run

:argdo write to save all files in the argument list, but it would be quicker simply

to run this:







:wall



Note that this saves all files in the buffer list, so it’s not exactly equivalent to

:argdo write (see :h :wa ).

Another useful command is :wnext (see :h :wn ), which is equivalent to running

:write followed by :next. If you are executing a macro in series across several

files in the argument list, you may prefer to use this.



Discussion

Suppose that something caused the macro to fail while executing on the third

buffer in the argument list. If we were using the :argdo normal @a command,

then the macro would fail only in that one buffer, whereas if we executed the

macro in series by using a count, then it would abort, and any items that

follow in the argument list would be left unchanged.

We’ve already seen this effect in Tip 67, on page 164. But the consequences

are slightly different this time. When we performed the same task on a block

of adjacent lines, we could see everything at a glance. If anything went wrong,

it was there right in front of our eyes.



www.it-ebooks.info



report erratum • discuss



Chapter 11. Macros



• 174



This time we’re working on a set of files, so we can’t see everything in a single

glance. If we execute the macro in series and it fails, then it will halt at the

place where the error occurs, whereas if we execute the macro in parallel and

it fails, we’ll have to browse through the argument list until we find the buffer

where the error was raised.

In the case where an error is raised, running the macro in parallel may complete the job faster, but it conceals useful information.



Tip 70



Evaluate an Iterator to Number Items in a List

Being able to insert a value that changes for each execution of a macro can be

useful. In this tip, we’ll learn a technique for incrementing a number as we

record a macro so that we can insert the numbers 1 to 5 on consecutive lines.

Suppose that we want to create a numbered list from a series of items on

adjacent lines. To demonstrate, we’ll start with this text:

macros/incremental.txt

partridge in a pear tree

turtle doves

French hens

calling birds

golden rings



We’ll transform it to look like this:

1)

2)

3)

4)

5)



partridge in a pear tree

turtle doves

French hens

calling birds

golden rings



We’ve already learned a couple of ways to make Vim perform simple arithmetic.

We can either use the and commands with a count (see Tip 10,

on page 20), or we can use the expression register (see Tip 16, on page 31).

For this solution, we’ll use the expression register with a touch of Vim script.



Rudimentary Vim Script

Let’s begin by stepping through a few simple command-line invocations. Using

the let keyword, we can create a variable called i and assign it a value of 0.

The :echo command allows us to inspect the current value assigned to a

variable.



www.it-ebooks.info



report erratum • discuss



Evaluate an Iterator to Number Items in a List











• 175



:let i=0

:echo i

0



We can increment the value of i:











:let i += 1

:echo i

1



The :echo command is fine for revealing the value that is assigned to a variable,

but ideally we want to insert that value into the document. We can do that

using the expression register. In Tip 16, on page 31, we saw that the expression register can be used to do simple sums and to insert the result into the

document. We can insert the value stored in variable i just by running

=i in Insert mode.



Record the Macro

Now let’s put all of this together:

Keystrokes



Buffer Contents



:let i=1



partridge in a pear tree



qa



partridge in a pear tree



I= i )



1) partridge in a pear tree





:let i += 1



1) partridge in a pear tree



q



1) partridge in a pear tree



Before we begin recording the macro, we set the variable i to 1. Inside the

macro, we use the expression register to insert the value stored in i. Then,

before we finish recording the macro, we increment the value stored in the

variable, which should now contain the value 2.



Execute the Macro

We can then play it back for the remaining lines, as shown in Table 19, Executing the Macro for the Remaining Lines, on page 176.

The :normal @a command tells Vim to execute the macro on each of the selected

lines (see Execute Macro in Parallel, on page 167). The value of i is 2 to begin

with, but it gets incremented each time the macro executes. The end result

is that each line is prefixed with consecutive digits.



www.it-ebooks.info



report erratum • discuss



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tip 69. Act Upon a Collection of Files

Tải bản đầy đủ ngay(0 tr)

×