Milly | 89872f5 | 2024-10-05 17:16:18 +0200 | [diff] [blame] | 1 | *usr_29.txt* For Vim version 9.1. Last change: 2024 Oct 05 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 2 | |
| 3 | VIM USER MANUAL - by Bram Moolenaar |
| 4 | |
| 5 | Moving through programs |
| 6 | |
| 7 | |
| 8 | The creator of Vim is a computer programmer. It's no surprise that Vim |
| 9 | contains many features to aid in writing programs. Jump around to find where |
| 10 | identifiers are defined and used. Preview declarations in a separate window. |
| 11 | There is more in the next chapter. |
| 12 | |
| 13 | |29.1| Using tags |
| 14 | |29.2| The preview window |
| 15 | |29.3| Moving through a program |
| 16 | |29.4| Finding global identifiers |
| 17 | |29.5| Finding local identifiers |
| 18 | |
| 19 | Next chapter: |usr_30.txt| Editing programs |
| 20 | Previous chapter: |usr_28.txt| Folding |
| 21 | Table of contents: |usr_toc.txt| |
| 22 | |
| 23 | ============================================================================== |
| 24 | *29.1* Using tags |
| 25 | |
| 26 | What is a tag? It is a location where an identifier is defined. An example |
| 27 | is a function definition in a C or C++ program. A list of tags is kept in a |
| 28 | tags file. This can be used by Vim to directly jump from any place to the |
| 29 | tag, the place where an identifier is defined. |
| 30 | To generate the tags file for all C files in the current directory, use the |
| 31 | following command: > |
| 32 | |
| 33 | ctags *.c |
| 34 | |
| 35 | "ctags" is a separate program. Most Unix systems already have it installed. |
Bram Moolenaar | 47c532e | 2022-03-19 15:18:53 +0000 | [diff] [blame] | 36 | If you do not have it yet, you can find Universal/Exuberant ctags at: |
Milly | 89872f5 | 2024-10-05 17:16:18 +0200 | [diff] [blame] | 37 | http://ctags.io |
| 38 | http://ctags.sf.net |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 39 | |
Bram Moolenaar | 47c532e | 2022-03-19 15:18:53 +0000 | [diff] [blame] | 40 | Universal ctags is preferred, Exuberant ctags is no longer being developed. |
| 41 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 42 | Now when you are in Vim and you want to go to a function definition, you can |
| 43 | jump to it by using the following command: > |
| 44 | |
| 45 | :tag startlist |
| 46 | |
| 47 | This command will find the function "startlist" even if it is in another file. |
| 48 | The CTRL-] command jumps to the tag of the word that is under the cursor. |
| 49 | This makes it easy to explore a tangle of C code. Suppose, for example, that |
| 50 | you are in the function "write_block". You can see that it calls |
| 51 | "write_line". But what does "write_line" do? By placing the cursor on the |
| 52 | call to "write_line" and pressing CTRL-], you jump to the definition of this |
| 53 | function. |
| 54 | The "write_line" function calls "write_char". You need to figure out what |
| 55 | it does. So you position the cursor over the call to "write_char" and press |
| 56 | CTRL-]. Now you are at the definition of "write_char". |
| 57 | |
| 58 | +-------------------------------------+ |
| 59 | |void write_block(char **s; int cnt) | |
| 60 | |{ | |
| 61 | | int i; | |
| 62 | | for (i = 0; i < cnt; ++i) | |
| 63 | | write_line(s[i]); | |
| 64 | |} | | |
| 65 | +-----------|-------------------------+ |
| 66 | | |
| 67 | CTRL-] | |
| 68 | | +----------------------------+ |
| 69 | +--> |void write_line(char *s) | |
| 70 | |{ | |
| 71 | | while (*s != 0) | |
| 72 | | write_char(*s++); | |
| 73 | |} | | |
| 74 | +--------|-------------------+ |
| 75 | | |
| 76 | CTRL-] | |
| 77 | | +------------------------------------+ |
| 78 | +--> |void write_char(char c) | |
| 79 | |{ | |
| 80 | | putchar((int)(unsigned char)c); | |
| 81 | |} | |
| 82 | +------------------------------------+ |
| 83 | |
| 84 | The ":tags" command shows the list of tags that you traversed through: |
| 85 | |
| 86 | :tags |
| 87 | # TO tag FROM line in file/text ~ |
| 88 | 1 1 write_line 8 write_block.c ~ |
| 89 | 2 1 write_char 7 write_line.c ~ |
| 90 | > ~ |
| 91 | > |
| 92 | Now to go back. The CTRL-T command goes to the preceding tag. In the example |
| 93 | above you get back to the "write_line" function, in the call to "write_char". |
| 94 | This command takes a count argument that indicates how many tags to jump |
| 95 | back. You have gone forward, and now back. Let's go forward again. The |
| 96 | following command goes to the tag on top of the list: > |
| 97 | |
| 98 | :tag |
| 99 | |
| 100 | You can prefix it with a count and jump forward that many tags. For example: |
| 101 | ":3tag". CTRL-T also can be preceded with a count. |
| 102 | These commands thus allow you to go down a call tree with CTRL-] and back |
| 103 | up again with CTRL-T. Use ":tags" to find out where you are. |
| 104 | |
| 105 | |
| 106 | SPLIT WINDOWS |
| 107 | |
| 108 | The ":tag" command replaces the file in the current window with the one |
| 109 | containing the new function. But suppose you want to see not only the old |
| 110 | function but also the new one? You can split the window using the ":split" |
| 111 | command followed by the ":tag" command. Vim has a shorthand command that does |
| 112 | both: > |
| 113 | :stag tagname |
| 114 | |
| 115 | To split the current window and jump to the tag under the cursor use this |
| 116 | command: > |
| 117 | |
| 118 | CTRL-W ] |
| 119 | |
| 120 | If a count is specified, the new window will be that many lines high. |
| 121 | |
| 122 | |
| 123 | MORE TAGS FILES |
| 124 | |
| 125 | When you have files in many directories, you can create a tags file in each of |
| 126 | them. Vim will then only be able to jump to tags within that directory. |
| 127 | To find more tags files, set the 'tags' option to include all the relevant |
| 128 | tags files. Example: > |
| 129 | |
| 130 | :set tags=./tags,./../tags,./*/tags |
| 131 | |
| 132 | This finds a tags file in the same directory as the current file, one |
| 133 | directory level higher and in all subdirectories. |
| 134 | This is quite a number of tags files, but it may still not be enough. For |
| 135 | example, when editing a file in "~/proj/src", you will not find the tags file |
| 136 | "~/proj/sub/tags". For this situation Vim offers to search a whole directory |
| 137 | tree for tags files. Example: > |
| 138 | |
| 139 | :set tags=~/proj/**/tags |
| 140 | |
| 141 | |
| 142 | ONE TAGS FILE |
| 143 | |
| 144 | When Vim has to search many places for tags files, you can hear the disk |
| 145 | rattling. It may get a bit slow. In that case it's better to spend this |
| 146 | time while generating one big tags file. You might do this overnight. |
Bram Moolenaar | 47c532e | 2022-03-19 15:18:53 +0000 | [diff] [blame] | 147 | This requires the Universal or Exuberant ctags program, mentioned above. |
| 148 | It offers an argument to search a whole directory tree: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 149 | |
| 150 | cd ~/proj |
| 151 | ctags -R . |
| 152 | |
Bram Moolenaar | 47c532e | 2022-03-19 15:18:53 +0000 | [diff] [blame] | 153 | The nice thing about this is that Universal/Exuberant ctags recognizes various |
| 154 | file types. Thus this doesn't work just for C and C++ programs, also for |
| 155 | Eiffel and even Vim scripts. See the ctags documentation to tune this. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 156 | Now you only need to tell Vim where your big tags file is: > |
| 157 | |
| 158 | :set tags=~/proj/tags |
| 159 | |
| 160 | |
| 161 | MULTIPLE MATCHES |
| 162 | |
| 163 | When a function is defined multiple times (or a method in several classes), |
| 164 | the ":tag" command will jump to the first one. If there is a match in the |
| 165 | current file, that one is used first. |
| 166 | You can now jump to other matches for the same tag with: > |
| 167 | |
| 168 | :tnext |
| 169 | |
| 170 | Repeat this to find further matches. If there are many, you can select which |
| 171 | one to jump to: > |
| 172 | |
| 173 | :tselect tagname |
| 174 | |
| 175 | Vim will present you with a list of choices: |
| 176 | |
| 177 | # pri kind tag file ~ |
| 178 | 1 F f mch_init os_amiga.c ~ |
| 179 | mch_init() ~ |
| 180 | 2 F f mch_init os_mac.c ~ |
| 181 | mch_init() ~ |
| 182 | 3 F f mch_init os_msdos.c ~ |
| 183 | mch_init(void) ~ |
| 184 | 4 F f mch_init os_riscos.c ~ |
| 185 | mch_init() ~ |
| 186 | Enter nr of choice (<CR> to abort): ~ |
| 187 | |
| 188 | You can now enter the number (in the first column) of the match that you would |
| 189 | like to jump to. The information in the other columns give you a good idea of |
| 190 | where the match is defined. |
| 191 | |
| 192 | To move between the matching tags, these commands can be used: |
| 193 | |
| 194 | :tfirst go to first match |
| 195 | :[count]tprevious go to [count] previous match |
| 196 | :[count]tnext go to [count] next match |
| 197 | :tlast go to last match |
| 198 | |
| 199 | If [count] is omitted then one is used. |
| 200 | |
| 201 | |
| 202 | GUESSING TAG NAMES |
| 203 | |
| 204 | Command line completion is a good way to avoid typing a long tag name. Just |
| 205 | type the first bit and press <Tab>: > |
| 206 | |
| 207 | :tag write_<Tab> |
| 208 | |
| 209 | You will get the first match. If it's not the one you want, press <Tab> until |
| 210 | you find the right one. |
| 211 | Sometimes you only know part of the name of a function. Or you have many |
| 212 | tags that start with the same string, but end differently. Then you can tell |
| 213 | Vim to use a pattern to find the tag. |
| 214 | Suppose you want to jump to a tag that contains "block". First type |
| 215 | this: > |
| 216 | |
| 217 | :tag /block |
| 218 | |
| 219 | Now use command line completion: press <Tab>. Vim will find all tags that |
| 220 | contain "block" and use the first match. |
| 221 | The "/" before a tag name tells Vim that what follows is not a literal tag |
| 222 | name, but a pattern. You can use all the items for search patterns here. For |
| 223 | example, suppose you want to select a tag that starts with "write_": > |
| 224 | |
| 225 | :tselect /^write_ |
| 226 | |
| 227 | The "^" specifies that the tag starts with "write_". Otherwise it would also |
| 228 | be found halfway a tag name. Similarly "$" at the end makes sure the pattern |
| 229 | matches until the end of a tag. |
| 230 | |
| 231 | |
| 232 | A TAGS BROWSER |
| 233 | |
| 234 | Since CTRL-] takes you to the definition of the identifier under the cursor, |
| 235 | you can use a list of identifier names as a table of contents. Here is an |
| 236 | example. |
Bram Moolenaar | 47c532e | 2022-03-19 15:18:53 +0000 | [diff] [blame] | 237 | First create a list of identifiers (this requires Universal or Exuberant |
| 238 | ctags): > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 239 | |
| 240 | ctags --c-types=f -f functions *.c |
| 241 | |
| 242 | Now start Vim without a file, and edit this file in Vim, in a vertically split |
| 243 | window: > |
| 244 | |
| 245 | vim |
| 246 | :vsplit functions |
| 247 | |
| 248 | The window contains a list of all the functions. There is some more stuff, |
| 249 | but you can ignore that. Do ":setlocal ts=99" to clean it up a bit. |
| 250 | In this window, define a mapping: > |
| 251 | |
| 252 | :nnoremap <buffer> <CR> 0ye<C-W>w:tag <C-R>"<CR> |
| 253 | |
| 254 | Move the cursor to the line that contains the function you want to go to. |
| 255 | Now press <Enter>. Vim will go to the other window and jump to the selected |
| 256 | function. |
| 257 | |
| 258 | |
| 259 | RELATED ITEMS |
| 260 | |
Bram Moolenaar | 0f6562e | 2015-11-24 18:48:14 +0100 | [diff] [blame] | 261 | To make case in tag names be ignored, you can set 'ignorecase' while leaving |
| 262 | 'tagcase' as "followic", or set 'tagcase' to "ignore". |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 263 | |
| 264 | The 'tagbsearch' option tells if the tags file is sorted or not. The default |
| 265 | is to assume a sorted tags file, which makes a tags search a lot faster, but |
| 266 | doesn't work if the tags file isn't sorted. |
| 267 | |
| 268 | The 'taglength' option can be used to tell Vim the number of significant |
| 269 | characters in a tag. |
| 270 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 271 | Cscope is a free program. It does not only find places where an identifier is |
| 272 | declared, but also where it is used. See |cscope|. |
| 273 | |
| 274 | ============================================================================== |
| 275 | *29.2* The preview window |
| 276 | |
| 277 | When you edit code that contains a function call, you need to use the correct |
| 278 | arguments. To know what values to pass you can look at how the function is |
| 279 | defined. The tags mechanism works very well for this. Preferably the |
| 280 | definition is displayed in another window. For this the preview window can be |
| 281 | used. |
| 282 | To open a preview window to display the function "write_char": > |
| 283 | |
| 284 | :ptag write_char |
| 285 | |
| 286 | Vim will open a window, and jumps to the tag "write_char". Then it takes you |
| 287 | back to the original position. Thus you can continue typing without the need |
| 288 | to use a CTRL-W command. |
| 289 | If the name of a function appears in the text, you can get its definition |
| 290 | in the preview window with: > |
| 291 | |
| 292 | CTRL-W } |
| 293 | |
| 294 | There is a script that automatically displays the text where the word under |
| 295 | the cursor was defined. See |CursorHold-example|. |
| 296 | |
| 297 | To close the preview window use this command: > |
| 298 | |
| 299 | :pclose |
| 300 | |
| 301 | To edit a specific file in the preview window, use ":pedit". This can be |
| 302 | useful to edit a header file, for example: > |
| 303 | |
| 304 | :pedit defs.h |
| 305 | |
| 306 | Finally, ":psearch" can be used to find a word in the current file and any |
| 307 | included files and display the match in the preview window. This is |
| 308 | especially useful when using library functions, for which you do not have a |
| 309 | tags file. Example: > |
| 310 | |
| 311 | :psearch popen |
| 312 | |
| 313 | This will show the "stdio.h" file in the preview window, with the function |
| 314 | prototype for popen(): |
| 315 | |
| 316 | FILE *popen __P((const char *, const char *)); ~ |
| 317 | |
| 318 | You can specify the height of the preview window, when it is opened, with the |
| 319 | 'previewheight' option. |
| 320 | |
| 321 | ============================================================================== |
| 322 | *29.3* Moving through a program |
| 323 | |
| 324 | Since a program is structured, Vim can recognize items in it. Specific |
| 325 | commands can be used to move around. |
| 326 | C programs often contain constructs like this: |
| 327 | |
| 328 | #ifdef USE_POPEN ~ |
| 329 | fd = popen("ls", "r") ~ |
| 330 | #else ~ |
| 331 | fd = fopen("tmp", "w") ~ |
| 332 | #endif ~ |
| 333 | |
| 334 | But then much longer, and possibly nested. Position the cursor on the |
| 335 | "#ifdef" and press %. Vim will jump to the "#else". Pressing % again takes |
| 336 | you to the "#endif". Another % takes you to the "#ifdef" again. |
| 337 | When the construct is nested, Vim will find the matching items. This is a |
| 338 | good way to check if you didn't forget an "#endif". |
| 339 | When you are somewhere inside a "#if" - "#endif", you can jump to the start |
| 340 | of it with: > |
| 341 | |
| 342 | [# |
| 343 | |
| 344 | If you are not after a "#if" or "#ifdef" Vim will beep. To jump forward to |
| 345 | the next "#else" or "#endif" use: > |
| 346 | |
| 347 | ]# |
| 348 | |
| 349 | These two commands skip any "#if" - "#endif" blocks that they encounter. |
| 350 | Example: |
| 351 | |
| 352 | #if defined(HAS_INC_H) ~ |
| 353 | a = a + inc(); ~ |
| 354 | # ifdef USE_THEME ~ |
| 355 | a += 3; ~ |
| 356 | # endif ~ |
| 357 | set_width(a); ~ |
| 358 | |
| 359 | With the cursor in the last line, "[#" moves to the first line. The "#ifdef" |
| 360 | - "#endif" block in the middle is skipped. |
| 361 | |
| 362 | |
| 363 | MOVING IN CODE BLOCKS |
| 364 | |
| 365 | In C code blocks are enclosed in {}. These can get pretty long. To move to |
| 366 | the start of the outer block use the "[[" command. Use "][" to find the end. |
| 367 | This assumes that the "{" and "}" are in the first column. |
| 368 | The "[{" command moves to the start of the current block. It skips over |
| 369 | pairs of {} at the same level. "]}" jumps to the end. |
| 370 | An overview: |
| 371 | |
| 372 | function(int a) |
| 373 | +-> { |
| 374 | | if (a) |
| 375 | | +-> { |
| 376 | [[ | | for (;;) --+ |
| 377 | | | +-> { | |
| 378 | | [{ | | foo(32); | --+ |
| 379 | | | [{ | if (bar(a)) --+ | ]} | |
| 380 | +-- | +-- break; | ]} | | |
| 381 | | } <-+ | | ][ |
| 382 | +-- foobar(a) | | |
| 383 | } <-+ | |
| 384 | } <-+ |
| 385 | |
| 386 | When writing C++ or Java, the outer {} block is for the class. The next level |
| 387 | of {} is for a method. When somewhere inside a class use "[m" to find the |
Bram Moolenaar | 446cb83 | 2008-06-24 21:56:24 +0000 | [diff] [blame] | 388 | previous start of a method. "]m" finds the next start of a method. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 389 | |
| 390 | Additionally, "[]" moves backward to the end of a function and "]]" moves |
| 391 | forward to the start of the next function. The end of a function is defined |
| 392 | by a "}" in the first column. |
| 393 | |
| 394 | int func1(void) |
| 395 | { |
| 396 | return 1; |
| 397 | +----------> } |
| 398 | | |
| 399 | [] | int func2(void) |
| 400 | | +-> { |
| 401 | | [[ | if (flag) |
| 402 | start +-- +-- return flag; |
| 403 | | ][ | return 2; |
| 404 | | +-> } |
| 405 | ]] | |
| 406 | | int func3(void) |
| 407 | +----------> { |
| 408 | return 3; |
| 409 | } |
| 410 | |
| 411 | Don't forget you can also use "%" to move between matching (), {} and []. |
| 412 | That also works when they are many lines apart. |
| 413 | |
| 414 | |
| 415 | MOVING IN BRACES |
| 416 | |
| 417 | The "[(" and "])" commands work similar to "[{" and "]}", except that they |
| 418 | work on () pairs instead of {} pairs. |
| 419 | > |
| 420 | [( |
| 421 | < <-------------------------------- |
| 422 | <------- |
| 423 | if (a == b && (c == d || (e > f)) && x > y) ~ |
| 424 | --------------> |
| 425 | --------------------------------> > |
| 426 | ]) |
| 427 | |
| 428 | MOVING IN COMMENTS |
| 429 | |
| 430 | To move back to the start of a comment use "[/". Move forward to the end of a |
| 431 | comment with "]/". This only works for /* - */ comments. |
| 432 | |
| 433 | +-> +-> /* |
| 434 | | [/ | * A comment about --+ |
| 435 | [/ | +-- * wonderful life. | ]/ |
| 436 | | */ <-+ |
| 437 | | |
| 438 | +-- foo = bar * 3; --+ |
| 439 | | ]/ |
| 440 | /* a short comment */ <-+ |
| 441 | |
| 442 | ============================================================================== |
| 443 | *29.4* Finding global identifiers |
| 444 | |
| 445 | You are editing a C program and wonder if a variable is declared as "int" or |
| 446 | "unsigned". A quick way to find this is with the "[I" command. |
| 447 | Suppose the cursor is on the word "column". Type: > |
| 448 | |
| 449 | [I |
| 450 | |
| 451 | Vim will list the matching lines it can find. Not only in the current file, |
| 452 | but also in all included files (and files included in them, etc.). The result |
| 453 | looks like this: |
| 454 | |
| 455 | structs.h ~ |
| 456 | 1: 29 unsigned column; /* column number */ ~ |
| 457 | |
| 458 | The advantage over using tags or the preview window is that included files are |
| 459 | searched. In most cases this results in the right declaration to be found. |
| 460 | Also when the tags file is out of date. Also when you don't have tags for the |
| 461 | included files. |
| 462 | However, a few things must be right for "[I" to do its work. First of all, |
| 463 | the 'include' option must specify how a file is included. The default value |
| 464 | works for C and C++. For other languages you will have to change it. |
| 465 | |
| 466 | |
| 467 | LOCATING INCLUDED FILES |
| 468 | |
| 469 | Vim will find included files in the places specified with the 'path' |
| 470 | option. If a directory is missing, some include files will not be found. You |
| 471 | can discover this with this command: > |
| 472 | |
| 473 | :checkpath |
| 474 | |
| 475 | It will list the include files that could not be found. Also files included |
| 476 | by the files that could be found. An example of the output: |
| 477 | |
| 478 | --- Included files not found in path --- ~ |
| 479 | <io.h> ~ |
| 480 | vim.h --> ~ |
| 481 | <functions.h> ~ |
| 482 | <clib/exec_protos.h> ~ |
| 483 | |
| 484 | The "io.h" file is included by the current file and can't be found. "vim.h" |
| 485 | can be found, thus ":checkpath" goes into this file and checks what it |
| 486 | includes. The "functions.h" and "clib/exec_protos.h" files, included by |
| 487 | "vim.h" are not found. |
| 488 | |
| 489 | Note: |
| 490 | Vim is not a compiler. It does not recognize "#ifdef" statements. |
| 491 | This means every "#include" statement is used, also when it comes |
| 492 | after "#if NEVER". |
| 493 | |
| 494 | To fix the files that could not be found, add a directory to the 'path' |
| 495 | option. A good place to find out about this is the Makefile. Look out for |
| 496 | lines that contain "-I" items, like "-I/usr/local/X11". To add this directory |
| 497 | use: > |
| 498 | |
| 499 | :set path+=/usr/local/X11 |
| 500 | |
Bram Moolenaar | 446cb83 | 2008-06-24 21:56:24 +0000 | [diff] [blame] | 501 | When there are many subdirectories, you can use the "*" wildcard. Example: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 502 | |
| 503 | :set path+=/usr/*/include |
| 504 | |
| 505 | This would find files in "/usr/local/include" as well as "/usr/X11/include". |
| 506 | |
| 507 | When working on a project with a whole nested tree of included files, the "**" |
| 508 | items is useful. This will search down in all subdirectories. Example: > |
| 509 | |
| 510 | :set path+=/projects/invent/**/include |
| 511 | |
| 512 | This will find files in the directories: |
| 513 | |
| 514 | /projects/invent/include ~ |
| 515 | /projects/invent/main/include ~ |
| 516 | /projects/invent/main/os/include ~ |
| 517 | etc. |
| 518 | |
| 519 | There are even more possibilities. Check out the 'path' option for info. |
| 520 | If you want to see which included files are actually found, use this |
| 521 | command: > |
| 522 | |
| 523 | :checkpath! |
| 524 | |
| 525 | You will get a (very long) list of included files, the files they include, and |
| 526 | so on. To shorten the list a bit, Vim shows "(Already listed)" for files that |
| 527 | were found before and doesn't list the included files in there again. |
| 528 | |
| 529 | |
| 530 | JUMPING TO A MATCH |
| 531 | |
| 532 | "[I" produces a list with only one line of text. When you want to have a |
| 533 | closer look at the first item, you can jump to that line with the command: > |
| 534 | |
| 535 | [<Tab> |
| 536 | |
| 537 | You can also use "[ CTRL-I", since CTRL-I is the same as pressing <Tab>. |
| 538 | |
| 539 | The list that "[I" produces has a number at the start of each line. When you |
| 540 | want to jump to another item than the first one, type the number first: > |
| 541 | |
| 542 | 3[<Tab> |
| 543 | |
| 544 | Will jump to the third item in the list. Remember that you can use CTRL-O to |
| 545 | jump back to where you started from. |
| 546 | |
| 547 | |
| 548 | RELATED COMMANDS |
| 549 | |
| 550 | [i only lists the first match |
| 551 | ]I only lists items below the cursor |
| 552 | ]i only lists the first item below the cursor |
| 553 | |
| 554 | |
| 555 | FINDING DEFINED IDENTIFIERS |
| 556 | |
| 557 | The "[I" command finds any identifier. To find only macros, defined with |
| 558 | "#define" use: > |
| 559 | |
| 560 | [D |
| 561 | |
| 562 | Again, this searches in included files. The 'define' option specifies what a |
| 563 | line looks like that defines the items for "[D". You could change it to make |
| 564 | it work with other languages than C or C++. |
| 565 | The commands related to "[D" are: |
| 566 | |
| 567 | [d only lists the first match |
| 568 | ]D only lists items below the cursor |
| 569 | ]d only lists the first item below the cursor |
| 570 | |
| 571 | ============================================================================== |
| 572 | *29.5* Finding local identifiers |
| 573 | |
| 574 | The "[I" command searches included files. To search in the current file only, |
| 575 | and jump to the first place where the word under the cursor is used: > |
| 576 | |
| 577 | gD |
| 578 | |
| 579 | Hint: Goto Definition. This command is very useful to find a variable or |
| 580 | function that was declared locally ("static", in C terms). Example (cursor on |
| 581 | "counter"): |
| 582 | |
| 583 | +-> static int counter = 0; |
| 584 | | |
| 585 | | int get_counter(void) |
| 586 | gD | { |
| 587 | | ++counter; |
| 588 | +-- return counter; |
| 589 | } |
| 590 | |
| 591 | To restrict the search even further, and look only in the current function, |
| 592 | use this command: > |
| 593 | |
| 594 | gd |
| 595 | |
| 596 | This will go back to the start of the current function and find the first |
| 597 | occurrence of the word under the cursor. Actually, it searches backwards to |
Bram Moolenaar | c236c16 | 2008-07-13 17:41:49 +0000 | [diff] [blame] | 598 | an empty line above a "{" in the first column. From there it searches forward |
| 599 | for the identifier. Example (cursor on "idx"): |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 600 | |
| 601 | int find_entry(char *name) |
| 602 | { |
| 603 | +-> int idx; |
| 604 | | |
| 605 | gd | for (idx = 0; idx < table_len; ++idx) |
| 606 | | if (strcmp(table[idx].name, name) == 0) |
| 607 | +-- return idx; |
| 608 | } |
| 609 | |
| 610 | ============================================================================== |
| 611 | |
| 612 | Next chapter: |usr_30.txt| Editing programs |
| 613 | |
Bram Moolenaar | d473c8c | 2018-08-11 18:00:22 +0200 | [diff] [blame] | 614 | Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl: |