Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 1 | *tips.txt* For Vim version 7.0aa. Last change: 2004 Feb 17 |
| 2 | |
| 3 | |
| 4 | VIM REFERENCE MANUAL by Bram Moolenaar |
| 5 | |
| 6 | |
| 7 | Tips and ideas for using Vim *tips* |
| 8 | |
| 9 | Don't forget to browse the user manual, it also contains lots of useful tips |
| 10 | |usr_toc.txt|. |
| 11 | |
| 12 | Editing C programs |C-editing| |
| 13 | Finding where identifiers are used |ident-search| |
| 14 | Switching screens in an xterm |xterm-screens| |
| 15 | Scrolling in Insert mode |scroll-insert| |
| 16 | Smooth scrolling |scroll-smooth| |
| 17 | Correcting common typing mistakes |type-mistakes| |
| 18 | Counting words, lines, etc. |count-items| |
| 19 | Restoring the cursor position |restore-position| |
| 20 | Renaming files |rename-files| |
| 21 | Speeding up external commands |speed-up| |
| 22 | Useful mappings |useful-mappings| |
| 23 | Compressing the help files |gzip-helpfile| |
| 24 | Hex editing |hex-editing| |
| 25 | Executing shell commands in a window |shell-window| |
| 26 | Using <> notation in autocommands |autocmd-<>| |
| 27 | |
| 28 | ============================================================================== |
| 29 | Editing C programs *C-editing* |
| 30 | |
| 31 | There are quite a few features in Vim to help you edit C program files. Here |
| 32 | is an overview with tags to jump to: |
| 33 | |
| 34 | |usr_29.txt| Moving through programs chapter in the user manual. |
| 35 | |usr_30.txt| Editing programs chapter in the user manual. |
| 36 | |C-indenting| Automatically set the indent of a line while typing |
| 37 | text. |
| 38 | |=| Re-indent a few lines. |
| 39 | |format-comments| Format comments. |
| 40 | |
| 41 | |:checkpath| Show all recursively included files. |
| 42 | |[i| Search for identifier under cursor in current and |
| 43 | included files. |
| 44 | |[_CTRL-I| Jump to match for "[i" |
| 45 | |[I| List all lines in current and included files where |
| 46 | identifier under the cursor matches. |
| 47 | |[d| Search for define under cursor in current and included |
| 48 | files. |
| 49 | |
| 50 | |CTRL-]| Jump to tag under cursor (e.g., definition of a |
| 51 | function). |
| 52 | |CTRL-T| Jump back to before a CTRL-] command. |
| 53 | |:tselect| Select one tag out of a list of matching tags. |
| 54 | |
| 55 | |gd| Go to Declaration of local variable under cursor. |
| 56 | |gD| Go to Declaration of global variable under cursor. |
| 57 | |
| 58 | |gf| Go to file name under the cursor. |
| 59 | |
| 60 | |%| Go to matching (), {}, [], /* */, #if, #else, #endif. |
| 61 | |[/| Go to previous start of comment. |
| 62 | |]/| Go to next end of comment. |
| 63 | |[#| Go back to unclosed #if, #ifdef, or #else. |
| 64 | |]#| Go forward to unclosed #else or #endif. |
| 65 | |[(| Go back to unclosed '(' |
| 66 | |])| Go forward to unclosed ')' |
| 67 | |[{| Go back to unclosed '{' |
| 68 | |]}| Go forward to unclosed '}' |
| 69 | |
| 70 | |v_ab| Select "a block" from "[(" to "])", including braces |
| 71 | |v_ib| Select "inner block" from "[(" to "])" |
| 72 | |v_aB| Select "a block" from "[{" to "]}", including brackets |
| 73 | |v_iB| Select "inner block" from "[{" to "]}" |
| 74 | |
| 75 | ============================================================================== |
| 76 | Finding where identifiers are used *ident-search* |
| 77 | |
| 78 | You probably already know that |tags| can be used to jump to the place where a |
| 79 | function or variable is defined. But sometimes you wish you could jump to all |
| 80 | the places where a function or variable is being used. This is possible in |
| 81 | two ways: |
| 82 | 1. Using the |:grep| command. This should work on most Unix systems, |
| 83 | but can be slow (it reads all files) and only searches in one directory. |
| 84 | 2. Using ID utils. This is fast and works in multiple directories. It uses a |
| 85 | database to store locations. You will need some additional programs for |
| 86 | this to work. And you need to keep the database up to date. |
| 87 | |
| 88 | Using the GNU id-tools: |
| 89 | |
| 90 | What you need: |
| 91 | - The GNU id-tools installed (mkid is needed to create ID and lid is needed to |
| 92 | use the macros). |
| 93 | - An identifier database file called "ID" in the current directory. You can |
| 94 | create it with the shell command "mkid file1 file2 ..". |
| 95 | |
| 96 | Put this in your .vimrc: > |
| 97 | map _u :call ID_search()<Bar>execute "/\\<" . g:word . "\\>"<CR> |
| 98 | map _n :n<Bar>execute "/\\<" . g:word . "\\>"<CR> |
| 99 | |
| 100 | function! ID_search() |
| 101 | let g:word = expand("<cword>") |
| 102 | let x = system("lid --key=none ". g:word) |
| 103 | let x = substitute(x, "\n", " ", "g") |
| 104 | execute "next " . x |
| 105 | endfun |
| 106 | |
| 107 | To use it, place the cursor on a word, type "_u" and vim will load the file |
| 108 | that contains the word. Search for the next occurrence of the word in the |
| 109 | same file with "n". Go to the next file with "_n". |
| 110 | |
| 111 | This has been tested with id-utils-3.2 (which is the name of the id-tools |
| 112 | archive file on your closest gnu-ftp-mirror). |
| 113 | |
| 114 | [the idea for this comes from Andreas Kutschera] |
| 115 | |
| 116 | ============================================================================== |
| 117 | Switching screens in an xterm *xterm-screens* *xterm-save-screen* |
| 118 | |
| 119 | (From comp.editors, by Juergen Weigert, in reply to a question) |
| 120 | |
| 121 | :> Another question is that after exiting vim, the screen is left as it |
| 122 | :> was, i.e. the contents of the file I was viewing (editing) was left on |
| 123 | :> the screen. The output from my previous like "ls" were lost, |
| 124 | :> ie. no longer in the scrolling buffer. I know that there is a way to |
| 125 | :> restore the screen after exiting vim or other vi like editors, |
| 126 | :> I just don't know how. Helps are appreciated. Thanks. |
| 127 | : |
| 128 | :I imagine someone else can answer this. I assume though that vim and vi do |
| 129 | :the same thing as each other for a given xterm setup. |
| 130 | |
| 131 | They not necessarily do the same thing, as this may be a termcap vs. |
| 132 | terminfo problem. You should be aware that there are two databases for |
| 133 | describing attributes of a particular type of terminal: termcap and |
| 134 | terminfo. This can cause differences when the entries differ AND when of |
| 135 | the programs in question one uses terminfo and the other uses termcap |
| 136 | (also see |+terminfo|). |
| 137 | |
| 138 | In your particular problem, you are looking for the control sequences |
| 139 | ^[[?47h and ^[[?47l. These switch between xterms alternate and main screen |
| 140 | buffer. As a quick workaround a command sequence like > |
| 141 | echo -n "^[[?47h"; vim ... ; echo -n "^[[?47l" |
| 142 | may do what you want. (My notation ^[ means the ESC character, further down |
| 143 | you'll see that the databases use \E instead). |
| 144 | |
| 145 | On startup, vim echoes the value of the termcap variable ti (terminfo: |
| 146 | smcup) to the terminal. When exiting, it echoes te (terminfo: rmcup). Thus |
| 147 | these two variables are the correct place where the above mentioned control |
| 148 | sequences should go. |
| 149 | |
| 150 | Compare your xterm termcap entry (found in /etc/termcap) with your xterm |
| 151 | terminfo entry (retrieved with /usr/5bin/infocmp -C xterm). Both should |
| 152 | contain entries similar to: > |
| 153 | :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h: |
| 154 | |
| 155 | PS: If you find any difference, someone (your sysadmin?) should better check |
| 156 | the complete termcap and terminfo database for consistency. |
| 157 | |
| 158 | NOTE 1: If you recompile Vim with FEAT_XTERM_SAVE defined in feature.h, the |
| 159 | builtin xterm will include the mentioned "te" and "ti" entries. |
| 160 | |
| 161 | NOTE 2: If you want to disable the screen switching, and you don't want to |
| 162 | change your termcap, you can add these lines to your .vimrc: > |
| 163 | :set t_ti= t_te= |
| 164 | |
| 165 | ============================================================================== |
| 166 | Scrolling in Insert mode *scroll-insert* |
| 167 | |
| 168 | If you are in insert mode and you want to see something that is just off the |
| 169 | screen, you can use CTRL-X CTRL-E and CTRL-X CTRL-Y to scroll the screen. |
| 170 | |i_CTRL-X_CTRL-E| |
| 171 | |
| 172 | To make this easier, you could use these mappings: > |
| 173 | :inoremap <C-E> <C-X><C-E> |
| 174 | :inoremap <C-Y> <C-X><C-Y> |
| 175 | (Type this literally, make sure the '<' flag is not in 'cpoptions'). |
| 176 | You then lose the ability to copy text from the line above/below the cursor |
| 177 | |i_CTRL-E|. |
| 178 | |
| 179 | Also consider setting 'scrolloff' to a larger value, so that you can always see |
| 180 | some context around the cursor. If 'scrolloff' is bigger than half the window |
| 181 | height, the cursor will always be in the middle and the text is scrolled when |
| 182 | the cursor is moved up/down. |
| 183 | |
| 184 | ============================================================================== |
| 185 | Smooth scrolling *scroll-smooth* |
| 186 | |
| 187 | If you like the scrolling to go a bit smoother, you can use these mappings: > |
| 188 | :map <C-U> <C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y> |
| 189 | :map <C-D> <C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E> |
| 190 | |
| 191 | (Type this literally, make sure the '<' flag is not in 'cpoptions'). |
| 192 | |
| 193 | ============================================================================== |
| 194 | Correcting common typing mistakes *type-mistakes* |
| 195 | |
| 196 | When there are a few words that you keep on typing in the wrong way, make |
| 197 | abbreviations that correct them. For example: > |
| 198 | :ab teh the |
| 199 | :ab fro for |
| 200 | |
| 201 | ============================================================================== |
| 202 | Counting words, lines, etc. *count-items* |
| 203 | |
| 204 | To count how often any pattern occurs in a buffer, set 'report' to 0, and use |
| 205 | the substitute command to replace the pattern with itself. The reported |
| 206 | number of substitutions is the number of items. Examples: > |
| 207 | |
| 208 | :set report=0 |
| 209 | :%s/./&/g characters |
| 210 | :%s/\i\+/&/g words |
| 211 | :%s/^ lines |
| 212 | :%s/the/&/g "the" anywhere |
| 213 | :%s/\<the\>/&/g "the" as a word |
| 214 | |
| 215 | You might want to reset 'hlsearch' or do ":nohlsearch". |
| 216 | |
| 217 | This does not work if the 'modifiable' option is off. An alternative is using |
| 218 | |v_g_CTRL-G| in Visual mode. |
| 219 | |
| 220 | *count-bytes* |
| 221 | If you want to count bytes, you can use this: |
| 222 | |
| 223 | Visually select the characters (block is also possible) |
| 224 | Use "y" to yank the characters |
| 225 | Use the strlen() function: > |
| 226 | :echo strlen(@") |
| 227 | A line break is counted for one byte. |
| 228 | |
| 229 | ============================================================================== |
| 230 | Restoring the cursor position *restore-position* |
| 231 | |
| 232 | Sometimes you want to write a mapping that makes a change somewhere in the |
| 233 | file and restores the cursor position, without scrolling the text. For |
| 234 | example, to change the date mark in a file: > |
| 235 | :map <F2> msHmtgg/Last [cC]hange:\s*/e+1<CR>"_D"=strftime("%Y %b %d")<CR>p'tzt`s |
| 236 | |
| 237 | Breaking up saving the position: |
| 238 | ms store cursor position in the 's' mark |
| 239 | H go to the first line in the window |
| 240 | mt store this position in the 't' mark |
| 241 | |
| 242 | Breaking up restoring the position: |
| 243 | 't go to the line previously at the top of the window |
| 244 | zt scroll to move this line to the top of the window |
| 245 | `s jump to the original position of the cursor |
| 246 | |
| 247 | ============================================================================== |
| 248 | Renaming files *rename-files* |
| 249 | |
| 250 | Say I have a directory with the following files in them (directory picked at |
| 251 | random :-): |
| 252 | |
| 253 | buffer.c |
| 254 | charset.c |
| 255 | digraph.c |
| 256 | ... |
| 257 | |
| 258 | and I want to rename *.c *.bla. I'd do it like this: > |
| 259 | |
| 260 | $ vim |
| 261 | :r! ls *.c |
| 262 | :%s/\(.*\).c/mv & \1.bla |
| 263 | :w !sh |
| 264 | :q! |
| 265 | |
| 266 | ============================================================================== |
| 267 | Speeding up external commands *speed-up* |
| 268 | |
| 269 | In some situations, execution of an external command can be very slow. This |
| 270 | can also slow down wildcard expansion on Unix. Here are a few suggestions to |
| 271 | increase the speed. |
| 272 | |
| 273 | If your .cshrc (or other file, depending on the shell used) is very long, you |
| 274 | should separate it into a section for interactive use and a section for |
| 275 | non-interactive use (often called secondary shells). When you execute a |
| 276 | command from Vim like ":!ls", you do not need the interactive things (for |
| 277 | example, setting the prompt). Put the stuff that is not needed after these |
| 278 | lines: > |
| 279 | |
| 280 | if ($?prompt == 0) then |
| 281 | exit 0 |
| 282 | endif |
| 283 | |
| 284 | Another way is to include the "-f" flag in the 'shell' option, e.g.: > |
| 285 | |
| 286 | :set shell=csh\ -f |
| 287 | |
| 288 | (the backslash is needed to include the space in the option). |
| 289 | This will make csh completely skip the use of the .cshrc file. This may cause |
| 290 | some things to stop working though. |
| 291 | |
| 292 | ============================================================================== |
| 293 | Useful mappings *useful-mappings* |
| 294 | |
| 295 | Here are a few mappings that some people like to use. |
| 296 | |
| 297 | *map-backtick* > |
| 298 | :map ' ` |
| 299 | Make the single quote work like a backtick. Puts the cursor on the column of |
| 300 | a mark, instead of going to the first non-blank character in the line. |
| 301 | |
| 302 | *emacs-keys* |
| 303 | For Emacs-style editing on the command-line: > |
| 304 | " start of line |
| 305 | :cnoremap <C-A> <Home> |
| 306 | " back one character |
| 307 | :cnoremap <C-B> <Left> |
| 308 | " delete character under cursor |
| 309 | :cnoremap <C-D> <Del> |
| 310 | " end of line |
| 311 | :cnoremap <C-E> <End> |
| 312 | " forward one character |
| 313 | :cnoremap <C-F> <Right> |
| 314 | " recall newer command-line |
| 315 | :cnoremap <C-N> <Down> |
| 316 | " recall previous (older) command-line |
| 317 | :cnoremap <C-P> <Up> |
| 318 | " back one word |
| 319 | :cnoremap <Esc><C-B> <S-Left> |
| 320 | " forward one word |
| 321 | :cnoremap <Esc><C-F> <S-Right> |
| 322 | |
| 323 | NOTE: This requires that the '<' flag is excluded from 'cpoptions'. |<>| |
| 324 | |
| 325 | *format-bullet-list* |
| 326 | This mapping will format any bullet list. It requires that there is an empty |
| 327 | line above and below each list entry. The expression commands are used to |
| 328 | be able to give comments to the parts of the mapping. > |
| 329 | |
| 330 | :let m = ":map _f :set ai<CR>" " need 'autoindent' set |
| 331 | :let m = m . "{O<Esc>" " add empty line above item |
| 332 | :let m = m . "}{)^W" " move to text after bullet |
| 333 | :let m = m . "i <CR> <Esc>" " add space for indent |
| 334 | :let m = m . "gq}" " format text after the bullet |
| 335 | :let m = m . "{dd" " remove the empty line |
| 336 | :let m = m . "5lDJ" " put text after bullet |
| 337 | :execute m |" define the mapping |
| 338 | |
| 339 | (<> notation |<>|. Note that this is all typed literally. ^W is "^" "W", not |
| 340 | CTRL-W. You can copy/paste this into Vim if '<' is not included in |
| 341 | 'cpoptions') |
| 342 | |
| 343 | Note that the last comment starts with |", because the ":execute" command |
| 344 | doesn't accept a comment directly. |
| 345 | |
| 346 | You also need to set 'textwidth' to a non-zero value, e.g., > |
| 347 | :set tw=70 |
| 348 | |
| 349 | A mapping that does about the same, but takes the indent for the list from the |
| 350 | first line (Note: this mapping is a single long line with a lot of spaces): > |
| 351 | :map _f :set ai<CR>}{a <Esc>WWmmkD`mi<CR><Esc>kkddpJgq}'mJO<Esc>j |
| 352 | < |
| 353 | *collapse* |
| 354 | These two mappings reduce a sequence of empty (;b) or blank (;n) lines into a |
| 355 | single line > |
| 356 | :map ;b GoZ<Esc>:g/^$/.,/./-j<CR>Gdd |
| 357 | :map ;n GoZ<Esc>:g/^[ <Tab>]*$/.,/[^ <Tab>]/-j<CR>Gdd |
| 358 | |
| 359 | ============================================================================== |
| 360 | Compressing the help files *gzip-helpfile* |
| 361 | |
| 362 | For those of you who are really short on disk space, you can compress the help |
| 363 | files and still be able to view them with Vim. This makes accessing the help |
| 364 | files a bit slower and requires the "gzip" program. |
| 365 | |
| 366 | (1) Compress all the help files: "gzip doc/*.txt". |
| 367 | |
| 368 | (2) Edit "doc/tags" and change the ".txt" to ".txt.gz": > |
| 369 | :%s=\(\t.*\.txt\)\t=\1.gz\t= |
| 370 | |
| 371 | (3) Add this line to your vimrc: > |
| 372 | set helpfile={dirname}/help.txt.gz |
| 373 | |
| 374 | Where {dirname} is the directory where the help files are. The |gzip| plugin |
| 375 | will take care of decompressing the files. |
| 376 | You must make sure that $VIMRUNTIME is set to where the other Vim files are, |
| 377 | when they are not in the same location as the compressed "doc" directory. See |
| 378 | |$VIMRUNTIME|. |
| 379 | |
| 380 | ============================================================================== |
| 381 | Executing shell commands in a window *shell-window* |
| 382 | |
| 383 | There have been questions for the possibility to execute a shell in a window |
| 384 | inside Vim. The answer: you can't! Including this would add a lot of code to |
| 385 | Vim, which is a good reason not to do this. After all, Vim is an editor, it |
| 386 | is not supposed to do non-editing tasks. However, to get something like this, |
| 387 | you might try splitting your terminal screen or display window with the |
| 388 | "splitvt" program. You can probably find it on some ftp server. The person |
| 389 | that knows more about this is Sam Lantinga <slouken@cs.ucdavis.edu>. |
| 390 | An alternative is the "window" command, found on BSD Unix systems, which |
| 391 | supports multiple overlapped windows. Or the "screen" program, found at |
| 392 | www.uni-erlangen.de, which supports a stack of windows. |
| 393 | |
| 394 | ============================================================================== |
| 395 | Hex editing *hex-editing* *using-xxd* |
| 396 | |
| 397 | See section |23.4| of the user manual. |
| 398 | |
| 399 | If one has a particular extension that one uses for binary files (such as exe, |
| 400 | bin, etc), you may find it helpful to automate the process with the following |
| 401 | bit of autocmds for your <.vimrc>. Change that "*.bin" to whatever |
| 402 | comma-separated list of extension(s) you find yourself wanting to edit: > |
| 403 | |
| 404 | " vim -b : edit binary using xxd-format! |
| 405 | augroup Binary |
| 406 | au! |
| 407 | au BufReadPre *.bin let &bin=1 |
| 408 | au BufReadPost *.bin if &bin | %!xxd |
| 409 | au BufReadPost *.bin set ft=xxd | endif |
| 410 | au BufWritePre *.bin if &bin | %!xxd -r |
| 411 | au BufWritePre *.bin endif |
| 412 | au BufWritePost *.bin if &bin | %!xxd |
| 413 | au BufWritePost *.bin set nomod | endif |
| 414 | augroup END |
| 415 | |
| 416 | ============================================================================== |
| 417 | Using <> notation in autocommands *autocmd-<>* |
| 418 | |
| 419 | The <> notation is not recognized in the argument of an :autocmd. To avoid |
| 420 | having to use special characters, you could use a self-destroying mapping to |
| 421 | get the <> notation and then call the mapping from the autocmd. Example: |
| 422 | |
| 423 | *map-self-destroy* > |
| 424 | " This is for automatically adding the name of the file to the menu list. |
| 425 | " It uses a self-destroying mapping! |
| 426 | " 1. use a line in the buffer to convert the 'dots' in the file name to \. |
| 427 | " 2. store that in register '"' |
| 428 | " 3. add that name to the Buffers menu list |
| 429 | " WARNING: this does have some side effects, like overwriting the |
| 430 | " current register contents and removing any mapping for the "i" command. |
| 431 | " |
| 432 | autocmd BufNewFile,BufReadPre * nmap i :nunmap i<CR>O<C-R>%<Esc>:.g/\./s/\./\\./g<CR>0"9y$u:menu Buffers.<C-R>9 :buffer <C-R>%<C-V><CR><CR> |
| 433 | autocmd BufNewFile,BufReadPre * normal i |
| 434 | |
| 435 | Another method, perhaps better, is to use the ":execute" command. In the |
| 436 | string you can use the <> notation by preceding it with a backslash. Don't |
| 437 | forget to double the number of existing backslashes and put a backslash before |
| 438 | '"'. |
| 439 | > |
| 440 | autocmd BufNewFile,BufReadPre * exe "normal O\<C-R>%\<Esc>:.g/\\./s/\\./\\\\./g\<CR>0\"9y$u:menu Buffers.\<C-R>9 :buffer \<C-R>%\<C-V>\<CR>\<CR>" |
| 441 | |
| 442 | For a real buffer menu, user functions should be used (see |:function|), but |
| 443 | then the <> notation isn't used, which defeats using it as an example here. |
| 444 | |
| 445 | vim:tw=78:ts=8:ft=help:norl: |