Vim practical skills: global command

:globalThe command combines the two capabilities of the Ex command and Vim's pattern matching. With this command, the Ex command can be run on all matching lines in a specified pattern. In terms of the efficiency of handling repetitive tasks, global commands are one of the most powerful Vim tools besides point paradigm and macros.

Technique 98 Know the global command

:global The command allows the Ex command to be run on all matching lines in a specified pattern. First study its syntax.

:globalCommands usually take the following form (see  :h :g ).

:[range] global[!] /{pattern}/ [cmd]

First of all, by default, the :globalcommand scope is the entire file (%), which is different from most other Ex commands (including :delete, :substitute and  :normal). The default scope of these commands is only the current line (.).

Second, the {pattern} domain and search history are related to each other. This means that if you leave this field blank, Vim will automatically use the current search mode.

In addition, it [cmd]can be :globalany Ex command except  commands. In practical applications, the Ex commands listed in Table 5-1 all play a great role in processing text. By the way, if you don't specify any  [cmd], Vim will use it by default  :print.

Also, you can use  :global! or  :vglobal(v for invert) to reverse :globalthe behavior of the command. These two commands will instruct Vim to execute on lines that do not match the specified pattern  [cmd]. In the next section, you will see the application examples of :global and  respectively  :vglobal.

Finally, it should be pointed out that the  :globalcommand [range] is usually divided into two rounds when executed on the specified  text line. In the first round, Vim [pattern]marks all matching lines. The second round is executed on all marked text lines  [cmd]. In addition, because  [cmd] the range can be set individually, it can be operated within a multi-line text segment. This powerful technique will be explained in Tip 101.

Technique 99 Delete all text lines that contain patterns

Combining  :global commands with  :deletecommands can quickly crop file content. For those matching  {pattern} text lines, you can either choose to keep them or discard them.

The following content is taken from the links to the previous topics on the Vimcasts.org archive page.

global/episodes.html

<ol>
  <li>
    <a href="/episodes/show-invisibles/">
      Show invisibles
    </a>
  </li>
  <li>
    <a href="/episodes/tabs-and-spaces/">
      Tabs and Spaces
    </a>
  </li>
  <li>
    <a href="/episodes/whitespace-preferences-and-filetypes/">
      Whitespace preferences and filetypes
    </a>
  </li>
</ol>

Obviously, all list items consist of two parts of data: the title of the subject and its URL. Next, the :globaltwo sets of data will be retrieved separately using  commands.

Use':g/re/d' to delete all matching lines

What if you only want to keep  <a> the title in the label and delete the other lines? In this example, since the content of each group of links occupies one line, and the other text lines only contain two types of tags, either open or closed, if you design a pattern that can match HTML tags, then use it to call  :globalcommands, You can delete all matching lines of the pattern.

The following command can do this.

➾ /\v\<\/?\w+>
➾ :g//d

If you run these two commands in the archive file of Vimcasts.org, the content of the file will become:

Show invisibles
Tabs and Spaces
Whitespace preferences and filetypes

:substituteSimilar to the  command, you can also :globalleave the search field of the command blank. In this way, Vim will reuse the last search pattern (see Tip 91). This means that in the process of constructing regular expressions, coarse-grained matching can be performed first, and then fine-tuned, as shown in Tip 85.

The regular expression in this example uses a  very magicpattern (covered in Tip 74). First, it will match the left angle bracket ( \<); then , it will match the optional forward slash ( \/?); next, it will match one or more word-type characters ( \w+); finally, it will match the delimiter ( >) that represents the end of the word . Although this regular expression does not match all tags, it is sufficient for this particular example.

The origin of the word Grep

Please carefully consider  :globalthe short form of the command:

➾ :g/re/p

reRepresent regular expression, which  pis  :printan abbreviation, it as the default  [cmd]use. If we ignore the symbol /, we will find that the word "grep" is already ready to come out.

Use':v/re/d' to keep only matching lines

This time, we will do the opposite. As we mentioned earlier, the :vglobalor abbreviated  :vcommand is exactly  :gthe opposite of the operation of the command. In other words, it is used to execute Ex commands on non-matching lines in the specified pattern.

In this example, the lines of text containing the URL are easy to identify, and they all contain  hrefattributes. Therefore, you can get these text lines by running the following command.

➾ :v/href/d

The above command can be interpreted as "delete all hreflines of text not included  ". The final result is as follows.

<a href="/episodes/show-invisibles/">
<a href="/episodes/tabs-and-spaces/">
<a href="/episodes/whitespace-preferences-and-filetypes/">

