Damien Lejay | bfa1636 | 2025-06-10 21:12:31 +0200 | [diff] [blame] | 1 | *usr_30.txt* For Vim version 9.1. Last change: 2025 Jun 10 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 2 | |
| 3 | VIM USER MANUAL - by Bram Moolenaar |
| 4 | |
| 5 | Editing programs |
| 6 | |
| 7 | |
| 8 | Vim has various commands that aid in writing computer programs. Compile a |
| 9 | program and directly jump to reported errors. Automatically set the indent |
| 10 | for many languages and format comments. |
| 11 | |
| 12 | |30.1| Compiling |
| 13 | |30.2| Indenting C files |
| 14 | |30.3| Automatic indenting |
| 15 | |30.4| Other indenting |
| 16 | |30.5| Tabs and spaces |
| 17 | |30.6| Formatting comments |
| 18 | |
| 19 | Next chapter: |usr_31.txt| Exploiting the GUI |
| 20 | Previous chapter: |usr_29.txt| Moving through programs |
| 21 | Table of contents: |usr_toc.txt| |
| 22 | |
| 23 | ============================================================================== |
| 24 | *30.1* Compiling |
| 25 | |
| 26 | Vim has a set of so called "quickfix" commands. They enable you to compile a |
| 27 | program from within Vim and then go through the errors generated and fix them |
| 28 | (hopefully). You can then recompile and fix any new errors that are found |
| 29 | until finally your program compiles without any error. |
| 30 | |
| 31 | The following command runs the program "make" (supplying it with any argument |
| 32 | you give) and captures the results: > |
| 33 | |
| 34 | :make {arguments} |
| 35 | |
| 36 | If errors were generated, they are captured and the editor positions you where |
| 37 | the first error occurred. |
Bram Moolenaar | 13fcaaf | 2005-04-15 21:13:42 +0000 | [diff] [blame] | 38 | Take a look at an example ":make" session. (Typical :make sessions generate |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 39 | far more errors and fewer stupid ones.) After typing ":make" the screen looks |
| 40 | like this: |
| 41 | |
| 42 | :!make | &tee /tmp/vim215953.err ~ |
| 43 | gcc -g -Wall -o prog main.c sub.c ~ |
| 44 | main.c: In function 'main': ~ |
| 45 | main.c:6: too many arguments to function 'do_sub' ~ |
| 46 | main.c: At top level: ~ |
| 47 | main.c:10: parse error before '}' ~ |
| 48 | make: *** [prog] Error 1 ~ |
| 49 | |
| 50 | 2 returned ~ |
| 51 | "main.c" 11L, 111C ~ |
| 52 | (3 of 6): too many arguments to function 'do_sub' ~ |
Bram Moolenaar | c81e5e7 | 2007-05-05 18:24:42 +0000 | [diff] [blame] | 53 | Press ENTER or type command to continue ~ |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 54 | |
| 55 | From this you can see that you have errors in the file "main.c". When you |
| 56 | press <Enter>, Vim displays the file "main.c", with the cursor positioned on |
| 57 | line 6, the first line with an error. You did not need to specify the file or |
| 58 | the line number, Vim knew where to go by looking in the error messages. |
| 59 | |
| 60 | +---------------------------------------------------+ |
| 61 | |int main() | |
| 62 | |{ | |
| 63 | | int i=3; | |
| 64 | cursor -> | do_sub("foo"); | |
| 65 | | ++i; | |
| 66 | | return (0); | |
| 67 | |} | |
| 68 | |} | |
| 69 | | ~ | |
| 70 | |(3 of 12): too many arguments to function 'do_sub' | |
| 71 | +---------------------------------------------------+ |
| 72 | |
| 73 | The following command goes to where the next error occurs: > |
| 74 | |
| 75 | :cnext |
| 76 | |
| 77 | Vim jumps to line 10, the last line in the file, where there is an extra '}'. |
| 78 | When there is not enough room, Vim will shorten the error message. To see |
| 79 | the whole message use: > |
| 80 | |
| 81 | :cc |
| 82 | |
| 83 | You can get an overview of all the error messages with the ":clist" command. |
| 84 | The output looks like this: > |
| 85 | |
| 86 | :clist |
| 87 | < 3 main.c: 6:too many arguments to function 'do_sub' ~ |
| 88 | 5 main.c: 10:parse error before '}' ~ |
| 89 | |
| 90 | Only the lines where Vim recognized a file name and line number are listed |
| 91 | here. It assumes those are the interesting lines and the rest is just boring |
| 92 | messages. However, sometimes unrecognized lines do contain something you want |
| 93 | to see. Output from the linker, for example, about an undefined function. |
| 94 | To see all the messages add a "!" to the command: > |
| 95 | |
| 96 | :clist! |
| 97 | < 1 gcc -g -Wall -o prog main.c sub.c ~ |
| 98 | 2 main.c: In function 'main': ~ |
| 99 | 3 main.c:6: too many arguments to function 'do_sub' ~ |
| 100 | 4 main.c: At top level: ~ |
| 101 | 5 main.c:10: parse error before '}' ~ |
| 102 | 6 make: *** [prog] Error 1 ~ |
| 103 | |
| 104 | Vim will highlight the current error. To go back to the previous error, use: |
| 105 | > |
| 106 | :cprevious |
| 107 | |
| 108 | Other commands to move around in the error list: |
| 109 | |
| 110 | :cfirst to first error |
| 111 | :clast to last error |
| 112 | :cc 3 to error nr 3 |
| 113 | |
| 114 | |
| 115 | USING ANOTHER COMPILER |
| 116 | |
| 117 | The name of the program to run when the ":make" command is executed is defined |
| 118 | by the 'makeprg' option. Usually this is set to "make", but Visual C++ users |
| 119 | should set this to "nmake" by executing the following command: > |
| 120 | |
| 121 | :set makeprg=nmake |
| 122 | |
| 123 | You can also include arguments in this option. Special characters need to |
| 124 | be escaped with a backslash. Example: > |
| 125 | |
| 126 | :set makeprg=nmake\ -f\ project.mak |
| 127 | |
| 128 | You can include special Vim keywords in the command specification. The % |
| 129 | character expands to the name of the current file. So if you execute the |
| 130 | command: > |
Bram Moolenaar | 26df092 | 2014-02-23 23:39:13 +0100 | [diff] [blame] | 131 | :set makeprg=make\ %:S |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 132 | |
| 133 | When you are editing main.c, then ":make" executes the following command: > |
| 134 | |
| 135 | make main.c |
| 136 | |
| 137 | This is not too useful, so you will refine the command a little and use the :r |
| 138 | (root) modifier: > |
| 139 | |
Bram Moolenaar | 26df092 | 2014-02-23 23:39:13 +0100 | [diff] [blame] | 140 | :set makeprg=make\ %:r:S.o |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 141 | |
| 142 | Now the command executed is as follows: > |
| 143 | |
| 144 | make main.o |
| 145 | |
| 146 | More about these modifiers here: |filename-modifiers|. |
| 147 | |
| 148 | |
| 149 | OLD ERROR LISTS |
| 150 | |
Bram Moolenaar | c81e5e7 | 2007-05-05 18:24:42 +0000 | [diff] [blame] | 151 | Suppose you ":make" a program. There is a warning message in one file and an |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 152 | error message in another. You fix the error and use ":make" again to check if |
| 153 | it was really fixed. Now you want to look at the warning message. It doesn't |
| 154 | show up in the last error list, since the file with the warning wasn't |
| 155 | compiled again. You can go back to the previous error list with: > |
| 156 | |
| 157 | :colder |
| 158 | |
| 159 | Then use ":clist" and ":cc {nr}" to jump to the place with the warning. |
| 160 | To go forward to the next error list: > |
| 161 | |
| 162 | :cnewer |
| 163 | |
| 164 | Vim remembers ten error lists. |
| 165 | |
| 166 | |
| 167 | SWITCHING COMPILERS |
| 168 | |
| 169 | You have to tell Vim what format the error messages are that your compiler |
| 170 | produces. This is done with the 'errorformat' option. The syntax of this |
| 171 | option is quite complicated and it can be made to fit almost any compiler. |
| 172 | You can find the explanation here: |errorformat|. |
| 173 | |
| 174 | You might be using various different compilers. Setting the 'makeprg' option, |
| 175 | and especially the 'errorformat' each time is not easy. Vim offers a simple |
| 176 | method for this. For example, to switch to using the Microsoft Visual C++ |
| 177 | compiler: > |
| 178 | |
| 179 | :compiler msvc |
| 180 | |
| 181 | This will find the Vim script for the "msvc" compiler and set the appropriate |
| 182 | options. |
| 183 | You can write your own compiler files. See |write-compiler-plugin|. |
| 184 | |
| 185 | |
| 186 | OUTPUT REDIRECTION |
| 187 | |
| 188 | The ":make" command redirects the output of the executed program to an error |
| 189 | file. How this works depends on various things, such as the 'shell'. If your |
| 190 | ":make" command doesn't capture the output, check the 'makeef' and |
| 191 | 'shellpipe' options. The 'shellquote' and 'shellxquote' options might also |
| 192 | matter. |
| 193 | |
| 194 | In case you can't get ":make" to redirect the file for you, an alternative is |
| 195 | to compile the program in another window and redirect the output into a file. |
| 196 | Then have Vim read this file with: > |
| 197 | |
| 198 | :cfile {filename} |
| 199 | |
| 200 | Jumping to errors will work like with the ":make" command. |
| 201 | |
| 202 | ============================================================================== |
Bram Moolenaar | 8c8de83 | 2008-06-24 22:58:06 +0000 | [diff] [blame] | 203 | *30.2* Indenting C style text |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 204 | |
| 205 | A program is much easier to understand when the lines have been properly |
Bram Moolenaar | 8c8de83 | 2008-06-24 22:58:06 +0000 | [diff] [blame] | 206 | indented. Vim offers various ways to make this less work. For C or C style |
| 207 | programs like Java or C++, set the 'cindent' option. Vim knows a lot about C |
| 208 | programs and will try very hard to automatically set the indent for you. Set |
| 209 | the 'shiftwidth' option to the amount of spaces you want for a deeper level. |
| 210 | Four spaces will work fine. One ":set" command will do it: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 211 | |
| 212 | :set cindent shiftwidth=4 |
| 213 | |
| 214 | With this option enabled, when you type something such as "if (x)", the next |
| 215 | line will automatically be indented an additional level. |
| 216 | |
| 217 | if (flag) |
| 218 | Automatic indent ---> do_the_work(); |
| 219 | Automatic unindent <-- if (other_flag) { |
| 220 | Automatic indent ---> do_file(); |
| 221 | keep indent do_some_more(); |
| 222 | Automatic unindent <-- } |
| 223 | |
| 224 | When you type something in curly braces ({}), the text will be indented at the |
| 225 | start and unindented at the end. The unindenting will happen after typing the |
| 226 | '}', since Vim can't guess what you are going to type. |
| 227 | |
| 228 | One side effect of automatic indentation is that it helps you catch errors in |
| 229 | your code early. When you type a } to finish a function, only to find that |
| 230 | the automatic indentation gives it more indent than what you expected, there |
| 231 | is probably a } missing. Use the "%" command to find out which { matches the |
| 232 | } you typed. |
| 233 | A missing ) and ; also cause extra indent. Thus if you get more white |
| 234 | space than you would expect, check the preceding lines. |
| 235 | |
| 236 | When you have code that is badly formatted, or you inserted and deleted lines, |
| 237 | you need to re-indent the lines. The "=" operator does this. The simplest |
| 238 | form is: > |
| 239 | |
| 240 | == |
| 241 | |
| 242 | This indents the current line. Like with all operators, there are three ways |
| 243 | to use it. In Visual mode "=" indents the selected lines. A useful text |
| 244 | object is "a{". This selects the current {} block. Thus, to re-indent the |
Bram Moolenaar | c81e5e7 | 2007-05-05 18:24:42 +0000 | [diff] [blame] | 245 | code block the cursor is in: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 246 | |
| 247 | =a{ |
| 248 | |
UM-Li | 04e1aaa | 2024-04-29 20:22:10 +0200 | [diff] [blame] | 249 | If you have really badly indented code, you can re-indent the whole file with: |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 250 | > |
| 251 | gg=G |
| 252 | |
| 253 | However, don't do this in files that have been carefully indented manually. |
| 254 | The automatic indenting does a good job, but in some situations you might want |
| 255 | to overrule it. |
| 256 | |
| 257 | |
| 258 | SETTING INDENT STYLE |
| 259 | |
| 260 | Different people have different styles of indentation. By default Vim does a |
| 261 | pretty good job of indenting in a way that 90% of programmers do. There are |
| 262 | different styles, however; so if you want to, you can customize the |
| 263 | indentation style with the 'cinoptions' option. |
| 264 | By default 'cinoptions' is empty and Vim uses the default style. You can |
| 265 | add various items where you want something different. For example, to make |
| 266 | curly braces be placed like this: |
| 267 | |
| 268 | if (flag) ~ |
| 269 | { ~ |
| 270 | i = 8; ~ |
| 271 | j = 0; ~ |
| 272 | } ~ |
| 273 | |
| 274 | Use this command: > |
| 275 | |
| 276 | :set cinoptions+={2 |
| 277 | |
| 278 | There are many of these items. See |cinoptions-values|. |
| 279 | |
| 280 | ============================================================================== |
| 281 | *30.3* Automatic indenting |
| 282 | |
| 283 | You don't want to switch on the 'cindent' option manually every time you edit |
| 284 | a C file. This is how you make it work automatically: > |
| 285 | |
| 286 | :filetype indent on |
| 287 | |
| 288 | Actually, this does a lot more than switching on 'cindent' for C files. First |
| 289 | of all, it enables detecting the type of a file. That's the same as what is |
| 290 | used for syntax highlighting. |
| 291 | When the filetype is known, Vim will search for an indent file for this |
| 292 | type of file. The Vim distribution includes a number of these for various |
| 293 | programming languages. This indent file will then prepare for automatic |
| 294 | indenting specifically for this file. |
| 295 | |
| 296 | If you don't like the automatic indenting, you can switch it off again: > |
| 297 | |
| 298 | :filetype indent off |
| 299 | |
| 300 | If you don't like the indenting for one specific type of file, this is how you |
| 301 | avoid it. Create a file with just this one line: > |
| 302 | |
| 303 | :let b:did_indent = 1 |
| 304 | |
| 305 | Now you need to write this in a file with a specific name: |
| 306 | |
| 307 | {directory}/indent/{filetype}.vim |
| 308 | |
| 309 | The {filetype} is the name of the file type, such as "cpp" or "java". You can |
| 310 | see the exact name that Vim detected with this command: > |
| 311 | |
| 312 | :set filetype |
| 313 | |
| 314 | In this file the output is: |
| 315 | |
| 316 | filetype=help ~ |
| 317 | |
Bram Moolenaar | c81e5e7 | 2007-05-05 18:24:42 +0000 | [diff] [blame] | 318 | Thus you would use "help" for {filetype}. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 319 | For the {directory} part you need to use your runtime directory. Look at |
| 320 | the output of this command: > |
| 321 | |
| 322 | set runtimepath |
| 323 | |
| 324 | Now use the first item, the name before the first comma. Thus if the output |
| 325 | looks like this: |
| 326 | |
| 327 | runtimepath=~/.vim,/usr/local/share/vim/vim60/runtime,~/.vim/after ~ |
| 328 | |
| 329 | You use "~/.vim" for {directory}. Then the resulting file name is: |
| 330 | |
| 331 | ~/.vim/indent/help.vim ~ |
| 332 | |
| 333 | Instead of switching the indenting off, you could write your own indent file. |
| 334 | How to do that is explained here: |indent-expression|. |
| 335 | |
| 336 | ============================================================================== |
| 337 | *30.4* Other indenting |
| 338 | |
Bram Moolenaar | e7b1ea0 | 2020-08-07 19:54:59 +0200 | [diff] [blame] | 339 | The simplest form of automatic indenting is with the 'autoindent' option. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 340 | It uses the indent from the previous line. A bit smarter is the 'smartindent' |
| 341 | option. This is useful for languages where no indent file is available. |
Bram Moolenaar | c81e5e7 | 2007-05-05 18:24:42 +0000 | [diff] [blame] | 342 | 'smartindent' is not as smart as 'cindent', but smarter than 'autoindent'. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 343 | With 'smartindent' set, an extra level of indentation is added for each { |
| 344 | and removed for each }. An extra level of indentation will also be added for |
| 345 | any of the words in the 'cinwords' option. Lines that begin with # are |
| 346 | treated specially: all indentation is removed. This is done so that |
| 347 | preprocessor directives will all start in column 1. The indentation is |
| 348 | restored for the next line. |
| 349 | |
| 350 | |
| 351 | CORRECTING INDENTS |
| 352 | |
| 353 | When you are using 'autoindent' or 'smartindent' to get the indent of the |
| 354 | previous line, there will be many times when you need to add or remove one |
| 355 | 'shiftwidth' worth of indent. A quick way to do this is using the CTRL-D and |
| 356 | CTRL-T commands in Insert mode. |
| 357 | For example, you are typing a shell script that is supposed to look like |
| 358 | this: |
| 359 | |
| 360 | if test -n a; then ~ |
| 361 | echo a ~ |
| 362 | echo "-------" ~ |
| 363 | fi ~ |
| 364 | |
Bram Moolenaar | 06b5d51 | 2010-05-22 15:37:44 +0200 | [diff] [blame] | 365 | Start off by setting these options: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 366 | |
| 367 | :set autoindent shiftwidth=3 |
| 368 | |
| 369 | You start by typing the first line, <Enter> and the start of the second line: |
| 370 | |
| 371 | if test -n a; then ~ |
| 372 | echo ~ |
| 373 | |
| 374 | Now you see that you need an extra indent. Type CTRL-T. The result: |
| 375 | |
| 376 | if test -n a; then ~ |
| 377 | echo ~ |
| 378 | |
| 379 | The CTRL-T command, in Insert mode, adds one 'shiftwidth' to the indent, no |
| 380 | matter where in the line you are. |
| 381 | You continue typing the second line, <Enter> and the third line. This time |
| 382 | the indent is OK. Then <Enter> and the last line. Now you have this: |
| 383 | |
| 384 | if test -n a; then ~ |
| 385 | echo a ~ |
| 386 | echo "-------" ~ |
| 387 | fi ~ |
| 388 | |
| 389 | To remove the superfluous indent in the last line press CTRL-D. This deletes |
| 390 | one 'shiftwidth' worth of indent, no matter where you are in the line. |
| 391 | When you are in Normal mode, you can use the ">>" and "<<" commands to |
| 392 | shift lines. ">" and "<" are operators, thus you have the usual three ways to |
| 393 | specify the lines you want to indent. A useful combination is: > |
| 394 | |
| 395 | >i{ |
| 396 | |
| 397 | This adds one indent to the current block of lines, inside {}. The { and } |
| 398 | lines themselves are left unmodified. ">a{" includes them. In this example |
| 399 | the cursor is on "printf": |
| 400 | |
| 401 | original text after ">i{" after ">a{" |
| 402 | |
| 403 | if (flag) if (flag) if (flag) ~ |
| 404 | { { { ~ |
| 405 | printf("yes"); printf("yes"); printf("yes"); ~ |
| 406 | flag = 0; flag = 0; flag = 0; ~ |
| 407 | } } } ~ |
| 408 | |
| 409 | ============================================================================== |
| 410 | *30.5* Tabs and spaces |
| 411 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 412 | A QUICK HISTORY OF THE RATIONALE BEHIND TABS |
| 413 | |
| 414 | `vi` (the ancestor of Vim) was created by Bill Joy. At the time, he was using |
| 415 | a PDP-11 with limited memory and I/O operation capabilities. Back then, it |
| 416 | was common to optimize the size of source code with the following trick. |
| 417 | The ASCII table was first designed to remotely control teleprinters. When |
| 418 | control character 9 (the Horizontal Tab, caret notation: ^I) was sent to a |
| 419 | teleprinter, it would move the carriage to the next tab stop. Assuming tab |
| 420 | stops were separated by 8 columns (a typical standard), this means that a |
| 421 | single control character could produce the same visual effect as up to 8 space |
| 422 | characters. For example, the following two lines will display identically > |
| 423 | |
| 424 | 1234^I9 |
| 425 | 1234 9 |
| 426 | |
| 427 | Using the <Tab> key was also faster than typing <Space> several times; the |
| 428 | same was true for <BS>. |
| 429 | |
| 430 | |
| 431 | THE ISSUE WITH TABS AND INDENTATION |
| 432 | |
| 433 | In Vim, the number of columns between two (virtual) horizontal tab stops |
| 434 | is controlled by 'tabstop' and is set to eight by default. Although you can |
| 435 | change it, you quickly run into trouble later. Other programs won't know what |
| 436 | tabstop value you used. They probably use the default value of eight, and |
| 437 | your text suddenly looks very different. Also, most printers use a fixed |
| 438 | tabstop value of eight. Thus it's best to keep 'tabstop' alone; if you edit a |
| 439 | file which was written with a different tabstop setting, see |25.3| for how |
| 440 | to fix that. |
| 441 | For indenting lines in a program, using a multiple of eight columns makes |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 442 | you quickly run into the right border of the window. Using a single space |
| 443 | doesn't provide enough visual difference. Many people prefer to use four |
| 444 | spaces, a good compromise. |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 445 | Since a tab character at the beginning of a line is visually represented |
| 446 | as eight spaces and you want to use an indent of four spaces, you can't use a |
| 447 | tab character to make your indent. |
| 448 | To remedy this, `vi` had the 'shiftwidth' option. When set to 4, on a new |
| 449 | line, pressing <C-t> in Insert mode would indent the line by 4 spaces, |
| 450 | a result impossible to get with the <Tab> key and 'tabstop' set to 8. |
| 451 | To optimize space, `vi` would also silently remove packs of spaces and replace |
| 452 | them with tab characters. The following shows what happens pressing <C-t> |
Christian Brabandt | 77959dc | 2025-05-30 20:14:16 +0200 | [diff] [blame] | 453 | a few times. |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 454 | A "." stands for a space character and "------->" for a tab character. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 455 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 456 | type result ~ |
| 457 | <C-t> .... |
| 458 | <C-t><C-t> -------> |
| 459 | <C-t><C-t><C-t> ------->.... |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 460 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 461 | Similarly pressing <C-d> in Insert mode would decrease the indent. Hence |
| 462 | with `set tabstop=8 shiftwidth=2` one has |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 463 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 464 | type result ~ |
| 465 | <C-t><Tab><C-t> ..----->.. |
| 466 | <C-t><Tab><C-t><C-d> -------> |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 467 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 468 | A third option that one could set in `vi` was 'autoindent'. It copies the |
Christian Brabandt | 77959dc | 2025-05-30 20:14:16 +0200 | [diff] [blame] | 469 | indent level of the previous lines, |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 470 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 471 | type result ~ |
| 472 | <Space><Tab>hello .------>hello |
| 473 | <Space><Tab>hello<Enter> .------>hello |
| 474 | -------> |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 475 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 476 | but the new line is produced by optimizing the number of characters used. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 477 | |
| 478 | |
| 479 | JUST SPACES |
| 480 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 481 | But separating tab stops with 8 columns was not universal: IBM had a standard |
| 482 | at 10 columns, and today some Go developers write code with `tabstop=4`. Every |
| 483 | time text is displayed with a different 'tabstop' value, it risks misaligning |
| 484 | the text, especially once the file is shared and opened on another machine. |
| 485 | In the meantime, computers got much better and the few octets saved by using |
| 486 | tabs were no longer making any real difference. It became possible to use |
| 487 | only spaces and thus guarantee the same resulting text everywhere. But using |
| 488 | only spaces was impossible in `vi` without sacrificing features. Remember that |
| 489 | 'autoindent' would systematically try to input a tab character when it could. |
| 490 | Vim 4.0 made working with only spaces as convenient as working only with |
| 491 | tabs (or a mix of tabs and spaces), by introducing the 'expandtab' option. |
| 492 | When set, Vim will replace any horizontal tab character it would normally |
| 493 | insert with an equivalent number of spaces, to end up with the same visual |
| 494 | effect. <BS> would continue to remove only one character at a time. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 495 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 496 | type result ~ |
| 497 | <Tab> ........ |
| 498 | <Tab><BS> ....... |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 499 | |
| 500 | |
| 501 | CHANGING TABS IN SPACES (AND BACK) |
| 502 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 503 | Setting 'expandtab' does not immediately affect existing tab characters. In |
| 504 | order to purge a file from all its horizontal tab characters, Vim 5.3 |
| 505 | introduced the |:retab| command. Use these commands: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 506 | |
| 507 | :set expandtab |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 508 | :retab |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 509 | |
| 510 | This is a little bit dangerous, because it can also change tabs inside a |
| 511 | string. To check if these exist, you could use this: > |
| 512 | |
| 513 | /"[^"\t]*\t[^"]*" |
| 514 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 515 | It's recommended not to use actual tab characters inside a string. Replace |
| 516 | them with "\t" to avoid trouble. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 517 | |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 518 | The other way around works just as well: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 519 | |
| 520 | :set noexpandtab |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 521 | :retab! |
| 522 | |
| 523 | |
| 524 | SOFT TAB STOPS |
| 525 | |
| 526 | When using only spaces, or a mix of spaces and horizontal tabs, one gets the |
| 527 | unpleasant feeling that the two keys <Tab> and <BS> do not act in mirror, as |
| 528 | they do when using only tab characters. |
| 529 | Vim 5.4 introduced the 'softtabstop' option. On top of the (hard) tab stops |
| 530 | used to display the horizontal tab characters in the text, Vim adds extra |
| 531 | soft tab stops dedicated only to the cursor. When 'softtabstop' is set to a |
| 532 | positive value, and the <Tab> key will push the cursor to the next soft tab |
| 533 | stop. Vim will insert the correct combination of tab characters and spaces to |
| 534 | make the effect visually. Likewise pressing <BS> will have the cursor try to |
| 535 | reach the nearest soft tab stop. The following example uses |
| 536 | `:set softtabstop=4` |
| 537 | |
| 538 | type result ~ |
| 539 | <Tab> .... |
| 540 | <Tab><Tab>a ------->a |
| 541 | <Tab><Tab>a<Tab> ------->a... |
| 542 | <Tab><Tab>a<Tab><BS> ------->a |
| 543 | |
| 544 | To maintain global coherence, one can `:set softtabstop=-1` so that |
| 545 | the value of 'shiftwidth' is use for the number of columns between two soft |
| 546 | tab stops. |
| 547 | |
| 548 | If you prefer to have different values for 'shiftwidth' and 'softtabstop', |
| 549 | you can still do so and use <C-t> to indent with 'shiftwidth'. Or you can |
Damien Lejay | bfa1636 | 2025-06-10 21:12:31 +0200 | [diff] [blame] | 550 | use the 'smarttab' option, allowing for a unified <Tab> key that knows what to |
| 551 | do in the different situations. |
Damien Lejay | a4a3f71 | 2025-05-30 17:36:37 +0200 | [diff] [blame] | 552 | |
| 553 | |
| 554 | VARIABLE TAB STOPS |
| 555 | |
| 556 | As we said before, the ASCII table was designed to remotely control |
| 557 | teleprinters. A given teleprinter could be configured to have their physical |
| 558 | tab stops have variable spacing. After all, the ^I control character was |
| 559 | only stipulating: go to the next tab stop wherever it is. |
| 560 | Vim 7.3 introduced 'vartabstop' to emulate the same functionality. For |
| 561 | example if Vim was compiled with `+vartabs` and `:set vartabstop=2,4` one gets |
| 562 | |
| 563 | actual character result ~ |
| 564 | ^I -> |
| 565 | ^I^I ->---> |
| 566 | ^I^I^I ->--->---> |
| 567 | |
| 568 | Similarly, 'varsofttabstop' was also introduced, to have variably spaced |
| 569 | soft tab stops. With `:set varsofttabstop=2,4` one gets |
| 570 | |
| 571 | type result ~ |
| 572 | <Tab> .. |
| 573 | <Tab><Tab> ...... |
| 574 | <Tab><Tab><Tab> ------->.... |
| 575 | |
| 576 | |
| 577 | EXAMPLES OF CONFIGURATION |
| 578 | |
| 579 | By default, Vim is configured to use only tabs: > |
| 580 | |
| 581 | :set tabstop=8 |
| 582 | :set shiftwidth=8 |
| 583 | :set noexpandtab |
| 584 | :set softtabstop=0 |
| 585 | :set nosmarttab |
| 586 | < |
| 587 | If you want to write C code as if it were Python (only spaces, with indents |
| 588 | of 4 spaces), here is what you can use: > |
| 589 | |
| 590 | :set shiftwidth=4 |
| 591 | :set softtabstop=-1 |
| 592 | :set expandtab |
| 593 | < |
| 594 | If you want the same behavior but with better control over alignment |
| 595 | (e.g. lining up parameters or comments in multiples of 2 spaces), use: > |
| 596 | |
| 597 | :set shiftwidth=4 |
| 598 | :set softtabstop=2 |
| 599 | :set expandtab |
| 600 | :set smarttab |
| 601 | < |
| 602 | If instead, you would like to write C code like Bram Moolenaar would have |
| 603 | (using a mix of tabs and spaces), you can use > |
| 604 | |
| 605 | :set shiftwidth=4 |
| 606 | :set softtabstop=-1 |
| 607 | < |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 608 | |
| 609 | ============================================================================== |
| 610 | *30.6* Formatting comments |
| 611 | |
| 612 | One of the great things about Vim is that it understands comments. You can |
| 613 | ask Vim to format a comment and it will do the right thing. |
| 614 | Suppose, for example, that you have the following comment: |
| 615 | |
| 616 | /* ~ |
| 617 | * This is a test ~ |
| 618 | * of the text formatting. ~ |
| 619 | */ ~ |
| 620 | |
| 621 | You then ask Vim to format it by positioning the cursor at the start of the |
| 622 | comment and type: > |
| 623 | |
| 624 | gq]/ |
| 625 | |
| 626 | "gq" is the operator to format text. "]/" is the motion that takes you to the |
| 627 | end of a comment. The result is: |
| 628 | |
| 629 | /* ~ |
| 630 | * This is a test of the text formatting. ~ |
| 631 | */ ~ |
| 632 | |
| 633 | Notice that Vim properly handled the beginning of each line. |
| 634 | An alternative is to select the text that is to be formatted in Visual mode |
| 635 | and type "gq". |
| 636 | |
| 637 | To add a new line to the comment, position the cursor on the middle line and |
| 638 | press "o". The result looks like this: |
| 639 | |
| 640 | /* ~ |
| 641 | * This is a test of the text formatting. ~ |
| 642 | * ~ |
| 643 | */ ~ |
| 644 | |
| 645 | Vim has automatically inserted a star and a space for you. Now you can type |
| 646 | the comment text. When it gets longer than 'textwidth', Vim will break the |
| 647 | line. Again, the star is inserted automatically: |
| 648 | |
| 649 | /* ~ |
| 650 | * This is a test of the text formatting. ~ |
| 651 | * Typing a lot of text here will make Vim ~ |
| 652 | * break ~ |
| 653 | */ ~ |
| 654 | |
| 655 | For this to work some flags must be present in 'formatoptions': |
| 656 | |
| 657 | r insert the star when typing <Enter> in Insert mode |
| 658 | o insert the star when using "o" or "O" in Normal mode |
| 659 | c break comment text according to 'textwidth' |
| 660 | |
| 661 | See |fo-table| for more flags. |
| 662 | |
| 663 | |
| 664 | DEFINING A COMMENT |
| 665 | |
| 666 | The 'comments' option defines what a comment looks like. Vim distinguishes |
| 667 | between a single-line comment and a comment that has a different start, end |
| 668 | and middle part. |
| 669 | Many single-line comments start with a specific character. In C++ // is |
| 670 | used, in Makefiles #, in Vim scripts ". For example, to make Vim understand |
| 671 | C++ comments: > |
| 672 | |
| 673 | :set comments=:// |
| 674 | |
| 675 | The colon separates the flags of an item from the text by which the comment is |
| 676 | recognized. The general form of an item in 'comments' is: |
| 677 | |
| 678 | {flags}:{text} |
| 679 | |
| 680 | The {flags} part can be empty, as in this case. |
| 681 | Several of these items can be concatenated, separated by commas. This |
| 682 | allows recognizing different types of comments at the same time. For example, |
| 683 | let's edit an e-mail message. When replying, the text that others wrote is |
| 684 | preceded with ">" and "!" characters. This command would work: > |
| 685 | |
| 686 | :set comments=n:>,n:! |
| 687 | |
| 688 | There are two items, one for comments starting with ">" and one for comments |
| 689 | that start with "!". Both use the flag "n". This means that these comments |
| 690 | nest. Thus a line starting with ">" may have another comment after the ">". |
| 691 | This allows formatting a message like this: |
| 692 | |
| 693 | > ! Did you see that site? ~ |
| 694 | > ! It looks really great. ~ |
| 695 | > I don't like it. The ~ |
| 696 | > colors are terrible. ~ |
| 697 | What is the URL of that ~ |
| 698 | site? ~ |
| 699 | |
| 700 | Try setting 'textwidth' to a different value, e.g., 80, and format the text by |
| 701 | Visually selecting it and typing "gq". The result is: |
| 702 | |
Bram Moolenaar | 13fcaaf | 2005-04-15 21:13:42 +0000 | [diff] [blame] | 703 | > ! Did you see that site? It looks really great. ~ |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 704 | > I don't like it. The colors are terrible. ~ |
| 705 | What is the URL of that site? ~ |
| 706 | |
| 707 | You will notice that Vim did not move text from one type of comment to |
| 708 | another. The "I" in the second line would have fit at the end of the first |
| 709 | line, but since that line starts with "> !" and the second line with ">", Vim |
| 710 | knows that this is a different kind of comment. |
| 711 | |
| 712 | |
| 713 | A THREE PART COMMENT |
| 714 | |
| 715 | A C comment starts with "/*", has "*" in the middle and "*/" at the end. The |
| 716 | entry in 'comments' for this looks like this: > |
| 717 | |
| 718 | :set comments=s1:/*,mb:*,ex:*/ |
| 719 | |
| 720 | The start is defined with "s1:/*". The "s" indicates the start of a |
| 721 | three-piece comment. The colon separates the flags from the text by which the |
| 722 | comment is recognized: "/*". There is one flag: "1". This tells Vim that the |
| 723 | middle part has an offset of one space. |
| 724 | The middle part "mb:*" starts with "m", which indicates it is a middle |
| 725 | part. The "b" flag means that a blank must follow the text. Otherwise Vim |
| 726 | would consider text like "*pointer" also to be the middle of a comment. |
| 727 | The end part "ex:*/" has the "e" for identification. The "x" flag has a |
| 728 | special meaning. It means that after Vim automatically inserted a star, |
| 729 | typing / will remove the extra space. |
| 730 | |
| 731 | For more details see |format-comments|. |
| 732 | |
| 733 | ============================================================================== |
| 734 | |
| 735 | Next chapter: |usr_31.txt| Exploiting the GUI |
| 736 | |
Bram Moolenaar | d473c8c | 2018-08-11 18:00:22 +0200 | [diff] [blame] | 737 | Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl: |