Christian Brabandt | b4ddc6c | 2024-01-02 16:51:11 +0100 | [diff] [blame] | 1 | *usr_12.txt* For Vim version 9.1. Last change: 2022 Nov 19 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 2 | |
| 3 | VIM USER MANUAL - by Bram Moolenaar |
| 4 | |
| 5 | Clever tricks |
| 6 | |
| 7 | |
| 8 | By combining several commands you can make Vim do nearly everything. In this |
| 9 | chapter a number of useful combinations will be presented. This uses the |
| 10 | commands introduced in the previous chapters and a few more. |
| 11 | |
| 12 | |12.1| Replace a word |
| 13 | |12.2| Change "Last, First" to "First Last" |
| 14 | |12.3| Sort a list |
| 15 | |12.4| Reverse line order |
| 16 | |12.5| Count words |
| 17 | |12.6| Find a man page |
| 18 | |12.7| Trim blanks |
| 19 | |12.8| Find where a word is used |
| 20 | |
| 21 | Next chapter: |usr_20.txt| Typing command-line commands quickly |
| 22 | Previous chapter: |usr_11.txt| Recovering from a crash |
| 23 | Table of contents: |usr_toc.txt| |
| 24 | |
| 25 | ============================================================================== |
| 26 | *12.1* Replace a word |
| 27 | |
| 28 | The substitute command can be used to replace all occurrences of a word with |
| 29 | another word: > |
| 30 | |
| 31 | :%s/four/4/g |
| 32 | |
| 33 | The "%" range means to replace in all lines. The "g" flag at the end causes |
| 34 | all words in a line to be replaced. |
| 35 | This will not do the right thing if your file also contains "thirtyfour". |
| 36 | It would be replaced with "thirty4". To avoid this, use the "\<" item to |
| 37 | match the start of a word: > |
| 38 | |
| 39 | :%s/\<four/4/g |
| 40 | |
Bram Moolenaar | c81e5e7 | 2007-05-05 18:24:42 +0000 | [diff] [blame] | 41 | Obviously, this still goes wrong on "fourteen". Use "\>" to match the end of |
| 42 | a word: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 43 | |
| 44 | :%s/\<four\>/4/g |
| 45 | |
| 46 | If you are programming, you might want to replace "four" in comments, but not |
| 47 | in the code. Since this is difficult to specify, add the "c" flag to have the |
| 48 | substitute command prompt you for each replacement: > |
| 49 | |
| 50 | |
| 51 | :%s/\<four\>/4/gc |
| 52 | |
| 53 | |
| 54 | REPLACING IN SEVERAL FILES |
| 55 | |
| 56 | Suppose you want to replace a word in more than one file. You could edit each |
| 57 | file and type the command manually. It's a lot faster to use record and |
| 58 | playback. |
| 59 | Let's assume you have a directory with C++ files, all ending in ".cpp". |
| 60 | There is a function called "GetResp" that you want to rename to "GetAnswer". |
| 61 | |
| 62 | vim *.cpp Start Vim, defining the argument list to |
| 63 | contain all the C++ files. You are now in the |
| 64 | first file. |
| 65 | qq Start recording into the q register |
| 66 | :%s/\<GetResp\>/GetAnswer/g |
| 67 | Do the replacements in the first file. |
| 68 | :wnext Write this file and move to the next one. |
| 69 | q Stop recording. |
| 70 | @q Execute the q register. This will replay the |
| 71 | substitution and ":wnext". You can verify |
| 72 | that this doesn't produce an error message. |
| 73 | 999@q Execute the q register on the remaining files. |
| 74 | |
| 75 | At the last file you will get an error message, because ":wnext" cannot move |
| 76 | to the next file. This stops the execution, and everything is done. |
| 77 | |
| 78 | Note: |
| 79 | When playing back a recorded sequence, an error stops the execution. |
| 80 | Therefore, make sure you don't get an error message when recording. |
| 81 | |
| 82 | There is one catch: If one of the .cpp files does not contain the word |
| 83 | "GetResp", you will get an error and replacing will stop. To avoid this, add |
| 84 | the "e" flag to the substitute command: > |
| 85 | |
| 86 | :%s/\<GetResp\>/GetAnswer/ge |
| 87 | |
| 88 | The "e" flag tells ":substitute" that not finding a match is not an error. |
| 89 | |
| 90 | ============================================================================== |
| 91 | *12.2* Change "Last, First" to "First Last" |
| 92 | |
| 93 | You have a list of names in this form: |
| 94 | |
| 95 | Doe, John ~ |
| 96 | Smith, Peter ~ |
| 97 | |
| 98 | You want to change that to: |
| 99 | |
| 100 | John Doe ~ |
| 101 | Peter Smith ~ |
| 102 | |
| 103 | This can be done with just one command: > |
| 104 | |
| 105 | :%s/\([^,]*\), \(.*\)/\2 \1/ |
| 106 | |
| 107 | Let's break this down in parts. Obviously it starts with a substitute |
| 108 | command. The "%" is the line range, which stands for the whole file. Thus |
| 109 | the substitution is done in every line in the file. |
| 110 | The arguments for the substitute command are "/from/to/". The slashes |
| 111 | separate the "from" pattern and the "to" string. This is what the "from" |
| 112 | pattern contains: |
| 113 | \([^,]*\), \(.*\) ~ |
| 114 | |
| 115 | The first part between \( \) matches "Last" \( \) |
| 116 | match anything but a comma [^,] |
| 117 | any number of times * |
| 118 | matches ", " literally , |
| 119 | The second part between \( \) matches "First" \( \) |
| 120 | any character . |
| 121 | any number of times * |
| 122 | |
| 123 | In the "to" part we have "\2" and "\1". These are called backreferences. |
| 124 | They refer to the text matched by the "\( \)" parts in the pattern. "\2" |
| 125 | refers to the text matched by the second "\( \)", which is the "First" name. |
| 126 | "\1" refers to the first "\( \)", which is the "Last" name. |
| 127 | You can use up to nine backreferences in the "to" part of a substitute |
| 128 | command. "\0" stands for the whole matched pattern. There are a few more |
| 129 | special items in a substitute command, see |sub-replace-special|. |
| 130 | |
| 131 | ============================================================================== |
| 132 | *12.3* Sort a list |
| 133 | |
| 134 | In a Makefile you often have a list of files. For example: |
| 135 | |
| 136 | OBJS = \ ~ |
| 137 | version.o \ ~ |
| 138 | pch.o \ ~ |
| 139 | getopt.o \ ~ |
| 140 | util.o \ ~ |
| 141 | getopt1.o \ ~ |
| 142 | inp.o \ ~ |
| 143 | patch.o \ ~ |
| 144 | backup.o ~ |
| 145 | |
| 146 | To sort this list, filter the text through the external sort command: > |
| 147 | |
| 148 | /^OBJS |
| 149 | j |
| 150 | :.,/^$/-1!sort |
| 151 | |
| 152 | This goes to the first line, where "OBJS" is the first thing in the line. |
| 153 | Then it goes one line down and filters the lines until the next empty line. |
| 154 | You could also select the lines in Visual mode and then use "!sort". That's |
| 155 | easier to type, but more work when there are many lines. |
| 156 | The result is this: |
| 157 | |
| 158 | OBJS = \ ~ |
| 159 | backup.o ~ |
| 160 | getopt.o \ ~ |
| 161 | getopt1.o \ ~ |
| 162 | inp.o \ ~ |
| 163 | patch.o \ ~ |
| 164 | pch.o \ ~ |
| 165 | util.o \ ~ |
| 166 | version.o \ ~ |
| 167 | |
| 168 | |
| 169 | Notice that a backslash at the end of each line is used to indicate the line |
| 170 | continues. After sorting, this is wrong! The "backup.o" line that was at |
| 171 | the end didn't have a backslash. Now that it sorts to another place, it |
| 172 | must have a backslash. |
| 173 | The simplest solution is to add the backslash with "A \<Esc>". You can |
| 174 | keep the backslash in the last line, if you make sure an empty line comes |
| 175 | after it. That way you don't have this problem again. |
| 176 | |
| 177 | ============================================================================== |
| 178 | *12.4* Reverse line order |
| 179 | |
| 180 | The |:global| command can be combined with the |:move| command to move all the |
| 181 | lines before the first line, resulting in a reversed file. The command is: > |
| 182 | |
Bram Moolenaar | 11e3c5b | 2021-04-21 18:09:37 +0200 | [diff] [blame] | 183 | :global/^/move 0 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 184 | |
| 185 | Abbreviated: > |
| 186 | |
| 187 | :g/^/m 0 |
| 188 | |
| 189 | The "^" regular expression matches the beginning of the line (even if the line |
Bram Moolenaar | 11e3c5b | 2021-04-21 18:09:37 +0200 | [diff] [blame] | 190 | is blank). The |:move| command moves the matching line to after the imaginary |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 191 | zeroth line, so the current matching line becomes the first line of the file. |
| 192 | As the |:global| command is not confused by the changing line numbering, |
| 193 | |:global| proceeds to match all remaining lines of the file and puts each as |
| 194 | the first. |
| 195 | |
| 196 | This also works on a range of lines. First move to above the first line and |
| 197 | mark it with "mt". Then move the cursor to the last line in the range and |
| 198 | type: > |
| 199 | |
| 200 | :'t+1,.g/^/m 't |
| 201 | |
| 202 | ============================================================================== |
| 203 | *12.5* Count words |
| 204 | |
| 205 | Sometimes you have to write a text with a maximum number of words. Vim can |
| 206 | count the words for you. |
| 207 | When the whole file is what you want to count the words in, use this |
| 208 | command: > |
| 209 | |
| 210 | g CTRL-G |
| 211 | |
| 212 | Do not type a space after the g, this is just used here to make the command |
| 213 | easy to read. |
| 214 | The output looks like this: |
| 215 | |
| 216 | Col 1 of 0; Line 141 of 157; Word 748 of 774; Byte 4489 of 4976 ~ |
| 217 | |
| 218 | You can see on which word you are (748), and the total number of words in the |
| 219 | file (774). |
| 220 | |
| 221 | When the text is only part of a file, you could move to the start of the text, |
| 222 | type "g CTRL-G", move to the end of the text, type "g CTRL-G" again, and then |
| 223 | use your brain to compute the difference in the word position. That's a good |
| 224 | exercise, but there is an easier way. With Visual mode, select the text you |
| 225 | want to count words in. Then type g CTRL-G. The result: |
| 226 | |
| 227 | Selected 5 of 293 Lines; 70 of 1884 Words; 359 of 10928 Bytes ~ |
| 228 | |
| 229 | For other ways to count words, lines and other items, see |count-items|. |
| 230 | |
| 231 | ============================================================================== |
| 232 | *12.6* Find a man page *find-manpage* |
| 233 | |
| 234 | While editing a shell script or C program, you are using a command or function |
| 235 | that you want to find the man page for (this is on Unix). Let's first use a |
| 236 | simple way: Move the cursor to the word you want to find help on and press > |
| 237 | |
| 238 | K |
| 239 | |
| 240 | Vim will run the external "man" program on the word. If the man page is |
| 241 | found, it is displayed. This uses the normal pager to scroll through the text |
| 242 | (mostly the "more" program). When you get to the end pressing <Enter> will |
| 243 | get you back into Vim. |
| 244 | |
| 245 | A disadvantage is that you can't see the man page and the text you are working |
| 246 | on at the same time. There is a trick to make the man page appear in a Vim |
| 247 | window. First, load the man filetype plugin: > |
| 248 | |
| 249 | :runtime! ftplugin/man.vim |
| 250 | |
| 251 | Put this command in your vimrc file if you intend to do this often. Now you |
| 252 | can use the ":Man" command to open a window on a man page: > |
| 253 | |
| 254 | :Man csh |
| 255 | |
| 256 | You can scroll around and the text is highlighted. This allows you to find |
| 257 | the help you were looking for. Use CTRL-W w to jump to the window with the |
| 258 | text you were working on. |
| 259 | To find a man page in a specific section, put the section number first. |
| 260 | For example, to look in section 3 for "echo": > |
| 261 | |
| 262 | :Man 3 echo |
| 263 | |
| 264 | To jump to another man page, which is in the text with the typical form |
| 265 | "word(1)", press CTRL-] on it. Further ":Man" commands will use the same |
| 266 | window. |
| 267 | |
| 268 | To display a man page for the word under the cursor, use this: > |
| 269 | |
| 270 | \K |
| 271 | |
| 272 | (If you redefined the <Leader>, use it instead of the backslash). |
| 273 | For example, you want to know the return value of "strstr()" while editing |
| 274 | this line: |
| 275 | |
Bram Moolenaar | eddf53b | 2006-02-27 00:11:10 +0000 | [diff] [blame] | 276 | if ( strstr (input, "aap") == ) ~ |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 277 | |
| 278 | Move the cursor to somewhere on "strstr" and type "\K". A window will open |
| 279 | to display the man page for strstr(). |
| 280 | |
| 281 | ============================================================================== |
| 282 | *12.7* Trim blanks |
| 283 | |
| 284 | Some people find spaces and tabs at the end of a line useless, wasteful, and |
| 285 | ugly. To remove whitespace at the end of every line, execute the following |
| 286 | command: > |
| 287 | |
| 288 | :%s/\s\+$// |
| 289 | |
| 290 | The line range "%" is used, thus this works on the whole file. The pattern |
| 291 | that the ":substitute" command matches with is "\s\+$". This finds white |
| 292 | space characters (\s), 1 or more of them (\+), before the end-of-line ($). |
Bram Moolenaar | 1ccd8ff | 2017-08-11 19:50:37 +0200 | [diff] [blame] | 293 | Later will be explained how you write patterns like this, see |usr_27.txt|. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 294 | The "to" part of the substitute command is empty: "//". Thus it replaces |
| 295 | with nothing, effectively deleting the matched white space. |
| 296 | |
Bram Moolenaar | 4b4dc64 | 2007-05-12 15:23:40 +0000 | [diff] [blame] | 297 | Another wasteful use of spaces is placing them before a tab. Often these can |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 298 | be deleted without changing the amount of white space. But not always! |
| 299 | Therefore, you can best do this manually. Use this search command: > |
| 300 | |
| 301 | / |
| 302 | |
| 303 | You cannot see it, but there is a space before a tab in this command. Thus |
| 304 | it's "/<Space><Tab>". Now use "x" to delete the space and check that the |
Bram Moolenaar | 4b4dc64 | 2007-05-12 15:23:40 +0000 | [diff] [blame] | 305 | amount of white space doesn't change. You might have to insert a tab if it |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 306 | does change. Type "n" to find the next match. Repeat this until no more |
| 307 | matches can be found. |
| 308 | |
| 309 | ============================================================================== |
| 310 | *12.8* Find where a word is used |
| 311 | |
| 312 | If you are a UNIX user, you can use a combination of Vim and the grep command |
| 313 | to edit all the files that contain a given word. This is extremely useful if |
| 314 | you are working on a program and want to view or edit all the files that |
| 315 | contain a specific variable. |
| 316 | For example, suppose you want to edit all the C program files that contain |
| 317 | the word "frame_counter". To do this you use the command: > |
| 318 | |
| 319 | vim `grep -l frame_counter *.c` |
| 320 | |
| 321 | Let's look at this command in detail. The grep command searches through a set |
| 322 | of files for a given word. Because the -l argument is specified, the command |
| 323 | will only list the files containing the word and not print the matching lines. |
| 324 | The word it is searching for is "frame_counter". Actually, this can be any |
| 325 | regular expression. (Note: What grep uses for regular expressions is not |
| 326 | exactly the same as what Vim uses.) |
| 327 | The entire command is enclosed in backticks (`). This tells the UNIX shell |
| 328 | to run this command and pretend that the results were typed on the command |
| 329 | line. So what happens is that the grep command is run and produces a list of |
| 330 | files, these files are put on the Vim command line. This results in Vim |
| 331 | editing the file list that is the output of grep. You can then use commands |
| 332 | like ":next" and ":first" to browse through the files. |
| 333 | |
| 334 | |
| 335 | FINDING EACH LINE |
| 336 | |
| 337 | The above command only finds the files in which the word is found. You still |
| 338 | have to find the word within the files. |
| 339 | Vim has a built-in command that you can use to search a set of files for a |
| 340 | given string. If you want to find all occurrences of "error_string" in all C |
| 341 | program files, for example, enter the following command: > |
| 342 | |
| 343 | :grep error_string *.c |
| 344 | |
| 345 | This causes Vim to search for the string "error_string" in all the specified |
| 346 | files (*.c). The editor will now open the first file where a match is found |
| 347 | and position the cursor on the first matching line. To go to the next |
Bram Moolenaar | 8fc061c | 2004-12-29 21:03:02 +0000 | [diff] [blame] | 348 | matching line (no matter in what file it is), use the ":cnext" command. To go |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 349 | to the previous match, use the ":cprev" command. Use ":clist" to see all the |
| 350 | matches and where they are. |
| 351 | The ":grep" command uses the external commands grep (on Unix) or findstr |
| 352 | (on Windows). You can change this by setting the option 'grepprg'. |
| 353 | |
| 354 | ============================================================================== |
| 355 | |
| 356 | Next chapter: |usr_20.txt| Typing command-line commands quickly |
| 357 | |
Bram Moolenaar | d473c8c | 2018-08-11 18:00:22 +0200 | [diff] [blame] | 358 | Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl: |