With just one command, the entire document is refined into the text segment of interest.

Technique 100 Collect TODO items into registers

By  :globaland  :yank these two commands together, you can match all  {pattern}lines of text into a register collected.

The following code contains several comment lines beginning with "TODO".

global/markdown.js

Markdown.dialects.Gruber = {
  lists: function() {
      // TODO: Cache this regexp for certain depths.
      function regex_for_depth(depth) { /* implementation */ }
  },
  "`": function inlineCode( text ) {
      var m = text.match( /(`+)(([\s\S]*?)\1)/ );
      if ( m && m[2] )
          return [ m[1].length + m[2].length ];
      else {
          // TODO: No matching end code found - warn!
          return [ 1, "`" ];
      }
  }
}

Suppose you want to collect all TODO items together. Just enter the following command and this information will become clear at a glance.

:g/TODO
 // TODO: Cache this regexp for certain depths.
        // TODO: No matching end code found - warn! 

Remember, it :printis :globalthe default of the  command  [cmd], it simply echoes all lines of text that match the word "TODO". This is not very useful, because once other commands are executed, the information will disappear.

Here is another approach. First copy all the text lines containing the word "TODO" to a certain register, and then paste the contents of the register into other files in case of emergency.

This time, register a will be used. Run qaqit first to  clear it. Decompose this command. qaWill make vim start recording the macro and save it to register a, and the last one  qis responsible for terminating the recording. Since we did not hit any keys during the recording of the macro, the register was eventually cleared. You can use the following command to confirm it.

➾ :reg a
--- Registers ---
  "a

Now, the line containing the TODO comment can be copied to this register.

:g/TODO/yank A:reg a
"a // TODO: Cache this regexp for certain depths.
       // TODO: No matching end code found - warn! 

Here is a trick, which is to use the capital letter A to refer to the register. This means that Vim will append the contents to the specified register, aand if you use lowercase letters  , it will overwrite the contents of the original register. Therefore, this global command can be interpreted as "Append all text lines matching the pattern /TODO/ to the register in turn  a."

This time, when you run :reg ait again  , you will find that the register  aalready contains two sets of TODO items from the document. (For the convenience of reading, these contents have been adjusted to two lines, but in Vim, the newline character will actually be displayed as ^J.) After that, just open a new buffer in any split window, and then run the  "apcommand. aPaste the contents of the register  into it.

in conclusion

In this example, only two TODO items are collected, which can be completed quickly even with manual operations. However, the technology introduced above has good scalability. If a document contains more than a dozen TODO items, using this technique will make us more effective.

You can even use the  :globalcommand with  :bufdoor  :argdotogether to collect all TODO items from a set of files. This task is left as an exercise for you. You can refer to the similar workflow in Tip 36.

There is another option:

➾ :g/TODO/t$

The :tcommands used here  have been introduced in Tip 29. This command copies all TODO items to the end of the current file instead of appending them to the register. Once you have run the command, you can see these TODO items at the end of the file. Since this method does not affect the contents of the register, it is relatively simple and straightforward, but it is not very neat when used with  :argdoand :bufdocommands.

Technique 101 Sort the attributes of all rules in the CSS file in alphabetical order

When the Ex command is used  :globalin combination, the [cmd]range can also be specified separately. Vim allows  :g/{pattern}a reference point, the dynamic range is set. Next, let’s take a look at how to take advantage of this and arrange all the attributes of each rule in the CSS file in alphabetical order.

Use the following CSS file as a demonstration.

global/unsorted.css

Line 1 html {
       -   margin: 0;
       -   padding: 0;
       -   border: 0;
       5   font-size: 100%;
       -   font: inherit;
       -   vertical-align: baseline;
       - }
       - body {
      10   line-height: 1.5;
       -   color: black;
       -   background: white;
       - }

Suppose you want to sort the attributes in each set of rules in alphabetical order.  This function can be achieved with the help of Vim's built-in commands  :sort(see :h :sort).

Sort the attributes of a single rule

First use  :sortcommands to practice on a subset of the file (see Table 15-1).

First of all, using the text object  vi{ , you can easily select a text block surrounded by {}. Then, run  :'<,'>sortit to rearrange these lines of text in alphabetical order. If only one rule is sorted at a time, this method is perfectly adequate, but what about a style sheet that contains hundreds of rules? Wouldn't it be better if this process could be automated?

Table 15-1 Sorting a subset of files

Key operation

Buffer content

{start}

html {
 margin: 0;
 padding: 0;
 border: 0;
 font-size: 100%;
 font: inherit;
 vertical-align: baseline;
}

we{

html {
 margin: 0;
 padding: 0;
 border: 0;
 font-size: 100%;
  font: inherit;
 vertical-align: baseline; 
}

:'<,'>sort

html {
 border: 0;
 font-size: 100%;
 font: inherit;
 margin: 0;
 padding: 0;
 vertical-align: baseline;
}

Sort the attributes of all rules

In fact, you can :global sort the attributes of all rules in a file with one  command. Suppose you run the following command in the style sheet of this example.

➾ :g/{/ .+1,/}/-1 sort

The final result will be the following.

html {
  border: 0;
  font-size: 100%;
  font: inherit;
  margin: 0;
  padding: 0;
  vertical-align: baseline;
}
body {
  background: white;
  color: black;
  line-height: 1.5;
}

This sorting command will be executed in the {} block of each rule. Although the style sheet in this example only contains more than a dozen lines of text, this method is also applicable to CSS files with more content.

This command is very complicated, but after mastering its mechanism, you will sincerely admire  :globalthe power of the command. :globalThe standard format of the command is as follows.

:g/{pattern}/[cmd]

Keep in mind that the Ex command usually accepts "range" as its argument (as discussed in Tip 28). For :globalinside the command  [cmd], the rule is still valid. Therefore, the command template can be expanded into the following form.

:g/{pattern}/[range][cmd]

In fact, it may be used  :g/{pattern} to match as a reference point, a dynamic set  [cmd]of  [range]. The symbol usually indicates the line where the cursor is located, but in  :globalthe context of the command, it indicates  {pattern} the matching line.

You can split the original command into two separate Ex commands for explanation, and analyze the second half of the command first. The following is a valid Ex command.

➾ :.+1,/}/-1 sort

If the offset in the range is removed, the range can be simplified to  .,/}/, and its meaning is "from the current line to the line that matches the pattern /}/". The offset values ​​of +1 and -1 are only used to narrow the operating range, let us focus on the content between {}. For the original CSS file before sorting, if the cursor is placed on line 1 or line 9, the above Ex command will reorder the rules within the corresponding {} in alphabetical order.

In other words, simply place the cursor at the beginning of each {} block and run the  :.,/}/ sort command to reorder the rules in alphabetical order. understand? Now, try to  perform a search with the  :globalcommand  {pattern}.

