Movatterモバイル変換


[0]ホーム

URL:


Quick links:help overview ·quick reference ·user manual toc ·reference manual toc·faq
Go to keyword (shortcut:k)
Site search (shortcut:s)
usr_52.txt  ForVim version 9.2.  Last change: 2026 Feb 14     VIM USER MANUALbyBramMoolenaar       Write larger pluginsWhen pluginsdo more than simple things, they tend to grow big.  This fileexplains how to make sure they still load fast and how to split them up insmaller parts.52.1  Export and import52.2  Autoloading52.3  Autoloading without import/export52.4  Other mechanisms to use52.5  UsingaVim9script from legacyscript52.6Vim9 examples: comment and highlight-yankplugin     Next chapter:usr_90.txt  Installing Vim Previous chapter:usr_51.txt  CreateapluginTable of contents:usr_toc.txt==============================================================================52.1  Export and importVim9script was designed to makeit easier to write large Vim scripts.  Itlooks more like otherscript languages, especially Typescript.  Also,functions are compiled into instructions that can be executed quickly.  ThismakesVim9scripta lot faster, up toa 100 times.The basic ideais thatascript file has items that are private, only usedinside thescript file, and items that are exported, which can be used byscripts that import them.  That makes very clear whatis defined where.Let's start with an example,ascript that exports one function and has oneprivate function:vim9scriptexport def GetMessage(count: string): string   var nr = str2nr(count)   var result = $'To {nr} we say '   result ..= GetReply(nr)   return resultenddefdef GetReply(nr: number): string  if nr == 42     return 'yes'  elseif nr == 22     return 'maybe'  else     return 'no'  endifenddefThevim9script commandis required,export only works inaVim9 script.The `export def GetMessage(...` line starts withexport, meaning that thisfunction can be called by other scripts.  The line `def GetReply(...` does notstart withexport, thisisascript-local function,it can only be usedinside thisscript file.Now about thescript where thisis imported.  In this example we use thislayout, which works well foraplugin below the "pack" directory:.../plugin/theplugin.vim.../lib/getmessage.vimAssuming the "..." directory has been added to'runtimepath', Vim will lookfor plugins in the "plugin" directory and source "theplugin.vim".  Vim doesnot recognize the "lib" directory, you canput any scripts there.The abovescript that exports GetMessage() goes in lib/getmessage.vim.  TheGetMessage() functionis used in plugin/theplugin.vim:vim9scriptimport "../lib/getmessage.vim"command -nargs=1 ShowMessage echomsg getmessage.GetMessage(<f-args>)Theimport command usesa relative path,it starts with "../", which meanstogo one directory up.  For other kinds of paths see the:import command.How we can try out the command that theplugin provides:ShowMessage 1To 1 we say noShowMessage 22To 22 we say maybeNotice that the function GetMessage()is prefixed with the importedscriptname "getmessage".  That way, for every imported function used, you know whatscriptit was imported from.  If you import several scripts each of them coulddefinea GetMessage() function:vim9scriptimport "../lib/getmessage.vim"import "../lib/getother.vim"command -nargs=1 ShowMessage echomsg getmessage.GetMessage(<f-args>)command -nargs=1 ShowOther echomsg getother.GetMessage(<f-args>)If the importedscript nameis long or you useit in many places, you canshortenit by adding an "as" argument:import "../lib/getmessage.vim" as msgcommand -nargs=1 ShowMessage echomsg msg.GetMessage(<f-args>)RELOADINGOne thing to keep in mind: the imported "lib/getmessage.vim"script will besourced only once.  Whenitis importeda second time sourcingit will beskipped, since the items init have already been created.  It does not matterif this import commandis in another script, or in the samescript thatissourced again.Thisis efficient when usinga plugin, but when still developingapluginitmeans thatchanging "lib/getmessage.vim" afterit has been imported will haveno effect.  You need to quit Vim and startit again. (Rationale: the itemsdefined in thescript could be used ina compiled function, sourcing thescript again may break those functions).USING GLOBALSSometimes you will want to use globalvariables or functions, so that they canbe used anywhere.A good exampleisa global variable that passesapreference toa plugin.  To avoid other scripts using the same name, useaprefix thatis very unlikely to be used elsewhere.  For example, if you havea"mytags" plugin, you could use:g:mytags_location = '$HOME/project'g:mytags_style = 'fast'==============================================================================52.2  AutoloadingAfter splitting your largescript into pieces, all the lines will still beloaded and executed the moment thescriptis used.  Everyimport loads theimportedscript to find the items defined there.  Although thatis good forfindingerrors early,it also takes time.  Whichis wasted if thefunctionalityis not often used.Instead of havingimport load thescript immediately,it can be postponeduntil needed.  Using the example above, only one change needs to be made inthe plugin/theplugin.vim script:import autoload "../lib/getmessage.vim"Nothing in the rest of thescript needs to change.  However, the types willnot be checked.  Not even the existence of the GetMessage() functionischecked untilitis used.  You will have to decide whatis more important foryour script: faststartup or gettingerrors early.  You can also add the"autoload" argument later, after you have checked everything works.AUTOLOAD DIRECTORYAnother formis to useautoload withascript name thatis not an absolute orrelative path:import autoload "monthlib.vim"This will search for thescript "monthlib.vim" in theautoload directories of'runtimepath'.  WithUnix one of the directories oftenis "~/.vim/autoload".It will also search under'packpath', under "start".The main advantage of thisis that thisscript can be easily shared with otherscripts.  Youdo need to make sure that thescript nameis unique, since Vimwill search all the "autoload" directories in'runtimepath', and if you areusing several plugins withaplugin manager,it may adda directory to'runtimepath', each of which might have an "autoload" directory.Without autoload:import "monthlib.vim"Vim will search for thescript "monthlib.vim" in the import directories of'runtimepath'.Note that in thiscase adding or removing "autoload" changeswhere thescriptis found.  Witha relative or absolute path the location doesnot change.==============================================================================52.3  Autoloading without import/exportwrite-library-scriptA mechanism from before import/exportis still useful and some users may findita bit simpler.  The ideais that you calla function witha special name.That functionis then in anautoload script.  We will call that onescriptalibrary script.Theautoload mechanismis based ona function name that has "#" characters:mylib#myfunction(arg)Vim will recognize the function name by the embedded "#" character and whenitis not defined yet search for thescript "autoload/mylib.vim" in'runtimepath'.  Thatscriptmust define the "mylib#myfunction()" function.Obviously the name "mylib"is the part before the "#" andis usedas the nameof the script, adding ".vim".You canput many otherfunctions in the mylib.vim script, you are free toorganize yourfunctions in library scripts.  But youmust use function nameswhere the part before the '#' matches thescript name.  Otherwise Vim wouldnot know whatscript to load.  Thisis whereit differs from the import/exportmechanism.If you get really enthusiastic and write lots of library scripts, you maywant to use subdirectories.  Example:netlib#ftp#read('somefile')Here thescript nameis taken from the function name up to the last "#". The"#" in the middle are replaced bya slash, the last one by ".vim".  Thus youget "netlib/ftp.vim".  ForUnix the libraryscript used for this could be:~/.vim/autoload/netlib/ftp.vimWhere the functionis defined like this:def netlib#ftp#read(fname: string)#  Read the file fname through ftpenddefNotice that the name the functionis defined withis exactly the sameas thename used for calling the function.  And the part before the last '#'exactly matches the subdirectory andscript name.You can use the same mechanism for variables:var weekdays = dutch#weekdaysThis will load thescript "autoload/dutch.vim", which should contain somethinglike:var dutch#weekdays = ['zondag', 'maandag', 'dinsdag', 'woensdag',\ 'donderdag', 'vrijdag', 'zaterdag']Further reading:autoload.==============================================================================52.4  Other mechanisms to useSome may find the use of several filesa hassle and prefer to keep everythingtogether in one script.  To avoid this resulting in slowstartup thereisamechanism that only definesa small part and postpones the rest to whenitisactually used.write-plugin-quickloadThe basic ideais that thepluginis loaded twice.  The first time usercommands and mappings are defined that offer the functionality.  The secondtime thefunctions that implement the functionality are defined.It may sound surprising that quickload means loadingascript twice.  What wemeanis thatit loads quickly the first time, postponing the bulk of thescript to the second time, which only happens when you actually use it.  Whenyou always use the functionalityit actually gets slower!This usesaFuncUndefined autocommand.  This works differently from theautoload functionality explained above.The following example shows how it's done:" Vim global plugin for demonstrating quick loading" Last Change:2005 Feb 25" Maintainer:Bram Moolenaar <Bram@vim.org>" License:This file is placed in the public domain.if !exists("s:did_load")command -nargs=* BNRead  call BufNetRead(<f-args>)map <F19> :call BufNetWrite('something')<CR>let s:did_load = 1exe 'au FuncUndefined BufNet* source ' .. expand('<sfile>')finishendiffunction BufNetRead(...)echo 'BufNetRead(' .. string(a:000) .. ')'" read functionality hereendfunctionfunction BufNetWrite(...)echo 'BufNetWrite(' .. string(a:000) .. ')'" write functionality hereendfunctionWhen thescriptis first loaded "s:did_load"is not set.  The commands betweenthe "if" and "endif" will be executed.  This ends ina:finish command, thusthe rest of thescriptis not executed.The second time thescriptis loaded "s:did_load" exists and the commandsafter the "endif" are executed.  This defines the (possible long)BufNetRead() and BufNetWrite() functions.If you drop thisscript in yourplugin directory Vim will executeit onstartup.  Thisis the sequence of events that happens:1. The "BNRead" commandis defined and the<F19> keyis mapped when thescriptis sourcedat startup.AFuncUndefinedautocommandis defined.  The   ":finish" command causes thescript to terminate early.2. The user types the BNRead command or presses the<F19> key.  The   BufNetRead() or BufNetWrite() function will be called.3. Vim can't find the function and triggers theFuncUndefinedautocommand   event.  Since thepattern "BufNet*" matches the invoked function, the   command "source fname" will be executed.  "fname" will be equal to the name   of the script, no matter whereitis located, becauseit comes from   expanding "<sfile>" (seeexpand()).4. Thescriptis sourced again, the "s:did_load" variable exists and thefunctions are defined.Notice that thefunctions that are loaded afterwards match thepattern in theFuncUndefined autocommand.  Youmust make sure that no otherplugin definesfunctions that match this pattern.==============================================================================52.5  UsingaVim9script from legacyscriptsource-vim9-scriptIn some cases you havea legacy Vimscript where you want to use items fromaVim9 script.  For example in your.vimrc you want to initializea plugin.  Thebest way todo thisis to use:import.  For example:import 'myNicePlugin.vim'call myNicePlugin.NiceInit('today')This finds the exported function "NiceInit" in theVim9script file and makesit availableasscript-local item "myNicePlugin.NiceInit".:import alwaysuses thescript namespace, even when "s:"is not given.  If "myNicePlugin.vim"was already sourceditis not sourced again.Besides avoiding putting any items in the global namespace (where name clashescan cause unexpected errors), this also means thescriptis sourced only once,no matter how many times items fromit are imported.In some cases, e.g. for testing, you may just want to source theVim9 script.Thatis OK, but then only global items will be available.  TheVim9scriptwill have to make sure to useaunique name for these global items. Example:source ~/.vim/extra/myNicePlugin.vimcall g:NicePluginTest()==============================================================================52.6Vim9 examples: comment and highlight-yankpluginCOMMENT PACKAGEVim comes witha comment plugin, written inVim9 script.comment-installHavea lookat the package locatedat $VIMRUNTIME/pack/dist/opt/comment/HIGHLIGHT YANK PLUGINVim comes with the highlight-yank plugin, written inVim9scripthlyank-install, hereisa simplified implementation:vim9scriptdef HighlightedYank(hlgroup = 'IncSearch', duration = 300, in_visual = true)  if v:event.operator ==? 'y'    if !in_visual && visualmode() != null_string      visualmode(1)      return    endif    var [beg, end] = [getpos("'["), getpos("']")]    var type = v:event.regtype ?? 'v'    var pos = getregionpos(beg, end, {type: type, exclusive: false})    var m = matchaddpos(hlgroup, pos->mapnew((_, v) => {      var col_beg = v[0][2] + v[0][3]      var col_end = v[1][2] + v[1][3] + 1      return [v[0][1], col_beg, col_end - col_beg]    }))    var winid = win_getid()    timer_start(duration, (_) => m->matchdelete(winid))  endifenddefautocmd TextYankPost * HighlightedYank()For the complete example, havea look into the package locatedat$VIMRUNTIME/pack/dist/opt/hlyank/==============================================================================Next chapter:usr_90.txt  Installing VimCopyright: seemanual-copyright  vim:tw=78:ts=8:noet:ft=help:norl:

Quick links:help overview ·quick reference ·user manual toc ·reference manual toc·faq


[8]ページ先頭

©2009-2026 Movatter.jp