| *usr_12.txt* For Vim version 7.0aa. Last change: 2006 Feb 26 |
| |
| VIM USER MANUAL - by Bram Moolenaar |
| |
| Clever tricks |
| |
| |
| By combining several commands you can make Vim do nearly everything. In this |
| chapter a number of useful combinations will be presented. This uses the |
| commands introduced in the previous chapters and a few more. |
| |
| |12.1| Replace a word |
| |12.2| Change "Last, First" to "First Last" |
| |12.3| Sort a list |
| |12.4| Reverse line order |
| |12.5| Count words |
| |12.6| Find a man page |
| |12.7| Trim blanks |
| |12.8| Find where a word is used |
| |
| Next chapter: |usr_20.txt| Typing command-line commands quickly |
| Previous chapter: |usr_11.txt| Recovering from a crash |
| Table of contents: |usr_toc.txt| |
| |
| ============================================================================== |
| *12.1* Replace a word |
| |
| The substitute command can be used to replace all occurrences of a word with |
| another word: > |
| |
| :%s/four/4/g |
| |
| The "%" range means to replace in all lines. The "g" flag at the end causes |
| all words in a line to be replaced. |
| This will not do the right thing if your file also contains "thirtyfour". |
| It would be replaced with "thirty4". To avoid this, use the "\<" item to |
| match the start of a word: > |
| |
| :%s/\<four/4/g |
| |
| Obviously, this still goes wrong on "fourty". Use "\>" to match the end of a |
| word: > |
| |
| :%s/\<four\>/4/g |
| |
| If you are programming, you might want to replace "four" in comments, but not |
| in the code. Since this is difficult to specify, add the "c" flag to have the |
| substitute command prompt you for each replacement: > |
| |
| |
| :%s/\<four\>/4/gc |
| |
| |
| REPLACING IN SEVERAL FILES |
| |
| Suppose you want to replace a word in more than one file. You could edit each |
| file and type the command manually. It's a lot faster to use record and |
| playback. |
| Let's assume you have a directory with C++ files, all ending in ".cpp". |
| There is a function called "GetResp" that you want to rename to "GetAnswer". |
| |
| vim *.cpp Start Vim, defining the argument list to |
| contain all the C++ files. You are now in the |
| first file. |
| qq Start recording into the q register |
| :%s/\<GetResp\>/GetAnswer/g |
| Do the replacements in the first file. |
| :wnext Write this file and move to the next one. |
| q Stop recording. |
| @q Execute the q register. This will replay the |
| substitution and ":wnext". You can verify |
| that this doesn't produce an error message. |
| 999@q Execute the q register on the remaining files. |
| |
| At the last file you will get an error message, because ":wnext" cannot move |
| to the next file. This stops the execution, and everything is done. |
| |
| Note: |
| When playing back a recorded sequence, an error stops the execution. |
| Therefore, make sure you don't get an error message when recording. |
| |
| There is one catch: If one of the .cpp files does not contain the word |
| "GetResp", you will get an error and replacing will stop. To avoid this, add |
| the "e" flag to the substitute command: > |
| |
| :%s/\<GetResp\>/GetAnswer/ge |
| |
| The "e" flag tells ":substitute" that not finding a match is not an error. |
| |
| ============================================================================== |
| *12.2* Change "Last, First" to "First Last" |
| |
| You have a list of names in this form: |
| |
| Doe, John ~ |
| Smith, Peter ~ |
| |
| You want to change that to: |
| |
| John Doe ~ |
| Peter Smith ~ |
| |
| This can be done with just one command: > |
| |
| :%s/\([^,]*\), \(.*\)/\2 \1/ |
| |
| Let's break this down in parts. Obviously it starts with a substitute |
| command. The "%" is the line range, which stands for the whole file. Thus |
| the substitution is done in every line in the file. |
| The arguments for the substitute command are "/from/to/". The slashes |
| separate the "from" pattern and the "to" string. This is what the "from" |
| pattern contains: |
| \([^,]*\), \(.*\) ~ |
| |
| The first part between \( \) matches "Last" \( \) |
| match anything but a comma [^,] |
| any number of times * |
| matches ", " literally , |
| The second part between \( \) matches "First" \( \) |
| any character . |
| any number of times * |
| |
| In the "to" part we have "\2" and "\1". These are called backreferences. |
| They refer to the text matched by the "\( \)" parts in the pattern. "\2" |
| refers to the text matched by the second "\( \)", which is the "First" name. |
| "\1" refers to the first "\( \)", which is the "Last" name. |
| You can use up to nine backreferences in the "to" part of a substitute |
| command. "\0" stands for the whole matched pattern. There are a few more |
| special items in a substitute command, see |sub-replace-special|. |
| |
| ============================================================================== |
| *12.3* Sort a list |
| |
| In a Makefile you often have a list of files. For example: |
| |
| OBJS = \ ~ |
| version.o \ ~ |
| pch.o \ ~ |
| getopt.o \ ~ |
| util.o \ ~ |
| getopt1.o \ ~ |
| inp.o \ ~ |
| patch.o \ ~ |
| backup.o ~ |
| |
| To sort this list, filter the text through the external sort command: > |
| |
| /^OBJS |
| j |
| :.,/^$/-1!sort |
| |
| This goes to the first line, where "OBJS" is the first thing in the line. |
| Then it goes one line down and filters the lines until the next empty line. |
| You could also select the lines in Visual mode and then use "!sort". That's |
| easier to type, but more work when there are many lines. |
| The result is this: |
| |
| OBJS = \ ~ |
| backup.o ~ |
| getopt.o \ ~ |
| getopt1.o \ ~ |
| inp.o \ ~ |
| patch.o \ ~ |
| pch.o \ ~ |
| util.o \ ~ |
| version.o \ ~ |
| |
| |
| Notice that a backslash at the end of each line is used to indicate the line |
| continues. After sorting, this is wrong! The "backup.o" line that was at |
| the end didn't have a backslash. Now that it sorts to another place, it |
| must have a backslash. |
| The simplest solution is to add the backslash with "A \<Esc>". You can |
| keep the backslash in the last line, if you make sure an empty line comes |
| after it. That way you don't have this problem again. |
| |
| ============================================================================== |
| *12.4* Reverse line order |
| |
| The |:global| command can be combined with the |:move| command to move all the |
| lines before the first line, resulting in a reversed file. The command is: > |
| |
| :global/^/m 0 |
| |
| Abbreviated: > |
| |
| :g/^/m 0 |
| |
| The "^" regular expression matches the beginning of the line (even if the line |
| is blank). The |:move| command moves the matching line to after the mythical |
| zeroth line, so the current matching line becomes the first line of the file. |
| As the |:global| command is not confused by the changing line numbering, |
| |:global| proceeds to match all remaining lines of the file and puts each as |
| the first. |
| |
| This also works on a range of lines. First move to above the first line and |
| mark it with "mt". Then move the cursor to the last line in the range and |
| type: > |
| |
| :'t+1,.g/^/m 't |
| |
| ============================================================================== |
| *12.5* Count words |
| |
| Sometimes you have to write a text with a maximum number of words. Vim can |
| count the words for you. |
| When the whole file is what you want to count the words in, use this |
| command: > |
| |
| g CTRL-G |
| |
| Do not type a space after the g, this is just used here to make the command |
| easy to read. |
| The output looks like this: |
| |
| Col 1 of 0; Line 141 of 157; Word 748 of 774; Byte 4489 of 4976 ~ |
| |
| You can see on which word you are (748), and the total number of words in the |
| file (774). |
| |
| When the text is only part of a file, you could move to the start of the text, |
| type "g CTRL-G", move to the end of the text, type "g CTRL-G" again, and then |
| use your brain to compute the difference in the word position. That's a good |
| exercise, but there is an easier way. With Visual mode, select the text you |
| want to count words in. Then type g CTRL-G. The result: |
| |
| Selected 5 of 293 Lines; 70 of 1884 Words; 359 of 10928 Bytes ~ |
| |
| For other ways to count words, lines and other items, see |count-items|. |
| |
| ============================================================================== |
| *12.6* Find a man page *find-manpage* |
| |
| While editing a shell script or C program, you are using a command or function |
| that you want to find the man page for (this is on Unix). Let's first use a |
| simple way: Move the cursor to the word you want to find help on and press > |
| |
| K |
| |
| Vim will run the external "man" program on the word. If the man page is |
| found, it is displayed. This uses the normal pager to scroll through the text |
| (mostly the "more" program). When you get to the end pressing <Enter> will |
| get you back into Vim. |
| |
| A disadvantage is that you can't see the man page and the text you are working |
| on at the same time. There is a trick to make the man page appear in a Vim |
| window. First, load the man filetype plugin: > |
| |
| :runtime! ftplugin/man.vim |
| |
| Put this command in your vimrc file if you intend to do this often. Now you |
| can use the ":Man" command to open a window on a man page: > |
| |
| :Man csh |
| |
| You can scroll around and the text is highlighted. This allows you to find |
| the help you were looking for. Use CTRL-W w to jump to the window with the |
| text you were working on. |
| To find a man page in a specific section, put the section number first. |
| For example, to look in section 3 for "echo": > |
| |
| :Man 3 echo |
| |
| To jump to another man page, which is in the text with the typical form |
| "word(1)", press CTRL-] on it. Further ":Man" commands will use the same |
| window. |
| |
| To display a man page for the word under the cursor, use this: > |
| |
| \K |
| |
| (If you redefined the <Leader>, use it instead of the backslash). |
| For example, you want to know the return value of "strstr()" while editing |
| this line: |
| |
| if ( strstr (input, "aap") == ) ~ |
| |
| Move the cursor to somewhere on "strstr" and type "\K". A window will open |
| to display the man page for strstr(). |
| |
| ============================================================================== |
| *12.7* Trim blanks |
| |
| Some people find spaces and tabs at the end of a line useless, wasteful, and |
| ugly. To remove whitespace at the end of every line, execute the following |
| command: > |
| |
| :%s/\s\+$// |
| |
| The line range "%" is used, thus this works on the whole file. The pattern |
| that the ":substitute" command matches with is "\s\+$". This finds white |
| space characters (\s), 1 or more of them (\+), before the end-of-line ($). |
| Later will be explained how you write patterns like this |usr_27.txt|. |
| The "to" part of the substitute command is empty: "//". Thus it replaces |
| with nothing, effectively deleting the matched white space. |
| |
| Another wasteful use of spaces is placing them before a Tab. Often these can |
| be deleted without changing the amount of white space. But not always! |
| Therefore, you can best do this manually. Use this search command: > |
| |
| / |
| |
| You cannot see it, but there is a space before a tab in this command. Thus |
| it's "/<Space><Tab>". Now use "x" to delete the space and check that the |
| amount of white space doesn't change. You might have to insert a Tab if it |
| does change. Type "n" to find the next match. Repeat this until no more |
| matches can be found. |
| |
| ============================================================================== |
| *12.8* Find where a word is used |
| |
| If you are a UNIX user, you can use a combination of Vim and the grep command |
| to edit all the files that contain a given word. This is extremely useful if |
| you are working on a program and want to view or edit all the files that |
| contain a specific variable. |
| For example, suppose you want to edit all the C program files that contain |
| the word "frame_counter". To do this you use the command: > |
| |
| vim `grep -l frame_counter *.c` |
| |
| Let's look at this command in detail. The grep command searches through a set |
| of files for a given word. Because the -l argument is specified, the command |
| will only list the files containing the word and not print the matching lines. |
| The word it is searching for is "frame_counter". Actually, this can be any |
| regular expression. (Note: What grep uses for regular expressions is not |
| exactly the same as what Vim uses.) |
| The entire command is enclosed in backticks (`). This tells the UNIX shell |
| to run this command and pretend that the results were typed on the command |
| line. So what happens is that the grep command is run and produces a list of |
| files, these files are put on the Vim command line. This results in Vim |
| editing the file list that is the output of grep. You can then use commands |
| like ":next" and ":first" to browse through the files. |
| |
| |
| FINDING EACH LINE |
| |
| The above command only finds the files in which the word is found. You still |
| have to find the word within the files. |
| Vim has a built-in command that you can use to search a set of files for a |
| given string. If you want to find all occurrences of "error_string" in all C |
| program files, for example, enter the following command: > |
| |
| :grep error_string *.c |
| |
| This causes Vim to search for the string "error_string" in all the specified |
| files (*.c). The editor will now open the first file where a match is found |
| and position the cursor on the first matching line. To go to the next |
| matching line (no matter in what file it is), use the ":cnext" command. To go |
| to the previous match, use the ":cprev" command. Use ":clist" to see all the |
| matches and where they are. |
| The ":grep" command uses the external commands grep (on Unix) or findstr |
| (on Windows). You can change this by setting the option 'grepprg'. |
| |
| ============================================================================== |
| |
| Next chapter: |usr_20.txt| Typing command-line commands quickly |
| |
| Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl: |