inccommand_spec.lua 85 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811
  1. local helpers = require('test.functional.helpers')(after_each)
  2. local Screen = require('test.functional.ui.screen')
  3. local clear = helpers.clear
  4. local command = helpers.command
  5. local curbufmeths = helpers.curbufmeths
  6. local eq = helpers.eq
  7. local eval = helpers.eval
  8. local feed_command = helpers.feed_command
  9. local expect = helpers.expect
  10. local feed = helpers.feed
  11. local insert = helpers.insert
  12. local meths = helpers.meths
  13. local neq = helpers.neq
  14. local ok = helpers.ok
  15. local retry = helpers.retry
  16. local source = helpers.source
  17. local poke_eventloop = helpers.poke_eventloop
  18. local nvim = helpers.nvim
  19. local sleep = helpers.sleep
  20. local nvim_dir = helpers.nvim_dir
  21. local assert_alive = helpers.assert_alive
  22. local default_text = [[
  23. Inc substitution on
  24. two lines
  25. ]]
  26. local multiline_text = [[
  27. 1 2 3
  28. A B C
  29. 4 5 6
  30. X Y Z
  31. 7 8 9
  32. ]]
  33. local multimatch_text = [[
  34. a bdc eae a fgl lzia r
  35. x
  36. ]]
  37. local multibyte_text = [[
  38. £ ¥ ѫѫ PEPPERS
  39. £ ¥ ѫfѫ
  40. a£ ѫ¥KOL
  41. £ ¥ libm
  42. £ ¥
  43. ]]
  44. local long_multiline_text = [[
  45. 1 2 3
  46. A B C
  47. 4 5 6
  48. X Y Z
  49. 7 8 9
  50. K L M
  51. a b c
  52. d e f
  53. q r s
  54. x y z
  55. £ m n
  56. t œ ¥
  57. ]]
  58. local function common_setup(screen, inccommand, text)
  59. if screen then
  60. command("syntax on")
  61. command("set nohlsearch")
  62. command("hi Substitute guifg=red guibg=yellow")
  63. command("set display-=msgsep")
  64. screen:attach()
  65. screen:set_default_attr_ids({
  66. [1] = {foreground = Screen.colors.Fuchsia},
  67. [2] = {foreground = Screen.colors.Brown, bold = true},
  68. [3] = {foreground = Screen.colors.SlateBlue},
  69. [4] = {bold = true, foreground = Screen.colors.SlateBlue},
  70. [5] = {foreground = Screen.colors.DarkCyan},
  71. [6] = {bold = true},
  72. [7] = {underline = true, bold = true, foreground = Screen.colors.SlateBlue},
  73. [8] = {foreground = Screen.colors.Slateblue, underline = true},
  74. [9] = {background = Screen.colors.Yellow},
  75. [10] = {reverse = true},
  76. [11] = {reverse = true, bold=true},
  77. [12] = {foreground = Screen.colors.Red, background = Screen.colors.Yellow},
  78. [13] = {bold = true, foreground = Screen.colors.SeaGreen},
  79. [14] = {foreground = Screen.colors.White, background = Screen.colors.Red},
  80. [15] = {bold=true, foreground=Screen.colors.Blue},
  81. [16] = {background=Screen.colors.Grey90}, -- cursorline
  82. [17] = {foreground = Screen.colors.Blue1},
  83. vis = {background=Screen.colors.LightGrey}
  84. })
  85. end
  86. command("set inccommand=" .. (inccommand or ""))
  87. if text then
  88. insert(text)
  89. end
  90. end
  91. describe(":substitute, inccommand=split interactivity", function()
  92. before_each(function()
  93. clear()
  94. common_setup(nil, "split", default_text)
  95. end)
  96. -- Test the tests: verify that the `1==bufnr('$')` assertion
  97. -- in the "no preview" tests (below) actually means something.
  98. it("previews interactive cmdline", function()
  99. feed(':%s/tw/MO/g')
  100. retry(nil, 1000, function()
  101. eq(2, eval("bufnr('$')"))
  102. end)
  103. end)
  104. it("no preview if invoked by a script", function()
  105. source('%s/tw/MO/g')
  106. poke_eventloop()
  107. eq(1, eval("bufnr('$')"))
  108. -- sanity check: assert the buffer state
  109. expect(default_text:gsub("tw", "MO"))
  110. end)
  111. it("no preview if invoked by feedkeys()", function()
  112. -- in a script...
  113. source([[:call feedkeys(":%s/tw/MO/g\<CR>")]])
  114. poke_eventloop()
  115. -- or interactively...
  116. feed([[:call feedkeys(":%s/tw/MO/g\<CR>")<CR>]])
  117. poke_eventloop()
  118. eq(1, eval("bufnr('$')"))
  119. -- sanity check: assert the buffer state
  120. expect(default_text:gsub("tw", "MO"))
  121. end)
  122. end)
  123. describe(":substitute, 'inccommand' preserves", function()
  124. before_each(clear)
  125. it('listed buffers (:ls)', function()
  126. local screen = Screen.new(30,10)
  127. common_setup(screen, "split", "ABC")
  128. feed_command("%s/AB/BA/")
  129. feed_command("ls")
  130. screen:expect([[
  131. {15:~ }|
  132. {15:~ }|
  133. {15:~ }|
  134. {15:~ }|
  135. {15:~ }|
  136. :ls |
  137. 1 %a + "[No Name]" |
  138. line 1 |
  139. {13:Press ENTER or type command to}|
  140. {13: continue}^ |
  141. ]])
  142. end)
  143. for _, case in pairs{"", "split", "nosplit"} do
  144. it("various delimiters (inccommand="..case..")", function()
  145. insert(default_text)
  146. feed_command("set inccommand=" .. case)
  147. local delims = { '/', '#', ';', '%', ',', '@', '!' }
  148. for _,delim in pairs(delims) do
  149. feed_command("%s"..delim.."lines"..delim.."LINES"..delim.."g")
  150. expect([[
  151. Inc substitution on
  152. two LINES
  153. ]])
  154. feed_command("undo")
  155. end
  156. end)
  157. end
  158. for _, case in pairs{"", "split", "nosplit"} do
  159. it("'undolevels' (inccommand="..case..")", function()
  160. feed_command("set undolevels=139")
  161. feed_command("setlocal undolevels=34")
  162. feed_command("set inccommand=" .. case)
  163. insert("as")
  164. feed(":%s/as/glork/<enter>")
  165. eq(meths.get_option('undolevels'), 139)
  166. eq(curbufmeths.get_option('undolevels'), 34)
  167. end)
  168. end
  169. for _, case in ipairs({"", "split", "nosplit"}) do
  170. it("empty undotree() (inccommand="..case..")", function()
  171. feed_command("set undolevels=1000")
  172. feed_command("set inccommand=" .. case)
  173. local expected_undotree = eval("undotree()")
  174. -- Start typing an incomplete :substitute command.
  175. feed([[:%s/e/YYYY/g]])
  176. poke_eventloop()
  177. -- Cancel the :substitute.
  178. feed([[<C-\><C-N>]])
  179. -- The undo tree should be unchanged.
  180. eq(expected_undotree, eval("undotree()"))
  181. eq({}, eval("undotree()")["entries"])
  182. end)
  183. end
  184. for _, case in ipairs({"", "split", "nosplit"}) do
  185. it("undotree() with branches (inccommand="..case..")", function()
  186. feed_command("set undolevels=1000")
  187. feed_command("set inccommand=" .. case)
  188. -- Make some changes.
  189. feed([[isome text 1<C-\><C-N>]])
  190. feed([[osome text 2<C-\><C-N>]])
  191. -- Add an undo branch.
  192. feed([[u]])
  193. -- More changes, more undo branches.
  194. feed([[osome text 3<C-\><C-N>]])
  195. feed([[AX<C-\><C-N>]])
  196. feed([[...]])
  197. feed([[uu]])
  198. feed([[osome text 4<C-\><C-N>]])
  199. feed([[u<C-R>u]])
  200. feed([[osome text 5<C-\><C-N>]])
  201. expect([[
  202. some text 1
  203. some text 3XX
  204. some text 5]])
  205. local expected_undotree = eval("undotree()")
  206. eq(5, #expected_undotree["entries"]) -- sanity
  207. -- Start typing an incomplete :substitute command.
  208. feed([[:%s/e/YYYY/g]])
  209. poke_eventloop()
  210. -- Cancel the :substitute.
  211. feed([[<C-\><C-N>]])
  212. -- The undo tree should be unchanged.
  213. eq(expected_undotree, eval("undotree()"))
  214. end)
  215. end
  216. for _, case in pairs{"", "split", "nosplit"} do
  217. it("b:changedtick (inccommand="..case..")", function()
  218. feed_command("set inccommand=" .. case)
  219. feed([[isome text 1<C-\><C-N>]])
  220. feed([[osome text 2<C-\><C-N>]])
  221. local expected_tick = eval("b:changedtick")
  222. ok(expected_tick > 0)
  223. expect([[
  224. some text 1
  225. some text 2]])
  226. feed(":%s/e/XXX/")
  227. poke_eventloop()
  228. eq(expected_tick, eval("b:changedtick"))
  229. end)
  230. end
  231. for _, case in pairs{"", "split", "nosplit"} do
  232. it("visual selection for non-previewable command (inccommand="..case..") #5888", function()
  233. local screen = Screen.new(30,10)
  234. common_setup(screen, case, default_text)
  235. feed('1G2V')
  236. feed(':s')
  237. screen:expect([[
  238. {vis:Inc substitution on} |
  239. t{vis:wo lines} |
  240. |
  241. {15:~ }|
  242. {15:~ }|
  243. {15:~ }|
  244. {15:~ }|
  245. {15:~ }|
  246. {15:~ }|
  247. :'<,'>s^ |
  248. ]])
  249. feed('o')
  250. screen:expect([[
  251. {vis:Inc substitution on} |
  252. t{vis:wo lines} |
  253. |
  254. {15:~ }|
  255. {15:~ }|
  256. {15:~ }|
  257. {15:~ }|
  258. {15:~ }|
  259. {15:~ }|
  260. :'<,'>so^ |
  261. ]])
  262. end)
  263. end
  264. end)
  265. describe(":substitute, 'inccommand' preserves undo", function()
  266. local cases = { "", "split", "nosplit" }
  267. local substrings = {
  268. ":%s/1",
  269. ":%s/1/",
  270. ":%s/1/<bs>",
  271. ":%s/1/a",
  272. ":%s/1/a<bs>",
  273. ":%s/1/ax",
  274. ":%s/1/ax<bs>",
  275. ":%s/1/ax<bs><bs>",
  276. ":%s/1/ax<bs><bs><bs>",
  277. ":%s/1/ax/",
  278. ":%s/1/ax/<bs>",
  279. ":%s/1/ax/<bs>/",
  280. ":%s/1/ax/g",
  281. ":%s/1/ax/g<bs>",
  282. ":%s/1/ax/g<bs><bs>"
  283. }
  284. local function test_sub(substring, split, redoable)
  285. clear()
  286. feed_command("set inccommand=" .. split)
  287. insert("1")
  288. feed("o2<esc>")
  289. feed_command("undo")
  290. feed("o3<esc>")
  291. if redoable then
  292. feed("o4<esc>")
  293. feed_command("undo")
  294. end
  295. feed(substring.. "<enter>")
  296. feed_command("undo")
  297. feed("g-")
  298. expect([[
  299. 1
  300. 2]])
  301. feed("g+")
  302. expect([[
  303. 1
  304. 3]])
  305. end
  306. local function test_notsub(substring, split, redoable)
  307. clear()
  308. feed_command("set inccommand=" .. split)
  309. insert("1")
  310. feed("o2<esc>")
  311. feed_command("undo")
  312. feed("o3<esc>")
  313. if redoable then
  314. feed("o4<esc>")
  315. feed_command("undo")
  316. end
  317. feed(substring .. "<esc>")
  318. feed("g-")
  319. expect([[
  320. 1
  321. 2]])
  322. feed("g+")
  323. expect([[
  324. 1
  325. 3]])
  326. if redoable then
  327. feed("<c-r>")
  328. expect([[
  329. 1
  330. 3
  331. 4]])
  332. end
  333. end
  334. local function test_threetree(substring, split)
  335. clear()
  336. feed_command("set inccommand=" .. split)
  337. insert("1")
  338. feed("o2<esc>")
  339. feed("o3<esc>")
  340. feed("uu")
  341. feed("oa<esc>")
  342. feed("ob<esc>")
  343. feed("uu")
  344. feed("oA<esc>")
  345. feed("oB<esc>")
  346. -- This is the undo tree (x-Axis is timeline), we're at B now
  347. -- ----------------A - B
  348. -- /
  349. -- | --------a - b
  350. -- |/
  351. -- 1 - 2 - 3
  352. feed("2u")
  353. feed(substring .. "<esc>")
  354. expect([[
  355. 1]])
  356. feed("g-")
  357. expect([[
  358. ]])
  359. feed("g+")
  360. expect([[
  361. 1]])
  362. feed("<c-r>")
  363. expect([[
  364. 1
  365. A]])
  366. feed("g-") -- go to b
  367. feed("2u")
  368. feed(substring .. "<esc>")
  369. feed("<c-r>")
  370. expect([[
  371. 1
  372. a]])
  373. feed("g-") -- go to 3
  374. feed("2u")
  375. feed(substring .. "<esc>")
  376. feed("<c-r>")
  377. expect([[
  378. 1
  379. 2]])
  380. end
  381. it("at a non-leaf of the undo tree", function()
  382. for _, case in pairs(cases) do
  383. for _, str in pairs(substrings) do
  384. for _, redoable in pairs({true}) do
  385. test_sub(str, case, redoable)
  386. end
  387. end
  388. end
  389. end)
  390. it("at a leaf of the undo tree", function()
  391. for _, case in pairs(cases) do
  392. for _, str in pairs(substrings) do
  393. for _, redoable in pairs({false}) do
  394. test_sub(str, case, redoable)
  395. end
  396. end
  397. end
  398. end)
  399. it("when interrupting substitution", function()
  400. for _, case in pairs(cases) do
  401. for _, str in pairs(substrings) do
  402. for _, redoable in pairs({true,false}) do
  403. test_notsub(str, case, redoable)
  404. end
  405. end
  406. end
  407. end)
  408. it("in a complex undo scenario", function()
  409. for _, case in pairs(cases) do
  410. for _, str in pairs(substrings) do
  411. test_threetree(str, case)
  412. end
  413. end
  414. end)
  415. it('with undolevels=0', function()
  416. for _, case in pairs(cases) do
  417. clear()
  418. common_setup(nil, case, default_text)
  419. feed_command("set undolevels=0")
  420. feed("1G0")
  421. insert("X")
  422. feed(":%s/tw/MO/<esc>")
  423. feed_command("undo")
  424. expect(default_text)
  425. feed_command("undo")
  426. expect(default_text:gsub("Inc", "XInc"))
  427. feed_command("undo")
  428. feed_command("%s/tw/MO/g")
  429. expect(default_text:gsub("tw", "MO"))
  430. feed_command("undo")
  431. expect(default_text)
  432. feed_command("undo")
  433. expect(default_text:gsub("tw", "MO"))
  434. end
  435. end)
  436. it('with undolevels=1', function()
  437. local screen = Screen.new(20,10)
  438. for _, case in pairs(cases) do
  439. clear()
  440. common_setup(screen, case, default_text)
  441. screen:expect([[
  442. Inc substitution on |
  443. two lines |
  444. ^ |
  445. {15:~ }|
  446. {15:~ }|
  447. {15:~ }|
  448. {15:~ }|
  449. {15:~ }|
  450. {15:~ }|
  451. |
  452. ]])
  453. feed_command("set undolevels=1")
  454. feed("1G0")
  455. insert("X")
  456. feed("IY<esc>")
  457. feed(":%s/tw/MO/<esc>")
  458. -- feed_command("undo") here would cause "Press ENTER".
  459. feed("u")
  460. expect(default_text:gsub("Inc", "XInc"))
  461. feed("u")
  462. expect(default_text)
  463. feed(":%s/tw/MO/g<enter>")
  464. feed(":%s/MO/GO/g<enter>")
  465. feed(":%s/GO/NO/g<enter>")
  466. feed("u")
  467. expect(default_text:gsub("tw", "GO"))
  468. feed("u")
  469. expect(default_text:gsub("tw", "MO"))
  470. feed("u")
  471. if case == "split" then
  472. screen:expect([[
  473. Inc substitution on |
  474. ^MOo lines |
  475. |
  476. {15:~ }|
  477. {15:~ }|
  478. {15:~ }|
  479. {15:~ }|
  480. {15:~ }|
  481. {15:~ }|
  482. Already ...t change |
  483. ]])
  484. else
  485. screen:expect([[
  486. Inc substitution on |
  487. ^MOo lines |
  488. |
  489. {15:~ }|
  490. {15:~ }|
  491. {15:~ }|
  492. {15:~ }|
  493. {15:~ }|
  494. {15:~ }|
  495. Already ...t change |
  496. ]])
  497. end
  498. end
  499. end)
  500. it('with undolevels=2', function()
  501. local screen = Screen.new(20,10)
  502. for _, case in pairs(cases) do
  503. clear()
  504. common_setup(screen, case, default_text)
  505. feed_command("set undolevels=2")
  506. feed("2GAx<esc>")
  507. feed("Ay<esc>")
  508. feed("Az<esc>")
  509. feed(":%s/tw/AR<esc>")
  510. -- feed_command("undo") here would cause "Press ENTER".
  511. feed("u")
  512. expect(default_text:gsub("lines", "linesxy"))
  513. feed("u")
  514. expect(default_text:gsub("lines", "linesx"))
  515. feed("u")
  516. expect(default_text)
  517. feed("u")
  518. if case == "split" then
  519. screen:expect([[
  520. Inc substitution on |
  521. two line^s |
  522. |
  523. {15:~ }|
  524. {15:~ }|
  525. {15:~ }|
  526. {15:~ }|
  527. {15:~ }|
  528. {15:~ }|
  529. Already ...t change |
  530. ]])
  531. else
  532. screen:expect([[
  533. Inc substitution on |
  534. two line^s |
  535. |
  536. {15:~ }|
  537. {15:~ }|
  538. {15:~ }|
  539. {15:~ }|
  540. {15:~ }|
  541. {15:~ }|
  542. Already ...t change |
  543. ]])
  544. end
  545. feed(":%s/tw/MO/g<enter>")
  546. feed(":%s/MO/GO/g<enter>")
  547. feed(":%s/GO/NO/g<enter>")
  548. feed(":%s/NO/LO/g<enter>")
  549. feed("u")
  550. expect(default_text:gsub("tw", "NO"))
  551. feed("u")
  552. expect(default_text:gsub("tw", "GO"))
  553. feed("u")
  554. expect(default_text:gsub("tw", "MO"))
  555. feed("u")
  556. if case == "split" then
  557. screen:expect([[
  558. Inc substitution on |
  559. ^MOo lines |
  560. |
  561. {15:~ }|
  562. {15:~ }|
  563. {15:~ }|
  564. {15:~ }|
  565. {15:~ }|
  566. {15:~ }|
  567. Already ...t change |
  568. ]])
  569. else
  570. screen:expect([[
  571. Inc substitution on |
  572. ^MOo lines |
  573. |
  574. {15:~ }|
  575. {15:~ }|
  576. {15:~ }|
  577. {15:~ }|
  578. {15:~ }|
  579. {15:~ }|
  580. Already ...t change |
  581. ]])
  582. end
  583. end
  584. end)
  585. it('with undolevels=-1', function()
  586. local screen = Screen.new(20,10)
  587. for _, case in pairs(cases) do
  588. clear()
  589. common_setup(screen, case, default_text)
  590. feed_command("set undolevels=-1")
  591. feed(":%s/tw/MO/g<enter>")
  592. -- feed_command("undo") here will result in a "Press ENTER" prompt
  593. feed("u")
  594. if case == "split" then
  595. screen:expect([[
  596. Inc substitution on |
  597. ^MOo lines |
  598. |
  599. {15:~ }|
  600. {15:~ }|
  601. {15:~ }|
  602. {15:~ }|
  603. {15:~ }|
  604. {15:~ }|
  605. Already ...t change |
  606. ]])
  607. else
  608. screen:expect([[
  609. Inc substitution on |
  610. ^MOo lines |
  611. |
  612. {15:~ }|
  613. {15:~ }|
  614. {15:~ }|
  615. {15:~ }|
  616. {15:~ }|
  617. {15:~ }|
  618. Already ...t change |
  619. ]])
  620. end
  621. -- repeat with an interrupted substitution
  622. clear()
  623. common_setup(screen, case, default_text)
  624. feed_command("set undolevels=-1")
  625. feed("1G")
  626. feed("IL<esc>")
  627. feed(":%s/tw/MO/g<esc>")
  628. feed("u")
  629. screen:expect([[
  630. ^LInc substitution on|
  631. two lines |
  632. |
  633. {15:~ }|
  634. {15:~ }|
  635. {15:~ }|
  636. {15:~ }|
  637. {15:~ }|
  638. {15:~ }|
  639. Already ...t change |
  640. ]])
  641. end
  642. end)
  643. end)
  644. describe(":substitute, inccommand=split", function()
  645. local screen = Screen.new(30,15)
  646. before_each(function()
  647. clear()
  648. common_setup(screen, "split", default_text .. default_text)
  649. end)
  650. it("preserves 'modified' buffer flag", function()
  651. feed_command("set nomodified")
  652. feed(":%s/tw")
  653. screen:expect([[
  654. Inc substitution on |
  655. {12:tw}o lines |
  656. Inc substitution on |
  657. {12:tw}o lines |
  658. |
  659. {11:[No Name] }|
  660. |2| {12:tw}o lines |
  661. |4| {12:tw}o lines |
  662. {15:~ }|
  663. {15:~ }|
  664. {15:~ }|
  665. {15:~ }|
  666. {15:~ }|
  667. {10:[Preview] }|
  668. :%s/tw^ |
  669. ]])
  670. feed([[<C-\><C-N>]]) -- Cancel the :substitute command.
  671. eq(0, eval("&modified"))
  672. end)
  673. it("shows preview when cmd modifiers are present", function()
  674. -- one modifier
  675. feed(':keeppatterns %s/tw/to')
  676. screen:expect{any=[[{12:to}o lines]]}
  677. feed('<Esc>')
  678. screen:expect{any=[[two lines]]}
  679. -- multiple modifiers
  680. feed(':keeppatterns silent %s/tw/to')
  681. screen:expect{any=[[{12:to}o lines]]}
  682. feed('<Esc>')
  683. screen:expect{any=[[two lines]]}
  684. -- non-modifier prefix
  685. feed(':silent tabedit %s/tw/to')
  686. screen:expect([[
  687. Inc substitution on |
  688. two lines |
  689. Inc substitution on |
  690. two lines |
  691. |
  692. {15:~ }|
  693. {15:~ }|
  694. {15:~ }|
  695. {15:~ }|
  696. {15:~ }|
  697. {15:~ }|
  698. {15:~ }|
  699. {15:~ }|
  700. {15:~ }|
  701. :silent tabedit %s/tw/to^ |
  702. ]])
  703. feed('<Esc>')
  704. -- leading colons
  705. feed(':::%s/tw/to')
  706. screen:expect{any=[[{12:to}o lines]]}
  707. feed('<Esc>')
  708. screen:expect{any=[[two lines]]}
  709. end)
  710. it("ignores new-window modifiers when splitting the preview window", function()
  711. -- one modifier
  712. feed(':topleft %s/tw/to')
  713. screen:expect([[
  714. Inc substitution on |
  715. {12:to}o lines |
  716. Inc substitution on |
  717. {12:to}o lines |
  718. |
  719. {11:[No Name] [+] }|
  720. |2| {12:to}o lines |
  721. |4| {12:to}o lines |
  722. {15:~ }|
  723. {15:~ }|
  724. {15:~ }|
  725. {15:~ }|
  726. {15:~ }|
  727. {10:[Preview] }|
  728. :topleft %s/tw/to^ |
  729. ]])
  730. feed('<Esc>')
  731. screen:expect{any=[[two lines]]}
  732. -- multiple modifiers
  733. feed(':topleft vert %s/tw/to')
  734. screen:expect([[
  735. Inc substitution on |
  736. {12:to}o lines |
  737. Inc substitution on |
  738. {12:to}o lines |
  739. |
  740. {11:[No Name] [+] }|
  741. |2| {12:to}o lines |
  742. |4| {12:to}o lines |
  743. {15:~ }|
  744. {15:~ }|
  745. {15:~ }|
  746. {15:~ }|
  747. {15:~ }|
  748. {10:[Preview] }|
  749. :topleft vert %s/tw/to^ |
  750. ]])
  751. feed('<Esc>')
  752. screen:expect{any=[[two lines]]}
  753. end)
  754. it('shows split window when typing the pattern', function()
  755. feed(":%s/tw")
  756. screen:expect([[
  757. Inc substitution on |
  758. {12:tw}o lines |
  759. Inc substitution on |
  760. {12:tw}o lines |
  761. |
  762. {11:[No Name] [+] }|
  763. |2| {12:tw}o lines |
  764. |4| {12:tw}o lines |
  765. {15:~ }|
  766. {15:~ }|
  767. {15:~ }|
  768. {15:~ }|
  769. {15:~ }|
  770. {10:[Preview] }|
  771. :%s/tw^ |
  772. ]])
  773. end)
  774. it('shows preview with empty replacement', function()
  775. feed(":%s/tw/")
  776. screen:expect([[
  777. Inc substitution on |
  778. o lines |
  779. Inc substitution on |
  780. o lines |
  781. |
  782. {11:[No Name] [+] }|
  783. |2| o lines |
  784. |4| o lines |
  785. {15:~ }|
  786. {15:~ }|
  787. {15:~ }|
  788. {15:~ }|
  789. {15:~ }|
  790. {10:[Preview] }|
  791. :%s/tw/^ |
  792. ]])
  793. feed("x")
  794. screen:expect([[
  795. Inc substitution on |
  796. {12:x}o lines |
  797. Inc substitution on |
  798. {12:x}o lines |
  799. |
  800. {11:[No Name] [+] }|
  801. |2| {12:x}o lines |
  802. |4| {12:x}o lines |
  803. {15:~ }|
  804. {15:~ }|
  805. {15:~ }|
  806. {15:~ }|
  807. {15:~ }|
  808. {10:[Preview] }|
  809. :%s/tw/x^ |
  810. ]])
  811. feed("<bs>")
  812. screen:expect([[
  813. Inc substitution on |
  814. o lines |
  815. Inc substitution on |
  816. o lines |
  817. |
  818. {11:[No Name] [+] }|
  819. |2| o lines |
  820. |4| o lines |
  821. {15:~ }|
  822. {15:~ }|
  823. {15:~ }|
  824. {15:~ }|
  825. {15:~ }|
  826. {10:[Preview] }|
  827. :%s/tw/^ |
  828. ]])
  829. end)
  830. it('shows split window when typing replacement', function()
  831. feed(":%s/tw/XX")
  832. screen:expect([[
  833. Inc substitution on |
  834. {12:XX}o lines |
  835. Inc substitution on |
  836. {12:XX}o lines |
  837. |
  838. {11:[No Name] [+] }|
  839. |2| {12:XX}o lines |
  840. |4| {12:XX}o lines |
  841. {15:~ }|
  842. {15:~ }|
  843. {15:~ }|
  844. {15:~ }|
  845. {15:~ }|
  846. {10:[Preview] }|
  847. :%s/tw/XX^ |
  848. ]])
  849. end)
  850. it('does not show split window for :s/', function()
  851. feed("2gg")
  852. feed(":s/tw")
  853. screen:expect([[
  854. Inc substitution on |
  855. {12:tw}o lines |
  856. Inc substitution on |
  857. two lines |
  858. |
  859. {15:~ }|
  860. {15:~ }|
  861. {15:~ }|
  862. {15:~ }|
  863. {15:~ }|
  864. {15:~ }|
  865. {15:~ }|
  866. {15:~ }|
  867. {15:~ }|
  868. :s/tw^ |
  869. ]])
  870. end)
  871. it("'hlsearch' is active, 'cursorline' is not", function()
  872. feed_command("set hlsearch cursorline")
  873. feed("gg")
  874. -- Assert that 'cursorline' is active.
  875. screen:expect([[
  876. {16:^Inc substitution on }|
  877. two lines |
  878. Inc substitution on |
  879. two lines |
  880. |
  881. {15:~ }|
  882. {15:~ }|
  883. {15:~ }|
  884. {15:~ }|
  885. {15:~ }|
  886. {15:~ }|
  887. {15:~ }|
  888. {15:~ }|
  889. {15:~ }|
  890. :set hlsearch cursorline |
  891. ]])
  892. feed(":%s/tw")
  893. -- 'cursorline' is NOT active during preview.
  894. screen:expect([[
  895. Inc substitution on |
  896. {12:tw}o lines |
  897. Inc substitution on |
  898. {12:tw}o lines |
  899. |
  900. {11:[No Name] [+] }|
  901. |2| {12:tw}o lines |
  902. |4| {12:tw}o lines |
  903. {15:~ }|
  904. {15:~ }|
  905. {15:~ }|
  906. {15:~ }|
  907. {15:~ }|
  908. {10:[Preview] }|
  909. :%s/tw^ |
  910. ]])
  911. end)
  912. it('highlights the replacement text', function()
  913. feed('ggO')
  914. feed('M M M<esc>')
  915. feed(':%s/M/123/g')
  916. screen:expect([[
  917. {12:123} {12:123} {12:123} |
  918. Inc substitution on |
  919. two lines |
  920. Inc substitution on |
  921. two lines |
  922. {11:[No Name] [+] }|
  923. |1| {12:123} {12:123} {12:123} |
  924. {15:~ }|
  925. {15:~ }|
  926. {15:~ }|
  927. {15:~ }|
  928. {15:~ }|
  929. {15:~ }|
  930. {10:[Preview] }|
  931. :%s/M/123/g^ |
  932. ]])
  933. end)
  934. it("highlights nothing when there's no match", function()
  935. feed('gg')
  936. feed(':%s/Inx')
  937. screen:expect([[
  938. Inc substitution on |
  939. two lines |
  940. Inc substitution on |
  941. two lines |
  942. |
  943. {11:[No Name] [+] }|
  944. |
  945. {15:~ }|
  946. {15:~ }|
  947. {15:~ }|
  948. {15:~ }|
  949. {15:~ }|
  950. {15:~ }|
  951. {10:[Preview] }|
  952. :%s/Inx^ |
  953. ]])
  954. end)
  955. it('previews correctly when previewhight is small', function()
  956. feed_command('set cwh=3')
  957. feed_command('set hls')
  958. feed('ggdG')
  959. insert(string.rep('abc abc abc\n', 20))
  960. feed(':%s/abc/MMM/g')
  961. screen:expect([[
  962. {12:MMM} {12:MMM} {12:MMM} |
  963. {12:MMM} {12:MMM} {12:MMM} |
  964. {12:MMM} {12:MMM} {12:MMM} |
  965. {12:MMM} {12:MMM} {12:MMM} |
  966. {12:MMM} {12:MMM} {12:MMM} |
  967. {12:MMM} {12:MMM} {12:MMM} |
  968. {12:MMM} {12:MMM} {12:MMM} |
  969. {12:MMM} {12:MMM} {12:MMM} |
  970. {12:MMM} {12:MMM} {12:MMM} |
  971. {11:[No Name] [+] }|
  972. | 1| {12:MMM} {12:MMM} {12:MMM} |
  973. | 2| {12:MMM} {12:MMM} {12:MMM} |
  974. | 3| {12:MMM} {12:MMM} {12:MMM} |
  975. {10:[Preview] }|
  976. :%s/abc/MMM/g^ |
  977. ]])
  978. end)
  979. it('actually replaces text', function()
  980. feed(":%s/tw/XX/g<Enter>")
  981. screen:expect([[
  982. Inc substitution on |
  983. XXo lines |
  984. Inc substitution on |
  985. ^XXo lines |
  986. |
  987. {15:~ }|
  988. {15:~ }|
  989. {15:~ }|
  990. {15:~ }|
  991. {15:~ }|
  992. {15:~ }|
  993. {15:~ }|
  994. {15:~ }|
  995. {15:~ }|
  996. :%s/tw/XX/g |
  997. ]])
  998. end)
  999. it('shows correct line numbers with many lines', function()
  1000. feed("gg")
  1001. feed("2yy")
  1002. feed("2000p")
  1003. feed_command("1,1000s/tw/BB/g")
  1004. feed(":%s/tw/X")
  1005. screen:expect([[
  1006. BBo lines |
  1007. Inc substitution on |
  1008. {12:X}o lines |
  1009. Inc substitution on |
  1010. {12:X}o lines |
  1011. {11:[No Name] [+] }|
  1012. |1001| {12:X}o lines |
  1013. |1003| {12:X}o lines |
  1014. |1005| {12:X}o lines |
  1015. |1007| {12:X}o lines |
  1016. |1009| {12:X}o lines |
  1017. |1011| {12:X}o lines |
  1018. |1013| {12:X}o lines |
  1019. {10:[Preview] }|
  1020. :%s/tw/X^ |
  1021. ]])
  1022. end)
  1023. it('does not spam the buffer numbers', function()
  1024. -- The preview buffer is re-used (unless user deleted it), so buffer numbers
  1025. -- will not increase on each keystroke.
  1026. feed(":%s/tw/Xo/g")
  1027. -- Delete and re-type the g a few times.
  1028. feed("<BS>")
  1029. poke_eventloop()
  1030. feed("g")
  1031. poke_eventloop()
  1032. feed("<BS>")
  1033. poke_eventloop()
  1034. feed("g")
  1035. poke_eventloop()
  1036. feed("<CR>")
  1037. poke_eventloop()
  1038. feed(":vs tmp<enter>")
  1039. eq(3, helpers.call('bufnr', '$'))
  1040. end)
  1041. it('works with the n flag', function()
  1042. feed(":%s/tw/Mix/n<Enter>")
  1043. screen:expect([[
  1044. Inc substitution on |
  1045. two lines |
  1046. Inc substitution on |
  1047. two lines |
  1048. ^ |
  1049. {15:~ }|
  1050. {15:~ }|
  1051. {15:~ }|
  1052. {15:~ }|
  1053. {15:~ }|
  1054. {15:~ }|
  1055. {15:~ }|
  1056. {15:~ }|
  1057. {15:~ }|
  1058. 2 matches on 2 lines |
  1059. ]])
  1060. end)
  1061. it("deactivates if 'redrawtime' is exceeded #5602", function()
  1062. -- Assert that 'inccommand' is ENABLED initially.
  1063. eq("split", eval("&inccommand"))
  1064. -- Set 'redrawtime' to minimal value, to ensure timeout is triggered.
  1065. feed_command("set redrawtime=1 nowrap")
  1066. -- Load a big file.
  1067. feed_command("silent edit! test/functional/fixtures/bigfile_oneline.txt")
  1068. -- Start :substitute with a slow pattern.
  1069. feed([[:%s/B.*N/x]])
  1070. poke_eventloop()
  1071. -- Assert that 'inccommand' is DISABLED in cmdline mode.
  1072. eq("", eval("&inccommand"))
  1073. -- Assert that preview cleared (or never manifested).
  1074. screen:expect([[
  1075. 0000;<control>;Cc;0;BN;;;;;N;N|
  1076. 2F923;CJK COMPATIBILITY IDEOGR|
  1077. 2F924;CJK COMPATIBILITY IDEOGR|
  1078. 2F925;CJK COMPATIBILITY IDEOGR|
  1079. 2F926;CJK COMPATIBILITY IDEOGR|
  1080. 2F927;CJK COMPATIBILITY IDEOGR|
  1081. 2F928;CJK COMPATIBILITY IDEOGR|
  1082. 2F929;CJK COMPATIBILITY IDEOGR|
  1083. 2F92A;CJK COMPATIBILITY IDEOGR|
  1084. 2F92B;CJK COMPATIBILITY IDEOGR|
  1085. 2F92C;CJK COMPATIBILITY IDEOGR|
  1086. 2F92D;CJK COMPATIBILITY IDEOGR|
  1087. 2F92E;CJK COMPATIBILITY IDEOGR|
  1088. 2F92F;CJK COMPATIBILITY IDEOGR|
  1089. :%s/B.*N/x^ |
  1090. ]])
  1091. -- Assert that 'inccommand' is again ENABLED after leaving cmdline mode.
  1092. feed([[<C-\><C-N>]])
  1093. eq("split", eval("&inccommand"))
  1094. end)
  1095. it("deactivates if 'foldexpr' is slow #9557", function()
  1096. insert([[
  1097. a
  1098. a
  1099. a
  1100. a
  1101. a
  1102. a
  1103. a
  1104. a
  1105. ]])
  1106. source([[
  1107. function! Slowfold(lnum)
  1108. sleep 5m
  1109. return a:lnum % 3
  1110. endfun
  1111. ]])
  1112. command('set redrawtime=1 inccommand=split')
  1113. command('set foldmethod=expr foldexpr=Slowfold(v:lnum)')
  1114. feed(':%s/a/bcdef')
  1115. -- Assert that 'inccommand' is DISABLED in cmdline mode.
  1116. retry(nil, nil, function()
  1117. eq('', eval('&inccommand'))
  1118. end)
  1119. -- Assert that 'inccommand' is again ENABLED after leaving cmdline mode.
  1120. feed([[<C-\><C-N>]])
  1121. retry(nil, nil, function()
  1122. eq('split', eval('&inccommand'))
  1123. end)
  1124. end)
  1125. it("clears preview if non-previewable command is edited #5585", function()
  1126. feed('gg')
  1127. -- Put a non-previewable command in history.
  1128. feed_command("echo 'foo'")
  1129. -- Start an incomplete :substitute command.
  1130. feed(":1,2s/t/X")
  1131. screen:expect([[
  1132. Inc subs{12:X}itution on |
  1133. {12:X}wo lines |
  1134. Inc substitution on |
  1135. two lines |
  1136. |
  1137. {11:[No Name] [+] }|
  1138. |1| Inc subs{12:X}itution on |
  1139. |2| {12:X}wo lines |
  1140. {15:~ }|
  1141. {15:~ }|
  1142. {15:~ }|
  1143. {15:~ }|
  1144. {15:~ }|
  1145. {10:[Preview] }|
  1146. :1,2s/t/X^ |
  1147. ]])
  1148. -- Select the previous command.
  1149. feed("<C-P>")
  1150. -- Assert that preview was cleared.
  1151. screen:expect([[
  1152. Inc substitution on |
  1153. two lines |
  1154. Inc substitution on |
  1155. two lines |
  1156. |
  1157. {15:~ }|
  1158. {15:~ }|
  1159. {15:~ }|
  1160. {15:~ }|
  1161. {15:~ }|
  1162. {15:~ }|
  1163. {15:~ }|
  1164. {15:~ }|
  1165. {15:~ }|
  1166. :echo 'foo'^ |
  1167. ]])
  1168. end)
  1169. end)
  1170. describe("inccommand=nosplit", function()
  1171. local screen = Screen.new(20,10)
  1172. before_each(function()
  1173. clear()
  1174. common_setup(screen, "nosplit", default_text .. default_text)
  1175. end)
  1176. it("works with :smagic, :snomagic", function()
  1177. feed_command("set hlsearch")
  1178. insert("Line *.3.* here")
  1179. feed(":%smagic/3.*/X") -- start :smagic command
  1180. screen:expect([[
  1181. Inc substitution on |
  1182. two lines |
  1183. Inc substitution on |
  1184. two lines |
  1185. Line *.{12:X} |
  1186. {15:~ }|
  1187. {15:~ }|
  1188. {15:~ }|
  1189. {15:~ }|
  1190. :%smagic/3.*/X^ |
  1191. ]])
  1192. feed([[<C-\><C-N>]]) -- cancel
  1193. feed(":%snomagic/3.*/X") -- start :snomagic command
  1194. screen:expect([[
  1195. Inc substitution on |
  1196. two lines |
  1197. Inc substitution on |
  1198. two lines |
  1199. Line *.{12:X} here |
  1200. {15:~ }|
  1201. {15:~ }|
  1202. {15:~ }|
  1203. {15:~ }|
  1204. :%snomagic/3.*/X^ |
  1205. ]])
  1206. end)
  1207. it("shows preview when cmd modifiers are present", function()
  1208. -- one modifier
  1209. feed(':keeppatterns %s/tw/to')
  1210. screen:expect{any=[[{12:to}o lines]]}
  1211. feed('<Esc>')
  1212. screen:expect{any=[[two lines]]}
  1213. -- multiple modifiers
  1214. feed(':keeppatterns silent %s/tw/to')
  1215. screen:expect{any=[[{12:to}o lines]]}
  1216. feed('<Esc>')
  1217. screen:expect{any=[[two lines]]}
  1218. -- non-modifier prefix
  1219. feed(':silent tabedit %s/tw/to')
  1220. screen:expect([[
  1221. two lines |
  1222. Inc substitution on |
  1223. two lines |
  1224. |
  1225. {15:~ }|
  1226. {15:~ }|
  1227. {15:~ }|
  1228. {15:~ }|
  1229. :silent tabedit %s/t|
  1230. w/to^ |
  1231. ]])
  1232. end)
  1233. it("does not show window after toggling :set inccommand", function()
  1234. feed(":%s/tw/OKOK")
  1235. feed("<Esc>")
  1236. command("set icm=split")
  1237. feed(":%s/tw/OKOK")
  1238. feed("<Esc>")
  1239. command("set icm=nosplit")
  1240. feed(":%s/tw/OKOK")
  1241. poke_eventloop()
  1242. screen:expect([[
  1243. Inc substitution on |
  1244. {12:OKOK}o lines |
  1245. Inc substitution on |
  1246. {12:OKOK}o lines |
  1247. |
  1248. {15:~ }|
  1249. {15:~ }|
  1250. {15:~ }|
  1251. {15:~ }|
  1252. :%s/tw/OKOK^ |
  1253. ]])
  1254. end)
  1255. it('never shows preview buffer', function()
  1256. feed_command("set hlsearch")
  1257. feed(":%s/tw")
  1258. screen:expect([[
  1259. Inc substitution on |
  1260. {12:tw}o lines |
  1261. Inc substitution on |
  1262. {12:tw}o lines |
  1263. |
  1264. {15:~ }|
  1265. {15:~ }|
  1266. {15:~ }|
  1267. {15:~ }|
  1268. :%s/tw^ |
  1269. ]])
  1270. feed("/BM")
  1271. screen:expect([[
  1272. Inc substitution on |
  1273. {12:BM}o lines |
  1274. Inc substitution on |
  1275. {12:BM}o lines |
  1276. |
  1277. {15:~ }|
  1278. {15:~ }|
  1279. {15:~ }|
  1280. {15:~ }|
  1281. :%s/tw/BM^ |
  1282. ]])
  1283. feed("/")
  1284. screen:expect([[
  1285. Inc substitution on |
  1286. {12:BM}o lines |
  1287. Inc substitution on |
  1288. {12:BM}o lines |
  1289. |
  1290. {15:~ }|
  1291. {15:~ }|
  1292. {15:~ }|
  1293. {15:~ }|
  1294. :%s/tw/BM/^ |
  1295. ]])
  1296. feed("<enter>")
  1297. screen:expect([[
  1298. Inc substitution on |
  1299. BMo lines |
  1300. Inc substitution on |
  1301. ^BMo lines |
  1302. |
  1303. {15:~ }|
  1304. {15:~ }|
  1305. {15:~ }|
  1306. {15:~ }|
  1307. :%s/tw/BM/ |
  1308. ]])
  1309. end)
  1310. it("clears preview if non-previewable command is edited", function()
  1311. -- Put a non-previewable command in history.
  1312. feed_command("echo 'foo'")
  1313. -- Start an incomplete :substitute command.
  1314. feed(":1,2s/t/X")
  1315. screen:expect([[
  1316. Inc subs{12:X}itution on |
  1317. {12:X}wo lines |
  1318. Inc substitution on |
  1319. two lines |
  1320. |
  1321. {15:~ }|
  1322. {15:~ }|
  1323. {15:~ }|
  1324. {15:~ }|
  1325. :1,2s/t/X^ |
  1326. ]])
  1327. -- Select the previous command.
  1328. feed("<C-P>")
  1329. -- Assert that preview was cleared.
  1330. screen:expect([[
  1331. Inc substitution on |
  1332. two lines |
  1333. Inc substitution on |
  1334. two lines |
  1335. |
  1336. {15:~ }|
  1337. {15:~ }|
  1338. {15:~ }|
  1339. {15:~ }|
  1340. :echo 'foo'^ |
  1341. ]])
  1342. end)
  1343. it("does not execute trailing bar-separated commands #7494", function()
  1344. feed(':%s/two/three/g|q!')
  1345. screen:expect([[
  1346. Inc substitution on |
  1347. {12:three} lines |
  1348. Inc substitution on |
  1349. {12:three} lines |
  1350. |
  1351. {15:~ }|
  1352. {15:~ }|
  1353. {15:~ }|
  1354. {15:~ }|
  1355. :%s/two/three/g|q!^ |
  1356. ]])
  1357. eq(eval('v:null'), eval('v:exiting'))
  1358. end)
  1359. it("does not break bar-separated command #8796", function()
  1360. source([[
  1361. function! F()
  1362. if v:false | return | endif
  1363. endfun
  1364. ]])
  1365. command('call timer_start(10, {-> F()}, {"repeat":-1})')
  1366. feed(':%s/')
  1367. sleep(20) -- Allow some timer activity.
  1368. screen:expect([[
  1369. Inc substitution on |
  1370. two lines |
  1371. Inc substitution on |
  1372. two lines |
  1373. |
  1374. {15:~ }|
  1375. {15:~ }|
  1376. {15:~ }|
  1377. {15:~ }|
  1378. :%s/^ |
  1379. ]])
  1380. end)
  1381. end)
  1382. describe(":substitute, 'inccommand' with a failing expression", function()
  1383. local screen = Screen.new(20,10)
  1384. local cases = { "", "split", "nosplit" }
  1385. local function refresh(case)
  1386. clear()
  1387. common_setup(screen, case, default_text)
  1388. end
  1389. it('in the pattern does nothing', function()
  1390. for _, case in pairs(cases) do
  1391. refresh(case)
  1392. feed_command("set inccommand=" .. case)
  1393. feed(":silent! %s/tw\\(/LARD/<enter>")
  1394. expect(default_text)
  1395. end
  1396. end)
  1397. it('in the replacement deletes the matches', function()
  1398. for _, case in pairs(cases) do
  1399. refresh(case)
  1400. local replacements = { "\\='LARD", "\\=xx_novar__xx" }
  1401. for _, repl in pairs(replacements) do
  1402. feed_command("set inccommand=" .. case)
  1403. feed(":silent! %s/tw/" .. repl .. "/<enter>")
  1404. expect(default_text:gsub("tw", ""))
  1405. feed_command("undo")
  1406. end
  1407. end
  1408. end)
  1409. it('in the range does not error #5912', function()
  1410. for _, case in pairs(cases) do
  1411. refresh(case)
  1412. feed(':100s/')
  1413. screen:expect([[
  1414. Inc substitution on |
  1415. two lines |
  1416. |
  1417. {15:~ }|
  1418. {15:~ }|
  1419. {15:~ }|
  1420. {15:~ }|
  1421. {15:~ }|
  1422. {15:~ }|
  1423. :100s/^ |
  1424. ]])
  1425. feed('<enter>')
  1426. screen:expect([[
  1427. Inc substitution on |
  1428. two lines |
  1429. ^ |
  1430. {15:~ }|
  1431. {15:~ }|
  1432. {15:~ }|
  1433. {15:~ }|
  1434. {15:~ }|
  1435. {15:~ }|
  1436. {14:E16: Invalid range} |
  1437. ]])
  1438. end
  1439. end)
  1440. end)
  1441. describe("'inccommand' and :cnoremap", function()
  1442. local cases = { "", "split", "nosplit" }
  1443. local function refresh(case)
  1444. clear()
  1445. common_setup(nil, case, default_text)
  1446. end
  1447. it('work with remapped characters', function()
  1448. for _, case in pairs(cases) do
  1449. refresh(case)
  1450. local cmd = "%s/lines/LINES/g"
  1451. for i = 1, string.len(cmd) do
  1452. local c = string.sub(cmd, i, i)
  1453. feed_command("cnoremap ".. c .. " " .. c)
  1454. end
  1455. feed_command(cmd)
  1456. expect([[
  1457. Inc substitution on
  1458. two LINES
  1459. ]])
  1460. end
  1461. end)
  1462. it('work when mappings move the cursor', function()
  1463. for _, case in pairs(cases) do
  1464. refresh(case)
  1465. feed_command("cnoremap ,S LINES/<left><left><left><left><left><left>")
  1466. feed(":%s/lines/,Sor three <enter>")
  1467. expect([[
  1468. Inc substitution on
  1469. two or three LINES
  1470. ]])
  1471. feed_command("cnoremap ;S /X/<left><left><left>")
  1472. feed(":%s/;SI<enter>")
  1473. expect([[
  1474. Xnc substitution on
  1475. two or three LXNES
  1476. ]])
  1477. feed_command("cnoremap ,T //Y/<left><left><left>")
  1478. feed(":%s,TX<enter>")
  1479. expect([[
  1480. Ync substitution on
  1481. two or three LYNES
  1482. ]])
  1483. feed_command("cnoremap ;T s//Z/<left><left><left>")
  1484. feed(":%;TY<enter>")
  1485. expect([[
  1486. Znc substitution on
  1487. two or three LZNES
  1488. ]])
  1489. end
  1490. end)
  1491. it('still works with a broken mapping', function()
  1492. for _, case in pairs(cases) do
  1493. refresh(case)
  1494. feed_command("cnoremap <expr> x execute('bwipeout!')[-1].'x'")
  1495. feed(":%s/tw/tox<enter>")
  1496. -- error thrown b/c of the mapping
  1497. neq(nil, eval('v:errmsg'):find('^E523:'))
  1498. expect([[
  1499. Inc substitution on
  1500. toxo lines
  1501. ]])
  1502. end
  1503. end)
  1504. it('work when temporarily moving the cursor', function()
  1505. for _, case in pairs(cases) do
  1506. refresh(case)
  1507. feed_command("cnoremap <expr> x cursor(1, 1)[-1].'x'")
  1508. feed(":%s/tw/tox/g<enter>")
  1509. expect(default_text:gsub("tw", "tox"))
  1510. end
  1511. end)
  1512. it("work when a mapping disables 'inccommand'", function()
  1513. for _, case in pairs(cases) do
  1514. refresh(case)
  1515. feed_command("cnoremap <expr> x execute('set inccommand=')[-1]")
  1516. feed(":%s/tw/toxa/g<enter>")
  1517. expect(default_text:gsub("tw", "toa"))
  1518. end
  1519. end)
  1520. it('work with a complex mapping', function()
  1521. for _, case in pairs(cases) do
  1522. refresh(case)
  1523. source([[cnoremap x <C-\>eextend(g:, {'fo': getcmdline()})
  1524. \.fo<CR><C-c>:new<CR>:bw!<CR>:<C-r>=remove(g:, 'fo')<CR>x]])
  1525. feed(":%s/tw/tox")
  1526. feed("/<enter>")
  1527. expect(default_text:gsub("tw", "tox"))
  1528. end
  1529. end)
  1530. end)
  1531. describe("'inccommand' autocommands", function()
  1532. before_each(clear)
  1533. -- keys are events to be tested
  1534. -- values are arrays like
  1535. -- { open = { 1 }, close = { 2, 3} }
  1536. -- which would mean that during the test below the event fires for
  1537. -- buffer 1 when opening the preview window, and for buffers 2 and 3
  1538. -- when closing the preview window
  1539. local eventsExpected = {
  1540. BufAdd = {},
  1541. BufDelete = {},
  1542. BufEnter = {},
  1543. BufFilePost = {},
  1544. BufFilePre = {},
  1545. BufHidden = {},
  1546. BufLeave = {},
  1547. BufNew = {},
  1548. BufNewFile = {},
  1549. BufRead = {},
  1550. BufReadCmd = {},
  1551. BufReadPre = {},
  1552. BufUnload = {},
  1553. BufWinEnter = {},
  1554. BufWinLeave = {},
  1555. BufWipeout = {},
  1556. BufWrite = {},
  1557. BufWriteCmd = {},
  1558. BufWritePost = {},
  1559. Syntax = {},
  1560. FileType = {},
  1561. WinEnter = {},
  1562. WinLeave = {},
  1563. CmdwinEnter = {},
  1564. CmdwinLeave = {},
  1565. }
  1566. local function bufferlist(t)
  1567. local s = ""
  1568. for _, buffer in pairs(t) do
  1569. s = s .. ", " .. tostring(buffer)
  1570. end
  1571. return s
  1572. end
  1573. -- fill the table with default values
  1574. for event, _ in pairs(eventsExpected) do
  1575. eventsExpected[event].open = eventsExpected[event].open or {}
  1576. eventsExpected[event].close = eventsExpected[event].close or {}
  1577. end
  1578. local function register_autocmd(event)
  1579. meths.set_var(event .. "_fired", {})
  1580. feed_command("autocmd " .. event .. " * call add(g:" .. event .. "_fired, expand('<abuf>'))")
  1581. end
  1582. it('are not fired when splitting', function()
  1583. common_setup(nil, "split", default_text)
  1584. local eventsObserved = {}
  1585. for event, _ in pairs(eventsExpected) do
  1586. eventsObserved[event] = {}
  1587. register_autocmd(event)
  1588. end
  1589. feed(":%s/tw")
  1590. for event, _ in pairs(eventsExpected) do
  1591. eventsObserved[event].open = meths.get_var(event .. "_fired")
  1592. meths.set_var(event .. "_fired", {})
  1593. end
  1594. feed("/<enter>")
  1595. for event, _ in pairs(eventsExpected) do
  1596. eventsObserved[event].close = meths.get_var(event .. "_fired")
  1597. end
  1598. for event, _ in pairs(eventsExpected) do
  1599. eq(event .. bufferlist(eventsExpected[event].open),
  1600. event .. bufferlist(eventsObserved[event].open))
  1601. eq(event .. bufferlist(eventsExpected[event].close),
  1602. event .. bufferlist(eventsObserved[event].close))
  1603. end
  1604. end)
  1605. end)
  1606. describe("'inccommand' split windows", function()
  1607. local screen
  1608. local function refresh()
  1609. clear()
  1610. screen = Screen.new(40,30)
  1611. common_setup(screen, "split", default_text)
  1612. end
  1613. it('work after more splits', function()
  1614. refresh()
  1615. feed("gg")
  1616. feed_command("vsplit")
  1617. feed_command("split")
  1618. feed(":%s/tw")
  1619. screen:expect([[
  1620. Inc substitution on {10:│}Inc substitution on|
  1621. {12:tw}o lines {10:│}{12:tw}o lines |
  1622. {10:│} |
  1623. {15:~ }{10:│}{15:~ }|
  1624. {15:~ }{10:│}{15:~ }|
  1625. {15:~ }{10:│}{15:~ }|
  1626. {15:~ }{10:│}{15:~ }|
  1627. {15:~ }{10:│}{15:~ }|
  1628. {15:~ }{10:│}{15:~ }|
  1629. {15:~ }{10:│}{15:~ }|
  1630. {15:~ }{10:│}{15:~ }|
  1631. {15:~ }{10:│}{15:~ }|
  1632. {15:~ }{10:│}{15:~ }|
  1633. {15:~ }{10:│}{15:~ }|
  1634. {11:[No Name] [+] }{10:│}{15:~ }|
  1635. Inc substitution on {10:│}{15:~ }|
  1636. {12:tw}o lines {10:│}{15:~ }|
  1637. {10:│}{15:~ }|
  1638. {15:~ }{10:│}{15:~ }|
  1639. {15:~ }{10:│}{15:~ }|
  1640. {10:[No Name] [+] [No Name] [+] }|
  1641. |2| {12:tw}o lines |
  1642. {15:~ }|
  1643. {15:~ }|
  1644. {15:~ }|
  1645. {15:~ }|
  1646. {15:~ }|
  1647. {15:~ }|
  1648. {10:[Preview] }|
  1649. :%s/tw^ |
  1650. ]])
  1651. feed("<esc>")
  1652. feed_command("only")
  1653. feed_command("split")
  1654. feed_command("vsplit")
  1655. feed(":%s/tw")
  1656. screen:expect([[
  1657. Inc substitution on {10:│}Inc substitution on|
  1658. {12:tw}o lines {10:│}{12:tw}o lines |
  1659. {10:│} |
  1660. {15:~ }{10:│}{15:~ }|
  1661. {15:~ }{10:│}{15:~ }|
  1662. {15:~ }{10:│}{15:~ }|
  1663. {15:~ }{10:│}{15:~ }|
  1664. {15:~ }{10:│}{15:~ }|
  1665. {15:~ }{10:│}{15:~ }|
  1666. {15:~ }{10:│}{15:~ }|
  1667. {15:~ }{10:│}{15:~ }|
  1668. {15:~ }{10:│}{15:~ }|
  1669. {15:~ }{10:│}{15:~ }|
  1670. {15:~ }{10:│}{15:~ }|
  1671. {11:[No Name] [+] }{10:[No Name] [+] }|
  1672. Inc substitution on |
  1673. {12:tw}o lines |
  1674. |
  1675. {15:~ }|
  1676. {15:~ }|
  1677. {10:[No Name] [+] }|
  1678. |2| {12:tw}o lines |
  1679. {15:~ }|
  1680. {15:~ }|
  1681. {15:~ }|
  1682. {15:~ }|
  1683. {15:~ }|
  1684. {15:~ }|
  1685. {10:[Preview] }|
  1686. :%s/tw^ |
  1687. ]])
  1688. end)
  1689. local settings = {
  1690. "splitbelow",
  1691. "splitright",
  1692. "noequalalways",
  1693. "equalalways eadirection=ver",
  1694. "equalalways eadirection=hor",
  1695. "equalalways eadirection=both",
  1696. }
  1697. it("are not affected by various settings", function()
  1698. for _, setting in pairs(settings) do
  1699. refresh()
  1700. feed_command("set " .. setting)
  1701. feed(":%s/tw")
  1702. screen:expect([[
  1703. Inc substitution on |
  1704. {12:tw}o lines |
  1705. |
  1706. {15:~ }|
  1707. {15:~ }|
  1708. {15:~ }|
  1709. {15:~ }|
  1710. {15:~ }|
  1711. {15:~ }|
  1712. {15:~ }|
  1713. {15:~ }|
  1714. {15:~ }|
  1715. {15:~ }|
  1716. {15:~ }|
  1717. {15:~ }|
  1718. {15:~ }|
  1719. {15:~ }|
  1720. {15:~ }|
  1721. {15:~ }|
  1722. {15:~ }|
  1723. {11:[No Name] [+] }|
  1724. |2| {12:tw}o lines |
  1725. {15:~ }|
  1726. {15:~ }|
  1727. {15:~ }|
  1728. {15:~ }|
  1729. {15:~ }|
  1730. {15:~ }|
  1731. {10:[Preview] }|
  1732. :%s/tw^ |
  1733. ]])
  1734. end
  1735. end)
  1736. end)
  1737. describe("'inccommand' with 'gdefault'", function()
  1738. before_each(function()
  1739. clear()
  1740. end)
  1741. it("does not lock up #7244", function()
  1742. common_setup(nil, "nosplit", "{")
  1743. command("set gdefault")
  1744. feed(":s/{\\n")
  1745. eq({mode='c', blocking=false}, nvim("get_mode"))
  1746. feed("/A<Enter>")
  1747. expect("A")
  1748. eq({mode='n', blocking=false}, nvim("get_mode"))
  1749. end)
  1750. it("with multiline text and range, does not lock up #7244", function()
  1751. common_setup(nil, "nosplit", "{\n\n{")
  1752. command("set gdefault")
  1753. feed(":%s/{\\n")
  1754. eq({mode='c', blocking=false}, nvim("get_mode"))
  1755. feed("/A<Enter>")
  1756. expect("A\nA")
  1757. eq({mode='n', blocking=false}, nvim("get_mode"))
  1758. end)
  1759. it("does not crash on zero-width matches #7485", function()
  1760. common_setup(nil, "split", default_text)
  1761. command("set gdefault")
  1762. feed("gg")
  1763. feed("Vj")
  1764. feed(":s/\\%V")
  1765. eq({mode='c', blocking=false}, nvim("get_mode"))
  1766. feed("<Esc>")
  1767. eq({mode='n', blocking=false}, nvim("get_mode"))
  1768. end)
  1769. it("removes highlights after abort for a zero-width match", function()
  1770. local screen = Screen.new(30,5)
  1771. common_setup(screen, "nosplit", default_text)
  1772. command("set gdefault")
  1773. feed(":%s/\\%1c/a/")
  1774. screen:expect([[
  1775. {12:a}Inc substitution on |
  1776. {12:a}two lines |
  1777. {12:a} |
  1778. {15:~ }|
  1779. :%s/\%1c/a/^ |
  1780. ]])
  1781. feed("<Esc>")
  1782. screen:expect([[
  1783. Inc substitution on |
  1784. two lines |
  1785. ^ |
  1786. {15:~ }|
  1787. |
  1788. ]])
  1789. end)
  1790. end)
  1791. describe(":substitute", function()
  1792. local screen = Screen.new(30,15)
  1793. before_each(function()
  1794. clear()
  1795. end)
  1796. it("inccommand=split, highlights multiline substitutions", function()
  1797. common_setup(screen, "split", multiline_text)
  1798. feed("gg")
  1799. feed(":%s/2\\_.*X")
  1800. screen:expect([[
  1801. 1 {12:2 3} |
  1802. {12:A B C} |
  1803. {12:4 5 6} |
  1804. {12:X} Y Z |
  1805. 7 8 9 |
  1806. {11:[No Name] [+] }|
  1807. |1| 1 {12:2 3} |
  1808. |2|{12: A B C} |
  1809. |3|{12: 4 5 6} |
  1810. |4|{12: X} Y Z |
  1811. {15:~ }|
  1812. {15:~ }|
  1813. {15:~ }|
  1814. {10:[Preview] }|
  1815. :%s/2\_.*X^ |
  1816. ]])
  1817. feed("/MMM")
  1818. screen:expect([[
  1819. 1 {12:MMM} Y Z |
  1820. 7 8 9 |
  1821. |
  1822. {15:~ }|
  1823. {15:~ }|
  1824. {11:[No Name] [+] }|
  1825. |1| 1 {12:MMM} Y Z |
  1826. {15:~ }|
  1827. {15:~ }|
  1828. {15:~ }|
  1829. {15:~ }|
  1830. {15:~ }|
  1831. {15:~ }|
  1832. {10:[Preview] }|
  1833. :%s/2\_.*X/MMM^ |
  1834. ]])
  1835. feed("\\rK\\rLLL")
  1836. screen:expect([[
  1837. 1 {12:MMM} |
  1838. {12:K} |
  1839. {12:LLL} Y Z |
  1840. 7 8 9 |
  1841. |
  1842. {11:[No Name] [+] }|
  1843. |1| 1 {12:MMM} |
  1844. |2|{12: K} |
  1845. |3|{12: LLL} Y Z |
  1846. {15:~ }|
  1847. {15:~ }|
  1848. {15:~ }|
  1849. {15:~ }|
  1850. {10:[Preview] }|
  1851. :%s/2\_.*X/MMM\rK\rLLL^ |
  1852. ]])
  1853. end)
  1854. it("inccommand=nosplit, highlights multiline substitutions", function()
  1855. common_setup(screen, "nosplit", multiline_text)
  1856. feed("gg")
  1857. feed(":%s/2\\_.*X/MMM")
  1858. screen:expect([[
  1859. 1 {12:MMM} Y Z |
  1860. 7 8 9 |
  1861. |
  1862. {15:~ }|
  1863. {15:~ }|
  1864. {15:~ }|
  1865. {15:~ }|
  1866. {15:~ }|
  1867. {15:~ }|
  1868. {15:~ }|
  1869. {15:~ }|
  1870. {15:~ }|
  1871. {15:~ }|
  1872. {15:~ }|
  1873. :%s/2\_.*X/MMM^ |
  1874. ]])
  1875. feed("\\rK\\rLLL")
  1876. screen:expect([[
  1877. 1 {12:MMM} |
  1878. {12:K} |
  1879. {12:LLL} Y Z |
  1880. 7 8 9 |
  1881. |
  1882. {15:~ }|
  1883. {15:~ }|
  1884. {15:~ }|
  1885. {15:~ }|
  1886. {15:~ }|
  1887. {15:~ }|
  1888. {15:~ }|
  1889. {15:~ }|
  1890. {15:~ }|
  1891. :%s/2\_.*X/MMM\rK\rLLL^ |
  1892. ]])
  1893. end)
  1894. it("inccommand=split, highlights multiple matches on a line", function()
  1895. common_setup(screen, "split", multimatch_text)
  1896. command("set gdefault")
  1897. feed("gg")
  1898. feed(":%s/a/XLK")
  1899. screen:expect([[
  1900. {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:XLK} r|
  1901. x |
  1902. |
  1903. {15:~ }|
  1904. {15:~ }|
  1905. {11:[No Name] [+] }|
  1906. |1| {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:X}|
  1907. {12:LK} r |
  1908. {15:~ }|
  1909. {15:~ }|
  1910. {15:~ }|
  1911. {15:~ }|
  1912. {15:~ }|
  1913. {10:[Preview] }|
  1914. :%s/a/XLK^ |
  1915. ]])
  1916. end)
  1917. it("inccommand=nosplit, highlights multiple matches on a line", function()
  1918. common_setup(screen, "nosplit", multimatch_text)
  1919. command("set gdefault")
  1920. feed("gg")
  1921. feed(":%s/a/XLK")
  1922. screen:expect([[
  1923. {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:XLK} r|
  1924. x |
  1925. |
  1926. {15:~ }|
  1927. {15:~ }|
  1928. {15:~ }|
  1929. {15:~ }|
  1930. {15:~ }|
  1931. {15:~ }|
  1932. {15:~ }|
  1933. {15:~ }|
  1934. {15:~ }|
  1935. {15:~ }|
  1936. {15:~ }|
  1937. :%s/a/XLK^ |
  1938. ]])
  1939. end)
  1940. it("inccommand=split, with \\zs", function()
  1941. common_setup(screen, "split", multiline_text)
  1942. feed("gg")
  1943. feed(":%s/[0-9]\\n\\zs[A-Z]/OKO")
  1944. screen:expect([[
  1945. {12:OKO} B C |
  1946. 4 5 6 |
  1947. {12:OKO} Y Z |
  1948. 7 8 9 |
  1949. |
  1950. {11:[No Name] [+] }|
  1951. |1| 1 2 3 |
  1952. |2| {12:OKO} B C |
  1953. |3| 4 5 6 |
  1954. |4| {12:OKO} Y Z |
  1955. {15:~ }|
  1956. {15:~ }|
  1957. {15:~ }|
  1958. {10:[Preview] }|
  1959. :%s/[0-9]\n\zs[A-Z]/OKO^ |
  1960. ]])
  1961. end)
  1962. it("inccommand=nosplit, with \\zs", function()
  1963. common_setup(screen, "nosplit", multiline_text)
  1964. feed("gg")
  1965. feed(":%s/[0-9]\\n\\zs[A-Z]/OKO")
  1966. screen:expect([[
  1967. 1 2 3 |
  1968. {12:OKO} B C |
  1969. 4 5 6 |
  1970. {12:OKO} Y Z |
  1971. 7 8 9 |
  1972. |
  1973. {15:~ }|
  1974. {15:~ }|
  1975. {15:~ }|
  1976. {15:~ }|
  1977. {15:~ }|
  1978. {15:~ }|
  1979. {15:~ }|
  1980. {15:~ }|
  1981. :%s/[0-9]\n\zs[A-Z]/OKO^ |
  1982. ]])
  1983. end)
  1984. it("inccommand=split, substitutions of different length",
  1985. function()
  1986. common_setup(screen, "split", "T T123 T2T TTT T090804\nx")
  1987. feed(":%s/T\\([0-9]\\+\\)/\\1\\1/g")
  1988. screen:expect([[
  1989. T {12:123123} {12:22}T TTT {12:090804090804} |
  1990. x |
  1991. {15:~ }|
  1992. {15:~ }|
  1993. {15:~ }|
  1994. {11:[No Name] [+] }|
  1995. |1| T {12:123123} {12:22}T TTT {12:090804090}|
  1996. {12:804} |
  1997. {15:~ }|
  1998. {15:~ }|
  1999. {15:~ }|
  2000. {15:~ }|
  2001. {15:~ }|
  2002. {10:[Preview] }|
  2003. :%s/T\([0-9]\+\)/\1\1/g^ |
  2004. ]])
  2005. end)
  2006. it("inccommand=nosplit, substitutions of different length", function()
  2007. common_setup(screen, "nosplit", "T T123 T2T TTT T090804\nx")
  2008. feed(":%s/T\\([0-9]\\+\\)/\\1\\1/g")
  2009. screen:expect([[
  2010. T {12:123123} {12:22}T TTT {12:090804090804} |
  2011. x |
  2012. {15:~ }|
  2013. {15:~ }|
  2014. {15:~ }|
  2015. {15:~ }|
  2016. {15:~ }|
  2017. {15:~ }|
  2018. {15:~ }|
  2019. {15:~ }|
  2020. {15:~ }|
  2021. {15:~ }|
  2022. {15:~ }|
  2023. {15:~ }|
  2024. :%s/T\([0-9]\+\)/\1\1/g^ |
  2025. ]])
  2026. end)
  2027. it("inccommand=split, contraction of lines", function()
  2028. local text = [[
  2029. T T123 T T123 T2T TT T23423424
  2030. x
  2031. afa Q
  2032. adf la;lkd R
  2033. alx
  2034. ]]
  2035. common_setup(screen, "split", text)
  2036. feed(":%s/[QR]\\n")
  2037. screen:expect([[
  2038. afa {12:Q} |
  2039. adf la;lkd {12:R} |
  2040. alx |
  2041. |
  2042. {15:~ }|
  2043. {11:[No Name] [+] }|
  2044. |3| afa {12:Q} |
  2045. |4|{12: }adf la;lkd {12:R} |
  2046. |5|{12: }alx |
  2047. {15:~ }|
  2048. {15:~ }|
  2049. {15:~ }|
  2050. {15:~ }|
  2051. {10:[Preview] }|
  2052. :%s/[QR]\n^ |
  2053. ]])
  2054. feed("/KKK")
  2055. screen:expect([[
  2056. T T123 T T123 T2T TT T23423424|
  2057. x |
  2058. afa {12:KKK}adf la;lkd {12:KKK}alx |
  2059. |
  2060. {15:~ }|
  2061. {11:[No Name] [+] }|
  2062. |3| afa {12:KKK}adf la;lkd {12:KKK}alx |
  2063. {15:~ }|
  2064. {15:~ }|
  2065. {15:~ }|
  2066. {15:~ }|
  2067. {15:~ }|
  2068. {15:~ }|
  2069. {10:[Preview] }|
  2070. :%s/[QR]\n/KKK^ |
  2071. ]])
  2072. end)
  2073. it("inccommand=nosplit, contraction of lines", function()
  2074. local text = [[
  2075. T T123 T T123 T2T TT T23423424
  2076. x
  2077. afa Q
  2078. adf la;lkd R
  2079. alx
  2080. ]]
  2081. common_setup(screen, "nosplit", text)
  2082. feed(":%s/[QR]\\n/KKK")
  2083. screen:expect([[
  2084. T T123 T T123 T2T TT T23423424|
  2085. x |
  2086. afa {12:KKK}adf la;lkd {12:KKK}alx |
  2087. |
  2088. {15:~ }|
  2089. {15:~ }|
  2090. {15:~ }|
  2091. {15:~ }|
  2092. {15:~ }|
  2093. {15:~ }|
  2094. {15:~ }|
  2095. {15:~ }|
  2096. {15:~ }|
  2097. {15:~ }|
  2098. :%s/[QR]\n/KKK^ |
  2099. ]])
  2100. end)
  2101. it("inccommand=split, contraction of two subsequent NL chars", function()
  2102. -- luacheck: push ignore 611
  2103. local text = [[
  2104. AAA AA
  2105. BBB BB
  2106. CCC CC
  2107. ]]
  2108. -- luacheck: pop
  2109. -- This used to crash, but more than 20 highlight entries are required
  2110. -- to reproduce it (so that the marktree has multiple nodes)
  2111. common_setup(screen, "split", string.rep(text,10))
  2112. feed(":%s/\\n\\n/<c-v><c-m>/g")
  2113. screen:expect{grid=[[
  2114. CCC CC |
  2115. AAA AA |
  2116. BBB BB |
  2117. CCC CC |
  2118. |
  2119. {11:[No Name] [+] }|
  2120. | 1| AAA AA |
  2121. | 2|{12: }BBB BB |
  2122. | 3|{12: }CCC CC |
  2123. | 4|{12: }AAA AA |
  2124. | 5|{12: }BBB BB |
  2125. | 6|{12: }CCC CC |
  2126. | 7|{12: }AAA AA |
  2127. {10:[Preview] }|
  2128. :%s/\n\n/{17:^M}/g^ |
  2129. ]]}
  2130. assert_alive()
  2131. end)
  2132. it("inccommand=nosplit, contraction of two subsequent NL chars", function()
  2133. -- luacheck: push ignore 611
  2134. local text = [[
  2135. AAA AA
  2136. BBB BB
  2137. CCC CC
  2138. ]]
  2139. -- luacheck: pop
  2140. common_setup(screen, "nosplit", string.rep(text,10))
  2141. feed(":%s/\\n\\n/<c-v><c-m>/g")
  2142. screen:expect{grid=[[
  2143. CCC CC |
  2144. AAA AA |
  2145. BBB BB |
  2146. CCC CC |
  2147. AAA AA |
  2148. BBB BB |
  2149. CCC CC |
  2150. AAA AA |
  2151. BBB BB |
  2152. CCC CC |
  2153. AAA AA |
  2154. BBB BB |
  2155. CCC CC |
  2156. |
  2157. :%s/\n\n/{17:^M}/g^ |
  2158. ]]}
  2159. assert_alive()
  2160. end)
  2161. it("inccommand=split, multibyte text", function()
  2162. common_setup(screen, "split", multibyte_text)
  2163. feed(":%s/£.*ѫ/X¥¥")
  2164. screen:expect([[
  2165. a{12:X¥¥}¥KOL |
  2166. £ ¥ libm |
  2167. £ ¥ |
  2168. |
  2169. {15:~ }|
  2170. {11:[No Name] [+] }|
  2171. |1| {12:X¥¥} PEPPERS |
  2172. |2| {12:X¥¥} |
  2173. |3| a{12:X¥¥}¥KOL |
  2174. {15:~ }|
  2175. {15:~ }|
  2176. {15:~ }|
  2177. {15:~ }|
  2178. {10:[Preview] }|
  2179. :%s/£.*ѫ/X¥¥^ |
  2180. ]])
  2181. feed("\\ra££ ¥")
  2182. screen:expect([[
  2183. a{12:X¥¥} |
  2184. {12:a££ ¥}¥KOL |
  2185. £ ¥ libm |
  2186. £ ¥ |
  2187. |
  2188. {11:[No Name] [+] }|
  2189. |1| {12:X¥¥} |
  2190. |2|{12: a££ ¥} PEPPERS |
  2191. |3| {12:X¥¥} |
  2192. |4|{12: a££ ¥} |
  2193. |5| a{12:X¥¥} |
  2194. |6|{12: a££ ¥}¥KOL |
  2195. {15:~ }|
  2196. {10:[Preview] }|
  2197. :%s/£.*ѫ/X¥¥\ra££ ¥^ |
  2198. ]])
  2199. end)
  2200. it("inccommand=nosplit, multibyte text", function()
  2201. common_setup(screen, "nosplit", multibyte_text)
  2202. feed(":%s/£.*ѫ/X¥¥")
  2203. screen:expect([[
  2204. {12:X¥¥} PEPPERS |
  2205. {12:X¥¥} |
  2206. a{12:X¥¥}¥KOL |
  2207. £ ¥ libm |
  2208. £ ¥ |
  2209. |
  2210. {15:~ }|
  2211. {15:~ }|
  2212. {15:~ }|
  2213. {15:~ }|
  2214. {15:~ }|
  2215. {15:~ }|
  2216. {15:~ }|
  2217. {15:~ }|
  2218. :%s/£.*ѫ/X¥¥^ |
  2219. ]])
  2220. feed("\\ra££ ¥")
  2221. screen:expect([[
  2222. {12:X¥¥} |
  2223. {12:a££ ¥} PEPPERS |
  2224. {12:X¥¥} |
  2225. {12:a££ ¥} |
  2226. a{12:X¥¥} |
  2227. {12:a££ ¥}¥KOL |
  2228. £ ¥ libm |
  2229. £ ¥ |
  2230. |
  2231. {15:~ }|
  2232. {15:~ }|
  2233. {15:~ }|
  2234. {15:~ }|
  2235. {15:~ }|
  2236. :%s/£.*ѫ/X¥¥\ra££ ¥^ |
  2237. ]])
  2238. end)
  2239. it("inccommand=split, small cmdwinheight", function()
  2240. common_setup(screen, "split", long_multiline_text)
  2241. command("set cmdwinheight=2")
  2242. feed(":%s/[a-z]")
  2243. screen:expect([[
  2244. X Y Z |
  2245. 7 8 9 |
  2246. K L M |
  2247. {12:a} b c |
  2248. {12:d} e f |
  2249. {12:q} r s |
  2250. {12:x} y z |
  2251. £ {12:m} n |
  2252. {12:t} œ ¥ |
  2253. |
  2254. {11:[No Name] [+] }|
  2255. | 7| {12:a} b c |
  2256. | 8| {12:d} e f |
  2257. {10:[Preview] }|
  2258. :%s/[a-z]^ |
  2259. ]])
  2260. feed("/JLKR £")
  2261. screen:expect([[
  2262. X Y Z |
  2263. 7 8 9 |
  2264. K L M |
  2265. {12:JLKR £} b c |
  2266. {12:JLKR £} e f |
  2267. {12:JLKR £} r s |
  2268. {12:JLKR £} y z |
  2269. £ {12:JLKR £} n |
  2270. {12:JLKR £} œ ¥ |
  2271. |
  2272. {11:[No Name] [+] }|
  2273. | 7| {12:JLKR £} b c |
  2274. | 8| {12:JLKR £} e f |
  2275. {10:[Preview] }|
  2276. :%s/[a-z]/JLKR £^ |
  2277. ]])
  2278. feed("\\rѫ ab \\rXXXX")
  2279. screen:expect([[
  2280. K L M |
  2281. {12:JLKR £} |
  2282. {12:ѫ ab } |
  2283. {12:XXXX} b c |
  2284. {12:JLKR £} |
  2285. {12:ѫ ab } |
  2286. {12:XXXX} e f |
  2287. {12:JLKR £} |
  2288. {12:ѫ ab } |
  2289. {11:[No Name] [+] }|
  2290. | 7| {12:JLKR £} |
  2291. | 8|{12: ѫ ab } |
  2292. {10:[Preview] }|
  2293. :%s/[a-z]/JLKR £\rѫ ab \rXXX|
  2294. X^ |
  2295. ]])
  2296. end)
  2297. it("inccommand=split, large cmdwinheight", function()
  2298. common_setup(screen, "split", long_multiline_text)
  2299. command("set cmdwinheight=11")
  2300. feed(":%s/. .$")
  2301. screen:expect([[
  2302. t {12:œ ¥} |
  2303. {11:[No Name] [+] }|
  2304. | 1| 1 {12:2 3} |
  2305. | 2| A {12:B C} |
  2306. | 3| 4 {12:5 6} |
  2307. | 4| X {12:Y Z} |
  2308. | 5| 7 {12:8 9} |
  2309. | 6| K {12:L M} |
  2310. | 7| a {12:b c} |
  2311. | 8| d {12:e f} |
  2312. | 9| q {12:r s} |
  2313. |10| x {12:y z} |
  2314. |11| £ {12:m n} |
  2315. {10:[Preview] }|
  2316. :%s/. .$^ |
  2317. ]])
  2318. feed("/ YYY")
  2319. screen:expect([[
  2320. t {12: YYY} |
  2321. {11:[No Name] [+] }|
  2322. | 1| 1 {12: YYY} |
  2323. | 2| A {12: YYY} |
  2324. | 3| 4 {12: YYY} |
  2325. | 4| X {12: YYY} |
  2326. | 5| 7 {12: YYY} |
  2327. | 6| K {12: YYY} |
  2328. | 7| a {12: YYY} |
  2329. | 8| d {12: YYY} |
  2330. | 9| q {12: YYY} |
  2331. |10| x {12: YYY} |
  2332. |11| £ {12: YYY} |
  2333. {10:[Preview] }|
  2334. :%s/. .$/ YYY^ |
  2335. ]])
  2336. feed("\\r KKK")
  2337. screen:expect([[
  2338. a {12: YYY} |
  2339. {11:[No Name] [+] }|
  2340. | 1| 1 {12: YYY} |
  2341. | 2|{12: KKK} |
  2342. | 3| A {12: YYY} |
  2343. | 4|{12: KKK} |
  2344. | 5| 4 {12: YYY} |
  2345. | 6|{12: KKK} |
  2346. | 7| X {12: YYY} |
  2347. | 8|{12: KKK} |
  2348. | 9| 7 {12: YYY} |
  2349. |10|{12: KKK} |
  2350. |11| K {12: YYY} |
  2351. {10:[Preview] }|
  2352. :%s/. .$/ YYY\r KKK^ |
  2353. ]])
  2354. end)
  2355. it("inccommand=split, lookaround", function()
  2356. common_setup(screen, "split", "something\neverything\nsomeone")
  2357. feed([[:%s/\(some\)\@<lt>=thing/one/]])
  2358. screen:expect([[
  2359. some{12:one} |
  2360. everything |
  2361. someone |
  2362. {15:~ }|
  2363. {15:~ }|
  2364. {11:[No Name] [+] }|
  2365. |1| some{12:one} |
  2366. {15:~ }|
  2367. {15:~ }|
  2368. {15:~ }|
  2369. {15:~ }|
  2370. {15:~ }|
  2371. {15:~ }|
  2372. {10:[Preview] }|
  2373. :%s/\(some\)\@<=thing/one/^ |
  2374. ]])
  2375. feed("<C-c>")
  2376. feed('gg')
  2377. poke_eventloop()
  2378. feed([[:%s/\(some\)\@<lt>!thing/one/]])
  2379. screen:expect([[
  2380. something |
  2381. every{12:one} |
  2382. someone |
  2383. {15:~ }|
  2384. {15:~ }|
  2385. {11:[No Name] [+] }|
  2386. |2| every{12:one} |
  2387. {15:~ }|
  2388. {15:~ }|
  2389. {15:~ }|
  2390. {15:~ }|
  2391. {15:~ }|
  2392. {15:~ }|
  2393. {10:[Preview] }|
  2394. :%s/\(some\)\@<!thing/one/^ |
  2395. ]])
  2396. feed([[<C-c>]])
  2397. poke_eventloop()
  2398. feed([[:%s/some\(thing\)\@=/every/]])
  2399. screen:expect([[
  2400. {12:every}thing |
  2401. everything |
  2402. someone |
  2403. {15:~ }|
  2404. {15:~ }|
  2405. {11:[No Name] [+] }|
  2406. |1| {12:every}thing |
  2407. {15:~ }|
  2408. {15:~ }|
  2409. {15:~ }|
  2410. {15:~ }|
  2411. {15:~ }|
  2412. {15:~ }|
  2413. {10:[Preview] }|
  2414. :%s/some\(thing\)\@=/every/^ |
  2415. ]])
  2416. feed([[<C-c>]])
  2417. poke_eventloop()
  2418. feed([[:%s/some\(thing\)\@!/every/]])
  2419. screen:expect([[
  2420. something |
  2421. everything |
  2422. {12:every}one |
  2423. {15:~ }|
  2424. {15:~ }|
  2425. {11:[No Name] [+] }|
  2426. |3| {12:every}one |
  2427. {15:~ }|
  2428. {15:~ }|
  2429. {15:~ }|
  2430. {15:~ }|
  2431. {15:~ }|
  2432. {15:~ }|
  2433. {10:[Preview] }|
  2434. :%s/some\(thing\)\@!/every/^ |
  2435. ]])
  2436. end)
  2437. it("doesn't prompt to swap cmd range", function()
  2438. screen = Screen.new(50, 8) -- wide to avoid hit-enter prompt
  2439. common_setup(screen, "split", default_text)
  2440. feed(':2,1s/tw/MO/g')
  2441. -- substitution preview should have been made, without prompting
  2442. screen:expect([[
  2443. {12:MO}o lines |
  2444. {11:[No Name] [+] }|
  2445. |2| {12:MO}o lines |
  2446. {15:~ }|
  2447. {15:~ }|
  2448. {15:~ }|
  2449. {10:[Preview] }|
  2450. :2,1s/tw/MO/g^ |
  2451. ]])
  2452. -- but should be prompted on hitting enter
  2453. feed('<CR>')
  2454. screen:expect([[
  2455. {12:MO}o lines |
  2456. {11:[No Name] [+] }|
  2457. |2| {12:MO}o lines |
  2458. {15:~ }|
  2459. {15:~ }|
  2460. {15:~ }|
  2461. {10:[Preview] }|
  2462. {13:Backwards range given, OK to swap (y/n)?}^ |
  2463. ]])
  2464. feed('y')
  2465. screen:expect([[
  2466. Inc substitution on |
  2467. ^MOo lines |
  2468. |
  2469. {15:~ }|
  2470. {15:~ }|
  2471. {15:~ }|
  2472. {15:~ }|
  2473. {13:Backwards range given, OK to swap (y/n)?}y |
  2474. ]])
  2475. end)
  2476. end)
  2477. it(':substitute with inccommand during :terminal activity', function()
  2478. if helpers.skip_fragile(pending) then
  2479. return
  2480. end
  2481. retry(2, 40000, function()
  2482. local screen = Screen.new(30,15)
  2483. clear()
  2484. command("set cmdwinheight=3")
  2485. feed([[:terminal "]]..nvim_dir..[[/shell-test" REP 5000 xxx<cr>]])
  2486. command('file term')
  2487. feed('G') -- Follow :terminal output.
  2488. command('new')
  2489. common_setup(screen, 'split', 'foo bar baz\nbar baz fox\nbar foo baz')
  2490. command('wincmd =')
  2491. feed('gg')
  2492. feed(':%s/foo/ZZZ')
  2493. sleep(20) -- Allow some terminal activity.
  2494. helpers.poke_eventloop()
  2495. screen:expect_unchanged()
  2496. end)
  2497. end)
  2498. it(':substitute with inccommand, timer-induced :redraw #9777', function()
  2499. local screen = Screen.new(30,12)
  2500. clear()
  2501. command('set cmdwinheight=3')
  2502. command('call timer_start(10, {-> execute("redraw")}, {"repeat":-1})')
  2503. command('call timer_start(10, {-> execute("redrawstatus")}, {"repeat":-1})')
  2504. common_setup(screen, 'split', 'foo bar baz\nbar baz fox\nbar foo baz')
  2505. feed('gg')
  2506. feed(':%s/foo/ZZZ')
  2507. sleep(20) -- Allow some timer activity.
  2508. screen:expect([[
  2509. {12:ZZZ} bar baz |
  2510. bar baz fox |
  2511. bar {12:ZZZ} baz |
  2512. {15:~ }|
  2513. {15:~ }|
  2514. {15:~ }|
  2515. {11:[No Name] [+] }|
  2516. |1| {12:ZZZ} bar baz |
  2517. |3| bar {12:ZZZ} baz |
  2518. {15:~ }|
  2519. {10:[Preview] }|
  2520. :%s/foo/ZZZ^ |
  2521. ]])
  2522. end)
  2523. it(":substitute doesn't crash with inccommand, if undo is empty #12932", function()
  2524. local screen = Screen.new(10,5)
  2525. clear()
  2526. command('set undolevels=-1')
  2527. common_setup(screen, 'split', 'test')
  2528. feed(':%s/test')
  2529. sleep(100)
  2530. feed('/')
  2531. sleep(100)
  2532. feed('f')
  2533. screen:expect([[
  2534. {12:f} |
  2535. {15:~ }|
  2536. {15:~ }|
  2537. {15:~ }|
  2538. :%s/test/f^ |
  2539. ]])
  2540. assert_alive()
  2541. end)
  2542. it('long :%s/ with inccommand does not collapse cmdline', function()
  2543. local screen = Screen.new(10,5)
  2544. clear()
  2545. common_setup(screen)
  2546. command('set inccommand=nosplit')
  2547. feed(':%s/AAAAAAA', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
  2548. 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A')
  2549. screen:expect([[
  2550. {15:~ }|
  2551. {15:~ }|
  2552. :%s/AAAAAAAA|
  2553. AAAAAAAAAAAA|
  2554. AAAAAAA^ |
  2555. ]])
  2556. end)