Sender: Vale (shangu), email area: Vim
Question: detailed explanation of global commands
Mailing site: shuimu community (Fri Jun 15 17:05:55 2007), within the site
The Global Command is one of Vim's most powerful commands (I personally think it is No. 1). You can get twice the result with full familiarity with it,
This article summarizes some of the classic issues on the version. Based on your usage and understanding, I try to introduce them in detail through examples.
Its usage. The examples are difficult. Some examples are not very practical. If you are born with questions, you may need them. Example:
It is not very meticulous to avoid Luo Yun. The positions of the involved content in Vim Help are listed under the heading of each section.
For search. The words in this article are not necessarily standard (I have not read Vim's help in Chinese), and there are also mistakes in my opinion. please correct me.
| 1. | Global Command Format
| 2. | global and substitute
| 3. | [range] usage of the global flag
| 4. | global and VIM scripts
| 5. | Summary
========================================================== ==============================================
* 1. * Global Command Format
: H: G
: H 12.4
: [Range] global/{pattern}/{command}
The Global Command searches for {pattern} within the text range specified by [range] (the entire file by default), and
Run the command {command} On the matched line. If you want to execute the command on a line that does not match, use global! Or
Vglobal command.
Let's take a look at a classic example in the vim user manual.
[Example 1] inverted file line (that is, the TAC command under UNIX)
: G/^/M 0
This command marks/^/at the beginning of the line to match all lines of the file (this is a common technique for searching, if/./is used, it is
Match non-empty lines, less than the requirements of this example), and then use the move command to move each line to the first line (the next line of 0th)
Rows) to implement the reverse order function.
The Global Command is actually executed in two steps: first, scan all rows within the range specified by [range], and match {Pa
Ttern} rows are marked. Then, execute the {command} command on the marked rows in turn. If the marked rows are
If a command operation that matches a row is deleted, moved, or merged, its flag disappears automatically and the row is not executed
{Command} command. {Command} can be an ex command or multiple ex commands separated by |.
You can perform different operations on the marked rows or the rows from the marked rows.
The concept of tag is very important, as shown in the following example.
[Example 2] delete an even number of rows
: G/^/+ 1 d
This command matches all rows and then deletes the rows (where + 1 is used to locate the next row of the current row ). Why
Is it a line break? Because the second line is deleted when the + 1 D command is executed on the first line, while the second line is also marked
But does not exist, so the command to delete the third line will not be executed.
In this example, you can also use the normal command:
: % Norm jdd
% Specifies the entire file, and then execute jdd in Normal Mode in sequence, that is, move down and delete a row. Different from the Global Command
% Norm is executed in the order of row numbers. The second row is deleted in the first row, and all subsequent row numbers are subtracted.
1. Therefore, when jdd is executed in the second row, the fourth row is deleted. That is to say, the global command uses an even number
The line mark is removed, while the normal command is implemented by the automatic forward of subsequent lines.
[Example 3] Delete odd rows
: G/^/d | M.
The light is: G/^/d obviously does not work. This will delete all rows. We need to use the move command to remove the mark of the even rows. When
However, this example can be easily converted to [Example 2], which is only used to emphasize the concept of tag.
In this example, if you want to use the normal command for implementation, % norm DD will also delete the entire file, % norm jkdd
I don't know why the two are different. They may be related to the internal running mechanism of the normal command.
========================================================== ==============================================
* 2. * Global and substitute
: H 10.4
: Helpg MS-word/C
Many vimmer think that these two commands are similar. Indeed, they are similar in the form of searching and matching,
However, the substitute command replaces other commands executed by global (of course, the default [R
Ange] is the current row, which is also different ). Let's take a look at two examples to see how S and G think differently.
[Example 4] All double rows
: % S/. */&/R &/
: G/^/t.
Substitue is to search for any row, and then replace it with the two-row folder and press ENTER; Global is to copy each row (T is: Co
PY) to your own, more clear.
[Example 5] Text segmented by carriage return is converted into text segmented by carriage return.
Many TXT eBooks and text such as Vim Help have limited characters in each line, and empty lines are used between segments.
Separated. If you copy them to the word, the hard carriage return and empty lines will be annoying, although the word also has automatic
Adjust the format function, but it is a piece of cake in vim. First, let's see how to implement it with replacement.
: % S // n /@! //
/N /@! Is to find the carriage return that is not followed by the carriage return (about /@! Usage: H //@!, ), And then
Replace it with a space, that is, remove the carriage return used for typographical input. The Global Command is completely another way of thinking.
: G/./,/^ $/J
/./Mark non-empty rows,/^ $/search for the empty rows after them, and then merge the rows between them. Some may
Q: Will the J command be executed for each line in the segment? As mentioned above, Mark rows lost in previous operations
If you do not execute the operation command, the other lines in the segment have been merged when processing the first line of each segment. Therefore, only
Run the J command once. This command uses the Global flag as the starting line of [range ].
.
What if I want to keep the blank lines between paragraphs? If you use replacement, you need to find the carriage return without carriage return:
: % S // n/@ <! /N /@! //
This regular expression may make many vimmer headers big. For the global command, you only need to merge the range
To the end of the Global Command.
: G/./,/^ $/-1j
Global is often used in combination with substitute. The former is used to locate rows that meet certain conditions, and the latter is used in these rows.
Find and replace. For example:
[Example 6] Replace AAA with BBB unless the row contains CCC or DDD
: V/CCC/| DDD/S/AAA/BBB/g
[Example 7] Replace AAA with BBB, if the row contains CCC but cannot have ddd
How do I write a regular expression that matches AAA and satisfies the condition that the row has CCC but not DDD? I don't know. Even if you can write
It must be extremely complicated. Using the global command is not difficult:
: G/CCC/If Getline ('.')!~ 'Ddd '| S/AAA/BBB/g
This command First marks the line that matches CCC, and then runs the if Command (if is also the ex command !), Get the Getline Function
The current row, and then determine if it matches DDD. If it does not match (!~ Is replaced. Master this
The usage of the sample requires a certain understanding of the ex command, VIM function, and expression. In fact, this command is already
A quick version of the script. Some may think, isn't it enough to connect g and V? Unfortunately, the global command does not support
Nesting.
========================================================== ==============================================
* 3. * [range] usage of the global flag
: H range
The flag set in the first step of the global command can be used to set various forms of [rang
E]. This technique has been used in both [Example 2] and [Example 5], and flexible use of [range] is an important basic
. Let's take a look at the general problems of [Example 2] and [Example 3.
[Example 8] Delete m rows before/after N rows (for example, delete 3 rows before/after each 10 rows)
: G/^/D 3 |, + 6 m-1
: G/^/, + 6 m-1 | + 1 D 3
The two commands still use move to clear the flag of the reserved rows. Note that the current
The line is the location where the first command is addressable and executed. Let's look at two more practical examples.
[Example 9] extract the Conditional compilation content. For example, in a multi-platform C program, there are a lot of Conditional compilation code:
# Ifdef Win32
XXX1
Xxx2
# Endif
...
# Ifdef Win32
Xxx3
Xxx4
# Else
Yyy1
Yyy2
# Endif
Now we use the global command to extract the code on the Win32 platform and copy it to the end of the file:
: G/# ifdef Win32/+ 1,/# else/| # endif/-1 T $
The [range] of the T command is separated by commas. the starting line is/# ifdef Win32/mark the next line of the line, and the ending line is 1.
Search location, which appears after the start line # endif or # else, t copies the content between the two
End.
[Example 10] extract the code of the non-Win32 platform in the above C program (Part YYY)
First of all, this example is much more complex than explain, mainly involving the operation of [range ].
The global command does not matter much. The purpose of adding this parameter is to finish the problem for your reference.
The complexity of this example is: first, you cannot simply use # else and # endif for locating, because the code may have other
Conditional compilation, we must limit the search range to # ifdef Win32 block. In addition, in the block
It does not have the # else part, which will cause a lot of trouble for positioning. Solution:
: Try | G/# ifdef Win32 // # else/+ 1,/# endif/-1 T $ | endtry
Regardless of try and endtry, check the global part in the middle: Find Win32, then find # else, and
The row is used as the starting line of [range], and then from the current cursor (row where Win32 is located, not the next line of # else just found)
Line) Find # endif, use the previous line as the end line of [range], and then execute the T command. But
# Else block, such as the first code, the starting line of [range] Is yyy1, And the ending line is xxx2 (because
# Endif starts from the first line rather than yyy1). This is an invalid [range] and causes
Exception. If the global command is not placed in try, it will immediately stop.
Unlike commas (,), if [range] is separated by semicolons (;), the current cursor is moved to the starting line.
When you look for # endif, it starts from the next line of # else, and no [range] is invalid. Try is not needed, but the question is
Question: If no # else block is found, the # else part in the block is found incorrectly.
========================================================== ==============================================
* 4. * Global and VIM scripts
: H script
: H expression
Some people often ask: what functions does xxeditor have? Does Vim support? It is probably not supported because Vim is not a feature
User groups provide non-general functions, but few functions cannot be customized in vim,
Add it to your vimrc or plugin. Script is a powerful tool for customizing vim. This article does not discuss writing scripts,
It introduces how to use global to implement similar script functions. In fact, it uses the mechanism provided by commands
A simplified script.
[Example 11] calculate the sum of numeric columns in a file (or other operations)
: Let I = 0
: G/^/Let I + = str2nr (Getline ('.'))
: Echo I
First, define the variable I and clear it. Then, use the str2nr function to convert the current row into a number and accumulate it into I. Note that Vim does not support
Floating Point Number. Global actually replaces the for loop in the script.
One of the most common problems in VIM is how to generate a column of incremental numbers. There are many solutions: calling external commands, recording
Macro, using the substitute command, there are dedicated plug-ins, and using the Global Command can achieve some more advanced functions
Yes. See the following example.
[Example 12] Add a label to a valid code line
In the book _ data structures and algorithm analysis in C _, the author
Add a comment on the valid line in the code, for example:
/* 1 */unsigned int factorial (unsigned int N)
{
/* 2 */If (n <= 1)
/* 3 */return 1;
/* 4 */Return (N * factorial (n-1 ));
}
In order to align after adding labels, we insert enough spaces before each line of code (this is of course very simple ),
Then, use the global command to automatically add the label:
: Let I = 1 | G // A/S // {8} // = printf ("// * % 2D * //", I) /| let I + = 1
The variable I is used to record the number. The G command searches for rows with letters and replaces the first eight spaces with the comment number.
After the row processing is complete, add one. // = Is used in replacement, a very useful function.
Finally, let's return to the example of deleting a Specific Row and use variables to solve the problem.
[Example 13] Delete m rows before/after N rows
: Let n = 10 | Let M = 3
: Let I =-1 | G/^/Let I + = 1 | if I % n <M | D
: Let I =-1 | G/^/Let I + = 1 | if I % N> (n-m-1) | D
We use I to record the location of the row to be processed. The relationship between I value and M and N determines when to delete the row.
The processing method is much clearer and more common than the [Example 8] method.
========================================================== ==============================================
* 5. * Summary
Using the global command is not easy. Every part of the command is worth studying carefully: only the range principle is mastered.
Can be freely located in the file; only proficient in pattern can effectively match the desired line; only familiar
With the ex command, you can select the most suitable function for operations. Only variables, expressions, functions, and other content can be specified.
To enable the Global Command to implement the script function. In short, Global is a very good framework for VIM
The more familiar they are, the more powerful they can set up and use their weapons.
Of course, Global is not omnipotent, and its functions are lacking. The main problem is that it can only use regular expressions to mark matching.
Line. If any expression can be used to mark (or from another angle, as described by runsnake, the former MV moderator
Evaluate the regular expression) to achieve more convenient functions. For example
There are simple and unified solutions. The preceding example uses specialized text processing tools such as SED and awk, or Perl
Similar script languages are not difficult, and some implementations are more convenient. The Vim solution provided in this article is not necessarily simple.
Single, or even difficult to understand, aims to introduce the use of Global. For those that do not or cannot use
Its tool may be more valuable for reference. In fact, VIM has rich functions and deserves further study.
Shaolin's skills are wonderful, and the more you will, the stronger the skill, but as long as you have a six-pulse sword or a little none
This is enough to be a standalone.
========================================================== ==============================================
VIM: Tw = 78: fo = tcq2: ISK =! -~, ^ *, ^/|, ^/": TS = 8: Ft = help: Norl:
※Modification: · Vale modified this article at Sep 27 12:26:18 · [from: 219.143.141. *]
※Source: · Shui Mu community newsmth.net · [from: 219.143.156. *]