test_autocmd.vim 126 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269
  1. " Tests for autocommands
  2. source shared.vim
  3. source check.vim
  4. source term_util.vim
  5. source screendump.vim
  6. source vim9.vim
  7. source load.vim
  8. func s:cleanup_buffers() abort
  9. for bnr in range(1, bufnr('$'))
  10. if bufloaded(bnr) && bufnr('%') != bnr
  11. execute 'bd! ' . bnr
  12. endif
  13. endfor
  14. endfunc
  15. func CleanUpTestAuGroup()
  16. augroup testing
  17. au!
  18. augroup END
  19. augroup! testing
  20. endfunc
  21. func Test_vim_did_enter()
  22. call assert_false(v:vim_did_enter)
  23. " This script will never reach the main loop, can't check if v:vim_did_enter
  24. " becomes one.
  25. endfunc
  26. " Test for the CursorHold autocmd
  27. func Test_CursorHold_autocmd()
  28. CheckRunVimInTerminal
  29. call writefile(['one', 'two', 'three'], 'XoneTwoThree', 'D')
  30. let before =<< trim END
  31. set updatetime=10
  32. au CursorHold * call writefile([line('.')], 'XCHoutput', 'a')
  33. END
  34. call writefile(before, 'XCHinit', 'D')
  35. let buf = RunVimInTerminal('-S XCHinit XoneTwoThree', {})
  36. call term_sendkeys(buf, "G")
  37. call term_wait(buf, 50)
  38. call term_sendkeys(buf, "gg")
  39. call term_wait(buf)
  40. call WaitForAssert({-> assert_equal(['1'], readfile('XCHoutput')[-1:-1])})
  41. call term_sendkeys(buf, "j")
  42. call term_wait(buf)
  43. call WaitForAssert({-> assert_equal(['1', '2'], readfile('XCHoutput')[-2:-1])})
  44. call term_sendkeys(buf, "j")
  45. call term_wait(buf)
  46. call WaitForAssert({-> assert_equal(['1', '2', '3'], readfile('XCHoutput')[-3:-1])})
  47. call StopVimInTerminal(buf)
  48. call delete('XCHoutput')
  49. endfunc
  50. if has('timers')
  51. func ExitInsertMode(id)
  52. call feedkeys("\<Esc>")
  53. endfunc
  54. func Test_cursorhold_insert()
  55. " depends on timing
  56. let g:test_is_flaky = 1
  57. " Need to move the cursor.
  58. call feedkeys("ggG", "xt")
  59. let g:triggered = 0
  60. au CursorHoldI * let g:triggered += 1
  61. set updatetime=20
  62. call timer_start(LoadAdjust(200), 'ExitInsertMode')
  63. call feedkeys('a', 'x!')
  64. call assert_equal(1, g:triggered)
  65. unlet g:triggered
  66. au! CursorHoldI
  67. set updatetime&
  68. endfunc
  69. func Test_cursorhold_insert_with_timer_interrupt()
  70. CheckFeature job
  71. " Need to move the cursor.
  72. call feedkeys("ggG", "xt")
  73. " Confirm the timer invoked in exit_cb of the job doesn't disturb
  74. " CursorHoldI event.
  75. let g:triggered = 0
  76. au CursorHoldI * let g:triggered += 1
  77. set updatetime=100
  78. call job_start(has('win32') ? 'cmd /D /c echo:' : 'echo',
  79. \ {'exit_cb': {-> timer_start(200, 'ExitInsertMode')}})
  80. call feedkeys('a', 'x!')
  81. call assert_equal(1, g:triggered)
  82. unlet g:triggered
  83. au! CursorHoldI
  84. set updatetime&
  85. endfunc
  86. func Test_cursorhold_insert_ctrl_x()
  87. let g:triggered = 0
  88. au CursorHoldI * let g:triggered += 1
  89. set updatetime=20
  90. call timer_start(LoadAdjust(100), 'ExitInsertMode')
  91. " CursorHoldI does not trigger after CTRL-X
  92. call feedkeys("a\<C-X>", 'x!')
  93. call assert_equal(0, g:triggered)
  94. unlet g:triggered
  95. au! CursorHoldI
  96. set updatetime&
  97. endfunc
  98. func Test_cursorhold_insert_ctrl_g_U()
  99. au CursorHoldI * :
  100. set updatetime=20
  101. new
  102. call timer_start(100, { -> feedkeys("\<Left>foo\<Esc>", 't') })
  103. call feedkeys("i()\<C-g>U", 'tx!')
  104. sleep 200m
  105. call assert_equal('(foo)', getline(1))
  106. undo
  107. call assert_equal('', getline(1))
  108. bwipe!
  109. au! CursorHoldI
  110. set updatetime&
  111. endfunc
  112. func Test_OptionSet_modeline()
  113. CheckFunction test_override
  114. call test_override('starting', 1)
  115. au! OptionSet
  116. augroup set_tabstop
  117. au OptionSet tabstop call timer_start(1, {-> execute("echo 'Handler called'", "")})
  118. augroup END
  119. call writefile(['vim: set ts=7 sw=5 :', 'something'], 'XoptionsetModeline', 'D')
  120. set modeline
  121. let v:errmsg = ''
  122. call assert_fails('split XoptionsetModeline', 'E12:')
  123. call assert_equal(7, &ts)
  124. call assert_equal('', v:errmsg)
  125. augroup set_tabstop
  126. au!
  127. augroup END
  128. bwipe!
  129. set ts&
  130. call test_override('starting', 0)
  131. endfunc
  132. endif "has('timers')
  133. func Test_bufunload()
  134. augroup test_bufunload_group
  135. autocmd!
  136. autocmd BufUnload * call add(s:li, "bufunload")
  137. autocmd BufDelete * call add(s:li, "bufdelete")
  138. autocmd BufWipeout * call add(s:li, "bufwipeout")
  139. augroup END
  140. let s:li = []
  141. new
  142. setlocal bufhidden=
  143. bunload
  144. call assert_equal(["bufunload", "bufdelete"], s:li)
  145. let s:li = []
  146. new
  147. setlocal bufhidden=delete
  148. bunload
  149. call assert_equal(["bufunload", "bufdelete"], s:li)
  150. let s:li = []
  151. new
  152. setlocal bufhidden=unload
  153. bwipeout
  154. call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li)
  155. au! test_bufunload_group
  156. augroup! test_bufunload_group
  157. endfunc
  158. " SEGV occurs in older versions. (At least 7.4.2005 or older)
  159. func Test_autocmd_bufunload_with_tabnext()
  160. tabedit
  161. tabfirst
  162. augroup test_autocmd_bufunload_with_tabnext_group
  163. autocmd!
  164. autocmd BufUnload <buffer> tabnext
  165. augroup END
  166. quit
  167. call assert_equal(2, tabpagenr('$'))
  168. autocmd! test_autocmd_bufunload_with_tabnext_group
  169. augroup! test_autocmd_bufunload_with_tabnext_group
  170. tablast
  171. quit
  172. endfunc
  173. func Test_argdelete_in_next()
  174. au BufNew,BufEnter,BufLeave,BufWinEnter * argdel
  175. call assert_fails('next a b', 'E1156:')
  176. au! BufNew,BufEnter,BufLeave,BufWinEnter *
  177. endfunc
  178. func Test_autocmd_bufwinleave_with_tabfirst()
  179. tabedit
  180. augroup sample
  181. autocmd!
  182. autocmd BufWinLeave <buffer> tabfirst
  183. augroup END
  184. call setline(1, ['a', 'b', 'c'])
  185. edit! a.txt
  186. tabclose
  187. endfunc
  188. " SEGV occurs in older versions. (At least 7.4.2321 or older)
  189. func Test_autocmd_bufunload_avoiding_SEGV_01()
  190. split aa.txt
  191. let lastbuf = bufnr('$')
  192. augroup test_autocmd_bufunload
  193. autocmd!
  194. exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
  195. augroup END
  196. call assert_fails('edit bb.txt', 'E937:')
  197. autocmd! test_autocmd_bufunload
  198. augroup! test_autocmd_bufunload
  199. bwipe! aa.txt
  200. bwipe! bb.txt
  201. endfunc
  202. " SEGV occurs in older versions. (At least 7.4.2321 or older)
  203. func Test_autocmd_bufunload_avoiding_SEGV_02()
  204. setlocal buftype=nowrite
  205. let lastbuf = bufnr('$')
  206. augroup test_autocmd_bufunload
  207. autocmd!
  208. exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
  209. augroup END
  210. normal! i1
  211. call assert_fails('edit a.txt', 'E517:')
  212. autocmd! test_autocmd_bufunload
  213. augroup! test_autocmd_bufunload
  214. bwipe! a.txt
  215. endfunc
  216. func Test_autocmd_dummy_wipeout()
  217. " prepare files
  218. call writefile([''], 'Xdummywipetest1.txt', 'D')
  219. call writefile([''], 'Xdummywipetest2.txt', 'D')
  220. augroup test_bufunload_group
  221. autocmd!
  222. autocmd BufUnload * call add(s:li, "bufunload")
  223. autocmd BufDelete * call add(s:li, "bufdelete")
  224. autocmd BufWipeout * call add(s:li, "bufwipeout")
  225. augroup END
  226. let s:li = []
  227. split Xdummywipetest1.txt
  228. silent! vimgrep /notmatched/ Xdummywipetest*
  229. call assert_equal(["bufunload", "bufwipeout"], s:li)
  230. bwipeout
  231. au! test_bufunload_group
  232. augroup! test_bufunload_group
  233. endfunc
  234. func Test_win_tab_autocmd()
  235. let g:record = []
  236. augroup testing
  237. au WinNew * call add(g:record, 'WinNew')
  238. au WinClosed * call add(g:record, 'WinClosed')
  239. au WinEnter * call add(g:record, 'WinEnter')
  240. au WinLeave * call add(g:record, 'WinLeave')
  241. au TabNew * call add(g:record, 'TabNew')
  242. au TabClosed * call add(g:record, 'TabClosed')
  243. au TabEnter * call add(g:record, 'TabEnter')
  244. au TabLeave * call add(g:record, 'TabLeave')
  245. augroup END
  246. split
  247. tabnew
  248. close
  249. close
  250. call assert_equal([
  251. \ 'WinLeave', 'WinNew', 'WinEnter',
  252. \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
  253. \ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter',
  254. \ 'WinLeave', 'WinClosed', 'WinEnter'
  255. \ ], g:record)
  256. let g:record = []
  257. tabnew somefile
  258. tabnext
  259. bwipe somefile
  260. call assert_equal([
  261. \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
  262. \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
  263. \ 'WinClosed', 'TabClosed'
  264. \ ], g:record)
  265. augroup testing
  266. au!
  267. augroup END
  268. unlet g:record
  269. endfunc
  270. func Test_WinResized()
  271. CheckRunVimInTerminal
  272. let lines =<< trim END
  273. set scrolloff=0
  274. call setline(1, ['111', '222'])
  275. vnew
  276. call setline(1, ['aaa', 'bbb'])
  277. new
  278. call setline(1, ['foo', 'bar'])
  279. let g:resized = 0
  280. au WinResized * let g:resized += 1
  281. func WriteResizedEvent()
  282. call writefile([json_encode(v:event)], 'XresizeEvent')
  283. endfunc
  284. au WinResized * call WriteResizedEvent()
  285. END
  286. call writefile(lines, 'Xtest_winresized', 'D')
  287. let buf = RunVimInTerminal('-S Xtest_winresized', {'rows': 10})
  288. " redraw now to avoid a redraw after the :echo command
  289. call term_sendkeys(buf, ":redraw!\<CR>")
  290. call TermWait(buf)
  291. call term_sendkeys(buf, ":echo g:resized\<CR>")
  292. call WaitForAssert({-> assert_match('^0$', term_getline(buf, 10))}, 1000)
  293. " increase window height, two windows will be reported
  294. call term_sendkeys(buf, "\<C-W>+")
  295. call TermWait(buf)
  296. call term_sendkeys(buf, ":echo g:resized\<CR>")
  297. call WaitForAssert({-> assert_match('^1$', term_getline(buf, 10))}, 1000)
  298. let event = readfile('XresizeEvent')[0]->json_decode()
  299. call assert_equal({
  300. \ 'windows': [1002, 1001],
  301. \ }, event)
  302. " increase window width, three windows will be reported
  303. call term_sendkeys(buf, "\<C-W>>")
  304. call TermWait(buf)
  305. call term_sendkeys(buf, ":echo g:resized\<CR>")
  306. call WaitForAssert({-> assert_match('^2$', term_getline(buf, 10))}, 1000)
  307. let event = readfile('XresizeEvent')[0]->json_decode()
  308. call assert_equal({
  309. \ 'windows': [1002, 1001, 1000],
  310. \ }, event)
  311. call delete('XresizeEvent')
  312. call StopVimInTerminal(buf)
  313. endfunc
  314. func Test_WinScrolled()
  315. CheckRunVimInTerminal
  316. let lines =<< trim END
  317. set nowrap scrolloff=0
  318. for ii in range(1, 18)
  319. call setline(ii, repeat(nr2char(96 + ii), ii * 2))
  320. endfor
  321. let win_id = win_getid()
  322. let g:matched = v:false
  323. func WriteScrollEvent()
  324. call writefile([json_encode(v:event)], 'XscrollEvent')
  325. endfunc
  326. execute 'au WinScrolled' win_id 'let g:matched = v:true'
  327. let g:scrolled = 0
  328. au WinScrolled * let g:scrolled += 1
  329. au WinScrolled * let g:amatch = str2nr(expand('<amatch>'))
  330. au WinScrolled * let g:afile = str2nr(expand('<afile>'))
  331. au WinScrolled * call WriteScrollEvent()
  332. END
  333. call writefile(lines, 'Xtest_winscrolled', 'D')
  334. let buf = RunVimInTerminal('-S Xtest_winscrolled', {'rows': 6})
  335. call term_sendkeys(buf, ":echo g:scrolled\<CR>")
  336. call WaitForAssert({-> assert_match('^0 ', term_getline(buf, 6))}, 1000)
  337. " Scroll left/right in Normal mode.
  338. call term_sendkeys(buf, "zlzh:echo g:scrolled\<CR>")
  339. call WaitForAssert({-> assert_match('^2 ', term_getline(buf, 6))}, 1000)
  340. let event = readfile('XscrollEvent')[0]->json_decode()
  341. call assert_equal({
  342. \ 'all': {'leftcol': 1, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
  343. \ '1000': {'leftcol': -1, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
  344. \ }, event)
  345. " Scroll up/down in Normal mode.
  346. call term_sendkeys(buf, "\<c-e>\<c-y>:echo g:scrolled\<CR>")
  347. call WaitForAssert({-> assert_match('^4 ', term_getline(buf, 6))}, 1000)
  348. let event = readfile('XscrollEvent')[0]->json_decode()
  349. call assert_equal({
  350. \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
  351. \ '1000': {'leftcol': 0, 'topline': -1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
  352. \ }, event)
  353. " Scroll up/down in Insert mode.
  354. call term_sendkeys(buf, "Mi\<c-x>\<c-e>\<Esc>i\<c-x>\<c-y>\<Esc>")
  355. call term_sendkeys(buf, ":echo g:scrolled\<CR>")
  356. call WaitForAssert({-> assert_match('^6 ', term_getline(buf, 6))}, 1000)
  357. let event = readfile('XscrollEvent')[0]->json_decode()
  358. call assert_equal({
  359. \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
  360. \ '1000': {'leftcol': 0, 'topline': -1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
  361. \ }, event)
  362. " Scroll the window horizontally to focus the last letter of the third line
  363. " containing only six characters. Moving to the previous and shorter lines
  364. " should trigger another autocommand as Vim has to make them visible.
  365. call term_sendkeys(buf, "5zl2k")
  366. call term_sendkeys(buf, ":echo g:scrolled\<CR>")
  367. call WaitForAssert({-> assert_match('^8 ', term_getline(buf, 6))}, 1000)
  368. let event = readfile('XscrollEvent')[0]->json_decode()
  369. call assert_equal({
  370. \ 'all': {'leftcol': 5, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
  371. \ '1000': {'leftcol': -5, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
  372. \ }, event)
  373. " Ensure the command was triggered for the specified window ID.
  374. call term_sendkeys(buf, ":echo g:matched\<CR>")
  375. call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000)
  376. " Ensure the expansion of <amatch> and <afile> matches the window ID.
  377. call term_sendkeys(buf, ":echo g:amatch == win_id && g:afile == win_id\<CR>")
  378. call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000)
  379. call delete('XscrollEvent')
  380. call StopVimInTerminal(buf)
  381. endfunc
  382. func Test_WinScrolled_mouse()
  383. CheckRunVimInTerminal
  384. let lines =<< trim END
  385. set nowrap scrolloff=0
  386. set mouse=a term=xterm ttymouse=sgr mousetime=200 clipboard=
  387. call setline(1, ['foo']->repeat(32))
  388. split
  389. let g:scrolled = 0
  390. au WinScrolled * let g:scrolled += 1
  391. END
  392. call writefile(lines, 'Xtest_winscrolled_mouse', 'D')
  393. let buf = RunVimInTerminal('-S Xtest_winscrolled_mouse', {'rows': 10})
  394. " With the upper split focused, send a scroll-down event to the unfocused one.
  395. call test_setmouse(7, 1)
  396. call term_sendkeys(buf, "\<ScrollWheelDown>")
  397. call TermWait(buf)
  398. call term_sendkeys(buf, ":echo g:scrolled\<CR>")
  399. call WaitForAssert({-> assert_match('^1', term_getline(buf, 10))}, 1000)
  400. " Again, but this time while we're in insert mode.
  401. call term_sendkeys(buf, "i\<ScrollWheelDown>\<Esc>")
  402. call TermWait(buf)
  403. call term_sendkeys(buf, ":echo g:scrolled\<CR>")
  404. call WaitForAssert({-> assert_match('^2', term_getline(buf, 10))}, 1000)
  405. call StopVimInTerminal(buf)
  406. endfunc
  407. func Test_WinScrolled_close_curwin()
  408. CheckRunVimInTerminal
  409. let lines =<< trim END
  410. set nowrap scrolloff=0
  411. call setline(1, ['aaa', 'bbb'])
  412. vsplit
  413. au WinScrolled * close
  414. au VimLeave * call writefile(['123456'], 'Xtestout')
  415. END
  416. call writefile(lines, 'Xtest_winscrolled_close_curwin', 'D')
  417. let buf = RunVimInTerminal('-S Xtest_winscrolled_close_curwin', {'rows': 6})
  418. " This was using freed memory
  419. call term_sendkeys(buf, "\<C-E>")
  420. call TermWait(buf)
  421. call StopVimInTerminal(buf)
  422. " check the startup script finished to the end
  423. call assert_equal(['123456'], readfile('Xtestout'))
  424. call delete('Xtestout')
  425. endfunc
  426. func Test_WinScrolled_once_only()
  427. CheckRunVimInTerminal
  428. let lines =<< trim END
  429. set cmdheight=2
  430. call setline(1, ['aaa', 'bbb'])
  431. let trigger_count = 0
  432. func ShowInfo(id)
  433. echo g:trigger_count g:winid winlayout()
  434. endfunc
  435. vsplit
  436. split
  437. " use a timer to show the info after a redraw
  438. au WinScrolled * let trigger_count += 1 | let winid = expand('<amatch>') | call timer_start(100, 'ShowInfo')
  439. wincmd j
  440. wincmd l
  441. END
  442. call writefile(lines, 'Xtest_winscrolled_once', 'D')
  443. let buf = RunVimInTerminal('-S Xtest_winscrolled_once', #{rows: 10, cols: 60, statusoff: 2})
  444. call term_sendkeys(buf, "\<C-E>")
  445. call VerifyScreenDump(buf, 'Test_winscrolled_once_only_1', {})
  446. call StopVimInTerminal(buf)
  447. endfunc
  448. " Check that WinScrolled is not triggered immediately when defined and there
  449. " are split windows.
  450. func Test_WinScrolled_not_when_defined()
  451. CheckRunVimInTerminal
  452. let lines =<< trim END
  453. call setline(1, ['aaa', 'bbb'])
  454. echo 'nothing happened'
  455. func ShowTriggered(id)
  456. echo 'triggered'
  457. endfunc
  458. END
  459. call writefile(lines, 'Xtest_winscrolled_not', 'D')
  460. let buf = RunVimInTerminal('-S Xtest_winscrolled_not', #{rows: 10, cols: 60, statusoff: 2})
  461. call term_sendkeys(buf, ":split\<CR>")
  462. call TermWait(buf)
  463. " use a timer to show the message after redrawing
  464. call term_sendkeys(buf, ":au WinScrolled * call timer_start(100, 'ShowTriggered')\<CR>")
  465. call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_1', {})
  466. call term_sendkeys(buf, "\<C-E>")
  467. call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_2', {})
  468. call StopVimInTerminal(buf)
  469. endfunc
  470. func Test_WinScrolled_long_wrapped()
  471. CheckRunVimInTerminal
  472. let lines =<< trim END
  473. set scrolloff=0
  474. let height = winheight(0)
  475. let width = winwidth(0)
  476. let g:scrolled = 0
  477. au WinScrolled * let g:scrolled += 1
  478. call setline(1, repeat('foo', height * width))
  479. call cursor(1, height * width)
  480. END
  481. call writefile(lines, 'Xtest_winscrolled_long_wrapped', 'D')
  482. let buf = RunVimInTerminal('-S Xtest_winscrolled_long_wrapped', {'rows': 6})
  483. call term_sendkeys(buf, ":echo g:scrolled\<CR>")
  484. call WaitForAssert({-> assert_match('^0 ', term_getline(buf, 6))}, 1000)
  485. call term_sendkeys(buf, 'gj')
  486. call term_sendkeys(buf, ":echo g:scrolled\<CR>")
  487. call WaitForAssert({-> assert_match('^1 ', term_getline(buf, 6))}, 1000)
  488. call term_sendkeys(buf, '0')
  489. call term_sendkeys(buf, ":echo g:scrolled\<CR>")
  490. call WaitForAssert({-> assert_match('^2 ', term_getline(buf, 6))}, 1000)
  491. call term_sendkeys(buf, '$')
  492. call term_sendkeys(buf, ":echo g:scrolled\<CR>")
  493. call WaitForAssert({-> assert_match('^3 ', term_getline(buf, 6))}, 1000)
  494. call StopVimInTerminal(buf)
  495. endfunc
  496. func Test_WinScrolled_diff()
  497. CheckRunVimInTerminal
  498. let lines =<< trim END
  499. set diffopt+=foldcolumn:0
  500. call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
  501. vnew
  502. call setline(1, ['d', 'e', 'f', 'g', 'h', 'i'])
  503. windo diffthis
  504. func WriteScrollEvent()
  505. call writefile([json_encode(v:event)], 'XscrollEvent')
  506. endfunc
  507. au WinScrolled * call WriteScrollEvent()
  508. END
  509. call writefile(lines, 'Xtest_winscrolled_diff', 'D')
  510. let buf = RunVimInTerminal('-S Xtest_winscrolled_diff', {'rows': 8})
  511. call term_sendkeys(buf, "\<C-E>")
  512. call WaitForAssert({-> assert_match('^d', term_getline(buf, 3))}, 1000)
  513. let event = readfile('XscrollEvent')[0]->json_decode()
  514. call assert_equal({
  515. \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0},
  516. \ '1000': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
  517. \ '1001': {'leftcol': 0, 'topline': 0, 'topfill': -1, 'width': 0, 'height': 0, 'skipcol': 0}
  518. \ }, event)
  519. call term_sendkeys(buf, "2\<C-E>")
  520. call WaitForAssert({-> assert_match('^f', term_getline(buf, 3))}, 1000)
  521. let event = readfile('XscrollEvent')[0]->json_decode()
  522. call assert_equal({
  523. \ 'all': {'leftcol': 0, 'topline': 2, 'topfill': 2, 'width': 0, 'height': 0, 'skipcol': 0},
  524. \ '1000': {'leftcol': 0, 'topline': 2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
  525. \ '1001': {'leftcol': 0, 'topline': 0, 'topfill': -2, 'width': 0, 'height': 0, 'skipcol': 0}
  526. \ }, event)
  527. call term_sendkeys(buf, "\<C-E>")
  528. call WaitForAssert({-> assert_match('^g', term_getline(buf, 3))}, 1000)
  529. let event = readfile('XscrollEvent')[0]->json_decode()
  530. call assert_equal({
  531. \ 'all': {'leftcol': 0, 'topline': 2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
  532. \ '1000': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
  533. \ '1001': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}
  534. \ }, event)
  535. call term_sendkeys(buf, "2\<C-Y>")
  536. call WaitForAssert({-> assert_match('^e', term_getline(buf, 3))}, 1000)
  537. let event = readfile('XscrollEvent')[0]->json_decode()
  538. call assert_equal({
  539. \ 'all': {'leftcol': 0, 'topline': 3, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0},
  540. \ '1000': {'leftcol': 0, 'topline': -2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0},
  541. \ '1001': {'leftcol': 0, 'topline': -1, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0}
  542. \ }, event)
  543. call StopVimInTerminal(buf)
  544. call delete('XscrollEvent')
  545. endfunc
  546. func Test_WinClosed()
  547. " Test that the pattern is matched against the closed window's ID, and both
  548. " <amatch> and <afile> are set to it.
  549. new
  550. let winid = win_getid()
  551. let g:matched = v:false
  552. augroup test-WinClosed
  553. autocmd!
  554. execute 'autocmd WinClosed' winid 'let g:matched = v:true'
  555. autocmd WinClosed * let g:amatch = str2nr(expand('<amatch>'))
  556. autocmd WinClosed * let g:afile = str2nr(expand('<afile>'))
  557. augroup END
  558. close
  559. call assert_true(g:matched)
  560. call assert_equal(winid, g:amatch)
  561. call assert_equal(winid, g:afile)
  562. " Test that WinClosed is non-recursive.
  563. new
  564. new
  565. call assert_equal(3, winnr('$'))
  566. let g:triggered = 0
  567. augroup test-WinClosed
  568. autocmd!
  569. autocmd WinClosed * let g:triggered += 1
  570. autocmd WinClosed * 2 wincmd c
  571. augroup END
  572. close
  573. call assert_equal(1, winnr('$'))
  574. call assert_equal(1, g:triggered)
  575. autocmd! test-WinClosed
  576. augroup! test-WinClosed
  577. unlet g:matched
  578. unlet g:amatch
  579. unlet g:afile
  580. unlet g:triggered
  581. endfunc
  582. func Test_WinClosed_throws()
  583. vnew
  584. let bnr = bufnr()
  585. call assert_equal(1, bufloaded(bnr))
  586. augroup test-WinClosed
  587. autocmd WinClosed * throw 'foo'
  588. augroup END
  589. try
  590. close
  591. catch /.*/
  592. endtry
  593. call assert_equal(0, bufloaded(bnr))
  594. autocmd! test-WinClosed
  595. augroup! test-WinClosed
  596. endfunc
  597. func Test_WinClosed_throws_with_tabs()
  598. tabnew
  599. let bnr = bufnr()
  600. call assert_equal(1, bufloaded(bnr))
  601. augroup test-WinClosed
  602. autocmd WinClosed * throw 'foo'
  603. augroup END
  604. try
  605. close
  606. catch /.*/
  607. endtry
  608. call assert_equal(0, bufloaded(bnr))
  609. autocmd! test-WinClosed
  610. augroup! test-WinClosed
  611. endfunc
  612. " This used to trigger WinClosed twice for the same window, and the window's
  613. " buffer was NULL in the second autocommand.
  614. func Test_WinClosed_switch_tab()
  615. edit Xa
  616. split Xb
  617. split Xc
  618. tab split
  619. new
  620. augroup test-WinClosed
  621. autocmd WinClosed * tabprev | bwipe!
  622. augroup END
  623. close
  624. " Check that the tabline has been fully removed
  625. call assert_equal([1, 1], win_screenpos(0))
  626. autocmd! test-WinClosed
  627. augroup! test-WinClosed
  628. %bwipe!
  629. endfunc
  630. " This used to trigger WinClosed twice for the same window, and the window's
  631. " buffer was NULL in the second autocommand.
  632. func Test_WinClosed_BufUnload_close_other()
  633. tabnew
  634. let g:tab = tabpagenr()
  635. let g:buf = bufnr()
  636. new
  637. setlocal bufhidden=wipe
  638. augroup test-WinClosed
  639. autocmd BufUnload * ++once exe g:buf .. 'bwipe!'
  640. autocmd WinClosed * call tabpagebuflist(g:tab)
  641. augroup END
  642. close
  643. unlet g:tab
  644. unlet g:buf
  645. autocmd! test-WinClosed
  646. augroup! test-WinClosed
  647. %bwipe!
  648. endfunc
  649. func s:AddAnAutocmd()
  650. augroup vimBarTest
  651. au BufReadCmd * echo 'hello'
  652. augroup END
  653. call assert_equal(3, len(split(execute('au vimBarTest'), "\n")))
  654. endfunc
  655. func Test_early_bar()
  656. " test that a bar is recognized before the {event}
  657. call s:AddAnAutocmd()
  658. augroup vimBarTest | au! | let done = 77 | augroup END
  659. call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
  660. call assert_equal(77, done)
  661. call s:AddAnAutocmd()
  662. augroup vimBarTest| au!| let done = 88 | augroup END
  663. call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
  664. call assert_equal(88, done)
  665. " test that a bar is recognized after the {event}
  666. call s:AddAnAutocmd()
  667. augroup vimBarTest| au!BufReadCmd| let done = 99 | augroup END
  668. call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
  669. call assert_equal(99, done)
  670. " test that a bar is recognized after the {group}
  671. call s:AddAnAutocmd()
  672. au! vimBarTest|echo 'hello'
  673. call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
  674. endfunc
  675. func RemoveGroup()
  676. autocmd! StartOK
  677. augroup! StartOK
  678. endfunc
  679. func Test_augroup_warning()
  680. augroup TheWarning
  681. au VimEnter * echo 'entering'
  682. augroup END
  683. call assert_match("TheWarning.*VimEnter", execute('au VimEnter'))
  684. redir => res
  685. augroup! TheWarning
  686. redir END
  687. call assert_match("W19:", res)
  688. call assert_match("-Deleted-.*VimEnter", execute('au VimEnter'))
  689. " check "Another" does not take the pace of the deleted entry
  690. augroup Another
  691. augroup END
  692. call assert_match("-Deleted-.*VimEnter", execute('au VimEnter'))
  693. augroup! Another
  694. " no warning for postpone aucmd delete
  695. augroup StartOK
  696. au VimEnter * call RemoveGroup()
  697. augroup END
  698. call assert_match("StartOK.*VimEnter", execute('au VimEnter'))
  699. redir => res
  700. doautocmd VimEnter
  701. redir END
  702. call assert_notmatch("W19:", res)
  703. au! VimEnter
  704. call assert_fails('augroup!', 'E471:')
  705. endfunc
  706. func Test_BufReadCmdHelp()
  707. " This used to cause access to free memory
  708. au BufReadCmd * e +h
  709. help
  710. au! BufReadCmd
  711. endfunc
  712. func Test_BufReadCmdHelpJump()
  713. " This used to cause access to free memory
  714. au BufReadCmd * e +h{
  715. " } to fix highlighting
  716. call assert_fails('help', 'E434:')
  717. au! BufReadCmd
  718. endfunc
  719. " BufReadCmd is triggered for a "nofile" buffer. Check all values.
  720. func Test_BufReadCmdNofile()
  721. for val in ['nofile',
  722. \ 'nowrite',
  723. \ 'acwrite',
  724. \ 'quickfix',
  725. \ 'help',
  726. "\ 'terminal',
  727. \ 'prompt',
  728. "\ 'popup',
  729. \ ]
  730. new somefile
  731. exe 'set buftype=' .. val
  732. au BufReadCmd somefile call setline(1, 'triggered')
  733. edit
  734. call assert_equal('triggered', getline(1))
  735. au! BufReadCmd
  736. bwipe!
  737. endfor
  738. endfunc
  739. func Test_augroup_deleted()
  740. " This caused a crash before E936 was introduced
  741. augroup x
  742. call assert_fails('augroup! x', 'E936:')
  743. au VimEnter * echo
  744. augroup end
  745. augroup! x
  746. call assert_match("-Deleted-.*VimEnter", execute('au VimEnter'))
  747. au! VimEnter
  748. endfunc
  749. " Tests for autocommands on :close command.
  750. " This used to be in test13.
  751. func Test_three_windows()
  752. " Clean up buffers, because in some cases this function fails.
  753. call s:cleanup_buffers()
  754. " Write three files and open them, each in a window.
  755. " Then go to next window, with autocommand that deletes the previous one.
  756. " Do this twice, writing the file.
  757. e! Xtestje1
  758. call setline(1, 'testje1')
  759. w
  760. sp Xtestje2
  761. call setline(1, 'testje2')
  762. w
  763. sp Xtestje3
  764. call setline(1, 'testje3')
  765. w
  766. wincmd w
  767. au WinLeave Xtestje2 bwipe
  768. wincmd w
  769. call assert_equal('Xtestje1', expand('%'))
  770. au WinLeave Xtestje1 bwipe Xtestje3
  771. close
  772. call assert_equal('Xtestje1', expand('%'))
  773. " Test deleting the buffer on a Unload event. If this goes wrong there
  774. " will be the ATTENTION prompt.
  775. e Xtestje1
  776. au!
  777. au! BufUnload Xtestje1 bwipe
  778. call assert_fails('e Xtestje3', 'E937:')
  779. call assert_equal('Xtestje3', expand('%'))
  780. e Xtestje2
  781. sp Xtestje1
  782. call assert_fails('e', 'E937:')
  783. call assert_equal('Xtestje1', expand('%'))
  784. " Test changing buffers in a BufWipeout autocommand. If this goes wrong
  785. " there are ml_line errors and/or a Crash.
  786. au!
  787. only
  788. e Xanother
  789. e Xtestje1
  790. bwipe Xtestje2
  791. bwipe Xtestje3
  792. au BufWipeout Xtestje1 buf Xtestje1
  793. bwipe
  794. call assert_equal('Xanother', expand('%'))
  795. only
  796. help
  797. wincmd w
  798. 1quit
  799. call assert_equal('Xanother', expand('%'))
  800. au!
  801. enew
  802. call delete('Xtestje1')
  803. call delete('Xtestje2')
  804. call delete('Xtestje3')
  805. endfunc
  806. func Test_BufEnter()
  807. au! BufEnter
  808. au Bufenter * let val = val . '+'
  809. let g:val = ''
  810. split NewFile
  811. call assert_equal('+', g:val)
  812. bwipe!
  813. call assert_equal('++', g:val)
  814. " Also get BufEnter when editing a directory
  815. call mkdir('Xbufenterdir', 'D')
  816. split Xbufenterdir
  817. call assert_equal('+++', g:val)
  818. " On MS-Windows we can't edit the directory, make sure we wipe the right
  819. " buffer.
  820. bwipe! Xbufenterdir
  821. au! BufEnter
  822. " Editing a "nofile" buffer doesn't read the file but does trigger BufEnter
  823. " for historic reasons. Also test other 'buftype' values.
  824. for val in ['nofile',
  825. \ 'nowrite',
  826. \ 'acwrite',
  827. \ 'quickfix',
  828. \ 'help',
  829. "\ 'terminal',
  830. \ 'prompt',
  831. "\ 'popup',
  832. \ ]
  833. new somefile
  834. exe 'set buftype=' .. val
  835. au BufEnter somefile call setline(1, 'some text')
  836. edit
  837. call assert_equal('some text', getline(1))
  838. bwipe!
  839. au! BufEnter
  840. endfor
  841. endfunc
  842. " Closing a window might cause an endless loop
  843. " E814 for older Vims
  844. func Test_autocmd_bufwipe_in_SessLoadPost()
  845. edit Xtest
  846. tabnew
  847. file Xsomething
  848. set noswapfile
  849. mksession!
  850. let content =<< trim [CODE]
  851. set nocp noswapfile
  852. let v:swapchoice = "e"
  853. augroup test_autocmd_sessionload
  854. autocmd!
  855. autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!"
  856. augroup END
  857. func WriteErrors()
  858. call writefile([execute("messages")], "XerrorsBwipe")
  859. endfunc
  860. au VimLeave * call WriteErrors()
  861. [CODE]
  862. call writefile(content, 'Xvimrc', 'D')
  863. call system(GetVimCommand('Xvimrc') .. ' --headless --noplugins -S Session.vim -c cq')
  864. sleep 100m
  865. let errors = join(readfile('XerrorsBwipe'))
  866. call assert_match('E814:', errors)
  867. set swapfile
  868. for file in ['Session.vim', 'XerrorsBwipe']
  869. call delete(file)
  870. endfor
  871. endfunc
  872. " Using :blast and :ball for many events caused a crash, because b_nwindows was
  873. " not incremented correctly.
  874. func Test_autocmd_blast_badd()
  875. let content =<< trim [CODE]
  876. au BufNew,BufAdd,BufWinEnter,BufEnter,BufLeave,BufWinLeave,BufUnload,VimEnter foo* blast
  877. edit foo1
  878. au BufNew,BufAdd,BufWinEnter,BufEnter,BufLeave,BufWinLeave,BufUnload,VimEnter foo* ball
  879. edit foo2
  880. call writefile(['OK'], 'XerrorsBlast')
  881. qall
  882. [CODE]
  883. call writefile(content, 'XblastBall', 'D')
  884. call system(GetVimCommand() .. ' --clean -S XblastBall')
  885. sleep 100m
  886. call assert_match('OK', readfile('XerrorsBlast')->join())
  887. call delete('XerrorsBlast')
  888. endfunc
  889. " SEGV occurs in older versions.
  890. func Test_autocmd_bufwipe_in_SessLoadPost2()
  891. tabnew
  892. set noswapfile
  893. mksession!
  894. let content =<< trim [CODE]
  895. set nocp noswapfile
  896. function! DeleteInactiveBufs()
  897. tabfirst
  898. let tabblist = []
  899. for i in range(1, tabpagenr(''$''))
  900. call extend(tabblist, tabpagebuflist(i))
  901. endfor
  902. for b in range(1, bufnr(''$''))
  903. if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')
  904. exec ''bwipeout '' . b
  905. endif
  906. endfor
  907. echomsg "SessionLoadPost DONE"
  908. endfunction
  909. au SessionLoadPost * call DeleteInactiveBufs()
  910. func WriteErrors()
  911. call writefile([execute("messages")], "XerrorsPost")
  912. endfunc
  913. au VimLeave * call WriteErrors()
  914. [CODE]
  915. call writefile(content, 'Xvimrc', 'D')
  916. call system(GetVimCommand('Xvimrc') .. ' --headless --noplugins -S Session.vim -c cq')
  917. sleep 100m
  918. let errors = join(readfile('XerrorsPost'))
  919. " This probably only ever matches on unix.
  920. call assert_notmatch('Caught deadly signal SEGV', errors)
  921. call assert_match('SessionLoadPost DONE', errors)
  922. set swapfile
  923. for file in ['Session.vim', 'XerrorsPost']
  924. call delete(file)
  925. endfor
  926. endfunc
  927. func Test_empty_doau()
  928. doau \|
  929. endfunc
  930. func s:AutoCommandOptionSet(match)
  931. let template = "Option: <%s>, OldVal: <%s>, OldValLocal: <%s>, OldValGlobal: <%s>, NewVal: <%s>, Scope: <%s>, Command: <%s>\n"
  932. let item = remove(g:options, 0)
  933. let expected = printf(template, item[0], item[1], item[2], item[3], item[4], item[5], item[6])
  934. let actual = printf(template, a:match, v:option_old, v:option_oldlocal, v:option_oldglobal, v:option_new, v:option_type, v:option_command)
  935. let g:opt = [expected, actual]
  936. "call assert_equal(expected, actual)
  937. endfunc
  938. func Test_OptionSet()
  939. CheckFunction test_override
  940. CheckOption autochdir
  941. call test_override('starting', 1)
  942. set nocp
  943. au OptionSet * :call s:AutoCommandOptionSet(expand("<amatch>"))
  944. " 1: Setting number option"
  945. let g:options = [['number', 0, 0, 0, 1, 'global', 'set']]
  946. set nu
  947. call assert_equal([], g:options)
  948. call assert_equal(g:opt[0], g:opt[1])
  949. " 2: Setting local number option"
  950. let g:options = [['number', 1, 1, '', 0, 'local', 'setlocal']]
  951. setlocal nonu
  952. call assert_equal([], g:options)
  953. call assert_equal(g:opt[0], g:opt[1])
  954. " 3: Setting global number option"
  955. let g:options = [['number', 1, '', 1, 0, 'global', 'setglobal']]
  956. setglobal nonu
  957. call assert_equal([], g:options)
  958. call assert_equal(g:opt[0], g:opt[1])
  959. " 4: Setting local autoindent option"
  960. let g:options = [['autoindent', 0, 0, '', 1, 'local', 'setlocal']]
  961. setlocal ai
  962. call assert_equal([], g:options)
  963. call assert_equal(g:opt[0], g:opt[1])
  964. " 5: Setting global autoindent option"
  965. let g:options = [['autoindent', 0, '', 0, 1, 'global', 'setglobal']]
  966. setglobal ai
  967. call assert_equal([], g:options)
  968. call assert_equal(g:opt[0], g:opt[1])
  969. " 6: Setting global autoindent option"
  970. let g:options = [['autoindent', 1, 1, 1, 0, 'global', 'set']]
  971. set ai!
  972. call assert_equal([], g:options)
  973. call assert_equal(g:opt[0], g:opt[1])
  974. " 6a: Setting global autoindent option"
  975. let g:options = [['autoindent', 1, 1, 0, 0, 'global', 'set']]
  976. noa setlocal ai
  977. noa setglobal noai
  978. set ai!
  979. call assert_equal([], g:options)
  980. call assert_equal(g:opt[0], g:opt[1])
  981. " Should not print anything, use :noa
  982. " 7: don't trigger OptionSet"
  983. let g:options = [['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']]
  984. noa set nonu
  985. call assert_equal([['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']], g:options)
  986. call assert_equal(g:opt[0], g:opt[1])
  987. " 8: Setting several global list and number option"
  988. let g:options = [['list', 0, 0, 0, 1, 'global', 'set'], ['number', 0, 0, 0, 1, 'global', 'set']]
  989. set list nu
  990. call assert_equal([], g:options)
  991. call assert_equal(g:opt[0], g:opt[1])
  992. " 9: don't trigger OptionSet"
  993. let g:options = [['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid'], ['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']]
  994. noa set nolist nonu
  995. call assert_equal([['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid'], ['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']], g:options)
  996. call assert_equal(g:opt[0], g:opt[1])
  997. " 10: Setting global acd"
  998. let g:options = [['autochdir', 0, 0, '', 1, 'local', 'setlocal']]
  999. setlocal acd
  1000. call assert_equal([], g:options)
  1001. call assert_equal(g:opt[0], g:opt[1])
  1002. " 11: Setting global autoread (also sets local value)"
  1003. let g:options = [['autoread', 0, 0, 0, 1, 'global', 'set']]
  1004. set ar
  1005. call assert_equal([], g:options)
  1006. call assert_equal(g:opt[0], g:opt[1])
  1007. " 12: Setting local autoread"
  1008. let g:options = [['autoread', 1, 1, '', 1, 'local', 'setlocal']]
  1009. setlocal ar
  1010. call assert_equal([], g:options)
  1011. call assert_equal(g:opt[0], g:opt[1])
  1012. " 13: Setting global autoread"
  1013. let g:options = [['autoread', 1, '', 1, 0, 'global', 'setglobal']]
  1014. setglobal invar
  1015. call assert_equal([], g:options)
  1016. call assert_equal(g:opt[0], g:opt[1])
  1017. " 14: Setting option backspace through :let"
  1018. let g:options = [['backspace', 'indent,eol,start', 'indent,eol,start', 'indent,eol,start', '', 'global', 'set']]
  1019. let &bs = ''
  1020. call assert_equal([], g:options)
  1021. call assert_equal(g:opt[0], g:opt[1])
  1022. " 15: Setting option backspace through setbufvar()"
  1023. let g:options = [['backup', 0, 0, '', 1, 'local', 'setlocal']]
  1024. " try twice, first time, shouldn't trigger because option name is invalid,
  1025. " second time, it should trigger
  1026. let bnum = bufnr('%')
  1027. call assert_fails("call setbufvar(bnum, '&l:bk', 1)", 'E355:')
  1028. " should trigger, use correct option name
  1029. call setbufvar(bnum, '&backup', 1)
  1030. call assert_equal([], g:options)
  1031. call assert_equal(g:opt[0], g:opt[1])
  1032. " 16: Setting number option using setwinvar"
  1033. let g:options = [['number', 0, 0, '', 1, 'local', 'setlocal']]
  1034. call setwinvar(0, '&number', 1)
  1035. call assert_equal([], g:options)
  1036. call assert_equal(g:opt[0], g:opt[1])
  1037. " 17: Setting key option, shouldn't trigger"
  1038. let g:options = [['key', 'invalid', 'invalid1', 'invalid2', 'invalid3', 'invalid4', 'invalid5']]
  1039. setlocal key=blah
  1040. setlocal key=
  1041. call assert_equal([['key', 'invalid', 'invalid1', 'invalid2', 'invalid3', 'invalid4', 'invalid5']], g:options)
  1042. call assert_equal(g:opt[0], g:opt[1])
  1043. " 18a: Setting string global option"
  1044. let oldval = &backupext
  1045. let g:options = [['backupext', oldval, oldval, oldval, 'foo', 'global', 'set']]
  1046. set backupext=foo
  1047. call assert_equal([], g:options)
  1048. call assert_equal(g:opt[0], g:opt[1])
  1049. " 18b: Resetting string global option"
  1050. let g:options = [['backupext', 'foo', 'foo', 'foo', oldval, 'global', 'set']]
  1051. set backupext&
  1052. call assert_equal([], g:options)
  1053. call assert_equal(g:opt[0], g:opt[1])
  1054. " 18c: Setting global string global option"
  1055. let g:options = [['backupext', oldval, '', oldval, 'bar', 'global', 'setglobal']]
  1056. setglobal backupext=bar
  1057. call assert_equal([], g:options)
  1058. call assert_equal(g:opt[0], g:opt[1])
  1059. " 18d: Setting local string global option"
  1060. " As this is a global option this sets the global value even though
  1061. " :setlocal is used!
  1062. noa set backupext& " Reset global and local value (without triggering autocmd)
  1063. let g:options = [['backupext', oldval, oldval, '', 'baz', 'local', 'setlocal']]
  1064. setlocal backupext=baz
  1065. call assert_equal([], g:options)
  1066. call assert_equal(g:opt[0], g:opt[1])
  1067. " 18e: Setting again string global option"
  1068. noa setglobal backupext=ext_global " Reset global and local value (without triggering autocmd)
  1069. noa setlocal backupext=ext_local " Sets the global(!) value!
  1070. let g:options = [['backupext', 'ext_local', 'ext_local', 'ext_local', 'fuu', 'global', 'set']]
  1071. set backupext=fuu
  1072. call assert_equal([], g:options)
  1073. call assert_equal(g:opt[0], g:opt[1])
  1074. " 19a: Setting string global-local (to buffer) option"
  1075. let oldval = &tags
  1076. let g:options = [['tags', oldval, oldval, oldval, 'tagpath', 'global', 'set']]
  1077. set tags=tagpath
  1078. call assert_equal([], g:options)
  1079. call assert_equal(g:opt[0], g:opt[1])
  1080. " 19b: Resetting string global-local (to buffer) option"
  1081. let g:options = [['tags', 'tagpath', 'tagpath', 'tagpath', oldval, 'global', 'set']]
  1082. set tags&
  1083. call assert_equal([], g:options)
  1084. call assert_equal(g:opt[0], g:opt[1])
  1085. " 19c: Setting global string global-local (to buffer) option "
  1086. let g:options = [['tags', oldval, '', oldval, 'tagpath1', 'global', 'setglobal']]
  1087. setglobal tags=tagpath1
  1088. call assert_equal([], g:options)
  1089. call assert_equal(g:opt[0], g:opt[1])
  1090. " 19d: Setting local string global-local (to buffer) option"
  1091. let g:options = [['tags', 'tagpath1', 'tagpath1', '', 'tagpath2', 'local', 'setlocal']]
  1092. setlocal tags=tagpath2
  1093. call assert_equal([], g:options)
  1094. call assert_equal(g:opt[0], g:opt[1])
  1095. " 19e: Setting again string global-local (to buffer) option"
  1096. " Note: v:option_old is the old global value for global-local string options
  1097. " but the old local value for all other kinds of options.
  1098. noa setglobal tags=tag_global " Reset global and local value (without triggering autocmd)
  1099. noa setlocal tags=tag_local
  1100. let g:options = [['tags', 'tag_global', 'tag_local', 'tag_global', 'tagpath', 'global', 'set']]
  1101. set tags=tagpath
  1102. call assert_equal([], g:options)
  1103. call assert_equal(g:opt[0], g:opt[1])
  1104. " 19f: Setting string global-local (to buffer) option to an empty string"
  1105. " Note: v:option_old is the old global value for global-local string options
  1106. " but the old local value for all other kinds of options.
  1107. noa set tags=tag_global " Reset global and local value (without triggering autocmd)
  1108. noa setlocal tags= " empty string
  1109. let g:options = [['tags', 'tag_global', '', 'tag_global', 'tagpath', 'global', 'set']]
  1110. set tags=tagpath
  1111. call assert_equal([], g:options)
  1112. call assert_equal(g:opt[0], g:opt[1])
  1113. " 20a: Setting string local (to buffer) option"
  1114. let oldval = &spelllang
  1115. let g:options = [['spelllang', oldval, oldval, oldval, 'elvish,klingon', 'global', 'set']]
  1116. set spelllang=elvish,klingon
  1117. call assert_equal([], g:options)
  1118. call assert_equal(g:opt[0], g:opt[1])
  1119. " 20b: Resetting string local (to buffer) option"
  1120. let g:options = [['spelllang', 'elvish,klingon', 'elvish,klingon', 'elvish,klingon', oldval, 'global', 'set']]
  1121. set spelllang&
  1122. call assert_equal([], g:options)
  1123. call assert_equal(g:opt[0], g:opt[1])
  1124. " 20c: Setting global string local (to buffer) option"
  1125. let g:options = [['spelllang', oldval, '', oldval, 'elvish', 'global', 'setglobal']]
  1126. setglobal spelllang=elvish
  1127. call assert_equal([], g:options)
  1128. call assert_equal(g:opt[0], g:opt[1])
  1129. " 20d: Setting local string local (to buffer) option"
  1130. noa set spelllang& " Reset global and local value (without triggering autocmd)
  1131. let g:options = [['spelllang', oldval, oldval, '', 'klingon', 'local', 'setlocal']]
  1132. setlocal spelllang=klingon
  1133. call assert_equal([], g:options)
  1134. call assert_equal(g:opt[0], g:opt[1])
  1135. " 20e: Setting again string local (to buffer) option"
  1136. " Note: v:option_old is the old global value for global-local string options
  1137. " but the old local value for all other kinds of options.
  1138. noa setglobal spelllang=spellglobal " Reset global and local value (without triggering autocmd)
  1139. noa setlocal spelllang=spelllocal
  1140. let g:options = [['spelllang', 'spelllocal', 'spelllocal', 'spellglobal', 'foo', 'global', 'set']]
  1141. set spelllang=foo
  1142. call assert_equal([], g:options)
  1143. call assert_equal(g:opt[0], g:opt[1])
  1144. " 21a: Setting string global-local (to window) option"
  1145. let oldval = &statusline
  1146. let g:options = [['statusline', oldval, oldval, oldval, 'foo', 'global', 'set']]
  1147. set statusline=foo
  1148. call assert_equal([], g:options)
  1149. call assert_equal(g:opt[0], g:opt[1])
  1150. " 21b: Resetting string global-local (to window) option"
  1151. " Note: v:option_old is the old global value for global-local string options
  1152. " but the old local value for all other kinds of options.
  1153. let g:options = [['statusline', 'foo', 'foo', 'foo', oldval, 'global', 'set']]
  1154. set statusline&
  1155. call assert_equal([], g:options)
  1156. call assert_equal(g:opt[0], g:opt[1])
  1157. " 21c: Setting global string global-local (to window) option"
  1158. let g:options = [['statusline', oldval, '', oldval, 'bar', 'global', 'setglobal']]
  1159. setglobal statusline=bar
  1160. call assert_equal([], g:options)
  1161. call assert_equal(g:opt[0], g:opt[1])
  1162. " 21d: Setting local string global-local (to window) option"
  1163. noa set statusline& " Reset global and local value (without triggering autocmd)
  1164. let g:options = [['statusline', oldval, oldval, '', 'baz', 'local', 'setlocal']]
  1165. setlocal statusline=baz
  1166. call assert_equal([], g:options)
  1167. call assert_equal(g:opt[0], g:opt[1])
  1168. " 21e: Setting again string global-local (to window) option"
  1169. " Note: v:option_old is the old global value for global-local string options
  1170. " but the old local value for all other kinds of options.
  1171. noa setglobal statusline=bar " Reset global and local value (without triggering autocmd)
  1172. noa setlocal statusline=baz
  1173. let g:options = [['statusline', 'bar', 'baz', 'bar', 'foo', 'global', 'set']]
  1174. set statusline=foo
  1175. call assert_equal([], g:options)
  1176. call assert_equal(g:opt[0], g:opt[1])
  1177. " 22a: Setting string local (to window) option"
  1178. let oldval = &foldignore
  1179. let g:options = [['foldignore', oldval, oldval, oldval, 'fo', 'global', 'set']]
  1180. set foldignore=fo
  1181. call assert_equal([], g:options)
  1182. call assert_equal(g:opt[0], g:opt[1])
  1183. " 22b: Resetting string local (to window) option"
  1184. let g:options = [['foldignore', 'fo', 'fo', 'fo', oldval, 'global', 'set']]
  1185. set foldignore&
  1186. call assert_equal([], g:options)
  1187. call assert_equal(g:opt[0], g:opt[1])
  1188. " 22c: Setting global string local (to window) option"
  1189. let g:options = [['foldignore', oldval, '', oldval, 'bar', 'global', 'setglobal']]
  1190. setglobal foldignore=bar
  1191. call assert_equal([], g:options)
  1192. call assert_equal(g:opt[0], g:opt[1])
  1193. " 22d: Setting local string local (to window) option"
  1194. noa set foldignore& " Reset global and local value (without triggering autocmd)
  1195. let g:options = [['foldignore', oldval, oldval, '', 'baz', 'local', 'setlocal']]
  1196. setlocal foldignore=baz
  1197. call assert_equal([], g:options)
  1198. call assert_equal(g:opt[0], g:opt[1])
  1199. " 22e: Setting again string local (to window) option"
  1200. noa setglobal foldignore=glob " Reset global and local value (without triggering autocmd)
  1201. noa setlocal foldignore=loc
  1202. let g:options = [['foldignore', 'loc', 'loc', 'glob', 'fo', 'global', 'set']]
  1203. set foldignore=fo
  1204. call assert_equal([], g:options)
  1205. call assert_equal(g:opt[0], g:opt[1])
  1206. " 23a: Setting global number global option"
  1207. noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
  1208. noa setlocal cmdheight=1 " Sets the global(!) value!
  1209. let g:options = [['cmdheight', '1', '', '1', '2', 'global', 'setglobal']]
  1210. setglobal cmdheight=2
  1211. call assert_equal([], g:options)
  1212. call assert_equal(g:opt[0], g:opt[1])
  1213. " 23b: Setting local number global option"
  1214. noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
  1215. noa setlocal cmdheight=1 " Sets the global(!) value!
  1216. let g:options = [['cmdheight', '1', '1', '', '2', 'local', 'setlocal']]
  1217. setlocal cmdheight=2
  1218. call assert_equal([], g:options)
  1219. call assert_equal(g:opt[0], g:opt[1])
  1220. " 23c: Setting again number global option"
  1221. noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
  1222. noa setlocal cmdheight=1 " Sets the global(!) value!
  1223. let g:options = [['cmdheight', '1', '1', '1', '2', 'global', 'set']]
  1224. set cmdheight=2
  1225. call assert_equal([], g:options)
  1226. call assert_equal(g:opt[0], g:opt[1])
  1227. " 23d: Setting again number global option"
  1228. noa set cmdheight=8 " Reset global and local value (without triggering autocmd)
  1229. let g:options = [['cmdheight', '8', '8', '8', '2', 'global', 'set']]
  1230. set cmdheight=2
  1231. call assert_equal([], g:options)
  1232. call assert_equal(g:opt[0], g:opt[1])
  1233. " 24a: Setting global number global-local (to buffer) option"
  1234. noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd)
  1235. noa setlocal undolevels=1
  1236. let g:options = [['undolevels', '8', '', '8', '2', 'global', 'setglobal']]
  1237. setglobal undolevels=2
  1238. call assert_equal([], g:options)
  1239. call assert_equal(g:opt[0], g:opt[1])
  1240. " 24b: Setting local number global-local (to buffer) option"
  1241. noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd)
  1242. noa setlocal undolevels=1
  1243. let g:options = [['undolevels', '1', '1', '', '2', 'local', 'setlocal']]
  1244. setlocal undolevels=2
  1245. call assert_equal([], g:options)
  1246. call assert_equal(g:opt[0], g:opt[1])
  1247. " 24c: Setting again number global-local (to buffer) option"
  1248. noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd)
  1249. noa setlocal undolevels=1
  1250. let g:options = [['undolevels', '1', '1', '8', '2', 'global', 'set']]
  1251. set undolevels=2
  1252. call assert_equal([], g:options)
  1253. call assert_equal(g:opt[0], g:opt[1])
  1254. " 24d: Setting again global number global-local (to buffer) option"
  1255. noa set undolevels=8 " Reset global and local value (without triggering autocmd)
  1256. let g:options = [['undolevels', '8', '8', '8', '2', 'global', 'set']]
  1257. set undolevels=2
  1258. call assert_equal([], g:options)
  1259. call assert_equal(g:opt[0], g:opt[1])
  1260. " 25a: Setting global number local (to buffer) option"
  1261. noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd)
  1262. noa setlocal wrapmargin=1
  1263. let g:options = [['wrapmargin', '8', '', '8', '2', 'global', 'setglobal']]
  1264. setglobal wrapmargin=2
  1265. call assert_equal([], g:options)
  1266. call assert_equal(g:opt[0], g:opt[1])
  1267. " 25b: Setting local number local (to buffer) option"
  1268. noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd)
  1269. noa setlocal wrapmargin=1
  1270. let g:options = [['wrapmargin', '1', '1', '', '2', 'local', 'setlocal']]
  1271. setlocal wrapmargin=2
  1272. call assert_equal([], g:options)
  1273. call assert_equal(g:opt[0], g:opt[1])
  1274. " 25c: Setting again number local (to buffer) option"
  1275. noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd)
  1276. noa setlocal wrapmargin=1
  1277. let g:options = [['wrapmargin', '1', '1', '8', '2', 'global', 'set']]
  1278. set wrapmargin=2
  1279. call assert_equal([], g:options)
  1280. call assert_equal(g:opt[0], g:opt[1])
  1281. " 25d: Setting again global number local (to buffer) option"
  1282. noa set wrapmargin=8 " Reset global and local value (without triggering autocmd)
  1283. let g:options = [['wrapmargin', '8', '8', '8', '2', 'global', 'set']]
  1284. set wrapmargin=2
  1285. call assert_equal([], g:options)
  1286. call assert_equal(g:opt[0], g:opt[1])
  1287. " 26: Setting number global-local (to window) option.
  1288. " Such option does currently not exist.
  1289. " 27a: Setting global number local (to window) option"
  1290. noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd)
  1291. noa setlocal foldcolumn=1
  1292. let g:options = [['foldcolumn', '8', '', '8', '2', 'global', 'setglobal']]
  1293. setglobal foldcolumn=2
  1294. call assert_equal([], g:options)
  1295. call assert_equal(g:opt[0], g:opt[1])
  1296. " 27b: Setting local number local (to window) option"
  1297. noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd)
  1298. noa setlocal foldcolumn=1
  1299. let g:options = [['foldcolumn', '1', '1', '', '2', 'local', 'setlocal']]
  1300. setlocal foldcolumn=2
  1301. call assert_equal([], g:options)
  1302. call assert_equal(g:opt[0], g:opt[1])
  1303. " 27c: Setting again number local (to window) option"
  1304. noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd)
  1305. noa setlocal foldcolumn=1
  1306. let g:options = [['foldcolumn', '1', '1', '8', '2', 'global', 'set']]
  1307. set foldcolumn=2
  1308. call assert_equal([], g:options)
  1309. call assert_equal(g:opt[0], g:opt[1])
  1310. " 27d: Setting again global number local (to window) option"
  1311. noa set foldcolumn=8 " Reset global and local value (without triggering autocmd)
  1312. let g:options = [['foldcolumn', '8', '8', '8', '2', 'global', 'set']]
  1313. set foldcolumn=2
  1314. call assert_equal([], g:options)
  1315. call assert_equal(g:opt[0], g:opt[1])
  1316. " 28a: Setting global boolean global option"
  1317. noa setglobal nowrapscan " Reset global and local value (without triggering autocmd)
  1318. noa setlocal wrapscan " Sets the global(!) value!
  1319. let g:options = [['wrapscan', '1', '', '1', '0', 'global', 'setglobal']]
  1320. setglobal nowrapscan
  1321. call assert_equal([], g:options)
  1322. call assert_equal(g:opt[0], g:opt[1])
  1323. " 28b: Setting local boolean global option"
  1324. noa setglobal nowrapscan " Reset global and local value (without triggering autocmd)
  1325. noa setlocal wrapscan " Sets the global(!) value!
  1326. let g:options = [['wrapscan', '1', '1', '', '0', 'local', 'setlocal']]
  1327. setlocal nowrapscan
  1328. call assert_equal([], g:options)
  1329. call assert_equal(g:opt[0], g:opt[1])
  1330. " 28c: Setting again boolean global option"
  1331. noa setglobal nowrapscan " Reset global and local value (without triggering autocmd)
  1332. noa setlocal wrapscan " Sets the global(!) value!
  1333. let g:options = [['wrapscan', '1', '1', '1', '0', 'global', 'set']]
  1334. set nowrapscan
  1335. call assert_equal([], g:options)
  1336. call assert_equal(g:opt[0], g:opt[1])
  1337. " 28d: Setting again global boolean global option"
  1338. noa set nowrapscan " Reset global and local value (without triggering autocmd)
  1339. let g:options = [['wrapscan', '0', '0', '0', '1', 'global', 'set']]
  1340. set wrapscan
  1341. call assert_equal([], g:options)
  1342. call assert_equal(g:opt[0], g:opt[1])
  1343. " 29a: Setting global boolean global-local (to buffer) option"
  1344. noa setglobal noautoread " Reset global and local value (without triggering autocmd)
  1345. noa setlocal autoread
  1346. let g:options = [['autoread', '0', '', '0', '1', 'global', 'setglobal']]
  1347. setglobal autoread
  1348. call assert_equal([], g:options)
  1349. call assert_equal(g:opt[0], g:opt[1])
  1350. " 29b: Setting local boolean global-local (to buffer) option"
  1351. noa setglobal noautoread " Reset global and local value (without triggering autocmd)
  1352. noa setlocal autoread
  1353. let g:options = [['autoread', '1', '1', '', '0', 'local', 'setlocal']]
  1354. setlocal noautoread
  1355. call assert_equal([], g:options)
  1356. call assert_equal(g:opt[0], g:opt[1])
  1357. " 29c: Setting again boolean global-local (to buffer) option"
  1358. noa setglobal noautoread " Reset global and local value (without triggering autocmd)
  1359. noa setlocal autoread
  1360. let g:options = [['autoread', '1', '1', '0', '1', 'global', 'set']]
  1361. set autoread
  1362. call assert_equal([], g:options)
  1363. call assert_equal(g:opt[0], g:opt[1])
  1364. " 29d: Setting again global boolean global-local (to buffer) option"
  1365. noa set noautoread " Reset global and local value (without triggering autocmd)
  1366. let g:options = [['autoread', '0', '0', '0', '1', 'global', 'set']]
  1367. set autoread
  1368. call assert_equal([], g:options)
  1369. call assert_equal(g:opt[0], g:opt[1])
  1370. " 30a: Setting global boolean local (to buffer) option"
  1371. noa setglobal nocindent " Reset global and local value (without triggering autocmd)
  1372. noa setlocal cindent
  1373. let g:options = [['cindent', '0', '', '0', '1', 'global', 'setglobal']]
  1374. setglobal cindent
  1375. call assert_equal([], g:options)
  1376. call assert_equal(g:opt[0], g:opt[1])
  1377. " 30b: Setting local boolean local (to buffer) option"
  1378. noa setglobal nocindent " Reset global and local value (without triggering autocmd)
  1379. noa setlocal cindent
  1380. let g:options = [['cindent', '1', '1', '', '0', 'local', 'setlocal']]
  1381. setlocal nocindent
  1382. call assert_equal([], g:options)
  1383. call assert_equal(g:opt[0], g:opt[1])
  1384. " 30c: Setting again boolean local (to buffer) option"
  1385. noa setglobal nocindent " Reset global and local value (without triggering autocmd)
  1386. noa setlocal cindent
  1387. let g:options = [['cindent', '1', '1', '0', '1', 'global', 'set']]
  1388. set cindent
  1389. call assert_equal([], g:options)
  1390. call assert_equal(g:opt[0], g:opt[1])
  1391. " 30d: Setting again global boolean local (to buffer) option"
  1392. noa set nocindent " Reset global and local value (without triggering autocmd)
  1393. let g:options = [['cindent', '0', '0', '0', '1', 'global', 'set']]
  1394. set cindent
  1395. call assert_equal([], g:options)
  1396. call assert_equal(g:opt[0], g:opt[1])
  1397. " 31: Setting boolean global-local (to window) option
  1398. " Currently no such option exists.
  1399. " 32a: Setting global boolean local (to window) option"
  1400. noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd)
  1401. noa setlocal cursorcolumn
  1402. let g:options = [['cursorcolumn', '0', '', '0', '1', 'global', 'setglobal']]
  1403. setglobal cursorcolumn
  1404. call assert_equal([], g:options)
  1405. call assert_equal(g:opt[0], g:opt[1])
  1406. " 32b: Setting local boolean local (to window) option"
  1407. noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd)
  1408. noa setlocal cursorcolumn
  1409. let g:options = [['cursorcolumn', '1', '1', '', '0', 'local', 'setlocal']]
  1410. setlocal nocursorcolumn
  1411. call assert_equal([], g:options)
  1412. call assert_equal(g:opt[0], g:opt[1])
  1413. " 32c: Setting again boolean local (to window) option"
  1414. noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd)
  1415. noa setlocal cursorcolumn
  1416. let g:options = [['cursorcolumn', '1', '1', '0', '1', 'global', 'set']]
  1417. set cursorcolumn
  1418. call assert_equal([], g:options)
  1419. call assert_equal(g:opt[0], g:opt[1])
  1420. " 32d: Setting again global boolean local (to window) option"
  1421. noa set nocursorcolumn " Reset global and local value (without triggering autocmd)
  1422. let g:options = [['cursorcolumn', '0', '0', '0', '1', 'global', 'set']]
  1423. set cursorcolumn
  1424. call assert_equal([], g:options)
  1425. call assert_equal(g:opt[0], g:opt[1])
  1426. " 33: Test autocommands when an option value is converted internally.
  1427. noa set backspace=1 " Reset global and local value (without triggering autocmd)
  1428. let g:options = [['backspace', 'indent,eol', 'indent,eol', 'indent,eol', '2', 'global', 'set']]
  1429. set backspace=2
  1430. call assert_equal([], g:options)
  1431. call assert_equal(g:opt[0], g:opt[1])
  1432. " Cleanup
  1433. au! OptionSet
  1434. " set tags&
  1435. for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp', 'backupext', 'tags', 'spelllang', 'statusline', 'foldignore', 'cmdheight', 'undolevels', 'wrapmargin', 'foldcolumn', 'wrapscan', 'autoread', 'cindent', 'cursorcolumn']
  1436. exe printf(":set %s&vim", opt)
  1437. endfor
  1438. call test_override('starting', 0)
  1439. delfunc! AutoCommandOptionSet
  1440. endfunc
  1441. func Test_OptionSet_diffmode()
  1442. CheckFunction test_override
  1443. call test_override('starting', 1)
  1444. " 18: Changing an option when entering diff mode
  1445. new
  1446. au OptionSet diff :let &l:cul = v:option_new
  1447. call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
  1448. call assert_equal(0, &l:cul)
  1449. diffthis
  1450. call assert_equal(1, &l:cul)
  1451. vnew
  1452. call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
  1453. call assert_equal(0, &l:cul)
  1454. diffthis
  1455. call assert_equal(1, &l:cul)
  1456. diffoff
  1457. call assert_equal(0, &l:cul)
  1458. call assert_equal(1, getwinvar(2, '&l:cul'))
  1459. bw!
  1460. call assert_equal(1, &l:cul)
  1461. diffoff!
  1462. call assert_equal(0, &l:cul)
  1463. call assert_equal(0, getwinvar(1, '&l:cul'))
  1464. bw!
  1465. " Cleanup
  1466. au! OptionSet
  1467. call test_override('starting', 0)
  1468. endfunc
  1469. func Test_OptionSet_diffmode_close()
  1470. CheckFunction test_override
  1471. call test_override('starting', 1)
  1472. " 19: Try to close the current window when entering diff mode
  1473. " should not segfault
  1474. new
  1475. au OptionSet diff close
  1476. call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
  1477. call assert_fails(':diffthis', 'E788')
  1478. call assert_equal(1, &diff)
  1479. vnew
  1480. call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
  1481. call assert_fails(':diffthis', 'E788')
  1482. call assert_equal(1, &diff)
  1483. set diffopt-=closeoff
  1484. bw!
  1485. call assert_fails(':diffoff!', 'E788')
  1486. bw!
  1487. " Cleanup
  1488. au! OptionSet
  1489. call test_override('starting', 0)
  1490. "delfunc! AutoCommandOptionSet
  1491. endfunc
  1492. " Test for Bufleave autocommand that deletes the buffer we are about to edit.
  1493. func Test_BufleaveWithDelete()
  1494. new | edit XbufLeave1
  1495. augroup test_bufleavewithdelete
  1496. autocmd!
  1497. autocmd BufLeave XbufLeave1 bwipe XbufLeave2
  1498. augroup END
  1499. call assert_fails('edit XbufLeave2', 'E143:')
  1500. call assert_equal('XbufLeave1', bufname('%'))
  1501. autocmd! test_bufleavewithdelete BufLeave XbufLeave1
  1502. augroup! test_bufleavewithdelete
  1503. new
  1504. bwipe! XbufLeave1
  1505. endfunc
  1506. " Test for autocommand that changes the buffer list, when doing ":ball".
  1507. func Test_Acmd_BufAll()
  1508. enew!
  1509. %bwipe!
  1510. call writefile(['Test file Xxx1'], 'Xxx1', 'D')
  1511. call writefile(['Test file Xxx2'], 'Xxx2', 'D')
  1512. call writefile(['Test file Xxx3'], 'Xxx3', 'D')
  1513. " Add three files to the buffer list
  1514. split Xxx1
  1515. close
  1516. split Xxx2
  1517. close
  1518. split Xxx3
  1519. close
  1520. " Wipe the buffer when the buffer is opened
  1521. au BufReadPost Xxx2 bwipe
  1522. call append(0, 'Test file Xxx4')
  1523. ball
  1524. call assert_equal(2, winnr('$'))
  1525. call assert_equal('Xxx1', bufname(winbufnr(winnr('$'))))
  1526. wincmd t
  1527. au! BufReadPost
  1528. %bwipe!
  1529. enew! | only
  1530. endfunc
  1531. " Test for autocommand that changes current buffer on BufEnter event.
  1532. " Check if modelines are interpreted for the correct buffer.
  1533. func Test_Acmd_BufEnter()
  1534. %bwipe!
  1535. call writefile(['start of test file Xxx1',
  1536. \ "\<Tab>this is a test",
  1537. \ 'end of test file Xxx1'], 'Xxx1', 'D')
  1538. call writefile(['start of test file Xxx2',
  1539. \ 'vim: set noai :',
  1540. \ "\<Tab>this is a test",
  1541. \ 'end of test file Xxx2'], 'Xxx2', 'D')
  1542. au BufEnter Xxx2 brew
  1543. set ai modeline modelines=3
  1544. edit Xxx1
  1545. " edit Xxx2, autocmd will do :brew
  1546. edit Xxx2
  1547. exe "normal G?this is a\<CR>"
  1548. " Append text with autoindent to this file
  1549. normal othis should be auto-indented
  1550. call assert_equal("\<Tab>this should be auto-indented", getline('.'))
  1551. call assert_equal(3, line('.'))
  1552. " Remove autocmd and edit Xxx2 again
  1553. au! BufEnter Xxx2
  1554. buf! Xxx2
  1555. exe "normal G?this is a\<CR>"
  1556. " append text without autoindent to Xxx
  1557. normal othis should be in column 1
  1558. call assert_equal("this should be in column 1", getline('.'))
  1559. call assert_equal(4, line('.'))
  1560. %bwipe!
  1561. set ai&vim modeline&vim modelines&vim
  1562. endfunc
  1563. " Test for issue #57
  1564. " do not move cursor on <c-o> when autoindent is set
  1565. func Test_ai_CTRL_O()
  1566. enew!
  1567. set ai
  1568. let save_fo = &fo
  1569. set fo+=r
  1570. exe "normal o# abcdef\<Esc>2hi\<CR>\<C-O>d0\<Esc>"
  1571. exe "normal o# abcdef\<Esc>2hi\<C-O>d0\<Esc>"
  1572. call assert_equal(['# abc', 'def', 'def'], getline(2, 4))
  1573. set ai&vim
  1574. let &fo = save_fo
  1575. enew!
  1576. endfunc
  1577. " Test for autocommand that deletes the current buffer on BufLeave event.
  1578. " Also test deleting the last buffer, should give a new, empty buffer.
  1579. func Test_BufLeave_Wipe()
  1580. %bwipe!
  1581. let content = ['start of test file Xxx',
  1582. \ 'this is a test',
  1583. \ 'end of test file Xxx']
  1584. call writefile(content, 'Xxx1', 'D')
  1585. call writefile(content, 'Xxx2', 'D')
  1586. au BufLeave Xxx2 bwipe
  1587. edit Xxx1
  1588. split Xxx2
  1589. " delete buffer Xxx2, we should be back to Xxx1
  1590. bwipe
  1591. call assert_equal('Xxx1', bufname('%'))
  1592. call assert_equal(1, winnr('$'))
  1593. " Create an alternate buffer
  1594. %write! test.out
  1595. call assert_equal('test.out', bufname('#'))
  1596. " delete alternate buffer
  1597. bwipe test.out
  1598. call assert_equal('Xxx1', bufname('%'))
  1599. call assert_equal('', bufname('#'))
  1600. au BufLeave Xxx1 bwipe
  1601. " delete current buffer, get an empty one
  1602. bwipe!
  1603. call assert_equal(1, line('$'))
  1604. call assert_equal('', bufname('%'))
  1605. let g:bufinfo = getbufinfo()
  1606. call assert_equal(1, len(g:bufinfo))
  1607. call delete('test.out')
  1608. %bwipe
  1609. au! BufLeave
  1610. " check that bufinfo doesn't contain a pointer to freed memory
  1611. call test_garbagecollect_now()
  1612. endfunc
  1613. func Test_QuitPre()
  1614. edit Xfoo
  1615. let winid = win_getid(winnr())
  1616. split Xbar
  1617. au! QuitPre * let g:afile = expand('<afile>')
  1618. " Close the other window, <afile> should be correct.
  1619. exe win_id2win(winid) . 'q'
  1620. call assert_equal('Xfoo', g:afile)
  1621. unlet g:afile
  1622. bwipe Xfoo
  1623. bwipe Xbar
  1624. endfunc
  1625. func Test_Cmdline()
  1626. au! CmdlineChanged : let g:text = getcmdline()
  1627. let g:text = 0
  1628. call feedkeys(":echom 'hello'\<CR>", 'xt')
  1629. call assert_equal("echom 'hello'", g:text)
  1630. au! CmdlineChanged
  1631. au! CmdlineChanged : let g:entered = expand('<afile>')
  1632. let g:entered = 0
  1633. call feedkeys(":echom 'hello'\<CR>", 'xt')
  1634. call assert_equal(':', g:entered)
  1635. au! CmdlineChanged
  1636. autocmd CmdlineChanged : let g:log += [getcmdline()]
  1637. let g:log = []
  1638. cnoremap <F1> <Cmd>call setcmdline('ls')<CR>
  1639. call feedkeys(":\<F1>", 'xt')
  1640. call assert_equal(['ls'], g:log)
  1641. cunmap <F1>
  1642. let g:log = []
  1643. call feedkeys(":sign \<Tab>\<Tab>\<C-N>\<C-P>\<S-Tab>\<S-Tab>\<Esc>", 'xt')
  1644. call assert_equal([
  1645. \ 's',
  1646. \ 'si',
  1647. \ 'sig',
  1648. \ 'sign',
  1649. \ 'sign ',
  1650. \ 'sign define',
  1651. \ 'sign jump',
  1652. \ 'sign list',
  1653. \ 'sign jump',
  1654. \ 'sign define',
  1655. \ 'sign ',
  1656. \ ], g:log)
  1657. let g:log = []
  1658. set wildmenu wildoptions+=pum
  1659. call feedkeys(":sign \<S-Tab>\<PageUp>\<kPageUp>\<kPageDown>\<PageDown>\<Esc>", 'xt')
  1660. call assert_equal([
  1661. \ 's',
  1662. \ 'si',
  1663. \ 'sig',
  1664. \ 'sign',
  1665. \ 'sign ',
  1666. \ 'sign unplace',
  1667. \ 'sign jump',
  1668. \ 'sign define',
  1669. \ 'sign undefine',
  1670. \ 'sign unplace',
  1671. \ ], g:log)
  1672. set wildmenu& wildoptions&
  1673. let g:log = []
  1674. let @r = 'abc'
  1675. call feedkeys(":0\<C-R>r1\<C-R>\<C-O>r2\<C-R>\<C-R>r3\<Esc>", 'xt')
  1676. call assert_equal([
  1677. \ '0',
  1678. \ '0a',
  1679. \ '0ab',
  1680. \ '0abc',
  1681. \ '0abc1',
  1682. \ '0abc1abc',
  1683. \ '0abc1abc2',
  1684. \ '0abc1abc2abc',
  1685. \ '0abc1abc2abc3',
  1686. \ ], g:log)
  1687. unlet g:log
  1688. au! CmdlineChanged
  1689. au! CmdlineEnter : let g:entered = expand('<afile>')
  1690. au! CmdlineLeave : let g:left = expand('<afile>')
  1691. let g:entered = 0
  1692. let g:left = 0
  1693. call feedkeys(":echo 'hello'\<CR>", 'xt')
  1694. call assert_equal(':', g:entered)
  1695. call assert_equal(':', g:left)
  1696. au! CmdlineEnter
  1697. au! CmdlineLeave
  1698. let save_shellslash = &shellslash
  1699. " Nvim doesn't allow setting value of a hidden option to non-default value
  1700. if exists('+shellslash')
  1701. set noshellslash
  1702. endif
  1703. au! CmdlineEnter / let g:entered = expand('<afile>')
  1704. au! CmdlineLeave / let g:left = expand('<afile>')
  1705. let g:entered = 0
  1706. let g:left = 0
  1707. new
  1708. call setline(1, 'hello')
  1709. call feedkeys("/hello\<CR>", 'xt')
  1710. call assert_equal('/', g:entered)
  1711. call assert_equal('/', g:left)
  1712. bwipe!
  1713. au! CmdlineEnter
  1714. au! CmdlineLeave
  1715. let &shellslash = save_shellslash
  1716. au! CursorMovedC : let g:pos += [getcmdpos()]
  1717. let g:pos = []
  1718. call feedkeys(":foo bar baz\<C-W>\<C-W>\<C-W>\<Esc>", 'xt')
  1719. call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 5, 1], g:pos)
  1720. let g:pos = []
  1721. call feedkeys(":hello\<C-B>\<Esc>", 'xt')
  1722. call assert_equal([2, 3, 4, 5, 6, 1], g:pos)
  1723. let g:pos = []
  1724. call feedkeys(":hello\<C-U>\<Esc>", 'xt')
  1725. call assert_equal([2, 3, 4, 5, 6, 1], g:pos)
  1726. let g:pos = []
  1727. call feedkeys(":hello\<Left>\<C-R>=''\<CR>\<Left>\<Right>\<Esc>", 'xt')
  1728. call assert_equal([2, 3, 4, 5, 6, 5, 4, 5], g:pos)
  1729. let g:pos = []
  1730. call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Esc>", 'xt')
  1731. call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3], g:pos)
  1732. let g:pos = []
  1733. call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Left>\<Esc>", 'xt')
  1734. call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3, 2], g:pos)
  1735. au! CursorMovedC
  1736. " setcmdpos() is no-op inside an autocommand
  1737. au! CursorMovedC : let g:pos += [getcmdpos()] | call setcmdpos(1)
  1738. let g:pos = []
  1739. call feedkeys(":hello\<Left>\<Left>\<Esc>", 'xt')
  1740. call assert_equal([2, 3, 4, 5, 6, 5, 4], g:pos)
  1741. au! CursorMovedC
  1742. unlet g:entered
  1743. unlet g:left
  1744. unlet g:pos
  1745. endfunc
  1746. " Test for BufWritePre autocommand that deletes or unloads the buffer.
  1747. func Test_BufWritePre()
  1748. %bwipe
  1749. au BufWritePre Xxx1 bunload
  1750. au BufWritePre Xxx2 bwipe
  1751. call writefile(['start of Xxx1', 'test', 'end of Xxx1'], 'Xxx1', 'D')
  1752. call writefile(['start of Xxx2', 'test', 'end of Xxx2'], 'Xxx2', 'D')
  1753. edit Xtest
  1754. e! Xxx2
  1755. bdel Xtest
  1756. e Xxx1
  1757. " write it, will unload it and give an error msg
  1758. call assert_fails('w', 'E203:')
  1759. call assert_equal('Xxx2', bufname('%'))
  1760. edit Xtest
  1761. e! Xxx2
  1762. bwipe Xtest
  1763. " write it, will delete the buffer and give an error msg
  1764. call assert_fails('w', 'E203:')
  1765. call assert_equal('Xxx1', bufname('%'))
  1766. au! BufWritePre
  1767. endfunc
  1768. " Test for BufUnload autocommand that unloads all the other buffers
  1769. func Test_bufunload_all()
  1770. let g:test_is_flaky = 1
  1771. call writefile(['Test file Xxx1'], 'Xxx1', 'D')
  1772. call writefile(['Test file Xxx2'], 'Xxx2', 'D')
  1773. let content =<< trim [CODE]
  1774. func UnloadAllBufs()
  1775. let i = 1
  1776. while i <= bufnr('$')
  1777. if i != bufnr('%') && bufloaded(i)
  1778. exe i . 'bunload'
  1779. endif
  1780. let i += 1
  1781. endwhile
  1782. endfunc
  1783. au BufUnload * call UnloadAllBufs()
  1784. au VimLeave * call writefile(['Test Finished'], 'Xout')
  1785. set nohidden
  1786. edit Xxx1
  1787. split Xxx2
  1788. q
  1789. [CODE]
  1790. call writefile(content, 'Xbunloadtest', 'D')
  1791. call delete('Xout')
  1792. call system(GetVimCommandClean() .. ' -N --headless -S Xbunloadtest')
  1793. call assert_true(filereadable('Xout'))
  1794. call delete('Xout')
  1795. endfunc
  1796. " Some tests for buffer-local autocommands
  1797. func Test_buflocal_autocmd()
  1798. let g:bname = ''
  1799. edit xx
  1800. au BufLeave <buffer> let g:bname = expand("%")
  1801. " here, autocommand for xx should trigger.
  1802. " but autocommand shall not apply to buffer named <buffer>.
  1803. edit somefile
  1804. call assert_equal('xx', g:bname)
  1805. let g:bname = ''
  1806. " here, autocommand shall be auto-deleted
  1807. bwipe xx
  1808. " autocmd should not trigger
  1809. edit xx
  1810. call assert_equal('', g:bname)
  1811. " autocmd should not trigger
  1812. edit somefile
  1813. call assert_equal('', g:bname)
  1814. enew
  1815. unlet g:bname
  1816. endfunc
  1817. " Test for "*Cmd" autocommands
  1818. func Test_Cmd_Autocmds()
  1819. call writefile(['start of Xxx', "\tabc2", 'end of Xxx'], 'Xxx', 'D')
  1820. enew!
  1821. au BufReadCmd XtestA 0r Xxx|$del
  1822. edit XtestA " will read text of Xxd instead
  1823. call assert_equal('start of Xxx', getline(1))
  1824. au BufWriteCmd XtestA call append(line("$"), "write")
  1825. write " will append a line to the file
  1826. call assert_equal('write', getline('$'))
  1827. call assert_fails('read XtestA', 'E484') " should not read anything
  1828. call assert_equal('write', getline(4))
  1829. " now we have:
  1830. " 1 start of Xxx
  1831. " 2 abc2
  1832. " 3 end of Xxx
  1833. " 4 write
  1834. au FileReadCmd XtestB '[r Xxx
  1835. 2r XtestB " will read Xxx below line 2 instead
  1836. call assert_equal('start of Xxx', getline(3))
  1837. " now we have:
  1838. " 1 start of Xxx
  1839. " 2 abc2
  1840. " 3 start of Xxx
  1841. " 4 abc2
  1842. " 5 end of Xxx
  1843. " 6 end of Xxx
  1844. " 7 write
  1845. au FileWriteCmd XtestC '[,']copy $
  1846. normal 4GA1
  1847. 4,5w XtestC " will copy lines 4 and 5 to the end
  1848. call assert_equal("\tabc21", getline(8))
  1849. call assert_fails('r XtestC', 'E484') " should not read anything
  1850. call assert_equal("end of Xxx", getline(9))
  1851. " now we have:
  1852. " 1 start of Xxx
  1853. " 2 abc2
  1854. " 3 start of Xxx
  1855. " 4 abc21
  1856. " 5 end of Xxx
  1857. " 6 end of Xxx
  1858. " 7 write
  1859. " 8 abc21
  1860. " 9 end of Xxx
  1861. let g:lines = []
  1862. au FileAppendCmd XtestD call extend(g:lines, getline(line("'["), line("']")))
  1863. w >>XtestD " will add lines to 'lines'
  1864. call assert_equal(9, len(g:lines))
  1865. call assert_fails('$r XtestD', 'E484') " should not read anything
  1866. call assert_equal(9, line('$'))
  1867. call assert_equal('end of Xxx', getline('$'))
  1868. au BufReadCmd XtestE 0r Xxx|$del
  1869. sp XtestE " split window with test.out
  1870. call assert_equal('end of Xxx', getline(3))
  1871. let g:lines = []
  1872. exe "normal 2Goasdf\<Esc>\<C-W>\<C-W>"
  1873. au BufWriteCmd XtestE call extend(g:lines, getline(0, '$'))
  1874. wall " will write other window to 'lines'
  1875. call assert_equal(4, len(g:lines), g:lines)
  1876. call assert_equal("asdf", g:lines[2])
  1877. au! BufReadCmd
  1878. au! BufWriteCmd
  1879. au! FileReadCmd
  1880. au! FileWriteCmd
  1881. au! FileAppendCmd
  1882. %bwipe!
  1883. enew!
  1884. endfunc
  1885. func s:ReadFile()
  1886. setl noswapfile nomodified
  1887. let filename = resolve(expand("<afile>:p"))
  1888. execute 'read' fnameescape(filename)
  1889. 1d_
  1890. exe 'file' fnameescape(filename)
  1891. setl buftype=acwrite
  1892. endfunc
  1893. func s:WriteFile()
  1894. let filename = resolve(expand("<afile>:p"))
  1895. setl buftype=
  1896. noautocmd execute 'write' fnameescape(filename)
  1897. setl buftype=acwrite
  1898. setl nomodified
  1899. endfunc
  1900. func Test_BufReadCmd()
  1901. autocmd BufReadCmd *.test call s:ReadFile()
  1902. autocmd BufWriteCmd *.test call s:WriteFile()
  1903. call writefile(['one', 'two', 'three'], 'Xcmd.test', 'D')
  1904. edit Xcmd.test
  1905. call assert_match('Xcmd.test" line 1 of 3', execute('file'))
  1906. normal! Gofour
  1907. write
  1908. call assert_equal(['one', 'two', 'three', 'four'], readfile('Xcmd.test'))
  1909. bwipe!
  1910. au! BufReadCmd
  1911. au! BufWriteCmd
  1912. endfunc
  1913. func Test_BufWriteCmd()
  1914. autocmd BufWriteCmd Xbufwritecmd let g:written = 1
  1915. new
  1916. file Xbufwritecmd
  1917. set buftype=acwrite
  1918. call mkdir('Xbufwritecmd', 'D')
  1919. write
  1920. " BufWriteCmd should be triggered even if a directory has the same name
  1921. call assert_equal(1, g:written)
  1922. unlet g:written
  1923. au! BufWriteCmd
  1924. bwipe!
  1925. endfunc
  1926. func SetChangeMarks(start, end)
  1927. exe a:start .. 'mark ['
  1928. exe a:end .. 'mark ]'
  1929. endfunc
  1930. " Verify the effects of autocmds on '[ and ']
  1931. func Test_change_mark_in_autocmds()
  1932. edit! Xtest
  1933. call feedkeys("ia\<CR>b\<CR>c\<CR>d\<C-g>u\<Esc>", 'xtn')
  1934. call SetChangeMarks(2, 3)
  1935. write
  1936. call assert_equal([1, 4], [line("'["), line("']")])
  1937. call SetChangeMarks(2, 3)
  1938. au BufWritePre * call assert_equal([1, 4], [line("'["), line("']")])
  1939. write
  1940. au! BufWritePre
  1941. if has('unix')
  1942. write XtestFilter
  1943. write >> XtestFilter
  1944. call SetChangeMarks(2, 3)
  1945. " Marks are set to the entire range of the write
  1946. au FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")])
  1947. " '[ is adjusted to just before the line that will receive the filtered
  1948. " data
  1949. au FilterReadPre * call assert_equal([4, 4], [line("'["), line("']")])
  1950. " The filtered data is read into the buffer, and the source lines are
  1951. " still present, so the range is after the source lines
  1952. au FilterReadPost * call assert_equal([5, 12], [line("'["), line("']")])
  1953. %!cat XtestFilter
  1954. " After the filtered data is read, the original lines are deleted
  1955. call assert_equal([1, 8], [line("'["), line("']")])
  1956. au! FilterWritePre,FilterReadPre,FilterReadPost
  1957. undo
  1958. call SetChangeMarks(1, 4)
  1959. au FilterWritePre * call assert_equal([2, 3], [line("'["), line("']")])
  1960. au FilterReadPre * call assert_equal([3, 3], [line("'["), line("']")])
  1961. au FilterReadPost * call assert_equal([4, 11], [line("'["), line("']")])
  1962. 2,3!cat XtestFilter
  1963. call assert_equal([2, 9], [line("'["), line("']")])
  1964. au! FilterWritePre,FilterReadPre,FilterReadPost
  1965. undo
  1966. call delete('XtestFilter')
  1967. endif
  1968. call SetChangeMarks(1, 4)
  1969. au FileWritePre * call assert_equal([2, 3], [line("'["), line("']")])
  1970. 2,3write Xtest2
  1971. au! FileWritePre
  1972. call SetChangeMarks(2, 3)
  1973. au FileAppendPre * call assert_equal([1, 4], [line("'["), line("']")])
  1974. write >> Xtest2
  1975. au! FileAppendPre
  1976. call SetChangeMarks(1, 4)
  1977. au FileAppendPre * call assert_equal([2, 3], [line("'["), line("']")])
  1978. 2,3write >> Xtest2
  1979. au! FileAppendPre
  1980. call SetChangeMarks(1, 1)
  1981. au FileReadPre * call assert_equal([3, 1], [line("'["), line("']")])
  1982. au FileReadPost * call assert_equal([4, 11], [line("'["), line("']")])
  1983. 3read Xtest2
  1984. au! FileReadPre,FileReadPost
  1985. undo
  1986. call SetChangeMarks(4, 4)
  1987. " When the line is 0, it's adjusted to 1
  1988. au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
  1989. au FileReadPost * call assert_equal([1, 8], [line("'["), line("']")])
  1990. 0read Xtest2
  1991. au! FileReadPre,FileReadPost
  1992. undo
  1993. call SetChangeMarks(4, 4)
  1994. " When the line is 0, it's adjusted to 1
  1995. au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
  1996. au FileReadPost * call assert_equal([2, 9], [line("'["), line("']")])
  1997. 1read Xtest2
  1998. au! FileReadPre,FileReadPost
  1999. undo
  2000. bwipe!
  2001. call delete('Xtest')
  2002. call delete('Xtest2')
  2003. endfunc
  2004. func Test_Filter_noshelltemp()
  2005. CheckExecutable cat
  2006. enew!
  2007. call setline(1, ['a', 'b', 'c', 'd'])
  2008. let shelltemp = &shelltemp
  2009. set shelltemp
  2010. let g:filter_au = 0
  2011. au FilterWritePre * let g:filter_au += 1
  2012. au FilterReadPre * let g:filter_au += 1
  2013. au FilterReadPost * let g:filter_au += 1
  2014. %!cat
  2015. call assert_equal(3, g:filter_au)
  2016. if has('filterpipe')
  2017. set noshelltemp
  2018. let g:filter_au = 0
  2019. au FilterWritePre * let g:filter_au += 1
  2020. au FilterReadPre * let g:filter_au += 1
  2021. au FilterReadPost * let g:filter_au += 1
  2022. %!cat
  2023. call assert_equal(0, g:filter_au)
  2024. endif
  2025. au! FilterWritePre,FilterReadPre,FilterReadPost
  2026. let &shelltemp = shelltemp
  2027. bwipe!
  2028. endfunc
  2029. func Test_TextYankPost()
  2030. enew!
  2031. call setline(1, ['foo'])
  2032. let g:event = []
  2033. au TextYankPost * let g:event = copy(v:event)
  2034. call assert_equal({}, v:event)
  2035. call assert_fails('let v:event = {}', 'E46:')
  2036. call assert_fails('let v:event.mykey = 0', 'E742:')
  2037. norm "ayiw
  2038. call assert_equal(
  2039. \{'regcontents': ['foo'], 'inclusive': v:true, 'regname': 'a', 'operator': 'y', 'visual': v:false, 'regtype': 'v'},
  2040. \g:event)
  2041. norm y_
  2042. call assert_equal(
  2043. \{'regcontents': ['foo'], 'inclusive': v:false, 'regname': '', 'operator': 'y', 'visual': v:false, 'regtype': 'V'},
  2044. \g:event)
  2045. norm Vy
  2046. call assert_equal(
  2047. \{'regcontents': ['foo'], 'inclusive': v:true, 'regname': '', 'operator': 'y', 'visual': v:true, 'regtype': 'V'},
  2048. \g:event)
  2049. call feedkeys("\<C-V>y", 'x')
  2050. call assert_equal(
  2051. \{'regcontents': ['f'], 'inclusive': v:true, 'regname': '', 'operator': 'y', 'visual': v:true, 'regtype': "\x161"},
  2052. \g:event)
  2053. norm "xciwbar
  2054. call assert_equal(
  2055. \{'regcontents': ['foo'], 'inclusive': v:true, 'regname': 'x', 'operator': 'c', 'visual': v:false, 'regtype': 'v'},
  2056. \g:event)
  2057. norm "bdiw
  2058. call assert_equal(
  2059. \{'regcontents': ['bar'], 'inclusive': v:true, 'regname': 'b', 'operator': 'd', 'visual': v:false, 'regtype': 'v'},
  2060. \g:event)
  2061. call assert_equal({}, v:event)
  2062. au! TextYankPost
  2063. unlet g:event
  2064. bwipe!
  2065. endfunc
  2066. func Test_autocommand_all_events()
  2067. call assert_fails('au * * bwipe', 'E1155:')
  2068. call assert_fails('au * x bwipe', 'E1155:')
  2069. call assert_fails('au! * x bwipe', 'E1155:')
  2070. endfunc
  2071. func Test_autocmd_user()
  2072. au User MyEvent let s:res = [expand("<afile>"), expand("<amatch>")]
  2073. doautocmd User MyEvent
  2074. call assert_equal(['MyEvent', 'MyEvent'], s:res)
  2075. au! User
  2076. unlet s:res
  2077. endfunc
  2078. function s:Before_test_dirchanged()
  2079. augroup test_dirchanged
  2080. autocmd!
  2081. augroup END
  2082. let s:li = []
  2083. let s:dir_this = getcwd()
  2084. let s:dir_foo = s:dir_this . '/Xfoo'
  2085. call mkdir(s:dir_foo)
  2086. let s:dir_bar = s:dir_this . '/Xbar'
  2087. call mkdir(s:dir_bar)
  2088. endfunc
  2089. function s:After_test_dirchanged()
  2090. call chdir(s:dir_this)
  2091. call delete(s:dir_foo, 'd')
  2092. call delete(s:dir_bar, 'd')
  2093. augroup test_dirchanged
  2094. autocmd!
  2095. augroup END
  2096. endfunc
  2097. function Test_dirchanged_global()
  2098. call s:Before_test_dirchanged()
  2099. autocmd test_dirchanged DirChangedPre global call add(s:li, expand("<amatch>") .. " pre cd " .. v:event.directory)
  2100. autocmd test_dirchanged DirChanged global call add(s:li, "cd:")
  2101. autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>"))
  2102. call chdir(s:dir_foo)
  2103. let expected = ["global pre cd " .. s:dir_foo, "cd:", s:dir_foo]
  2104. call assert_equal(expected, s:li)
  2105. call chdir(s:dir_foo)
  2106. call assert_equal(expected, s:li)
  2107. exe 'lcd ' .. fnameescape(s:dir_bar)
  2108. call assert_equal(expected, s:li)
  2109. exe 'cd ' .. s:dir_foo
  2110. exe 'cd ' .. s:dir_bar
  2111. autocmd! test_dirchanged DirChanged global let g:result = expand("<afile>")
  2112. cd -
  2113. call assert_equal(s:dir_foo, substitute(g:result, '\\', '/', 'g'))
  2114. call s:After_test_dirchanged()
  2115. endfunc
  2116. function Test_dirchanged_local()
  2117. call s:Before_test_dirchanged()
  2118. autocmd test_dirchanged DirChanged window call add(s:li, "lcd:")
  2119. autocmd test_dirchanged DirChanged window call add(s:li, expand("<afile>"))
  2120. call chdir(s:dir_foo)
  2121. call assert_equal([], s:li)
  2122. exe 'lcd ' .. fnameescape(s:dir_bar)
  2123. call assert_equal(["lcd:", s:dir_bar], s:li)
  2124. exe 'lcd ' .. fnameescape(s:dir_bar)
  2125. call assert_equal(["lcd:", s:dir_bar], s:li)
  2126. call s:After_test_dirchanged()
  2127. endfunc
  2128. function Test_dirchanged_auto()
  2129. CheckFunction test_autochdir
  2130. CheckOption autochdir
  2131. call s:Before_test_dirchanged()
  2132. call test_autochdir()
  2133. autocmd test_dirchanged DirChangedPre auto call add(s:li, "pre cd " .. v:event.directory)
  2134. autocmd test_dirchanged DirChanged auto call add(s:li, "auto:")
  2135. autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>"))
  2136. set acd
  2137. cd ..
  2138. call assert_equal([], s:li)
  2139. exe 'edit ' . s:dir_foo . '/Xautofile'
  2140. call assert_equal(s:dir_foo, getcwd())
  2141. let expected = ["pre cd " .. s:dir_foo, "auto:", s:dir_foo]
  2142. call assert_equal(expected, s:li)
  2143. set noacd
  2144. bwipe!
  2145. call s:After_test_dirchanged()
  2146. endfunc
  2147. " Test TextChangedI and TextChangedP
  2148. func Test_ChangedP()
  2149. throw 'Skipped: use test/functional/autocmd/textchanged_spec.lua'
  2150. new
  2151. call setline(1, ['foo', 'bar', 'foobar'])
  2152. call test_override("char_avail", 1)
  2153. set complete=. completeopt=menuone
  2154. func! TextChangedAutocmd(char)
  2155. let g:autocmd .= a:char
  2156. endfunc
  2157. " TextChanged will not be triggered, only check that it isn't.
  2158. au! TextChanged <buffer> :call TextChangedAutocmd('N')
  2159. au! TextChangedI <buffer> :call TextChangedAutocmd('I')
  2160. au! TextChangedP <buffer> :call TextChangedAutocmd('P')
  2161. call cursor(3, 1)
  2162. let g:autocmd = ''
  2163. call feedkeys("o\<esc>", 'tnix')
  2164. call assert_equal('I', g:autocmd)
  2165. let g:autocmd = ''
  2166. call feedkeys("Sf", 'tnix')
  2167. call assert_equal('II', g:autocmd)
  2168. let g:autocmd = ''
  2169. call feedkeys("Sf\<C-N>", 'tnix')
  2170. call assert_equal('IIP', g:autocmd)
  2171. let g:autocmd = ''
  2172. call feedkeys("Sf\<C-N>\<C-N>", 'tnix')
  2173. call assert_equal('IIPP', g:autocmd)
  2174. let g:autocmd = ''
  2175. call feedkeys("Sf\<C-N>\<C-N>\<C-N>", 'tnix')
  2176. call assert_equal('IIPPP', g:autocmd)
  2177. let g:autocmd = ''
  2178. call feedkeys("Sf\<C-N>\<C-N>\<C-N>\<C-N>", 'tnix')
  2179. call assert_equal('IIPPPP', g:autocmd)
  2180. call assert_equal(['foo', 'bar', 'foobar', 'foo'], getline(1, '$'))
  2181. " TODO: how should it handle completeopt=noinsert,noselect?
  2182. " CleanUp
  2183. call test_override("char_avail", 0)
  2184. au! TextChanged
  2185. au! TextChangedI
  2186. au! TextChangedP
  2187. delfu TextChangedAutocmd
  2188. unlet! g:autocmd
  2189. set complete&vim completeopt&vim
  2190. bw!
  2191. endfunc
  2192. let g:setline_handled = v:false
  2193. func SetLineOne()
  2194. if !g:setline_handled
  2195. call setline(1, "(x)")
  2196. let g:setline_handled = v:true
  2197. endif
  2198. endfunc
  2199. func Test_TextChangedI_with_setline()
  2200. throw 'Skipped: use test/functional/autocmd/textchanged_spec.lua'
  2201. new
  2202. call test_override('char_avail', 1)
  2203. autocmd TextChangedI <buffer> call SetLineOne()
  2204. call feedkeys("i(\<CR>\<Esc>", 'tx')
  2205. call assert_equal('(', getline(1))
  2206. call assert_equal('x)', getline(2))
  2207. undo
  2208. call assert_equal('', getline(1))
  2209. call assert_equal('', getline(2))
  2210. call test_override('char_avail', 0)
  2211. bwipe!
  2212. endfunc
  2213. func Test_TextChanged_with_norm()
  2214. " For unknown reason this fails on MS-Windows
  2215. CheckNotMSWindows
  2216. CheckFeature terminal
  2217. let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
  2218. call assert_equal('running', term_getstatus(buf))
  2219. call term_sendkeys(buf, ":let g:a=0\<cr>")
  2220. call term_wait(buf, 50)
  2221. call term_sendkeys(buf, ":au! TextChanged * :let g:a+=1\<cr>")
  2222. call term_wait(buf, 50)
  2223. call term_sendkeys(buf, ":norm! ia\<cr>")
  2224. call term_wait(buf, 50)
  2225. call term_sendkeys(buf, ":echo g:a\<cr>")
  2226. call term_wait(buf, 50)
  2227. call WaitForAssert({-> assert_match('^1.*$', term_getline(buf, 3))})
  2228. bwipe!
  2229. endfunc
  2230. func Test_Changed_FirstTime()
  2231. CheckFeature terminal
  2232. CheckNotGui
  2233. " Starting a terminal to run Vim is always considered flaky.
  2234. let g:test_is_flaky = 1
  2235. " Prepare file for TextChanged event.
  2236. call writefile([''], 'Xchanged.txt', 'D')
  2237. let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
  2238. call assert_equal('running', term_getstatus(buf))
  2239. " Wait for the ruler (in the status line) to be shown.
  2240. " In ConPTY, there is additional character which is drawn up to the width of
  2241. " the screen.
  2242. if has('conpty')
  2243. call WaitForAssert({-> assert_match('\<All.*$', term_getline(buf, 3))})
  2244. else
  2245. call WaitForAssert({-> assert_match('\<All$', term_getline(buf, 3))})
  2246. endif
  2247. " It's only adding autocmd, so that no event occurs.
  2248. call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>")
  2249. call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
  2250. call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
  2251. call assert_equal([''], readfile('Xchanged.txt'))
  2252. " clean up
  2253. bwipe!
  2254. endfunc
  2255. func Test_autocmd_nested()
  2256. let g:did_nested = 0
  2257. augroup Testing
  2258. au WinNew * edit somefile
  2259. au BufNew * let g:did_nested = 1
  2260. augroup END
  2261. split
  2262. call assert_equal(0, g:did_nested)
  2263. close
  2264. bwipe! somefile
  2265. " old nested argument still works
  2266. augroup Testing
  2267. au!
  2268. au WinNew * nested edit somefile
  2269. au BufNew * let g:did_nested = 1
  2270. augroup END
  2271. split
  2272. call assert_equal(1, g:did_nested)
  2273. close
  2274. bwipe! somefile
  2275. " New ++nested argument works
  2276. augroup Testing
  2277. au!
  2278. au WinNew * ++nested edit somefile
  2279. au BufNew * let g:did_nested = 1
  2280. augroup END
  2281. split
  2282. call assert_equal(1, g:did_nested)
  2283. close
  2284. bwipe! somefile
  2285. augroup Testing
  2286. au!
  2287. augroup END
  2288. call assert_fails('au WinNew * ++nested ++nested echo bad', 'E983:')
  2289. call assert_fails('au WinNew * nested nested echo bad', 'E983:')
  2290. endfunc
  2291. func Test_autocmd_nested_cursor_invalid()
  2292. set laststatus=0
  2293. copen
  2294. cclose
  2295. call setline(1, ['foo', 'bar', 'baz'])
  2296. 3
  2297. augroup nested_inv
  2298. autocmd User foo ++nested copen
  2299. autocmd BufAdd * let &laststatus = 2 - &laststatus
  2300. augroup END
  2301. doautocmd User foo
  2302. augroup nested_inv
  2303. au!
  2304. augroup END
  2305. set laststatus&
  2306. cclose
  2307. bwipe!
  2308. endfunc
  2309. func Test_autocmd_nested_keeps_cursor_pos()
  2310. enew
  2311. call setline(1, 'foo')
  2312. autocmd User foo ++nested normal! $a
  2313. autocmd InsertLeave * :
  2314. doautocmd User foo
  2315. call assert_equal([0, 1, 3, 0], getpos('.'))
  2316. bwipe!
  2317. endfunc
  2318. func Test_autocmd_nested_switch_window()
  2319. " run this in a separate Vim so that SafeState works
  2320. CheckRunVimInTerminal
  2321. let lines =<< trim END
  2322. vim9script
  2323. ['()']->writefile('Xautofile')
  2324. autocmd VimEnter * ++nested edit Xautofile | split
  2325. autocmd BufReadPost * autocmd SafeState * ++once foldclosed('.')
  2326. autocmd WinEnter * matchadd('ErrorMsg', 'pat')
  2327. END
  2328. call writefile(lines, 'Xautoscript', 'D')
  2329. let buf = RunVimInTerminal('-S Xautoscript', {'rows': 10})
  2330. call VerifyScreenDump(buf, 'Test_autocmd_nested_switch', {})
  2331. call StopVimInTerminal(buf)
  2332. call delete('Xautofile')
  2333. endfunc
  2334. func Test_autocmd_once()
  2335. " Without ++once WinNew triggers twice
  2336. let g:did_split = 0
  2337. augroup Testing
  2338. au WinNew * let g:did_split += 1
  2339. augroup END
  2340. split
  2341. split
  2342. call assert_equal(2, g:did_split)
  2343. call assert_true(exists('#WinNew'))
  2344. close
  2345. close
  2346. " With ++once WinNew triggers once
  2347. let g:did_split = 0
  2348. augroup Testing
  2349. au!
  2350. au WinNew * ++once let g:did_split += 1
  2351. augroup END
  2352. split
  2353. split
  2354. call assert_equal(1, g:did_split)
  2355. call assert_false(exists('#WinNew'))
  2356. close
  2357. close
  2358. call assert_fails('au WinNew * ++once ++once echo bad', 'E983:')
  2359. endfunc
  2360. func Test_autocmd_bufreadpre()
  2361. new
  2362. let b:bufreadpre = 1
  2363. call append(0, range(100))
  2364. w! XAutocmdBufReadPre.txt
  2365. autocmd BufReadPre <buffer> :let b:bufreadpre += 1
  2366. norm! 50gg
  2367. sp
  2368. norm! 100gg
  2369. wincmd p
  2370. let g:wsv1 = winsaveview()
  2371. wincmd p
  2372. let g:wsv2 = winsaveview()
  2373. " triggers BufReadPre, should not move the cursor in either window
  2374. " The topline may change one line in a large window.
  2375. edit
  2376. call assert_inrange(g:wsv2.topline - 1, g:wsv2.topline + 1, winsaveview().topline)
  2377. call assert_equal(g:wsv2.lnum, winsaveview().lnum)
  2378. call assert_equal(2, b:bufreadpre)
  2379. wincmd p
  2380. call assert_equal(g:wsv1.topline, winsaveview().topline)
  2381. call assert_equal(g:wsv1.lnum, winsaveview().lnum)
  2382. call assert_equal(2, b:bufreadpre)
  2383. " Now set the cursor position in an BufReadPre autocommand
  2384. " (even though the position will be invalid, this should make Vim reset the
  2385. " cursor position in the other window.
  2386. wincmd p
  2387. 1 " set cpo+=g
  2388. " won't do anything, but try to set the cursor on an invalid lnum
  2389. autocmd BufReadPre <buffer> :norm! 70gg
  2390. " triggers BufReadPre, should not move the cursor in either window
  2391. e
  2392. call assert_equal(1, winsaveview().topline)
  2393. call assert_equal(1, winsaveview().lnum)
  2394. call assert_equal(3, b:bufreadpre)
  2395. wincmd p
  2396. call assert_equal(g:wsv1.topline, winsaveview().topline)
  2397. call assert_equal(g:wsv1.lnum, winsaveview().lnum)
  2398. call assert_equal(3, b:bufreadpre)
  2399. close
  2400. close
  2401. call delete('XAutocmdBufReadPre.txt')
  2402. set cpo-=g
  2403. endfunc
  2404. " FileChangedShell tested in test_filechanged.vim
  2405. " Tests for the following autocommands:
  2406. " - FileWritePre writing a compressed file
  2407. " - FileReadPost reading a compressed file
  2408. " - BufNewFile reading a file template
  2409. " - BufReadPre decompressing the file to be read
  2410. " - FilterReadPre substituting characters in the temp file
  2411. " - FilterReadPost substituting characters after filtering
  2412. " - FileReadPre set options for decompression
  2413. " - FileReadPost decompress the file
  2414. func Test_ReadWrite_Autocmds()
  2415. " Run this test only on Unix-like systems and if gzip is available
  2416. if !has('unix') || !executable("gzip")
  2417. return
  2418. endif
  2419. " Make $GZIP empty, "-v" would cause trouble.
  2420. let $GZIP = ""
  2421. " Use a FileChangedShell autocommand to avoid a prompt for 'Xtestfile.gz'
  2422. " being modified outside of Vim (noticed on Solaris).
  2423. au FileChangedShell * echo 'caught FileChangedShell'
  2424. " Test for the FileReadPost, FileWritePre and FileWritePost autocmds
  2425. augroup Test1
  2426. au!
  2427. au FileWritePre *.gz '[,']!gzip
  2428. au FileWritePost *.gz undo
  2429. au FileReadPost *.gz '[,']!gzip -d
  2430. augroup END
  2431. new
  2432. set bin
  2433. call append(0, [
  2434. \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
  2435. \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2436. \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
  2437. \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2438. \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
  2439. \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2440. \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
  2441. \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2442. \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
  2443. \ ])
  2444. 1,9write! Xtestfile.gz
  2445. enew! | close
  2446. new
  2447. " Read and decompress the testfile
  2448. 0read Xtestfile.gz
  2449. call assert_equal([
  2450. \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
  2451. \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2452. \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
  2453. \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2454. \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
  2455. \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2456. \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
  2457. \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2458. \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
  2459. \ ], getline(1, 9))
  2460. enew! | close
  2461. augroup Test1
  2462. au!
  2463. augroup END
  2464. " Test for the FileAppendPre and FileAppendPost autocmds
  2465. augroup Test2
  2466. au!
  2467. au BufNewFile *.c read Xtest.c
  2468. au FileAppendPre *.out '[,']s/new/NEW/
  2469. au FileAppendPost *.out !cat Xtest.c >> test.out
  2470. augroup END
  2471. call writefile(['/*', ' * Here is a new .c file', ' */'], 'Xtest.c', 'D')
  2472. new foo.c " should load Xtest.c
  2473. call assert_equal(['/*', ' * Here is a new .c file', ' */'], getline(2, 4))
  2474. w! >> test.out " append it to the output file
  2475. let contents = readfile('test.out')
  2476. call assert_equal(' * Here is a NEW .c file', contents[2])
  2477. call assert_equal(' * Here is a new .c file', contents[5])
  2478. call delete('test.out')
  2479. enew! | close
  2480. augroup Test2
  2481. au!
  2482. augroup END
  2483. " Test for the BufReadPre and BufReadPost autocmds
  2484. augroup Test3
  2485. au!
  2486. " setup autocommands to decompress before reading and re-compress
  2487. " afterwards
  2488. au BufReadPre *.gz exe '!gzip -d ' . shellescape(expand("<afile>"))
  2489. au BufReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>"))
  2490. au BufReadPost *.gz call rename(expand("<afile>"), expand("<afile>:r"))
  2491. au BufReadPost *.gz exe '!gzip ' . shellescape(expand("<afile>:r"))
  2492. augroup END
  2493. e! Xtestfile.gz " Edit compressed file
  2494. call assert_equal([
  2495. \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
  2496. \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2497. \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
  2498. \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2499. \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
  2500. \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2501. \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
  2502. \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2503. \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
  2504. \ ], getline(1, 9))
  2505. w! >> test.out " Append it to the output file
  2506. augroup Test3
  2507. au!
  2508. augroup END
  2509. " Test for the FilterReadPre and FilterReadPost autocmds.
  2510. set shelltemp " need temp files here
  2511. augroup Test4
  2512. au!
  2513. au FilterReadPre *.out call rename(expand("<afile>"), expand("<afile>") . ".t")
  2514. au FilterReadPre *.out exe 'silent !sed s/e/E/ ' . shellescape(expand("<afile>")) . ".t >" . shellescape(expand("<afile>"))
  2515. au FilterReadPre *.out exe 'silent !rm ' . shellescape(expand("<afile>")) . '.t'
  2516. au FilterReadPost *.out '[,']s/x/X/g
  2517. augroup END
  2518. e! test.out " Edit the output file
  2519. 1,$!cat
  2520. call assert_equal([
  2521. \ 'linE 2 AbcdefghijklmnopqrstuvwXyz',
  2522. \ 'linE 3 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  2523. \ 'linE 4 AbcdefghijklmnopqrstuvwXyz',
  2524. \ 'linE 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  2525. \ 'linE 6 AbcdefghijklmnopqrstuvwXyz',
  2526. \ 'linE 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  2527. \ 'linE 8 AbcdefghijklmnopqrstuvwXyz',
  2528. \ 'linE 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  2529. \ 'linE 10 AbcdefghijklmnopqrstuvwXyz'
  2530. \ ], getline(1, 9))
  2531. call assert_equal([
  2532. \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
  2533. \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2534. \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
  2535. \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2536. \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
  2537. \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2538. \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
  2539. \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2540. \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
  2541. \ ], readfile('test.out'))
  2542. augroup Test4
  2543. au!
  2544. augroup END
  2545. set shelltemp&vim
  2546. " Test for the FileReadPre and FileReadPost autocmds.
  2547. augroup Test5
  2548. au!
  2549. au FileReadPre *.gz exe 'silent !gzip -d ' . shellescape(expand("<afile>"))
  2550. au FileReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>"))
  2551. au FileReadPost *.gz '[,']s/l/L/
  2552. augroup END
  2553. new
  2554. 0r Xtestfile.gz " Read compressed file
  2555. call assert_equal([
  2556. \ 'Line 2 Abcdefghijklmnopqrstuvwxyz',
  2557. \ 'Line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2558. \ 'Line 4 Abcdefghijklmnopqrstuvwxyz',
  2559. \ 'Line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2560. \ 'Line 6 Abcdefghijklmnopqrstuvwxyz',
  2561. \ 'Line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2562. \ 'Line 8 Abcdefghijklmnopqrstuvwxyz',
  2563. \ 'Line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2564. \ 'Line 10 Abcdefghijklmnopqrstuvwxyz'
  2565. \ ], getline(1, 9))
  2566. call assert_equal([
  2567. \ 'line 2 Abcdefghijklmnopqrstuvwxyz',
  2568. \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2569. \ 'line 4 Abcdefghijklmnopqrstuvwxyz',
  2570. \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2571. \ 'line 6 Abcdefghijklmnopqrstuvwxyz',
  2572. \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2573. \ 'line 8 Abcdefghijklmnopqrstuvwxyz',
  2574. \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  2575. \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
  2576. \ ], readfile('Xtestfile.gz'))
  2577. augroup Test5
  2578. au!
  2579. augroup END
  2580. au! FileChangedShell
  2581. call delete('Xtestfile.gz')
  2582. call delete('test.out')
  2583. endfunc
  2584. func Test_throw_in_BufWritePre()
  2585. new
  2586. call setline(1, ['one', 'two', 'three'])
  2587. call assert_false(filereadable('Xthefile'))
  2588. augroup throwing
  2589. au BufWritePre X* throw 'do not write'
  2590. augroup END
  2591. try
  2592. w Xthefile
  2593. catch
  2594. let caught = 1
  2595. endtry
  2596. call assert_equal(1, caught)
  2597. call assert_false(filereadable('Xthefile'))
  2598. bwipe!
  2599. au! throwing
  2600. endfunc
  2601. func Test_autocmd_in_try_block()
  2602. call mkdir('Xintrydir', 'R')
  2603. au BufEnter * let g:fname = expand('%')
  2604. try
  2605. edit Xintrydir/
  2606. endtry
  2607. call assert_match('Xintrydir', g:fname)
  2608. unlet g:fname
  2609. au! BufEnter
  2610. endfunc
  2611. func Test_autocmd_SafeState()
  2612. CheckRunVimInTerminal
  2613. let lines =<< trim END
  2614. let g:safe = 0
  2615. let g:again = ''
  2616. au SafeState * let g:safe += 1
  2617. au SafeStateAgain * let g:again ..= 'x'
  2618. func CallTimer()
  2619. call timer_start(10, {id -> execute('let g:again ..= "t"')})
  2620. endfunc
  2621. END
  2622. call writefile(lines, 'XSafeState', 'D')
  2623. let buf = RunVimInTerminal('-S XSafeState', #{rows: 6})
  2624. " Sometimes we loop to handle a K_IGNORE, SafeState may be triggered once or
  2625. " more often.
  2626. call term_sendkeys(buf, ":echo g:safe\<CR>")
  2627. call WaitForAssert({-> assert_match('^\d ', term_getline(buf, 6))}, 1000)
  2628. " SafeStateAgain should be invoked at least three times
  2629. call term_sendkeys(buf, ":echo g:again\<CR>")
  2630. call WaitForAssert({-> assert_match('^xxx', term_getline(buf, 6))}, 1000)
  2631. call term_sendkeys(buf, ":let g:again = ''\<CR>:call CallTimer()\<CR>")
  2632. call TermWait(buf, 50)
  2633. call term_sendkeys(buf, ":\<CR>")
  2634. call TermWait(buf, 50)
  2635. call term_sendkeys(buf, ":echo g:again\<CR>")
  2636. call WaitForAssert({-> assert_match('xtx', term_getline(buf, 6))}, 1000)
  2637. call StopVimInTerminal(buf)
  2638. endfunc
  2639. func Test_autocmd_CmdWinEnter()
  2640. CheckRunVimInTerminal
  2641. " There is not cmdwin switch, so
  2642. " test for cmdline_hist
  2643. " (both are available with small builds)
  2644. CheckFeature cmdline_hist
  2645. let lines =<< trim END
  2646. let b:dummy_var = 'This is a dummy'
  2647. autocmd CmdWinEnter * quit
  2648. let winnr = winnr('$')
  2649. END
  2650. let filename = 'XCmdWinEnter'
  2651. call writefile(lines, filename)
  2652. let buf = RunVimInTerminal('-S '.filename, #{rows: 6})
  2653. call term_sendkeys(buf, "q:")
  2654. call TermWait(buf)
  2655. call term_sendkeys(buf, ":echo b:dummy_var\<cr>")
  2656. call WaitForAssert({-> assert_match('^This is a dummy', term_getline(buf, 6))}, 2000)
  2657. call term_sendkeys(buf, ":echo &buftype\<cr>")
  2658. call WaitForAssert({-> assert_notmatch('^nofile', term_getline(buf, 6))}, 1000)
  2659. call term_sendkeys(buf, ":echo winnr\<cr>")
  2660. call WaitForAssert({-> assert_match('^1', term_getline(buf, 6))}, 1000)
  2661. " clean up
  2662. call StopVimInTerminal(buf)
  2663. call delete(filename)
  2664. endfunc
  2665. func Test_autocmd_was_using_freed_memory()
  2666. CheckFeature quickfix
  2667. pedit xx
  2668. n x
  2669. augroup winenter
  2670. au WinEnter * if winnr('$') > 2 | quit | endif
  2671. augroup END
  2672. " Nvim needs large 'winwidth' and 'nowinfixwidth' to crash
  2673. set winwidth=99999 nowinfixwidth
  2674. split
  2675. augroup winenter
  2676. au! WinEnter
  2677. augroup END
  2678. set winwidth& winfixwidth&
  2679. bwipe xx
  2680. bwipe x
  2681. pclose
  2682. endfunc
  2683. func Test_BufWrite_lockmarks()
  2684. let g:test_is_flaky = 1
  2685. edit! Xtest
  2686. call setline(1, ['a', 'b', 'c', 'd'])
  2687. " :lockmarks preserves the marks
  2688. call SetChangeMarks(2, 3)
  2689. lockmarks write
  2690. call assert_equal([2, 3], [line("'["), line("']")])
  2691. " *WritePre autocmds get the correct line range, but lockmarks preserves the
  2692. " original values for the user
  2693. augroup lockmarks
  2694. au!
  2695. au BufWritePre,FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")])
  2696. au FileWritePre * call assert_equal([3, 4], [line("'["), line("']")])
  2697. augroup END
  2698. lockmarks write
  2699. call assert_equal([2, 3], [line("'["), line("']")])
  2700. if executable('cat')
  2701. lockmarks %!cat
  2702. call assert_equal([2, 3], [line("'["), line("']")])
  2703. endif
  2704. lockmarks 3,4write Xtest2
  2705. call assert_equal([2, 3], [line("'["), line("']")])
  2706. au! lockmarks
  2707. augroup! lockmarks
  2708. call delete('Xtest')
  2709. call delete('Xtest2')
  2710. endfunc
  2711. func Test_FileType_spell()
  2712. if !isdirectory('/tmp')
  2713. throw "Skipped: requires /tmp directory"
  2714. endif
  2715. " this was crashing with an invalid free()
  2716. setglobal spellfile=/tmp/en.utf-8.add
  2717. augroup crash
  2718. autocmd!
  2719. autocmd BufNewFile,BufReadPost crashfile setf somefiletype
  2720. autocmd BufNewFile,BufReadPost crashfile set ft=anotherfiletype
  2721. autocmd FileType anotherfiletype setlocal spell
  2722. augroup END
  2723. func! NoCrash() abort
  2724. edit /tmp/crashfile
  2725. endfunc
  2726. call NoCrash()
  2727. au! crash
  2728. setglobal spellfile=
  2729. endfunc
  2730. " this was wiping out the current buffer and using freed memory
  2731. func Test_SpellFileMissing_bwipe()
  2732. next 0
  2733. au SpellFileMissing 0 bwipe
  2734. call assert_fails('set spell spelllang=0', 'E937:')
  2735. au! SpellFileMissing
  2736. set nospell spelllang=en
  2737. bwipe
  2738. endfunc
  2739. " Test closing a window or editing another buffer from a FileChangedRO handler
  2740. " in a readonly buffer
  2741. func Test_FileChangedRO_winclose()
  2742. augroup FileChangedROTest
  2743. au!
  2744. autocmd FileChangedRO * quit
  2745. augroup END
  2746. new
  2747. set readonly
  2748. call assert_fails('normal i', 'E788:')
  2749. close
  2750. augroup! FileChangedROTest
  2751. augroup FileChangedROTest
  2752. au!
  2753. autocmd FileChangedRO * edit Xrofile
  2754. augroup END
  2755. new
  2756. set readonly
  2757. call assert_fails('normal i', 'E788:')
  2758. close
  2759. augroup! FileChangedROTest
  2760. endfunc
  2761. func LogACmd()
  2762. call add(g:logged, line('$'))
  2763. endfunc
  2764. func Test_TermChanged()
  2765. throw 'skipped: Nvim does not support TermChanged event'
  2766. CheckNotGui
  2767. enew!
  2768. tabnew
  2769. call setline(1, ['a', 'b', 'c', 'd'])
  2770. $
  2771. au TermChanged * call LogACmd()
  2772. let g:logged = []
  2773. let term_save = &term
  2774. set term=xterm
  2775. call assert_equal([1, 4], g:logged)
  2776. au! TermChanged
  2777. let &term = term_save
  2778. bwipe!
  2779. endfunc
  2780. " Test for FileReadCmd autocmd
  2781. func Test_autocmd_FileReadCmd()
  2782. func ReadFileCmd()
  2783. call append(line('$'), "v:cmdarg = " .. v:cmdarg)
  2784. endfunc
  2785. augroup FileReadCmdTest
  2786. au!
  2787. au FileReadCmd Xtest call ReadFileCmd()
  2788. augroup END
  2789. new
  2790. read ++bin Xtest
  2791. read ++nobin Xtest
  2792. read ++edit Xtest
  2793. read ++bad=keep Xtest
  2794. read ++bad=drop Xtest
  2795. read ++bad=- Xtest
  2796. read ++ff=unix Xtest
  2797. read ++ff=dos Xtest
  2798. read ++ff=mac Xtest
  2799. read ++enc=utf-8 Xtest
  2800. call assert_equal(['',
  2801. \ 'v:cmdarg = ++bin',
  2802. \ 'v:cmdarg = ++nobin',
  2803. \ 'v:cmdarg = ++edit',
  2804. \ 'v:cmdarg = ++bad=keep',
  2805. \ 'v:cmdarg = ++bad=drop',
  2806. \ 'v:cmdarg = ++bad=-',
  2807. \ 'v:cmdarg = ++ff=unix',
  2808. \ 'v:cmdarg = ++ff=dos',
  2809. \ 'v:cmdarg = ++ff=mac',
  2810. \ 'v:cmdarg = ++enc=utf-8'], getline(1, '$'))
  2811. bwipe!
  2812. augroup FileReadCmdTest
  2813. au!
  2814. augroup END
  2815. delfunc ReadFileCmd
  2816. endfunc
  2817. " Test for passing invalid arguments to autocmd
  2818. func Test_autocmd_invalid_args()
  2819. " Additional character after * for event
  2820. call assert_fails('autocmd *a Xinvfile set ff=unix', 'E215:')
  2821. augroup Test
  2822. augroup END
  2823. " Invalid autocmd event
  2824. call assert_fails('autocmd Bufabc Xinvfile set ft=vim', 'E216:')
  2825. " Invalid autocmd event in a autocmd group
  2826. call assert_fails('autocmd Test Bufabc Xinvfile set ft=vim', 'E216:')
  2827. augroup! Test
  2828. " Execute all autocmds
  2829. call assert_fails('doautocmd * BufEnter', 'E217:')
  2830. call assert_fails('augroup! x1a2b3', 'E367:')
  2831. call assert_fails('autocmd BufNew <buffer=999> pwd', 'E680:')
  2832. call assert_fails('autocmd BufNew \) set ff=unix', 'E55:')
  2833. endfunc
  2834. " Test for deep nesting of autocmds
  2835. func Test_autocmd_deep_nesting()
  2836. autocmd BufEnter Xdeepfile doautocmd BufEnter Xdeepfile
  2837. call assert_fails('doautocmd BufEnter Xdeepfile', 'E218:')
  2838. autocmd! BufEnter Xdeepfile
  2839. endfunc
  2840. " Tests for SigUSR1 autocmd event, which is only available on posix systems.
  2841. func Test_autocmd_sigusr1()
  2842. CheckUnix
  2843. let g:sigusr1_passed = 0
  2844. au Signal SIGUSR1 let g:sigusr1_passed = 1
  2845. call system('kill -s usr1 ' . getpid())
  2846. call WaitForAssert({-> assert_true(g:sigusr1_passed)})
  2847. au! Signal
  2848. unlet g:sigusr1_passed
  2849. endfunc
  2850. " Test for BufReadPre autocmd deleting the file
  2851. func Test_BufReadPre_delfile()
  2852. augroup TestAuCmd
  2853. au!
  2854. autocmd BufReadPre XbufreadPre call delete('XbufreadPre')
  2855. augroup END
  2856. call writefile([], 'XbufreadPre', 'D')
  2857. call assert_fails('new XbufreadPre', 'E200:')
  2858. call assert_equal('XbufreadPre', @%)
  2859. call assert_equal(1, &readonly)
  2860. augroup TestAuCmd
  2861. au!
  2862. augroup END
  2863. close!
  2864. endfunc
  2865. " Test for BufReadPre autocmd changing the current buffer
  2866. func Test_BufReadPre_changebuf()
  2867. augroup TestAuCmd
  2868. au!
  2869. autocmd BufReadPre Xchangebuf edit Xsomeotherfile
  2870. augroup END
  2871. call writefile([], 'Xchangebuf', 'D')
  2872. call assert_fails('new Xchangebuf', 'E201:')
  2873. call assert_equal('Xsomeotherfile', @%)
  2874. call assert_equal(1, &readonly)
  2875. augroup TestAuCmd
  2876. au!
  2877. augroup END
  2878. close!
  2879. endfunc
  2880. " Test for BufWipeouti autocmd changing the current buffer when reading a file
  2881. " in an empty buffer with 'f' flag in 'cpo'
  2882. func Test_BufDelete_changebuf()
  2883. new
  2884. augroup TestAuCmd
  2885. au!
  2886. autocmd BufWipeout * let bufnr = bufadd('somefile') | exe "b " .. bufnr
  2887. augroup END
  2888. let save_cpo = &cpo
  2889. set cpo+=f
  2890. call assert_fails('r Xfile', ['E812:', 'E484:'])
  2891. call assert_equal('somefile', @%)
  2892. let &cpo = save_cpo
  2893. augroup TestAuCmd
  2894. au!
  2895. augroup END
  2896. close!
  2897. endfunc
  2898. " Test for the temporary internal window used to execute autocmds
  2899. func Test_autocmd_window()
  2900. %bw!
  2901. edit one.txt
  2902. tabnew two.txt
  2903. vnew three.txt
  2904. tabnew four.txt
  2905. tabprevious
  2906. let g:blist = []
  2907. augroup aucmd_win_test1
  2908. au!
  2909. au BufEnter * call add(g:blist, [expand('<afile>'),
  2910. \ win_gettype(bufwinnr(expand('<afile>')))])
  2911. augroup END
  2912. doautoall BufEnter
  2913. call assert_equal([
  2914. \ ['one.txt', 'autocmd'],
  2915. \ ['two.txt', ''],
  2916. \ ['four.txt', 'autocmd'],
  2917. \ ['three.txt', ''],
  2918. \ ], g:blist)
  2919. augroup aucmd_win_test1
  2920. au!
  2921. augroup END
  2922. augroup! aucmd_win_test1
  2923. %bw!
  2924. endfunc
  2925. " Test for trying to close the temporary window used for executing an autocmd
  2926. func Test_close_autocmd_window()
  2927. %bw!
  2928. edit one.txt
  2929. tabnew two.txt
  2930. augroup aucmd_win_test2
  2931. au!
  2932. " Nvim makes aucmd_win the last window
  2933. " au BufEnter * if expand('<afile>') == 'one.txt' | 1close | endif
  2934. au BufEnter * if expand('<afile>') == 'one.txt' | close | endif
  2935. augroup END
  2936. call assert_fails('doautoall BufEnter', 'E813:')
  2937. augroup aucmd_win_test2
  2938. au!
  2939. augroup END
  2940. augroup! aucmd_win_test2
  2941. %bw!
  2942. endfunc
  2943. " Test for trying to close the tab that has the temporary window for exeucing
  2944. " an autocmd.
  2945. func Test_close_autocmd_tab()
  2946. edit one.txt
  2947. tabnew two.txt
  2948. augroup aucmd_win_test
  2949. au!
  2950. au BufEnter * if expand('<afile>') == 'one.txt' | tabfirst | tabonly | endif
  2951. augroup END
  2952. call assert_fails('doautoall BufEnter', 'E813:')
  2953. tabonly
  2954. augroup aucmd_win_test
  2955. au!
  2956. augroup END
  2957. augroup! aucmd_win_test
  2958. %bwipe!
  2959. endfunc
  2960. func Test_Visual_doautoall_redraw()
  2961. call setline(1, ['a', 'b'])
  2962. new
  2963. wincmd p
  2964. call feedkeys("G\<C-V>", 'txn')
  2965. autocmd User Explode ++once redraw
  2966. doautoall User Explode
  2967. %bwipe!
  2968. endfunc
  2969. " This was using freed memory.
  2970. func Test_BufNew_arglocal()
  2971. arglocal
  2972. au BufNew * arglocal
  2973. call assert_fails('drop xx', 'E1156:')
  2974. au! BufNew
  2975. endfunc
  2976. func Test_autocmd_closes_window()
  2977. au BufNew,BufWinLeave * e %e
  2978. file yyy
  2979. au BufNew,BufWinLeave * ball
  2980. n xxx
  2981. %bwipe
  2982. au! BufNew
  2983. au! BufWinLeave
  2984. endfunc
  2985. func Test_autocmd_quit_psearch()
  2986. sn aa bb
  2987. augroup aucmd_win_test
  2988. au!
  2989. au BufEnter,BufLeave,BufNew,WinEnter,WinLeave,WinNew * if winnr('$') > 1 | q | endif
  2990. augroup END
  2991. ps /
  2992. augroup aucmd_win_test
  2993. au!
  2994. augroup END
  2995. new
  2996. pclose
  2997. endfunc
  2998. " Fuzzer found some strange combination that caused a crash.
  2999. func Test_autocmd_normal_mess()
  3000. " For unknown reason this hangs on MS-Windows
  3001. CheckNotMSWindows
  3002. augroup aucmd_normal_test
  3003. au BufLeave,BufWinLeave,BufHidden,BufUnload,BufDelete,BufWipeout * norm 7q/qc
  3004. augroup END
  3005. " Nvim has removed :open
  3006. " call assert_fails('o4', 'E1159')
  3007. call assert_fails('e4', 'E1159')
  3008. silent! H
  3009. call assert_fails('e xx', 'E1159')
  3010. normal G
  3011. augroup aucmd_normal_test
  3012. au!
  3013. augroup END
  3014. endfunc
  3015. func Test_autocmd_closing_cmdwin()
  3016. " For unknown reason this hangs on MS-Windows
  3017. CheckNotMSWindows
  3018. au BufWinLeave * nested q
  3019. call assert_fails("norm 7q?\n", 'E855:')
  3020. au! BufWinLeave
  3021. new
  3022. only
  3023. endfunc
  3024. func Test_autocmd_vimgrep()
  3025. augroup aucmd_vimgrep
  3026. au QuickfixCmdPre,BufNew,BufReadCmd * sb
  3027. " Nvim makes aucmd_win the last window
  3028. " au QuickfixCmdPre,BufNew,BufReadCmd * q9
  3029. au QuickfixCmdPre,BufNew,BufReadCmd * exe 'q' .. (winnr('$') - (win_gettype(winnr('$')) == 'autocmd'))
  3030. augroup END
  3031. call assert_fails('lv ?a? foo', 'E926:')
  3032. augroup aucmd_vimgrep
  3033. au!
  3034. augroup END
  3035. endfunc
  3036. func Test_closing_autocmd_window()
  3037. let lines =<< trim END
  3038. edit Xa.txt
  3039. tabnew Xb.txt
  3040. autocmd BufEnter Xa.txt unhide 1
  3041. doautoall BufEnter
  3042. END
  3043. call CheckScriptFailure(lines, 'E814:')
  3044. au! BufEnter
  3045. bwipe Xa.txt
  3046. bwipe Xb.txt
  3047. endfunc
  3048. func Test_switch_window_in_autocmd_window()
  3049. edit Xa.txt
  3050. tabnew Xb.txt
  3051. autocmd BufEnter Xa.txt wincmd w
  3052. doautoall BufEnter
  3053. au! BufEnter
  3054. bwipe Xa.txt
  3055. call assert_false(bufexists('Xa.txt'))
  3056. bwipe Xb.txt
  3057. call assert_false(bufexists('Xb.txt'))
  3058. endfunc
  3059. " Test that using the autocommand window doesn't change current directory.
  3060. func Test_autocmd_window_cwd()
  3061. let saveddir = getcwd()
  3062. call mkdir('Xcwd/a/b/c/d', 'pR')
  3063. new Xa.txt
  3064. tabnew
  3065. new Xb.txt
  3066. tabprev
  3067. cd Xcwd
  3068. call assert_match('/Xcwd$', getcwd())
  3069. call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
  3070. autocmd BufEnter Xb.txt lcd ./a/b/c/d
  3071. doautoall BufEnter
  3072. au! BufEnter
  3073. call assert_match('/Xcwd$', getcwd())
  3074. call assert_match('\[global\] .*/Xcwd$', trim(execute('verbose pwd')))
  3075. tabnext
  3076. cd ./a
  3077. tcd ./b
  3078. lcd ./c
  3079. call assert_match('/Xcwd/a/b/c$', getcwd())
  3080. call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
  3081. autocmd BufEnter Xa.txt call assert_match('Xcwd/a/b/c$', getcwd())
  3082. doautoall BufEnter
  3083. au! BufEnter
  3084. call assert_match('/Xcwd/a/b/c$', getcwd())
  3085. call assert_match('\[window\] .*/Xcwd/a/b/c$', trim(execute('verbose pwd')))
  3086. bwipe!
  3087. call assert_match('/Xcwd/a/b$', getcwd())
  3088. call assert_match('\[tabpage\] .*/Xcwd/a/b$', trim(execute('verbose pwd')))
  3089. bwipe!
  3090. call assert_match('/Xcwd/a$', getcwd())
  3091. call assert_match('\[global\] .*/Xcwd/a$', trim(execute('verbose pwd')))
  3092. bwipe!
  3093. call chdir(saveddir)
  3094. endfunc
  3095. func Test_bufwipeout_changes_window()
  3096. " This should not crash, but we don't have any expectations about what
  3097. " happens, changing window in BufWipeout has unpredictable results.
  3098. tabedit
  3099. let g:window_id = win_getid()
  3100. topleft new
  3101. setlocal bufhidden=wipe
  3102. autocmd BufWipeout <buffer> call win_gotoid(g:window_id)
  3103. tabprevious
  3104. +tabclose
  3105. unlet g:window_id
  3106. au! BufWipeout
  3107. %bwipe!
  3108. endfunc
  3109. func Test_v_event_readonly()
  3110. autocmd CompleteChanged * let v:event.width = 0
  3111. call assert_fails("normal! i\<C-X>\<C-V>", 'E46:')
  3112. au! CompleteChanged
  3113. autocmd DirChangedPre * let v:event.directory = ''
  3114. call assert_fails('cd .', 'E46:')
  3115. au! DirChangedPre
  3116. autocmd ModeChanged * let v:event.new_mode = ''
  3117. call assert_fails('normal! cc', 'E46:')
  3118. au! ModeChanged
  3119. autocmd TextYankPost * let v:event.operator = ''
  3120. call assert_fails('normal! yy', 'E46:')
  3121. au! TextYankPost
  3122. endfunc
  3123. " Test for ModeChanged pattern
  3124. func Test_mode_changes()
  3125. let g:index = 0
  3126. let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'i', 'ix', 'i', 'ic', 'i', 'n', 'no', 'noV', 'n', 'V', 'v', 's', 'n']
  3127. func! TestMode()
  3128. call assert_equal(g:mode_seq[g:index], get(v:event, "old_mode"))
  3129. call assert_equal(g:mode_seq[g:index + 1], get(v:event, "new_mode"))
  3130. call assert_equal(mode(1), get(v:event, "new_mode"))
  3131. let g:index += 1
  3132. endfunc
  3133. au ModeChanged * :call TestMode()
  3134. let g:n_to_any = 0
  3135. au ModeChanged n:* let g:n_to_any += 1
  3136. call feedkeys("i\<esc>vVca\<CR>\<C-X>\<C-L>\<esc>ggdV\<MouseMove>G", 'tnix')
  3137. let g:V_to_v = 0
  3138. au ModeChanged V:v let g:V_to_v += 1
  3139. call feedkeys("Vv\<C-G>\<esc>", 'tnix')
  3140. call assert_equal(len(filter(g:mode_seq[1:], {idx, val -> val == 'n'})), g:n_to_any)
  3141. call assert_equal(1, g:V_to_v)
  3142. call assert_equal(len(g:mode_seq) - 1, g:index)
  3143. let g:n_to_i = 0
  3144. au ModeChanged n:i let g:n_to_i += 1
  3145. let g:n_to_niI = 0
  3146. au ModeChanged i:niI let g:n_to_niI += 1
  3147. let g:niI_to_i = 0
  3148. au ModeChanged niI:i let g:niI_to_i += 1
  3149. let g:nany_to_i = 0
  3150. au ModeChanged n*:i let g:nany_to_i += 1
  3151. let g:i_to_n = 0
  3152. au ModeChanged i:n let g:i_to_n += 1
  3153. let g:nori_to_any = 0
  3154. au ModeChanged [ni]:* let g:nori_to_any += 1
  3155. let g:i_to_any = 0
  3156. au ModeChanged i:* let g:i_to_any += 1
  3157. let g:index = 0
  3158. let g:mode_seq = ['n', 'i', 'niI', 'i', 'n']
  3159. call feedkeys("a\<C-O>l\<esc>", 'tnix')
  3160. call assert_equal(len(g:mode_seq) - 1, g:index)
  3161. call assert_equal(1, g:n_to_i)
  3162. call assert_equal(1, g:n_to_niI)
  3163. call assert_equal(1, g:niI_to_i)
  3164. call assert_equal(2, g:nany_to_i)
  3165. call assert_equal(1, g:i_to_n)
  3166. call assert_equal(2, g:i_to_any)
  3167. call assert_equal(3, g:nori_to_any)
  3168. if has('terminal')
  3169. let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n']
  3170. call feedkeys(":term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
  3171. call assert_equal(len(g:mode_seq) - 1, g:index)
  3172. call assert_equal(1, g:n_to_i)
  3173. call assert_equal(1, g:n_to_niI)
  3174. call assert_equal(1, g:niI_to_i)
  3175. call assert_equal(2, g:nany_to_i)
  3176. call assert_equal(1, g:i_to_n)
  3177. call assert_equal(2, g:i_to_any)
  3178. call assert_equal(5, g:nori_to_any)
  3179. endif
  3180. let g:n_to_c = 0
  3181. au ModeChanged n:c let g:n_to_c += 1
  3182. let g:c_to_n = 0
  3183. au ModeChanged c:n let g:c_to_n += 1
  3184. let g:mode_seq += ['c', 'n', 'c', 'n']
  3185. call feedkeys("q:\<C-C>\<Esc>", 'tnix')
  3186. call assert_equal(len(g:mode_seq) - 1, g:index)
  3187. call assert_equal(2, g:n_to_c)
  3188. call assert_equal(2, g:c_to_n)
  3189. let g:n_to_v = 0
  3190. au ModeChanged n:v let g:n_to_v += 1
  3191. let g:v_to_n = 0
  3192. au ModeChanged v:n let g:v_to_n += 1
  3193. let g:mode_seq += ['v', 'n']
  3194. call feedkeys("v\<C-C>", 'tnix')
  3195. call assert_equal(len(g:mode_seq) - 1, g:index)
  3196. call assert_equal(1, g:n_to_v)
  3197. call assert_equal(1, g:v_to_n)
  3198. let g:mode_seq += ['c', 'cr', 'c', 'cr', 'n']
  3199. call feedkeys(":\<Insert>\<Insert>\<Insert>\<CR>", 'tnix')
  3200. call assert_equal(len(g:mode_seq) - 1, g:index)
  3201. au! ModeChanged
  3202. delfunc TestMode
  3203. unlet! g:mode_seq
  3204. unlet! g:index
  3205. unlet! g:n_to_any
  3206. unlet! g:V_to_v
  3207. unlet! g:n_to_i
  3208. unlet! g:n_to_niI
  3209. unlet! g:niI_to_i
  3210. unlet! g:nany_to_i
  3211. unlet! g:i_to_n
  3212. unlet! g:nori_to_any
  3213. unlet! g:i_to_any
  3214. unlet! g:n_to_c
  3215. unlet! g:c_to_n
  3216. unlet! g:n_to_v
  3217. unlet! g:v_to_n
  3218. endfunc
  3219. func Test_recursive_ModeChanged()
  3220. au! ModeChanged * norm 0u
  3221. sil! norm 
  3222. au! ModeChanged
  3223. endfunc
  3224. func Test_ModeChanged_starts_visual()
  3225. " This was triggering ModeChanged before setting VIsual, causing a crash.
  3226. au! ModeChanged * norm 0u
  3227. sil! norm 
  3228. au! ModeChanged
  3229. endfunc
  3230. func Test_noname_autocmd()
  3231. augroup test_noname_autocmd_group
  3232. autocmd!
  3233. autocmd BufEnter * call add(s:li, ["BufEnter", expand("<afile>")])
  3234. autocmd BufDelete * call add(s:li, ["BufDelete", expand("<afile>")])
  3235. autocmd BufLeave * call add(s:li, ["BufLeave", expand("<afile>")])
  3236. autocmd BufUnload * call add(s:li, ["BufUnload", expand("<afile>")])
  3237. autocmd BufWipeout * call add(s:li, ["BufWipeout", expand("<afile>")])
  3238. augroup END
  3239. let s:li = []
  3240. edit foo
  3241. call assert_equal([['BufUnload', ''], ['BufDelete', ''], ['BufWipeout', ''], ['BufEnter', 'foo']], s:li)
  3242. au! test_noname_autocmd_group
  3243. augroup! test_noname_autocmd_group
  3244. endfunc
  3245. func Test_autocmd_split_dummy()
  3246. " Autocommand trying to split a window containing a dummy buffer.
  3247. auto BufReadPre * exe "sbuf " .. expand("<abuf>")
  3248. " Avoid the "W11" prompt
  3249. au FileChangedShell * let v:fcs_choice = 'reload'
  3250. func Xautocmd_changelist()
  3251. cal writefile(['Xtestfile2:4:4'], 'Xerr')
  3252. edit Xerr
  3253. lex 'Xtestfile2:4:4'
  3254. endfunc
  3255. call Xautocmd_changelist()
  3256. " Should get E86, but it doesn't always happen (timing?)
  3257. silent! call Xautocmd_changelist()
  3258. au! BufReadPre
  3259. au! FileChangedShell
  3260. delfunc Xautocmd_changelist
  3261. bwipe! Xerr
  3262. call delete('Xerr')
  3263. endfunc
  3264. " This was crashing because there was only one window to execute autocommands
  3265. " in.
  3266. func Test_autocmd_nested_setbufvar()
  3267. CheckFeature python3
  3268. set hidden
  3269. edit Xaaa
  3270. edit Xbbb
  3271. call setline(1, 'bar')
  3272. enew
  3273. au BufWriteCmd Xbbb ++nested call setbufvar('Xaaa', '&ft', 'foo') | bw! Xaaa
  3274. au FileType foo call py3eval('vim.current.buffer.options["cindent"]')
  3275. wall
  3276. au! BufWriteCmd
  3277. au! FileType foo
  3278. set nohidden
  3279. call delete('Xaaa')
  3280. call delete('Xbbb')
  3281. %bwipe!
  3282. endfunc
  3283. func SetupVimTest_shm()
  3284. let g:bwe = []
  3285. let g:brp = []
  3286. set shortmess-=l
  3287. messages clear
  3288. let dirname='XVimTestSHM'
  3289. call mkdir(dirname, 'R')
  3290. call writefile(['test'], dirname .. '/1')
  3291. call writefile(['test'], dirname .. '/2')
  3292. call writefile(['test'], dirname .. '/3')
  3293. augroup test
  3294. autocmd!
  3295. autocmd BufWinEnter * call add(g:bwe, $'BufWinEnter: {expand('<amatch>')}')
  3296. autocmd BufReadPost * call add(g:brp, $'BufReadPost: {expand('<amatch>')}')
  3297. augroup END
  3298. call setqflist([
  3299. \ {'filename': dirname .. '/1', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0},
  3300. \ {'filename': dirname .. '/2', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0},
  3301. \ {'filename': dirname .. '/3', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0}
  3302. \ ])
  3303. cdo! substitute/test/TEST
  3304. " clean up
  3305. noa enew!
  3306. set shortmess&vim
  3307. augroup test
  3308. autocmd!
  3309. augroup END
  3310. augroup! test
  3311. endfunc
  3312. func Test_autocmd_shortmess()
  3313. CheckNotMSWindows
  3314. call SetupVimTest_shm()
  3315. let output = execute(':mess')->split('\n')
  3316. let info = copy(output)->filter({idx, val -> val =~# '\d of 3'} )
  3317. let bytes = copy(output)->filter({idx, val -> val =~# 'bytes'} )
  3318. " We test the following here:
  3319. " BufReadPost should have been triggered 3 times, once per file
  3320. " BufWinEnter should have been triggered 3 times, once per file
  3321. " FileInfoMessage should have been shown 3 times, regardless of shm option
  3322. " "(x of 3)" message from :cnext has been shown 3 times
  3323. call assert_equal(3, g:brp->len())
  3324. call assert_equal(3, g:bwe->len())
  3325. call assert_equal(3, info->len())
  3326. call assert_equal(3, bytes->len())
  3327. delfunc SetupVimTest_shm
  3328. endfunc
  3329. func Test_autocmd_invalidates_undo_on_textchanged()
  3330. CheckRunVimInTerminal
  3331. let script =<< trim END
  3332. set hidden
  3333. " create quickfix list (at least 2 lines to move line)
  3334. vimgrep /u/j %
  3335. " enter quickfix window
  3336. cwindow
  3337. " set modifiable
  3338. setlocal modifiable
  3339. " set autocmd to clear quickfix list
  3340. autocmd! TextChanged <buffer> call setqflist([])
  3341. " move line
  3342. move+1
  3343. END
  3344. call writefile(script, 'XTest_autocmd_invalidates_undo_on_textchanged', 'D')
  3345. let buf = RunVimInTerminal('XTest_autocmd_invalidates_undo_on_textchanged', {'rows': 20})
  3346. call term_sendkeys(buf, ":so %\<cr>")
  3347. call term_sendkeys(buf, "G")
  3348. call WaitForAssert({-> assert_match('^XTest_autocmd_invalidates_undo_on_textchanged\s*$', term_getline(buf, 20))}, 1000)
  3349. call StopVimInTerminal(buf)
  3350. endfunc
  3351. func Test_autocmd_creates_new_buffer_on_bufleave()
  3352. e a.txt
  3353. e b.txt
  3354. setlocal bufhidden=wipe
  3355. autocmd BufLeave <buffer> diffsplit c.txt
  3356. bn
  3357. call assert_equal(1, winnr('$'))
  3358. call assert_equal('a.txt', bufname('%'))
  3359. bw a.txt
  3360. bw c.txt
  3361. endfunc
  3362. " Ensure `expected` was just recently written as a Vim session
  3363. func s:assert_session_path(expected)
  3364. call assert_equal(a:expected, v:this_session)
  3365. endfunc
  3366. " Check for `expected` after a session is written to-disk.
  3367. func s:watch_for_session_path(expected)
  3368. execute 'autocmd SessionWritePost * ++once execute "call s:assert_session_path(\"'
  3369. \ . a:expected
  3370. \ . '\")"'
  3371. endfunc
  3372. " Ensure v:this_session gets the full session path, if explicitly stated
  3373. func Test_explicit_session_absolute_path()
  3374. %bwipeout!
  3375. let directory = getcwd()
  3376. let v:this_session = ""
  3377. let name = "some_file.vim"
  3378. let expected = fnamemodify(name, ":p")
  3379. call s:watch_for_session_path(expected)
  3380. execute "mksession! " .. expected
  3381. call delete(expected)
  3382. endfunc
  3383. " Ensure v:this_session gets the full session path, if explicitly stated
  3384. func Test_explicit_session_relative_path()
  3385. %bwipeout!
  3386. let directory = getcwd()
  3387. let v:this_session = ""
  3388. let name = "some_file.vim"
  3389. let expected = fnamemodify(name, ":p")
  3390. call s:watch_for_session_path(expected)
  3391. execute "mksession! " .. name
  3392. call delete(expected)
  3393. endfunc
  3394. " Ensure v:this_session gets the full session path, if not specified
  3395. func Test_implicit_session()
  3396. %bwipeout!
  3397. let directory = getcwd()
  3398. let v:this_session = ""
  3399. let expected = fnamemodify("Session.vim", ":p")
  3400. call s:watch_for_session_path(expected)
  3401. mksession!
  3402. call delete(expected)
  3403. endfunc
  3404. " Test TextChangedI and TextChanged
  3405. func Test_Changed_ChangedI()
  3406. " Run this test in a terminal because it requires running the main loop.
  3407. " Don't use CheckRunVimInTerminal as that will skip the test on Windows.
  3408. CheckFeature terminal
  3409. CheckNotGui
  3410. " Starting a terminal to run Vim is always considered flaky.
  3411. let g:test_is_flaky = 1
  3412. call writefile(['one', 'two', 'three'], 'XTextChangedI2', 'D')
  3413. let before =<< trim END
  3414. set ttimeout ttimeoutlen=10
  3415. let [g:autocmd_n, g:autocmd_i] = ['','']
  3416. func TextChangedAutocmd(char)
  3417. let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick
  3418. call writefile([$'{g:autocmd_n},{g:autocmd_i}'], 'XTextChangedI3')
  3419. endfunc
  3420. au TextChanged <buffer> :call TextChangedAutocmd('N')
  3421. au TextChangedI <buffer> :call TextChangedAutocmd('I')
  3422. nnoremap <CR> o<Esc>
  3423. autocmd SafeState * ++once call writefile([''], 'XTextChangedI3')
  3424. END
  3425. call writefile(before, 'Xinit', 'D')
  3426. let buf = term_start(
  3427. \ GetVimCommandCleanTerm() .. '-n -S Xinit XTextChangedI2',
  3428. \ {'term_rows': 10})
  3429. call assert_equal('running', term_getstatus(buf))
  3430. call WaitForAssert({-> assert_true(filereadable('XTextChangedI3'))})
  3431. defer delete('XTextChangedI3')
  3432. call WaitForAssert({-> assert_equal([''], readfile('XTextChangedI3'))})
  3433. " TextChanged should trigger if a mapping enters and leaves Insert mode.
  3434. call term_sendkeys(buf, "\<CR>")
  3435. call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))})
  3436. call term_sendkeys(buf, "i")
  3437. call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
  3438. call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))})
  3439. " TextChangedI should trigger if change is done in Insert mode.
  3440. call term_sendkeys(buf, "f")
  3441. call WaitForAssert({-> assert_equal('N4,I5', readfile('XTextChangedI3')->join("\n"))})
  3442. call term_sendkeys(buf, "o")
  3443. call WaitForAssert({-> assert_equal('N4,I6', readfile('XTextChangedI3')->join("\n"))})
  3444. call term_sendkeys(buf, "o")
  3445. call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))})
  3446. " TextChanged shouldn't trigger when leaving Insert mode and TextChangedI
  3447. " has been triggered.
  3448. call term_sendkeys(buf, "\<Esc>")
  3449. call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
  3450. call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))})
  3451. " TextChanged should trigger if change is done in Normal mode.
  3452. call term_sendkeys(buf, "yyp")
  3453. call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
  3454. " TextChangedI shouldn't trigger if change isn't done in Insert mode.
  3455. call term_sendkeys(buf, "i")
  3456. call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
  3457. call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
  3458. call term_sendkeys(buf, "\<Esc>")
  3459. call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
  3460. call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))})
  3461. " TextChangedI should trigger if change is a mix of Normal and Insert modes.
  3462. func! s:validate_mixed_textchangedi(buf, keys)
  3463. let buf = a:buf
  3464. call term_sendkeys(buf, "ifoo")
  3465. call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
  3466. call term_sendkeys(buf, "\<Esc>")
  3467. call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
  3468. call term_sendkeys(buf, ":let [g:autocmd_n, g:autocmd_i] = ['', '']\<CR>")
  3469. call writefile([], 'XTextChangedI3')
  3470. call term_sendkeys(buf, a:keys)
  3471. call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))})
  3472. call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))})
  3473. call term_sendkeys(buf, "\<Esc>")
  3474. call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))})
  3475. call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))})
  3476. endfunc
  3477. call s:validate_mixed_textchangedi(buf, "o")
  3478. call s:validate_mixed_textchangedi(buf, "O")
  3479. call s:validate_mixed_textchangedi(buf, "ciw")
  3480. call s:validate_mixed_textchangedi(buf, "cc")
  3481. call s:validate_mixed_textchangedi(buf, "C")
  3482. call s:validate_mixed_textchangedi(buf, "s")
  3483. call s:validate_mixed_textchangedi(buf, "S")
  3484. " clean up
  3485. bwipe!
  3486. endfunc
  3487. " Test that filetype detection still works when SwapExists autocommand sets
  3488. " filetype in another buffer.
  3489. func Test_SwapExists_set_other_buf_filetype()
  3490. let lines =<< trim END
  3491. set nocompatible directory=.
  3492. filetype on
  3493. let g:buf = bufnr()
  3494. new
  3495. func SwapExists()
  3496. let v:swapchoice = 'o'
  3497. call setbufvar(g:buf, '&filetype', 'text')
  3498. endfunc
  3499. func SafeState()
  3500. edit <script>
  3501. redir! > XftSwapExists.out
  3502. set readonly? filetype?
  3503. redir END
  3504. qall!
  3505. endfunc
  3506. autocmd SwapExists * ++nested call SwapExists()
  3507. autocmd SafeState * ++nested ++once call SafeState()
  3508. END
  3509. call writefile(lines, 'XftSwapExists.vim', 'D')
  3510. new XftSwapExists.vim
  3511. if RunVim('', '', ' -S XftSwapExists.vim')
  3512. call assert_equal(
  3513. \ ['', ' readonly', ' filetype=vim'],
  3514. \ readfile('XftSwapExists.out'))
  3515. call delete('XftSwapExists.out')
  3516. endif
  3517. bwipe!
  3518. endfunc
  3519. " Test that file is not marked as modified when SwapExists autocommand sets
  3520. " 'modified' in another buffer.
  3521. func Test_SwapExists_set_other_buf_modified()
  3522. let lines =<< trim END
  3523. set nocompatible directory=.
  3524. let g:buf = bufnr()
  3525. new
  3526. func SwapExists()
  3527. let v:swapchoice = 'o'
  3528. call setbufvar(g:buf, '&modified', 1)
  3529. endfunc
  3530. func SafeState()
  3531. edit <script>
  3532. redir! > XmodSwapExists.out
  3533. set readonly? modified?
  3534. redir END
  3535. qall!
  3536. endfunc
  3537. autocmd SwapExists * ++nested call SwapExists()
  3538. autocmd SafeState * ++nested ++once call SafeState()
  3539. END
  3540. call writefile(lines, 'XmodSwapExists.vim', 'D')
  3541. new XmodSwapExists.vim
  3542. if RunVim('', '', ' -S XmodSwapExists.vim')
  3543. call assert_equal(
  3544. \ ['', ' readonly', 'nomodified'],
  3545. \ readfile('XmodSwapExists.out'))
  3546. call delete('XmodSwapExists.out')
  3547. endif
  3548. bwipe!
  3549. endfunc
  3550. func Test_BufEnter_botline()
  3551. set hidden
  3552. call writefile(range(10), 'Xxx1', 'D')
  3553. call writefile(range(20), 'Xxx2', 'D')
  3554. edit Xxx1
  3555. edit Xxx2
  3556. au BufEnter Xxx1 call assert_true(line('w$') > 1)
  3557. edit Xxx1
  3558. bwipe! Xxx1
  3559. bwipe! Xxx2
  3560. au! BufEnter Xxx1
  3561. set hidden&vim
  3562. endfunc
  3563. " This was using freed memory
  3564. func Test_autocmd_BufWinLeave_with_vsp()
  3565. new
  3566. let fname = 'XXXBufWinLeaveUAF.txt'
  3567. let dummy = 'XXXDummy.txt'
  3568. call writefile([], fname)
  3569. call writefile([], dummy)
  3570. defer delete(fname)
  3571. defer delete(dummy)
  3572. exe "e " fname
  3573. vsp
  3574. augroup testing
  3575. exe "au BufWinLeave " .. fname .. " :e " dummy .. "| vsp " .. fname
  3576. augroup END
  3577. bw
  3578. call CleanUpTestAuGroup()
  3579. exe "bw! " .. dummy
  3580. endfunc
  3581. func Test_OptionSet_cmdheight()
  3582. set mouse=a laststatus=2
  3583. au OptionSet cmdheight :let &l:ch = v:option_new
  3584. resize -1
  3585. call assert_equal(2, &l:ch)
  3586. resize +1
  3587. call assert_equal(1, &l:ch)
  3588. call Ntest_setmouse(&lines - 1, 1)
  3589. call feedkeys("\<LeftMouse>", 'xt')
  3590. call Ntest_setmouse(&lines - 2, 1)
  3591. call feedkeys("\<LeftDrag>", 'xt')
  3592. call assert_equal(2, &l:ch)
  3593. tabnew | resize +1
  3594. call assert_equal(1, &l:ch)
  3595. tabfirst
  3596. call assert_equal(2, &l:ch)
  3597. tabonly
  3598. set cmdheight& mouse& laststatus&
  3599. endfunc
  3600. func Test_eventignorewin()
  3601. defer CleanUpTestAuGroup()
  3602. augroup testing
  3603. au WinEnter * :call add(g:evs, ["WinEnter", expand("<afile>")])
  3604. au WinLeave * :call add(g:evs, ["WinLeave", expand("<afile>")])
  3605. au BufWinEnter * :call add(g:evs, ["BufWinEnter", expand("<afile>")])
  3606. augroup END
  3607. let g:evs = []
  3608. set eventignorewin=WinLeave,WinEnter
  3609. split foo
  3610. call assert_equal([['BufWinEnter', 'foo']], g:evs)
  3611. set eventignorewin=all
  3612. edit bar
  3613. call assert_equal([['BufWinEnter', 'foo']], g:evs)
  3614. set eventignorewin=
  3615. wincmd w
  3616. call assert_equal([['BufWinEnter', 'foo'], ['WinLeave', 'bar']], g:evs)
  3617. only!
  3618. %bwipe!
  3619. set eventignorewin&
  3620. unlet g:evs
  3621. endfunc
  3622. func Test_WinScrolled_Resized_eiw()
  3623. CheckRunVimInTerminal
  3624. let lines =<< trim END
  3625. call setline(1, ['foo']->repeat(32))
  3626. set eventignorewin=WinScrolled,WinResized
  3627. split
  3628. let [g:afile,g:resized,g:scrolled] = ['none',0,0]
  3629. au WinScrolled * let [g:afile,g:scrolled] = [expand('<afile>'),g:scrolled+1]
  3630. au WinResized * let [g:afile,g:resized] = [expand('<afile>'),g:resized+1]
  3631. END
  3632. call writefile(lines, 'Xtest_winscrolled_eiw', 'D')
  3633. let buf = RunVimInTerminal('-S Xtest_winscrolled_eiw', {'rows': 10})
  3634. " Both windows are ignoring resize events
  3635. call term_sendkeys(buf, "\<C-W>-")
  3636. call TermWait(buf)
  3637. call term_sendkeys(buf, ":echo g:afile g:resized g:scrolled\<CR>")
  3638. call WaitForAssert({-> assert_equal('none 0 0', term_getline(buf, 10))}, 1000)
  3639. " And scroll events
  3640. call term_sendkeys(buf, "Ggg")
  3641. call TermWait(buf)
  3642. call term_sendkeys(buf, ":echo g:afile g:resized g:scrolled\<CR>")
  3643. call WaitForAssert({-> assert_equal('none 0 0', term_getline(buf, 10))}, 1000)
  3644. " Un-ignore events in second window, make first window current and resize
  3645. call term_sendkeys(buf, ":set eventignorewin=\<CR>\<C-W>w\<C-W>+")
  3646. call TermWait(buf)
  3647. call term_sendkeys(buf, ":echo win_getid() g:afile g:resized g:scrolled\<CR>")
  3648. call WaitForAssert({-> assert_equal('1000 1001 1 1', term_getline(buf, 10))}, 1000)
  3649. call StopVimInTerminal(buf)
  3650. endfunc
  3651. " vim: shiftwidth=2 sts=2 expandtab