inccommand_spec.lua 77 KB

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