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 liệu liên quan Tài liệu mớiTip 96. Find and Replace Across Multiple Files
Chapter 14. Substitution
• 234
Vim” but not when it appears in the phrase “Pragmatic Bookshelf.” This pattern will do the trick:
➾
/Pragmatic\ze Vim
This uses the \ze item to exclude the word “Vim” from the match (see Tip 77,
on page 192). Then we can run this substitute command:
➾
:%s//Practical/g
Next we just need to figure out how to execute that command across the entire
project.
Execute a Substitute Command on All Files in the Current Project
In Tip 37, on page 80, we learned that the :argdo command allows us to run
an Ex command in a set of files. We can use this technique to run the substitute command for all files in a project. But first, we must populate the
argument list with all of those files by running this:
➾
:args **/*.txt
We should do one more thing before we continue. Run this:
➾
:set hidden
This setting enables us to navigate away from a modified file without first
saving it. Refer to Tip 37, on page 80, for a more detailed discussion.
Now we can execute our substitution command in all of these files by running
this:
➾
❮
:argdo %s//Practical/g
E486: Pattern not found: Pragmatic\ze Vim
This gets the job done, but Vim reports a “Pattern not found” error in the
output. Remember, some of the files that we’re working with contain the
phrase “Pragmatic Bookshelf” but not “Pragmatic Vim.” So when the substitute
command is executed in these files, Vim throws an error.
The error message is just noise. Vim carries on regardless, executing the
substitute command for each of the remaining files. It’s not critical, but it
can be distracting, especially if we’re dealing with a larger list of files. Supplying the e flag to the substitute command will suppress these error messages.
So we could instead run this:
➾
:argdo %s//Practical/ge
And this way presents fewer distractions.
www.it-ebooks.info
report erratum • discuss
Find and Replace Across Multiple Files
• 235
Let’s pause for a moment and think about what we’ve done. Running :args
**/*.txt loads all files from the current project into the argument list. Then
when we run :argdo %s//Practical/ge, Vim proceeds to execute the substitute
command in every one of those files. Our example contains only a handful of
buffers, but in a real-world situation, the list could number in the hundreds
or thousands. Using this technique, we can be sure that we’ll hit our targets,
but we also run the substitute command unnecessarily many times over. It’s
a scatter-shot approach.
Let’s see if we can tighten our focus.
Build a List of Files Containing Our Target Pattern
How about if we break the problem into two steps? First we’ll perform a
project-wide search for our target pattern. Then we’ll run the substitute
command on the files that returned a positive match.
To perform a project-wide search, we’ll reach for the :vimgrep command (see
Chapter 18, Search Project-Wide with grep, vimgrep, and Others, on page 269).
Since this uses Vim’s built-in search engine, we can reuse the exact same
pattern. Try running this:
➾
➾
/Pragmatic\ze Vim
:vimgrep /
Pressing
Each match returned by vimgrep is recorded in the quickfix list (see Chapter
17, Compile Code and Navigate Errors with the Quickfix List, on page 259). We
can browse the results by running :copen, which opens the quickfix window.
But instead of stepping through the results, one at a time, we want to run
the substitute command on every file that appears in the quickfix list.
It would be convenient if Vim included a :quickfixdo command, but there is no
such thing. So instead we’ll use this small snippet of Vim script:
substitution/qargs.vim
command! -nargs=0 -bar Qargs execute 'args' QuickfixFilenames()
function! QuickfixFilenames()
let buffer_numbers = {}
for quickfix_item in getqflist()
let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr'])
endfor
return join(map(values(buffer_numbers), 'fnameescape(v:val)'))
endfunction
www.it-ebooks.info
report erratum • discuss
Chapter 14. Substitution
• 236
You can either add this code to your vimrc file or install it as a plugin.1
Now we can run :Qargs, and it will populate the argument list with each of the
files named in the quickfix list. If we run the substitute command in each of
the files in the argument list now, we can be sure that it only includes the
files that match our pattern. We can leave off the e flag, since we don’t anticipate the substitute command raising any errors.
Here’s the full sequence of commands:
➾
➾
➾
➾
➾
/Pragmatic\ze Vim
:vimgrep /
:Qargs
:argdo %s//Practical/g
:argdo update
The :update command saves the file, but only if it has been changed (see
:h update ). Note that the last three commands could be combined into one,
like this:
➾
:Qargs | argdo %s//Practical/g | update
The | character has a different meaning on Vim’s command line than shell
users might expect. Whereas in Unix, the pipe character passes standard
output from one command into the standard input of the next command
(creating a “pipeline”). On Vim’s command line, | simply stands for a command
separator, making it equivalent to the semicolon in the Unix shell. Look up
:h :bar
for more details.
Previously we used a scatter-shot approach, where the substitute command
was executed in every file in the project, whether or not that file contained
our target pattern. This strategy is a refinement. We still have to look inside
every file in the project, but this time we use vimgrep to do it. Then, with our
custom :Qargs command, we copy each file from the quickfix list into the
argument list. This allows us to be more focused when we run the substitute
command, only targeting the files that contain a match for our pattern.
A convenient side effect of this approach is that we are left with an argument
list containing each file that was changed by the substitute command. If we
want to review our changes, we can run :first and then step through the files
by running :next.
1.
https://github.com/nelstrom/vim-qargs
www.it-ebooks.info
report erratum • discuss
CHAPTER 15
Global Commands
The :global command combines the power of Ex commands with Vim’s pattern
matching abilities. We can use it to run an Ex command on each line that
matches a specified pattern. Alongside the Dot Formula and macros, the
:global command is one of Vim’s power tools for performing repetitive work
efficiently.
Tip 97
Meet the Global Command
The :global command allows us to run an Ex command on each line that matches
a particular pattern. Let’s start by studying its syntax.
The :global command takes the following form (see :h :g
):
:[range] global[!] /{pattern}/ [cmd]
The default range for the :global command is the entire file (%). That sets it
apart from most other Ex commands, including :delete, :substitute, and :normal,
whose range is the current line (.) by default.
The {pattern} field integrates with search history. That means we can leave it
blank and Vim will automatically use the current search pattern.
The [cmd] could be any Ex command except for another :global command. In
practice, Ex commands that interact with the text in the document prove
most useful, such as those in Table 9, Ex Commands That Operate on the Text
in a Buffer, on page 52. If we don’t specify a [cmd], then Vim will use :print by
default.
www.it-ebooks.info
report erratum • discuss
Chapter 15. Global Commands
• 238
We can invert the behavior of the :global command either by running :global! or
:vglobal (mnemonic: invert). Each of these tells Vim to execute [cmd] on each
line that doesn’t match the specified pattern. In the next tip, we’ll see examples
of both :global and :vglobal in action.
The :global command works by making two passes through the lines specified
by [range]. In the first pass, Vim marks each line that matches the specified
{pattern}. Then on the second pass, the [cmd] is executed for each marked line.
The [cmd] can accept a range of its own, which allows us to operate on multiline
regions. This powerful technique is demonstrated by Tip 100, on page 242.
Tip 98
Delete Lines Containing a Pattern
Combining the :global and :delete commands allows us to cut down the size of a
file rapidly. We can either keep or discard all lines that match a {pattern}.
This file contains links to the first few episodes from the Vimcasts.org archive:
global/episodes.html
Each list item contains two pieces of data: the title of an episode and its URL.
We’ll use a :global command to expose each of these.
Delete Matching Lines with ‘:g/re/d’
What if we wanted to throw away everything except for the contents of each
tag? In this file, the contents of each link appear on a line of their own,
www.it-ebooks.info
report erratum • discuss
1038 practical vim
Tip 1. Meet the Dot Command
Tip 3. Take One Step Back, Then Three Forward
Tip 6. Meet the Dot Formula
Tip 7. Pause with Your Brush Off the Page
Tip 11. Don't Count If You Can Repeat
Tip 19. Overwrite Existing Text with Replace Mode
Tip 27. Meet Vim's Command Line
Tip 28. Execute a Command on One or More Consecutive Lines
Tip 34. Recall Commands from History
Tip 35. Run Commands in the Shell
V.Nền kinh tế quốc dân
F. PHẦN 6: VAI TRÒ CỦA NHỮNG NGƯỜI CÓ LỢI ÍCH LIÊN QUAN
D. PHẦN 4: VAI TRÒ VÀ CƠ CẤU CỦA BAN GIÁM ĐỐC
VI. QUẢN TRỊ ĐỘC LẬP
IV. Báo cáo tiểu ban kiểm toán
I. Vai trò và quyển hạn của hội đồng quản trị
VI. Thực trạng thực hiện quy định và điều lệ công ty
V. Trách nhiệm của thành viên hội đồng quản trị, tổng giám đốc và cán bộ quản lý cấp cao
III. Hội đồng quản trị
II. Cổ đông và đại hội đồng cổ đông