codekingpro/portable-devtools
114k
1*repeat.txt* For Vim version 9.2. Last change: 2026 Feb 142 3 4 VIM REFERENCE MANUAL by Bram Moolenaar5 6 7Repeating commands, Vim scripts and debugging *repeating*8 9Chapter 26 of the user manual introduces repeating |usr_26.txt|.10 111. Single repeats |single-repeat|122. Multiple repeats |multi-repeat|133. Complex repeats |complex-repeat|144. Using Vim scripts |using-scripts|155. Using Vim packages |packages|166. Creating Vim packages |package-create|177. Debugging scripts |debug-scripts|188. Profiling |profiling|19 20==============================================================================211. Single repeats *single-repeat*22 23 *.*24. Repeat last change, with count replaced with [count].25 Also repeat a yank command, when the 'y' flag is26 included in 'cpoptions'. Does not repeat a27 command-line command.28 29Simple changes can be repeated with the "." command. Without a count, the30count of the last change is used. If you enter a count, it will replace the31last one. |v:count| and |v:count1| will be set.32 33If the last change included a specification of a numbered register, the34register number will be incremented. See |redo-register| for an example how35to use this.36 37Note that when repeating a command that used a Visual selection, the same SIZE38of area is used, see |visual-repeat|.39 40 *@:*41@: Repeat last command-line [count] times.42 {not available when compiled without the43 |+cmdline_hist| feature}44 45 46==============================================================================472. Multiple repeats *multi-repeat*48 49 *:g* *:global* *E148*50:[range]g[lobal]/{pattern}/[cmd]51 Execute the Ex command [cmd] (default ":p") on the52 lines within [range] where {pattern} matches.53 54:[range]g[lobal]!/{pattern}/[cmd]55 Execute the Ex command [cmd] (default ":p") on the56 lines within [range] where {pattern} does NOT match.57 58 *:v* *:vglobal*59:[range]v[global]/{pattern}/[cmd]60 Same as :g!.61 62Example: >63 :g/^Obsolete/d _64Using the underscore after `:d` avoids clobbering registers or the clipboard.65This also makes it faster.66 67Instead of the '/' which surrounds the {pattern}, you can use any other68single byte character, but not an alphabetic character, '\', '"', '|' or '!'.69This is useful if you want to include a '/' in the search pattern or70replacement string.71 72For the definition of a pattern, see |pattern|.73 74NOTE [cmd] may contain a range; see |collapse| and |edit-paragraph-join| for75examples.76 77The global commands work by first scanning through the [range] lines and78marking each line where a match occurs (for a multi-line pattern, only the79start of the match matters).80In a second scan the [cmd] is executed for each marked line, as if the cursor81was in that line. For ":v" and ":g!" the command is executed for each not82marked line. If a line is deleted its mark disappears.83The default for [range] is the whole buffer (1,$). Use "CTRL-C" to interrupt84the command. If an error message is given for a line, the command for that85line is aborted and the global command continues with the next marked or86unmarked line.87 *E147*88When the command is used recursively, it only works on one line. Giving a89range is then not allowed. This is useful to find all lines that match a90pattern and do not match another pattern: >91 :g/found/v/notfound/{cmd}92This first finds all lines containing "found", but only executes {cmd} when93there is no match for "notfound".94 95Any Ex command can be used, see |ex-cmd-index|. To execute a Normal mode96command, you can use the `:normal` command: >97 :g/pat/normal {commands}98Make sure that {commands} ends with a whole command, otherwise Vim will wait99for you to type the rest of the command for each match. The screen will not100have been updated, so you don't know what you are doing. See |:normal|.101 102The undo/redo command will undo/redo the whole global command at once.103The previous context mark will only be set once (with "''" you go back to104where the cursor was before the global command).105 106The global command sets both the last used search pattern and the last used107substitute pattern (this is vi compatible). This makes it easy to globally108replace a string: >109 :g/pat/s//PAT/g110This replaces all occurrences of "pat" with "PAT". The same can be done with: >111 :%s/pat/PAT/g112Which is two characters shorter!113 114When using "global" in Ex mode, a special case is using ":visual" as a115command. This will move to a matching line, go to Normal mode to let you116execute commands there until you use |Q| to return to Ex mode. This will be117repeated for each matching line. While doing this you cannot use ":global".118To abort this type CTRL-C twice.119 120==============================================================================1213. Complex repeats *complex-repeat*122 123 *q* *recording*124q{0-9a-zA-Z"} Record typed characters into register {0-9a-zA-Z"}125 (uppercase to append). The 'q' command is disabled126 while executing a register, and it doesn't work inside127 a mapping and |:normal|.128 129 Note: If the register being used for recording is also130 used for |y| and |p| the result is most likely not131 what is expected, because the put will paste the132 recorded macro and the yank will overwrite the133 recorded macro.134 135 Note: The recording happens while you type, replaying136 the register happens as if the keys come from a137 mapping. This matters, for example, for undo, which138 only syncs when commands were typed.139 140q Stops recording. (Implementation note: The 'q' that141 stops recording is not stored in the register, unless142 it was the result of a mapping)143 144 *@*145@{0-9a-z".=*+} Execute the contents of register {0-9a-z".=*+} [count]146 times. Note that register '%' (name of the current147 file) and '#' (name of the alternate file) cannot be148 used.149 The register is executed like a mapping, that means150 that the difference between 'wildchar' and 'wildcharm'151 applies, and undo might not be synced in the same way.152 For "@=" you are prompted to enter an expression. The153 result of the expression is then executed.154 See also |@:|.155 156 *@@* *E748*157@@ Repeat the previous @{0-9a-z":*} [count] times.158 159 *:@*160:[addr]@{0-9a-z".=*+} Execute the contents of register {0-9a-z".=*+} as an161 Ex command. First set cursor at line [addr] (default162 is current line). When the last line in the register163 does not have a <CR> it will be added automatically164 when the 'e' flag is present in 'cpoptions'.165 For ":@=" the last used expression is used. The166 result of evaluating the expression is executed as an167 Ex command.168 Mappings are not recognized in these commands.169 When the |line-continuation| character (\) is present170 at the beginning of a line in a linewise register,171 then it is combined with the previous line. This is172 useful for yanking and executing parts of a Vim173 script.174 Future: Will execute the register for each line in the175 address range.176 177:[addr]*{0-9a-z".=+} *:star-compatible*178 When '*' is present in 'cpoptions' |cpo-star|, use179 ":*" in the same way as ":@". This is NOT the default180 when 'nocompatible' is used. When the '*' flag is not181 present in 'cpoptions', ":*" is an alias for ":'<,'>",182 select the Visual area |:star|.183 184 *:@:*185:[addr]@: Repeat last command-line. First set cursor at line186 [addr] (default is current line).187 188:[addr]@ *:@@*189:[addr]@@ Repeat the previous :@{register}. First set cursor at190 line [addr] (default is current line).191 192==============================================================================1934. Using Vim scripts *using-scripts*194 195For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.196 197 *:so* *:source* *load-vim-script*198:so[urce] {file} Read Ex commands from {file}. These are commands that199 start with a ":".200 Triggers the |SourcePre| autocommand.201 *:source-range*202:[range]so[urce] [++clear]203 Read Ex commands from the [range] of lines in the204 current buffer. When [range] is omitted read all205 lines.206 207 When sourcing commands from the current buffer, the208 same script-ID |<SID>| is used even if the buffer is209 sourced multiple times. If a buffer is sourced more210 than once, then the functions in the buffer are211 defined again.212 213 To source a range of lines that doesn't start with the214 |:vim9script| command in Vim9 script context, the215 |:vim9cmd| modifier can be used. If you use a Visual216 selection and type ":", the range in the form "'<,'>"217 can come before it: >218 :'<,'>vim9cmd source219< Otherwise the range goes after the modifier and must220 have a colon prefixed, like all Vim9 ranges: >221 :vim9cmd :5,9source222 223< When a range of lines in a buffer is sourced in the224 Vim9 script context, the previously defined225 script-local variables and functions are not cleared.226 This works like the range started with the227 ":vim9script noclear" command. The "++clear" argument228 can be used to clear the script-local variables and229 functions before sourcing the script. This works like230 the range started with the `:vim9script` command231 without the "noclear" argument. See |vim9-reload| for232 more information.233 Examples: >234 :4,5source235 :10,18source ++clear236 237< Implementation detail: When sourcing a [range] of238 lines that falls inside a folded region, the range239 will be adjusted to the start and end of the fold,240 but only if a two line specifiers range was used.241 242 *:source!*243:so[urce]! {file} Read Vim commands from {file}. These are commands244 that are executed from Normal mode, like you type245 them.246 When used after |:global|, |:argdo|, |:windo|,247 |:bufdo|, in a loop or when another command follows248 the display won't be updated while executing the249 commands.250 Cannot be used in the |sandbox|.251 252 *:ru* *:runtime*253:ru[ntime][!] [where] {file} ..254 Read Ex commands from {file} in each directory given255 by 'runtimepath' and/or 'packpath'. There is no error256 for non-existing files.257 258 Example: >259 :runtime syntax/c.vim260 261< There can be multiple {file} arguments, separated by262 spaces. Each {file} is searched for in the first263 directory from 'runtimepath', then in the second264 directory, etc. Use a backslash to include a space265 inside {file} (although it's better not to use spaces266 in file names, it causes trouble).267 268 When [!] is included, all found files are sourced.269 When it is not included only the first found file is270 sourced.271 272 When [where] is omitted only 'runtimepath' is used.273 Other values:274 START search under "start" in 'packpath'275 OPT search under "opt" in 'packpath'276 PACK search under "start" and "opt" in277 'packpath'278 ALL first use 'runtimepath', then search279 under "start" and "opt" in 'packpath'280 281 When {file} contains wildcards it is expanded to all282 matching files. Example: >283 :runtime! plugin/**/*.vim284< This is what Vim uses to load the plugin files when285 starting up. This similar command: >286 :runtime plugin/**/*.vim287< would source the first file only.288 289 When 'verbose' is one or higher, there is a message290 when no file could be found.291 When 'verbose' is two or higher, there is a message292 about each searched file.293 294 *:pa* *:packadd* *E919*295:pa[ckadd][!] {name} Search for an optional plugin directory in 'packpath'296 and source any plugin files found. The directory must297 match:298 pack/*/opt/{name} ~299 The directory is added to 'runtimepath' if it wasn't300 there yet.301 If the directory pack/*/opt/{name}/after exists it is302 added at the end of 'runtimepath'.303 304 If loading packages from "pack/*/start" was skipped,305 then this directory is searched first:306 pack/*/start/{name} ~307 308 Note that {name} is the directory name, not the name309 of the .vim file. All the files matching the pattern310 pack/*/opt/{name}/plugin/**/*.vim ~311 will be sourced. This allows for using subdirectories312 below "plugin", just like with plugins in313 'runtimepath'.314 315 If the filetype detection was not enabled yet (this316 is usually done with a `syntax enable` or `filetype on`317 command in your .vimrc file), this will also look318 for "{name}/ftdetect/*.vim" files.319 320 When the optional ! is added no plugin files or321 ftdetect scripts are loaded, only the matching322 directories are added to 'runtimepath'. This is323 useful in your .vimrc. The plugins will then be324 loaded during initialization, see |load-plugins| (note325 that the loading order will be reversed, because each326 directory is inserted before others).327 Note that for ftdetect scripts to be loaded328 you will need to write `filetype plugin indent on`329 AFTER all `packadd!` commands.330 331 To programmatically decide if `!` is needed during332 startup, check |v:vim_did_init|: use `!` if 0 (to not333 duplicate |load-plugins| step), no `!` otherwise (to334 force load plugin files as otherwise they won't be335 loaded automatically).336 337 Also see |pack-add|.338 {only available when compiled with |+eval|}339 340 *:packl* *:packloadall*341:packl[oadall][!] Load all packages in the "start" directory under each342 entry in 'packpath'.343 344 First all the directories found are added to345 'runtimepath', then the plugins found in the346 directories are sourced. This allows for a plugin to347 depend on something of another plugin, e.g. an348 "autoload" directory. See |packload-two-steps| for349 how this can be useful.350 351 This is normally done automatically during startup,352 after loading your .vimrc file. With this command it353 can be done earlier.354 355 Packages will be loaded only once. Using356 `:packloadall` a second time will have no effect.357 When the optional ! is added this command will load358 packages even when done before.359 360 Note that when using `:packloadall` in the |vimrc|361 file, the 'runtimepath' option is updated, and later362 all plugins in 'runtimepath' will be loaded, which363 means they are loaded again. Plugins are expected to364 handle that.365 366 An error only causes sourcing the script where it367 happens to be aborted, further plugins will be loaded.368 See |packages|.369 {only available when compiled with |+eval|}370 371:scripte[ncoding] [encoding] *:scripte* *:scriptencoding* *E167*372 Specify the character encoding used in the script.373 The following lines will be converted from [encoding]374 to the value of the 'encoding' option, if they are375 different. Examples: >376 scriptencoding iso-8859-5377 scriptencoding cp932378<379 When [encoding] is empty, no conversion is done. This380 can be used to restrict conversion to a sequence of381 lines: >382 scriptencoding euc-jp383 ... lines to be converted ...384 scriptencoding385 ... not converted ...386 387< When conversion isn't supported by the system, there388 is no error message and no conversion is done. When a389 line can't be converted there is no error and the390 original line is kept.391 392 Don't use "ucs-2" or "ucs-4", scripts cannot be in393 these encodings (they would contain NUL bytes).394 When a sourced script starts with a BOM (Byte Order395 Mark) in utf-8 format Vim will recognize it, no need396 to use ":scriptencoding utf-8" then.397 398 If you set the 'encoding' option in your |.vimrc|,399 `:scriptencoding` must be placed after that. E.g.: >400 set encoding=utf-8401 scriptencoding utf-8402<403 404:scriptv[ersion] {version} *:scriptv* *:scriptversion*405 *E999* *E984* *E1040*406 Specify the version of Vim for the lines that follow407 in the same file. Only applies at the toplevel of408 sourced scripts, not inside functions.409 410 If {version} is higher than what the current Vim411 version supports E999 will be given. You either need412 to rewrite the script to make it work with an older413 Vim version, or update Vim to a newer version. See414 |vimscript-version| for what changed between versions.415 416:vim9s[cript] [noclear] *:vim9s* *:vim9script*417 Marks a script file as containing |Vim9-script|418 commands. Also see |vim9-namespace|. *E1038*419 Must be the first command in the file. *E1039*420 For [noclear] see |vim9-reload|.421 Without the |+eval| feature this changes the syntax422 for some commands.423 See |:vim9cmd| for executing one command with Vim9424 syntax and semantics.425 426 *:scr* *:scriptnames*427:scr[iptnames] List all sourced script names, in the order they were428 first encountered. The number is used for the script429 ID |<SID>|.430 For a script that was used with `import autoload` but431 was not actually sourced yet an "A" is shown after the432 script ID.433 For a script that was referred to by one name but434 after resolving symbolic links got sourced with435 another name the other script is after "->". E.g.436 "20->22" means script 20 was sourced as script 22.437 Also see `getscriptinfo()`.438 {not available when compiled without the |+eval|439 feature}440 441:scr[iptnames][!] {scriptId} *:script*442 Edit script {scriptId}. Although ":scriptnames name"443 works, using ":script name" is recommended.444 When the current buffer can't be |abandon|ed and the !445 is not present, the command fails.446 447 *:fini* *:finish* *E168*448:fini[sh] Stop sourcing a script. Can only be used in a Vim449 script file. This is a quick way to skip the rest of450 the file. If it is used after a |:try| but before the451 matching |:finally| (if present), the commands452 following the ":finally" up to the matching |:endtry|453 are executed first. This process applies to all454 nested ":try"s in the script. The outermost ":endtry"455 then stops sourcing the script.456 457All commands and command sequences can be repeated by putting them in a named458register and then executing it. There are two ways to get the commands in the459register:460- Use the record command "q". You type the commands once, and while they are461 being executed they are stored in a register. Easy, because you can see462 what you are doing. If you make a mistake, "p"ut the register into the463 file, edit the command sequence, and then delete it into the register464 again. You can continue recording by appending to the register (use an465 uppercase letter).466- Delete or yank the command sequence into the register.467 468Often used command sequences can be put under a function key with the ':map'469command.470 471An alternative is to put the commands in a file, and execute them with the472':source!' command. Useful for long command sequences. Can be combined with473the ':map' command to put complicated commands under a function key.474 475The ':source' command reads Ex commands from a file or a buffer line by line.476You will have to type any needed keyboard input. The ':source!' command reads477from a script file character by character, interpreting each character as if478you typed it.479 480Example: When you give the ":!ls" command you get the |hit-enter| prompt. If481you ':source' a file with the line "!ls" in it, you will have to type the482<Enter> yourself. But if you ':source!' a file with the line ":!ls" in it,483the next characters from that file are read until a <CR> is found. You will484not have to type <CR> yourself, unless ":!ls" was the last line in the file.485 486It is possible to put ':source[!]' commands in the script file, so you can487make a top-down hierarchy of script files. The ':source' command can be488nested as deep as the number of files that can be opened at one time (about48915). The ':source!' command can be nested up to 15 levels deep.490 491You can use the "<sfile>" string (literally, this is not a special key) inside492of the sourced file, in places where a file name is expected. It will be493replaced by the file name of the sourced file. For example, if you have a494"other.vimrc" file in the same directory as your ".vimrc" file, you can source495it from your ".vimrc" file with this command: >496 :source <sfile>:h/other.vimrc497 498In script files terminal-dependent key codes are represented by499terminal-independent two character codes. This means that they can be used500in the same way on different kinds of terminals. The first character of a501key code is 0x80 or 128, shown on the screen as "~@". The second one can be502found in the list |key-notation|. Any of these codes can also be entered503with CTRL-V followed by the three digit decimal code. This does NOT work for504the <t_xx> termcap codes, these can only be used in mappings.505 506 *:source_crnl* *W15*507Win32: Files that are read with ":source" normally have <CR><NL> <EOL>s.508These always work. If you are using a file with <NL> <EOL>s (for example, a509file made on Unix), this will be recognized if 'fileformats' is not empty and510the first line does not end in a <CR>. This fails if the first line has511something like ":map <F1> :help^M", where "^M" is a <CR>. If the first line512ends in a <CR>, but following ones don't, you will get an error message,513because the <CR> from the first lines will be lost.514 515Mac Classic: Files that are read with ":source" normally have <CR> <EOL>s.516These always work. If you are using a file with <NL> <EOL>s (for example, a517file made on Unix), this will be recognized if 'fileformats' is not empty and518the first line does not end in a <CR>. Be careful not to use a file with <NL>519linebreaks which has a <CR> in first line.520 521On other systems, Vim expects ":source"ed files to end in a <NL>. These522always work. If you are using a file with <CR><NL> <EOL>s (for example, a523file made on MS-Windows), all lines will have a trailing <CR>. This may cause524problems for some commands (e.g., mappings). There is no automatic <EOL>525detection, because it's common to start with a line that defines a mapping526that ends in a <CR>, which will confuse the automaton.527 528 *line-continuation*529Long lines in a ":source"d Ex command script file can be split by inserting530a line continuation symbol "\" (backslash) at the start of the next line.531There can be white space before the backslash, which is ignored.532 533Example: the lines >534 :set comments=sr:/*,mb:*,el:*/,535 \://,536 \b:#,537 \:%,538 \n:>,539 \fb:-540are interpreted as if they were given in one line: >541 :set comments=sr:/*,mb:*,el:*/,://,b:#,:%,n:>,fb:-542 543All leading whitespace characters in the line before a backslash are ignored.544Note however that trailing whitespace in the line before it cannot be545inserted freely; it depends on the position where a command is split up546whether additional whitespace is allowed or not.547 548When a space is required it's best to put it right after the backslash. A549space at the end of a line is hard to see and may be accidentally deleted. >550 :syn match Comment551 \ "very long regexp"552 \ keepend553 554In |Vim9| script the backslash can often be omitted, but not always.555See |vim9-line-continuation|.556 557There is a problem with the ":append" and ":insert" commands: >558 :1append559 \asdf560 .561The backslash is seen as a line-continuation symbol, thus this results in the562command: >563 :1appendasdf564 .565To avoid this, add the 'C' flag to the 'cpoptions' option: >566 :set cpo+=C567 :1append568 \asdf569 .570 :set cpo-=C571 572Note that when the commands are inside a function, you need to add the 'C'573flag when defining the function, it is not relevant when executing it. >574 :set cpo+=C575 :function Foo()576 :1append577 \asdf578 .579 :endfunction580 :set cpo-=C581<582 *line-continuation-comment*583To add a comment in between the lines start with '"\ '. Notice the space584after the backslash. Example: >585 let array = [586 "\ first entry comment587 \ 'first',588 "\ second entry comment589 \ 'second',590 \ ]591 592Rationale:593 Most programs work with a trailing backslash to indicate line594 continuation. Using this in Vim would cause incompatibility with Vi.595 For example for this Vi mapping: >596 :map xx asdf\597< Therefore the unusual leading backslash is used.598 599 Starting a comment in a continuation line results in all following600 continuation lines to be part of the comment. Since it was like this601 for a long time, when making it possible to add a comment halfway a602 sequence of continuation lines, it was not possible to use \", since603 that was a valid continuation line. Using '"\ ' comes closest, even604 though it may look a bit weird. Requiring the space after the605 backslash is to make it very unlikely this is a normal comment line.606 607==============================================================================6085. Using Vim packages *packages*609 610A Vim package is a directory that contains one or more plugins. The611advantages over normal plugins:612- A package can be downloaded as an archive and unpacked in its own directory.613 Thus the files are not mixed with files of other plugins. That makes it614 easy to update and remove.615- A package can be a git, mercurial, etc. repository. That makes it really616 easy to update.617- A package can contain multiple plugins that depend on each other.618- A package can contain plugins that are automatically loaded on startup and619 ones that are only loaded when needed with `:packadd`.620 621 622Using a package and loading automatically ~623 624Let's assume your Vim files are in the "~/.vim" directory and you want to add625a package from a zip archive "/tmp/foopack.zip": >626 % mkdir -p ~/.vim/pack/foo627 % cd ~/.vim/pack/foo628 % unzip /tmp/foopack.zip629 630The directory name "foo" is arbitrary, you can pick anything you like.631 632You would now have these files under ~/.vim:633 pack/foo/README.txt634 pack/foo/start/foobar/plugin/foo.vim635 pack/foo/start/foobar/syntax/some.vim636 pack/foo/opt/foodebug/plugin/debugger.vim637 638When Vim starts up, after processing your .vimrc, it scans all directories in639'packpath' for plugins under the "pack/*/start" directory. First all those640directories are added to 'runtimepath'. Then all the plugins are loaded.641See |packload-two-steps| for how these two steps can be useful.642 643To allow for calling into package functionality while parsing your .vimrc,644|:colorscheme| and |autoload| will both automatically search under 'packpath'645as well in addition to 'runtimepath'. See the documentation for each for646details.647 648In the example Vim will find "pack/foo/start/foobar/plugin/foo.vim" and adds649"~/.vim/pack/foo/start/foobar" to 'runtimepath'.650 651If the "foobar" plugin kicks in and sets the 'filetype' to "some", Vim will652find the syntax/some.vim file, because its directory is in 'runtimepath'.653 654Vim will also load ftdetect files, if there are any.655 656Note that the files under "pack/foo/opt" are not loaded automatically, only657the ones under "pack/foo/start". See |pack-add| below for how the "opt"658directory is used.659 660Loading packages automatically will not happen if loading plugins is disabled,661see |load-plugins|.662 663To load packages earlier, so that 'runtimepath' gets updated: >664 :packloadall665This also works when loading plugins is disabled. The automatic loading will666only happen once.667 668If the package has an "after" directory, that directory is added to the end of669'runtimepath', so that anything there will be loaded later.670 671 672Using a single plugin and loading it automatically ~673 674If you don't have a package but a single plugin, you need to create the extra675directory level: >676 % mkdir -p ~/.vim/pack/foo/start/foobar677 % cd ~/.vim/pack/foo/start/foobar678 % unzip /tmp/someplugin.zip679 680You would now have these files:681 pack/foo/start/foobar/plugin/foo.vim682 pack/foo/start/foobar/syntax/some.vim683 684From here it works like above.685 686 687Optional plugins ~688 *pack-add*689To load an optional plugin from a pack use the `:packadd` command: >690 :packadd foodebug691This searches for "pack/*/opt/foodebug" in 'packpath' and will find692~/.vim/pack/foo/opt/foodebug/plugin/debugger.vim and source it.693 694This could be done if some conditions are met. For example, depending on695whether Vim supports a feature or a dependency is missing.696 697You can also load an optional plugin at startup, by putting this command in698your |.vimrc|: >699 :packadd! foodebug700The extra "!" is so that the plugin isn't loaded if Vim was started with701|--noplugin|.702 703It is perfectly normal for a package to only have files in the "opt"704directory. You then need to load each plugin when you want to use it.705 706 707Where to put what ~708 709Since color schemes, loaded with `:colorscheme`, are found below710"pack/*/start" and "pack/*/opt", you could put them anywhere. We recommend711you put them below "pack/*/opt", for example712".vim/pack/mycolors/opt/dark/colors/very_dark.vim".713 714Filetype plugins should go under "pack/*/start", so that they are always715found. Unless you have more than one plugin for a file type and want to716select which one to load with `:packadd`. E.g. depending on the compiler717version: >718 if foo_compiler_version > 34719 packadd foo_new720 else721 packadd foo_old722 endif723 724The "after" directory is most likely not useful in a package. It's not725disallowed though.726 727==============================================================================7286. Creating Vim packages *package-create*729 730This assumes you write one or more plugins that you distribute as a package.731 732If you have two unrelated plugins you would use two packages, so that Vim733users can choose what they include or not. Or you can decide to use one734package with optional plugins, and tell the user to add the preferred ones735with `:packadd`.736 737Decide how you want to distribute the package. You can create an archive or738you could use a repository. An archive can be used by more users, but is a739bit harder to update to a new version. A repository can usually be kept740up-to-date easily, but it requires a program like "git" to be available.741You can do both, github can automatically create an archive for a release.742 743Your directory layout would be like this:744 start/foobar/plugin/foo.vim " always loaded, defines commands745 start/foobar/plugin/bar.vim " always loaded, defines commands746 start/foobar/autoload/foo.vim " loaded when foo command used747 start/foobar/doc/foo.txt " help for foo.vim748 start/foobar/doc/tags " help tags749 start/foobar/lang/<lang_id>/LC_MESSAGES/foobar.mo750 " messages for the plugin in the751 " <lang_id> language. These files are752 " optional.753 opt/fooextra/plugin/extra.vim " optional plugin, defines commands754 opt/fooextra/autoload/extra.vim " loaded when extra command used755 opt/fooextra/doc/extra.txt " help for extra.vim756 opt/fooextra/doc/tags " help tags757 758This allows for the user to do: >759 mkdir ~/.vim/pack760 cd ~/.vim/pack761 git clone https://github.com/you/foobar.git myfoobar762<763Here "myfoobar" is a name that the user can choose, the only condition is that764it differs from other packages.765 766In your documentation you explain what the plugins do, and tell the user how767to load the optional plugin: >768 :packadd! fooextra769<770You could add this packadd command in one of your plugins, to be executed when771the optional plugin is needed.772 773 *package-doc* *package-documentation*774Run the `:helptags` command to generate the doc/tags file. Including this775generated file in the package means that the user can drop the package in the776pack directory and the help command works right away. Don't forget to re-run777the command after changing the plugin help: >778 :helptags path/start/foobar/doc779 :helptags path/opt/fooextra/doc780<781 *package-translation*782In order for a plugin to display translated messages, a few steps are783required.784The author of the plugin who likes to translate messages must define the name785of the package and the location of the directory where the translations can be786found using the |bindtextdomain()| function: >787 :call bindtextdomain("foobar",788 \ fnamemodify(expand("<script>"), ':p:h') .. '/../lang/')789<790Where:791 "foobar" is the unique package identifier by which the |gettext()|792 function will later search for translation strings for this793 plugin.794 "lang/" is the relative or absolute path to the directory structure795 where the translation file is located.796 797The directory structure where the message translation files should be placed798is (from the top-level directory of the package):799"lang/<lang_id>/LC_MESSAGES". For the format of <lang_id> see |multi-lang|.800This function needs to be called only once during the initialization of the801plugin.802Once this is done, the |gettext()| function can be used to retrieve translated803messages: >804 :echo gettext("Hello", "foobar")805<806Where:807 "Hello" the message "Hello" to be translated into the user's language808 |:lang|809 "foobar" the package identifier, which was previously defined using the810 |bindtextdomain()| function.811 812After that you need to create a template file for translation - POT-file.813To do this, execute the following commands (using the Vim repository): >814 cd ~/forkvim/src/po815 make -f Makefile "PLUGPACKAGE={package}" \816 "PO_PLUG_INPUTLIST={path/to/scripts-that-need-translations.vim}" \817 ["POT_PLUGPACKAGE_PATH={path/where/to/write/{package}.pot}" \]818 ["VIMPROG={path/to/vim} \]819 {package}.pot820<821Where:822PLUGPACKAGE A variable containing the name of the package that we823 specified in the |bindtextdomain()| and824 |gettext()| functions, for example, "foobar".825PO_PLUG_INPUTLIST A variable containing scripts that have strings826 to translate, i.e. where we specified the |gettext()|827 function. Scripts are specified with an absolute828 or relative path. Example:829 start/foobar/plugin/bar.vim830 use blanks to separate scripts.831POT_PLUGPACKAGE_PATH A variable containing the directory where the prepared832 POT file will be saved. This is not a required833 variable, if no directory is specified, then the POT834 file will be placed in the "src/po" directory.835VIMPROG A variable containing a directory with a working Vim.836 If the Vim editor is already built and installed, and837 is contained in the $PATH environment variable,838 then you can specify just the name of the vim839 executable.840{package}.pot This is the Target. It is specified as the name of841 the package, for example, "foobar" with the addition842 of the .pot extension.843Once a POT file is created, its contents are copied into separate PO files for844each language for which the translation will be prepared.845 846When the translation is finished, it is necessary to convert the PO files into847binary MO-files format and place these MO-files into the "lang/" directory,848the structure of which we created earlier.849To do this, run the following commands:850>851 cd ~/forkvim/src/po852 make -f Makefile "PLUGPACKAGE={package}" \853 "PO_PLUGPACKAGE={path/to/{lang}.po}" \854 ["MO_PLUGPACKAGE_PATH={path/to/lang/<lang_id>/LC_MESSAGES}" \]855 {package}.mo856<857Where:858PLUGPACKAGE A variable containing the name of the package that we859 specified in the |bindtextdomain()| and |gettext()|860 functions, for example, "foobar".861PO_PLUGPACKAGE A variable containing a PO file. The file is862 specified with an absolute or relative path. For863 example, "~/myproject/translate/en.po"864MO_PLUGPACKAGE_PATH A variable containing the structure of the "lang/"865 directory, where the file with translations will be866 placed, for example, "foobar.mo". This is not867 a required variable, if the directory is not868 specified, the MO file will be saved in the "src/po"869 directory.870{package}.mo This is the Target. It is specified as the name of871 the package, for example, "foobar" with the addition872 of the .mo extension.873 874 *package-translate_example*875Let's show it all on some concrete example and translate the876"ftplugin/aap.vim" file into Russian and German.877 878First, let's prepare the "aap.vim" file, specifying |bindtextdomain()| and879|gettext()| function calls in it.880>881 " Only do this when not done yet for this buffer882 if exists("b:did_ftplugin")883 finish884 endif885 886 " Don't load another plugin for this buffer887 let b:did_ftplugin = 1888 call bindtextdomain("aap", fnamemodify(expand("<script>"), ':p:h') .. '/../lang/')889 890 " Reset 'formatoptions', 'comments', 'commentstring' and 'expandtab' to undo891 " this plugin.892 let b:undo_ftplugin = "setl fo< com< cms< et<"893 894 " Set 'formatoptions' to break comment lines but not other lines,895 " and insert the comment leader when hitting <CR> or using "o".896 setlocal fo-=t fo+=croql897 898 " Set 'comments' to format dashed lists in comments.899 setlocal comments=s:#\ -,m:#\ \ ,e:#,n:#,fb:-900 setlocal commentstring=#\ %s901 902 " Expand tabs to spaces to avoid trouble.903 setlocal expandtab904 905 if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")906 let b:browsefilter = gettext("Aap Recipe Files (*.aap)\t*.aap\n", "aap")907 if has("win32")908 let b:browsefilter ..= gettext("All Files (*.*)\t*\n", "aap")909 else910 let b:browsefilter ..= gettext("All Files (*)\t*\n", "aap")911 endif912 let b:undo_ftplugin ..= " | unlet! b:browsefilter"913 endif914<915Now let's create a POT file for it (example uses Windows paths):916>917 cd /d f:\forkvim\src\po918 (the following command must be entered in one line, here it is separated for example)919 nmake.exe -f Make_mvc.mak "PLUGPACKAGE=aap"920 "PO_PLUG_INPUTLIST=d:\Programs\vim\vim91\ftplugin\aap.vim"921 "POT_PLUGPACKAGE_PATH=e:\project\translate\plugins"922 "VIMPROG=d:\Programs\vim\vim91\vim.exe"923 aap.pot924<925After the POT file of our package is created, go to the directory where we926saved it and perform the translation.927>928 cd /d e:\project\translate\plugins929 copy aap.pot ru.po930 copy aap.pot de.po931<932We have prepared a PO file with a translation into Russian:933 # Test plugins translate ~934 # ~935 msgid "" ~936 msgstr "" ~937 "Project-Id-Version: aap\n" ~938 "Report-Msgid-Bugs-To: \n" ~939 "POT-Creation-Date: 2024-06-23 14:58+0300\n" ~940 "PO-Revision-Date: 2024-06-23 14:58+0300\n" ~941 "Last-Translator: Restorer\n" ~942 "Language-Team: RuVim\n" ~943 "Language: ru\n" ~944 "MIME-Version: 1.0\n" ~945 "Content-Type: text/plain; charset=UTF-8\n" ~946 "Content-Transfer-Encoding: 8bit\n" ~947 948 #: ../../runtime/ftplugin/aap.vim:32 ~949 msgid "Aap Recipe Files (*.aap)\t*.aap\n" ~950 msgstr "Файлы инструкций Aap (*.aap)\t*.aap\n" ~951 952 #: ../../runtime/ftplugin/aap.vim:34 ~953 msgid "All Files (*.*)\t*\n" ~954 msgstr "Все файлы (*.*)\t*\n" ~955 956 #: ../../runtime/ftplugin/aap.vim:36 ~957 msgid "All Files (*)\t*\n" ~958 msgstr "Все файлы (*)\t*\n" ~959 960And the PO file in German:961 # Test plugins translate~962 #~963 msgid ""~964 msgstr ""~965 "Project-Id-Version: aap\n"~966 "Report-Msgid-Bugs-To: \n"~967 "POT-Creation-Date: 2024-06-23 14:58+0300\n"~968 "PO-Revision-Date: 2024-06-24 13:11+0300\n"~969 "Last-Translator: Restorer\n"~970 "Language-Team: German\n"~971 "Language: de\n"~972 "MIME-Version: 1.0\n"~973 "Content-Type: text/plain; charset=UTF-8\n"~974 "Content-Transfer-Encoding: 8bit\n"~975 976 #: ../../runtime/ftplugin/aap.vim:32~977 msgid "Aap Recipe Files (*.aap)\t*.aap\n"~978 msgstr "Aap-Rezeptdateien (*.aap)\t*.aap\n"~979 980 #: ../../runtime/ftplugin/aap.vim:34~981 msgid "All Files (*.*)\t*\n"~982 msgstr "Alle Dateien (*.*)\t*.*\n"~983 984 #: ../../runtime/ftplugin/aap.vim:36~985 msgid "All Files (*)\t*\n"~986 msgstr "Alle Dateien (*)\t*\n"~987 988Now convert these files into MO files so that |gettext()| can display message989translations. Note that since this is not a specialized plugin package, we990will put the MO files in the "lang/" directory of the Vim editor.991Type the following commands:992>993 cd /d f:\forkvim\src\po994< (the following command must be entered in one line, here it is separated for example)995 For Russian: >996 nmake.exe -f Make_mvc.mak "PLUGPACKAGE=aap"997 "PO_PLUGPACKAGE=e:\project\translate\plugins\ru.po"998 "MO_PLUGPACKAGE_PATH=d:\Programs\vim\vim91\lang\ru\LC_MESSAGES"999 aap.mo1000< For German: >1001 nmake.exe -f Make_mvc.mak "PLUGPACKAGE=aap"1002 "PO_PLUGPACKAGE=e:\project\translate\plugins\de.po"1003 "MO_PLUGPACKAGE_PATH=d:\Programs\vim\vim91\lang\de\LC_MESSAGES"1004 aap.mo1005<1006That's it, the translations are ready and you can see the plugin's messages1007in your native language.1008 1009Let's also try to translate a plugin package. For example, when a package1010contains several scripts containing strings that need to be translated.1011For example, let's translate the "netrw" package into Japanese.1012For this example, we will translate only a few lines from this package.1013Let's prepare the scripts where we need to translate the message strings.1014 1015The file "autoload\netrw.vim":1016>1017 " Load Once:1018 if &cp || exists("g:loaded_netrw")1019 finish1020 endif1021 call bindtextdomain("netrw", fnamemodify(expand("<script>"), ':p:h') .. '/../lang/')1022 1023 " Check that vim has patches that netrw requires.1024 " Patches needed for v7.4: 1557, and 213.1025 " (netrw will benefit from vim's having patch#656, too)1026 let s:needspatches=[1557,213]1027 if exists("s:needspatches")1028 for ptch in s:needspatches1029 if v:version < 704 || (v:version == 704 && !has("patch".ptch))1030 if !exists("s:needpatch{ptch}")1031 unsilent echomsg gettext("***sorry*** this version of netrw requires vim v7.4 with patch#", "netrw") .. ptch1032 endif1033 let s:needpatch{ptch}= 11034 finish1035 endif1036 endfor1037 endif1038<1039The file "autoload\netrwSettings.vim":1040>1041 " Load Once:1042 if exists("g:loaded_netrwSettings") || &cp1043 finish1044 endif1045 call bindtextdomain("netrw", fnamemodify(expand("<script>"), ':p:h') .. '/../lang/')1046 let g:loaded_netrwSettings = "v18"1047 if v:version < 7001048 echohl WarningMsg1049 echo gettext("***warning*** this version of netrwSettings needs vim 7.0", "netrw")1050 echohl Normal1051 finish1052 endif1053<1054Now we will prepare a POT file for further translation of messages.1055Execute the following commands:1056>1057 cd ~/forkvim/src/po1058 make -f Makefile "VIMPROG=/usr/local/bin/vim" "PLUGPACKAGE=netrw" \1059 "POT_PLUGPACKAGE_PATH=~/project/translate/plugins" \1060 "PO_PLUG_INPUTLIST=../../runtime/autoload/netrw.vim1061 ../../runtime/autoload/netrwSettings.vim" \1062 netrw.pot1063<1064Go to the directory with the POT file and make the translation:1065>1066 cd ~/project/translate/plugins1067 cp ./netrw.pot ja.po1068<1069When we have the translation ready in the "ja.po" file:1070 # Test plugins translate ~1071 # ~1072 msgid "" ~1073 msgstr "" ~1074 "Project-Id-Version: netrw\n" ~1075 "Report-Msgid-Bugs-To: \n" ~1076 "POT-Creation-Date: 2024-06-23 17:14+0300\n" ~1077 "PO-Revision-Date: 2024-06-23 17:14+0300\n" ~1078 "Last-Translator: Restorer\n" ~1079 "Language-Team: Japanese\n" ~1080 "Language: ja\n" ~1081 "MIME-Version: 1.0\n" ~1082 "Content-Type: text/plain; charset=UTF-8\n" ~1083 "Content-Transfer-Encoding: 8bit\n" ~1084 1085 #: ../../runtime/autoload/netrw.vim:51 ~1086 msgid "***sorry*** this version of netrw requires vim v7.4 with patch#" ~1087 msgstr "" ~1088 "***申し訳ありません***このバージョンのnetrwには、パッチ付きのvim v7.4が必要です#" ~1089 1090 #: ../../runtime/autoload/netrwSettings.vim:28 ~1091 msgid "***warning*** this version of netrwSettings needs vim 7.0" ~1092 msgstr "***警告***このバージョンのnetrwSettingsにはvim7.0が必要です" ~1093 1094Convert ja.po to a MO file:1095>1096 cd ~/forkvim/src/po1097 make -f Makefile "PLUGPACKAGE=netrw" \1098 "PO_PLUGPACKAGE=~/project/translate/plugins/ja.po" \1099 "MO_PLUGPACKAGE_PATH=/usr/local/share/vim/vim91/lang/ja/LC_MESSAGES" \1100 netrw.mo1101<1102Executing those steps will allow you to get translation of any third-party1103plug-in packages.1104 1105Dependencies between plugins ~1106 *packload-two-steps*1107Suppose you have two plugins that depend on the same functionality. You can1108put the common functionality in an autoload directory, so that it will be1109found automatically. Your package would have these files:1110 1111 pack/foo/start/one/plugin/one.vim >1112 call foolib#getit()1113< pack/foo/start/two/plugin/two.vim >1114 call foolib#getit()1115< pack/foo/start/lib/autoload/foolib.vim >1116 func foolib#getit()1117 1118This works, because loading packages will first add all found directories to1119'runtimepath' before sourcing the plugins.1120 1121==============================================================================11227. Debugging scripts *debug-scripts*1123 1124Besides the obvious messages that you can add to your scripts to find out what1125they are doing, Vim offers a debug mode. This allows you to step through a1126sourced file or user function and set breakpoints.1127 1128NOTE: The debugging mode is far from perfect. Debugging will have side1129effects on how Vim works. You cannot use it to debug everything. For1130example, the display is messed up by the debugging messages.1131 1132An alternative to debug mode is setting the 'verbose' option. With a bigger1133number it will give more verbose messages about what Vim is doing.1134 1135 1136STARTING DEBUG MODE *debug-mode*1137 1138To enter debugging mode use one of these methods:11391. Start Vim with the |-D| argument: >1140 vim -D file.txt1141< Debugging will start as soon as the first vimrc file is sourced. This is1142 useful to find out what is happening when Vim is starting up. A side1143 effect is that Vim will switch the terminal mode before initialisations1144 have finished, with unpredictable results.1145 For a GUI-only version (Windows, Macintosh) the debugging will start as1146 soon as the GUI window has been opened. To make this happen early, add a1147 ":gui" command in the vimrc file.1148 *:debug*11492. Run a command with ":debug" prepended. Debugging will only be done while1150 this command executes. Useful for debugging a specific script or user1151 function. And for scripts and functions used by autocommands. Example: >1152 :debug edit test.txt.gz1153 11543. Set a breakpoint in a sourced file or user function. You could do this in1155 the command line: >1156 vim -c "breakadd file */explorer.vim" .1157< This will run Vim and stop in the first line of the "explorer.vim" script.1158 Breakpoints can also be set while in debugging mode.1159 1160In debugging mode every executed command is displayed before it is executed.1161Comment lines, empty lines and lines that are not executed are skipped. When1162a line contains two commands, separated by "|", each command will be displayed1163separately.1164 1165 1166DEBUG MODE1167 1168Once in debugging mode, the usual Ex commands can be used. For example, to1169inspect the value of a variable: >1170 echo idx1171When inside a user function, this will print the value of the local variable1172"idx". Prepend "g:" to get the value of a global variable: >1173 echo g:idx1174All commands are executed in the context of the current function or script.1175You can also set options, for example setting or resetting 'verbose' will show1176what happens, but you might want to set it just before executing the lines you1177are interested in: >1178 :set verbose=201179 1180Commands that require updating the screen should be avoided, because their1181effect won't be noticed until after leaving debug mode. For example: >1182 :help1183won't be very helpful.1184 1185There is a separate command-line history for debug mode.1186 1187NOTE: In Vim9 script, if a command is written at the script level and1188continues on the next line, not using the old way with a backslash for line1189continuation, only the first line is printed before the debugging prompt.1190 1191The line number for a function line is relative to the start of the function.1192If you have trouble figuring out where you are, edit the file that defines1193the function in another Vim, search for the start of the function and do1194"99j". Replace "99" with the line number.1195 1196Additionally, these commands can be used:1197 *>cont*1198 cont Continue execution until the next breakpoint is hit.1199 *>quit*1200 quit Abort execution. This is like using CTRL-C, some