➾ /{/

The above command will place the cursor at the beginning of a {} block, where our target is. Now, combine it  :global with the Ex command  [cmd]again.

➾ :g/{/ .+1,/}/—1 sort

Among them, the pattern {will match the starting line of each {} block. For each matching line, it :sortwill be [range] executed from the matching line to the end of the {} block . In the end, the CSS properties of each rule will be neatly arranged in alphabetical order.

in conclusion

:globalThe broad form of the command is as follows.

:g/{start}/ .,{finish} [cmd]

It can be interpreted as "for  all text lines from the  {start} beginning to the  {finish}end, perform the specified  [cmd]".

For  :globalcombination with any Ex command command, the same paradigm can be employed. For example, if you want to indent the text content in a specified range, :h > you can use the Ex command:> (see ).

 

➾ :g/{/ .+1,/}/—1 >
6 lines >ed 1 time
   3 lines >ed 1 time

 

note:

 

Unlike :sort, Vim will prompt a message whenever the :> command is called. If you add :slient in front of [cmd] (see  :h :sil ), you can block this information:

➾ :g/{/sil .+1,/}/−1 >

This method is especially suitable for  :g/{pattern} matching a large number of text lines.

This article is excerpted from "Vim Practical Skills" (2nd Edition)

Vimå®ç¨æå · § 第2ç (å¼æ ¥ å¾ä¹¦åºå)

Vim is a feature-rich and powerful text editor. Its code completion, compilation, error jump and other convenient programming functions are particularly rich, and it is widely used by programmers. Vim can greatly improve the efficiency of programmers. For Vim masters, Vim can edit text at a speed that synchronizes with thinking. At the same time, it is difficult to learn and use Vim proficiently.

This book is written for programmers who want to improve themselves. Reading this book is the only way to master the superb Vim skills. The book has 21 chapters, including 123 tips. Each chapter is a collection of tips on a related topic. Each skill has a targeted solution to one or a class of problems, helping readers to improve the skills of Vim. This book is rich in examples and clear explanations. It uses a simple marking method to indicate interactive editing effects, which can help readers quickly master and master Vim.
This book is suitable for readers who want to learn and master Vim tools. Programmers who have a certain amount of Vim experience can also refer to it to solve specific problems.

Guess you like

Origin blog.csdn.net/epubit17/article/details/107612749