merging_spec.lua 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220
  1. -- ShaDa merging data support
  2. local t = require('test.testutil')
  3. local n = require('test.functional.testnvim')()
  4. local t_shada = require('test.functional.shada.testutil')
  5. local nvim_command, fn, eq = n.command, n.fn, t.eq
  6. local exc_exec, exec_capture = n.exc_exec, n.exec_capture
  7. local api = n.api
  8. local reset, clear, get_shada_rw = t_shada.reset, t_shada.clear, t_shada.get_shada_rw
  9. local read_shada_file = t_shada.read_shada_file
  10. local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-merging.shada')
  11. local mock_file_path = '/a/b/'
  12. if t.is_os('win') then
  13. mock_file_path = 'C:/a/'
  14. end
  15. describe('ShaDa history merging code', function()
  16. before_each(reset)
  17. after_each(function()
  18. clear()
  19. os.remove(shada_fname)
  20. end)
  21. it('takes item with greater timestamp from Neovim instance when reading', function()
  22. wshada('\004\001\009\147\000\196\002ab\196\001a')
  23. eq(0, exc_exec(sdrcmd()))
  24. wshada('\004\000\009\147\000\196\002ab\196\001b')
  25. eq(0, exc_exec(sdrcmd()))
  26. os.remove(shada_fname)
  27. eq(0, exc_exec('wshada! ' .. shada_fname))
  28. local found = 0
  29. for _, v in ipairs(read_shada_file(shada_fname)) do
  30. if v.type == 4 and v.value[1] == 0 and v.value[2] == 'ab' then
  31. eq(1, v.timestamp)
  32. eq('a', v.value[3])
  33. found = found + 1
  34. end
  35. end
  36. eq(1, found)
  37. end)
  38. it('takes item with equal timestamp from Neovim instance when reading', function()
  39. wshada('\004\000\009\147\000\196\002ab\196\001a')
  40. eq(0, exc_exec(sdrcmd()))
  41. wshada('\004\000\009\147\000\196\002ab\196\001b')
  42. eq(0, exc_exec(sdrcmd()))
  43. os.remove(shada_fname)
  44. eq(0, exc_exec('wshada! ' .. shada_fname))
  45. local found = 0
  46. for _, v in ipairs(read_shada_file(shada_fname)) do
  47. if v.type == 4 and v.value[1] == 0 and v.value[2] == 'ab' then
  48. eq(0, v.timestamp)
  49. eq('a', v.value[3])
  50. found = found + 1
  51. end
  52. end
  53. eq(1, found)
  54. end)
  55. it('takes item with greater timestamp from ShaDa when reading', function()
  56. wshada('\004\000\009\147\000\196\002ab\196\001a')
  57. eq(0, exc_exec(sdrcmd()))
  58. wshada('\004\001\009\147\000\196\002ab\196\001b')
  59. eq(0, exc_exec(sdrcmd()))
  60. os.remove(shada_fname)
  61. eq(0, exc_exec('wshada! ' .. shada_fname))
  62. local found = 0
  63. for _, v in ipairs(read_shada_file(shada_fname)) do
  64. if v.type == 4 and v.value[1] == 0 and v.value[2] == 'ab' then
  65. eq(1, v.timestamp)
  66. eq('b', v.value[3])
  67. found = found + 1
  68. end
  69. end
  70. eq(1, found)
  71. end)
  72. it('takes item with greater timestamp from Neovim instance when writing', function()
  73. wshada('\004\001\009\147\000\196\002ab\196\001a')
  74. eq(0, exc_exec(sdrcmd()))
  75. wshada('\004\000\009\147\000\196\002ab\196\001b')
  76. eq(0, exc_exec('wshada ' .. shada_fname))
  77. local found = 0
  78. for _, v in ipairs(read_shada_file(shada_fname)) do
  79. if v.type == 4 and v.value[1] == 0 and v.value[2] == 'ab' then
  80. eq(1, v.timestamp)
  81. eq('a', v.value[3])
  82. found = found + 1
  83. end
  84. end
  85. eq(1, found)
  86. end)
  87. it('takes item with equal timestamp from Neovim instance when writing', function()
  88. wshada('\004\000\009\147\000\196\002ab\196\001a')
  89. eq(0, exc_exec(sdrcmd()))
  90. wshada('\004\000\009\147\000\196\002ab\196\001b')
  91. eq(0, exc_exec('wshada ' .. shada_fname))
  92. local found = 0
  93. for _, v in ipairs(read_shada_file(shada_fname)) do
  94. if v.type == 4 and v.value[1] == 0 and v.value[2] == 'ab' then
  95. eq(0, v.timestamp)
  96. eq('a', v.value[3])
  97. found = found + 1
  98. end
  99. end
  100. eq(1, found)
  101. end)
  102. it('takes item with greater timestamp from ShaDa when writing', function()
  103. wshada('\004\000\009\147\000\196\002ab\196\001a')
  104. eq(0, exc_exec(sdrcmd()))
  105. wshada('\004\001\009\147\000\196\002ab\196\001b')
  106. eq(0, exc_exec('wshada ' .. shada_fname))
  107. local found = 0
  108. for _, v in ipairs(read_shada_file(shada_fname)) do
  109. if v.type == 4 and v.value[1] == 0 and v.value[2] == 'ab' then
  110. eq(1, v.timestamp)
  111. eq('b', v.value[3])
  112. found = found + 1
  113. end
  114. end
  115. eq(1, found)
  116. end)
  117. it('correctly reads history items with messed up timestamps', function()
  118. wshada(
  119. '\004\010\009\147\000\196\002ab\196\001a'
  120. .. '\004\010\009\147\000\196\002ac\196\001a'
  121. .. '\004\005\009\147\000\196\002ad\196\001a'
  122. .. '\004\100\009\147\000\196\002ae\196\001a'
  123. .. '\004\090\009\147\000\196\002af\196\001a'
  124. )
  125. eq(0, exc_exec(sdrcmd()))
  126. os.remove(shada_fname)
  127. eq(0, exc_exec('wshada! ' .. shada_fname))
  128. local items = { 'ad', 'ab', 'ac', 'af', 'ae' }
  129. for i, v in ipairs(items) do
  130. eq(v, fn.histget(':', i))
  131. end
  132. local found = 0
  133. for _, v in ipairs(read_shada_file(shada_fname)) do
  134. if v.type == 4 and v.value[1] == 0 then
  135. found = found + 1
  136. eq(items[found], v.value[2])
  137. eq('a', v.value[3])
  138. end
  139. end
  140. eq(#items, found)
  141. end)
  142. it('correctly reorders history items with messed up timestamps when writing', function()
  143. wshada(
  144. '\004\010\009\147\000\196\002ab\196\001a'
  145. .. '\004\010\009\147\000\196\002ac\196\001a'
  146. .. '\004\005\009\147\000\196\002ad\196\001a'
  147. .. '\004\100\009\147\000\196\002ae\196\001a'
  148. .. '\004\090\009\147\000\196\002af\196\001a'
  149. )
  150. eq(0, exc_exec('wshada ' .. shada_fname))
  151. local items = { 'ad', 'ab', 'ac', 'af', 'ae' }
  152. local found = 0
  153. for _, v in ipairs(read_shada_file(shada_fname)) do
  154. if v.type == 4 and v.value[1] == 0 then
  155. found = found + 1
  156. eq(items[found], v.value[2])
  157. eq('a', v.value[3])
  158. end
  159. end
  160. eq(#items, found)
  161. end)
  162. it('correctly merges history items with duplicate mid entry when writing', function()
  163. -- Regression test: ShaDa code used to crash here.
  164. -- Conditions:
  165. -- 1. Entry which is duplicate to non-last entry.
  166. -- 2. At least one more non-duplicate entry.
  167. wshada(
  168. '\004\000\009\147\000\196\002ab\196\001a'
  169. .. '\004\001\009\147\000\196\002ac\196\001a'
  170. .. '\004\002\009\147\000\196\002ad\196\001a'
  171. .. '\004\003\009\147\000\196\002ac\196\001a'
  172. .. '\004\004\009\147\000\196\002af\196\001a'
  173. .. '\004\005\009\147\000\196\002ae\196\001a'
  174. .. '\004\006\009\147\000\196\002ag\196\001a'
  175. .. '\004\007\009\147\000\196\002ah\196\001a'
  176. .. '\004\008\009\147\000\196\002ai\196\001a'
  177. )
  178. eq(0, exc_exec('wshada ' .. shada_fname))
  179. local items = { 'ab', 'ad', 'ac', 'af', 'ae', 'ag', 'ah', 'ai' }
  180. local found = 0
  181. for _, v in ipairs(read_shada_file(shada_fname)) do
  182. if v.type == 4 and v.value[1] == 0 then
  183. found = found + 1
  184. eq(items[found], v.value[2])
  185. eq('a', v.value[3])
  186. end
  187. end
  188. eq(#items, found)
  189. end)
  190. it('correctly merges history items with duplicate adj entry when writing', function()
  191. wshada(
  192. '\004\000\009\147\000\196\002ab\196\001a'
  193. .. '\004\001\009\147\000\196\002ac\196\001a'
  194. .. '\004\002\009\147\000\196\002ad\196\001a'
  195. .. '\004\003\009\147\000\196\002ad\196\001a'
  196. .. '\004\004\009\147\000\196\002af\196\001a'
  197. .. '\004\005\009\147\000\196\002ae\196\001a'
  198. .. '\004\006\009\147\000\196\002ag\196\001a'
  199. .. '\004\007\009\147\000\196\002ah\196\001a'
  200. .. '\004\008\009\147\000\196\002ai\196\001a'
  201. )
  202. eq(0, exc_exec('wshada ' .. shada_fname))
  203. local items = { 'ab', 'ac', 'ad', 'af', 'ae', 'ag', 'ah', 'ai' }
  204. local found = 0
  205. for _, v in ipairs(read_shada_file(shada_fname)) do
  206. if v.type == 4 and v.value[1] == 0 then
  207. found = found + 1
  208. eq(items[found], v.value[2])
  209. eq('a', v.value[3])
  210. end
  211. end
  212. eq(#items, found)
  213. end)
  214. end)
  215. describe('ShaDa search pattern support code', function()
  216. before_each(reset)
  217. after_each(function()
  218. clear()
  219. os.remove(shada_fname)
  220. end)
  221. it('uses last search pattern with gt timestamp from instance when reading', function()
  222. wshada('\002\001\011\130\162sX\194\162sp\196\001-')
  223. eq(0, exc_exec(sdrcmd()))
  224. wshada('\002\000\011\130\162sX\194\162sp\196\001?')
  225. eq(0, exc_exec(sdrcmd()))
  226. eq('-', fn.getreg('/'))
  227. end)
  228. it('uses last search pattern with gt tstamp from file when reading with bang', function()
  229. wshada('\002\001\011\130\162sX\194\162sp\196\001-')
  230. eq(0, exc_exec(sdrcmd()))
  231. wshada('\002\000\011\130\162sX\194\162sp\196\001?')
  232. eq(0, exc_exec(sdrcmd(true)))
  233. eq('?', fn.getreg('/'))
  234. end)
  235. it('uses last search pattern with eq timestamp from instance when reading', function()
  236. wshada('\002\001\011\130\162sX\194\162sp\196\001-')
  237. eq(0, exc_exec(sdrcmd()))
  238. wshada('\002\001\011\130\162sX\194\162sp\196\001?')
  239. eq(0, exc_exec(sdrcmd()))
  240. eq('-', fn.getreg('/'))
  241. end)
  242. it('uses last search pattern with gt timestamp from file when reading', function()
  243. wshada('\002\001\011\130\162sX\194\162sp\196\001-')
  244. eq(0, exc_exec(sdrcmd()))
  245. wshada('\002\002\011\130\162sX\194\162sp\196\001?')
  246. eq(0, exc_exec(sdrcmd()))
  247. eq('?', fn.getreg('/'))
  248. end)
  249. it('uses last search pattern with gt timestamp from instance when writing', function()
  250. wshada('\002\001\011\130\162sX\194\162sp\196\001-')
  251. eq(0, exc_exec(sdrcmd()))
  252. wshada('\002\000\011\130\162sX\194\162sp\196\001?')
  253. eq('-', fn.getreg('/'))
  254. eq(0, exc_exec('wshada ' .. shada_fname))
  255. local found = 0
  256. for _, v in ipairs(read_shada_file(shada_fname)) do
  257. if v.type == 2 and v.value.sp == '-' then
  258. found = found + 1
  259. end
  260. end
  261. eq(1, found)
  262. end)
  263. it('uses last search pattern with eq timestamp from instance when writing', function()
  264. wshada('\002\001\011\130\162sX\194\162sp\196\001-')
  265. eq(0, exc_exec(sdrcmd()))
  266. wshada('\002\001\011\130\162sX\194\162sp\196\001?')
  267. eq('-', fn.getreg('/'))
  268. eq(0, exc_exec('wshada ' .. shada_fname))
  269. local found = 0
  270. for _, v in ipairs(read_shada_file(shada_fname)) do
  271. if v.type == 2 and v.value.sp == '-' then
  272. found = found + 1
  273. end
  274. end
  275. eq(1, found)
  276. end)
  277. it('uses last search pattern with gt timestamp from file when writing', function()
  278. wshada('\002\001\011\130\162sX\194\162sp\196\001-')
  279. eq(0, exc_exec(sdrcmd()))
  280. wshada('\002\002\011\130\162sX\194\162sp\196\001?')
  281. eq('-', fn.getreg('/'))
  282. eq(0, exc_exec('wshada ' .. shada_fname))
  283. local found = 0
  284. for _, v in ipairs(read_shada_file(shada_fname)) do
  285. if v.type == 2 and v.value.sp == '?' then
  286. found = found + 1
  287. end
  288. end
  289. eq(1, found)
  290. end)
  291. it('uses last s/ pattern with gt timestamp from instance when reading', function()
  292. wshada('\002\001\011\130\162ss\195\162sp\196\001-')
  293. eq(0, exc_exec(sdrcmd()))
  294. wshada('\002\000\011\130\162ss\195\162sp\196\001?')
  295. eq(0, exc_exec(sdrcmd()))
  296. eq('-', fn.getreg('/'))
  297. end)
  298. it('uses last s/ pattern with gt timestamp from file when reading with !', function()
  299. wshada('\002\001\011\130\162ss\195\162sp\196\001-')
  300. eq(0, exc_exec(sdrcmd()))
  301. wshada('\002\000\011\130\162ss\195\162sp\196\001?')
  302. eq(0, exc_exec(sdrcmd(true)))
  303. eq('?', fn.getreg('/'))
  304. end)
  305. it('uses last s/ pattern with eq timestamp from instance when reading', function()
  306. wshada('\002\001\011\130\162ss\195\162sp\196\001-')
  307. eq(0, exc_exec(sdrcmd()))
  308. wshada('\002\001\011\130\162ss\195\162sp\196\001?')
  309. eq(0, exc_exec(sdrcmd()))
  310. eq('-', fn.getreg('/'))
  311. end)
  312. it('uses last s/ pattern with gt timestamp from file when reading', function()
  313. wshada('\002\001\011\130\162ss\195\162sp\196\001-')
  314. eq(0, exc_exec(sdrcmd()))
  315. wshada('\002\002\011\130\162ss\195\162sp\196\001?')
  316. eq(0, exc_exec(sdrcmd()))
  317. eq('?', fn.getreg('/'))
  318. end)
  319. it('uses last s/ pattern with gt timestamp from instance when writing', function()
  320. wshada('\002\001\011\130\162ss\195\162sp\196\001-')
  321. eq(0, exc_exec(sdrcmd()))
  322. wshada('\002\000\011\130\162ss\195\162sp\196\001?')
  323. eq('-', fn.getreg('/'))
  324. eq(0, exc_exec('wshada ' .. shada_fname))
  325. local found = 0
  326. for _, v in ipairs(read_shada_file(shada_fname)) do
  327. if v.type == 2 and v.value.sp == '-' then
  328. found = found + 1
  329. end
  330. end
  331. eq(1, found)
  332. end)
  333. it('uses last s/ pattern with eq timestamp from instance when writing', function()
  334. wshada('\002\001\011\130\162ss\195\162sp\196\001-')
  335. eq(0, exc_exec(sdrcmd()))
  336. wshada('\002\001\011\130\162ss\195\162sp\196\001?')
  337. eq('-', fn.getreg('/'))
  338. eq(0, exc_exec('wshada ' .. shada_fname))
  339. local found = 0
  340. for _, v in ipairs(read_shada_file(shada_fname)) do
  341. if v.type == 2 and v.value.sp == '-' then
  342. found = found + 1
  343. end
  344. end
  345. eq(1, found)
  346. end)
  347. it('uses last s/ pattern with gt timestamp from file when writing', function()
  348. wshada('\002\001\011\130\162ss\195\162sp\196\001-')
  349. eq(0, exc_exec(sdrcmd()))
  350. wshada('\002\002\011\130\162ss\195\162sp\196\001?')
  351. eq('-', fn.getreg('/'))
  352. eq(0, exc_exec('wshada ' .. shada_fname))
  353. local found = 0
  354. for _, v in ipairs(read_shada_file(shada_fname)) do
  355. if v.type == 2 and v.value.sp == '?' then
  356. found = found + 1
  357. end
  358. end
  359. eq(1, found)
  360. end)
  361. end)
  362. describe('ShaDa replacement string support code', function()
  363. before_each(reset)
  364. after_each(function()
  365. clear()
  366. os.remove(shada_fname)
  367. end)
  368. it('uses last replacement with gt timestamp from instance when reading', function()
  369. wshada('\003\001\004\145\196\001-')
  370. eq(0, exc_exec(sdrcmd()))
  371. wshada('\003\000\004\145\196\001?')
  372. eq(0, exc_exec(sdrcmd()))
  373. nvim_command('s/.*/~')
  374. eq('-', fn.getline('.'))
  375. nvim_command('bwipeout!')
  376. end)
  377. it('uses last replacement with gt timestamp from file when reading with bang', function()
  378. wshada('\003\001\004\145\196\001-')
  379. eq(0, exc_exec(sdrcmd()))
  380. wshada('\003\000\004\145\196\001?')
  381. eq(0, exc_exec(sdrcmd(true)))
  382. nvim_command('s/.*/~')
  383. eq('?', fn.getline('.'))
  384. nvim_command('bwipeout!')
  385. end)
  386. it('uses last replacement with eq timestamp from instance when reading', function()
  387. wshada('\003\001\004\145\196\001-')
  388. eq(0, exc_exec(sdrcmd()))
  389. wshada('\003\001\004\145\196\001?')
  390. eq(0, exc_exec(sdrcmd()))
  391. nvim_command('s/.*/~')
  392. eq('-', fn.getline('.'))
  393. nvim_command('bwipeout!')
  394. end)
  395. it('uses last replacement with gt timestamp from file when reading', function()
  396. wshada('\003\001\004\145\196\001-')
  397. eq(0, exc_exec(sdrcmd()))
  398. wshada('\003\002\004\145\196\001?')
  399. eq(0, exc_exec(sdrcmd()))
  400. nvim_command('s/.*/~')
  401. eq('?', fn.getline('.'))
  402. nvim_command('bwipeout!')
  403. end)
  404. it('uses last replacement with gt timestamp from instance when writing', function()
  405. wshada('\003\001\004\145\196\001-')
  406. eq(0, exc_exec(sdrcmd()))
  407. wshada('\003\000\004\145\196\001?')
  408. eq(0, exc_exec('wshada ' .. shada_fname))
  409. local found = 0
  410. for _, v in ipairs(read_shada_file(shada_fname)) do
  411. if v.type == 3 and v.value[1] == '-' then
  412. found = found + 1
  413. end
  414. end
  415. eq(1, found)
  416. end)
  417. it('uses last replacement with eq timestamp from instance when writing', function()
  418. wshada('\003\001\004\145\196\001-')
  419. eq(0, exc_exec(sdrcmd()))
  420. wshada('\003\001\004\145\196\001?')
  421. eq(0, exc_exec('wshada ' .. shada_fname))
  422. local found = 0
  423. for _, v in ipairs(read_shada_file(shada_fname)) do
  424. if v.type == 3 and v.value[1] == '-' then
  425. found = found + 1
  426. end
  427. end
  428. eq(1, found)
  429. end)
  430. it('uses last replacement with gt timestamp from file when writing', function()
  431. wshada('\003\001\004\145\196\001-')
  432. eq(0, exc_exec(sdrcmd()))
  433. wshada('\003\002\004\145\196\001?')
  434. eq(0, exc_exec('wshada ' .. shada_fname))
  435. local found = 0
  436. for _, v in ipairs(read_shada_file(shada_fname)) do
  437. if v.type == 3 and v.value[1] == '?' then
  438. found = found + 1
  439. end
  440. end
  441. eq(1, found)
  442. end)
  443. end)
  444. describe('ShaDa marks support code', function()
  445. before_each(reset)
  446. after_each(function()
  447. clear()
  448. os.remove(shada_fname)
  449. end)
  450. it('uses last A mark with gt timestamp from instance when reading', function()
  451. wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
  452. eq(0, exc_exec(sdrcmd()))
  453. wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
  454. eq(0, exc_exec(sdrcmd()))
  455. nvim_command('normal! `A')
  456. eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
  457. end)
  458. it('can merge with file with mark 9 as the only numeric mark', function()
  459. wshada('\007\001\014\130\161f\196\006' .. mock_file_path .. '-\161n9')
  460. eq(0, exc_exec(sdrcmd()))
  461. nvim_command('normal! `9oabc')
  462. eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
  463. eq(0, exc_exec('wshada ' .. shada_fname))
  464. local found = {}
  465. for _, v in ipairs(read_shada_file(shada_fname)) do
  466. if v.type == 7 and v.value.f == mock_file_path .. '-' then
  467. local name = ('%c'):format(v.value.n)
  468. found[name] = (found[name] or 0) + 1
  469. end
  470. end
  471. eq({ ['0'] = 1, ['1'] = 1 }, found)
  472. end)
  473. it('removes duplicates while merging', function()
  474. wshada(
  475. '\007\001\014\130\161f\196\006'
  476. .. mock_file_path
  477. .. '-\161n9'
  478. .. '\007\001\014\130\161f\196\006'
  479. .. mock_file_path
  480. .. '-\161n9'
  481. )
  482. eq(0, exc_exec(sdrcmd()))
  483. eq(0, exc_exec('wshada ' .. shada_fname))
  484. local found = 0
  485. for _, v in ipairs(read_shada_file(shada_fname)) do
  486. if v.type == 7 and v.value.f == mock_file_path .. '-' then
  487. print(require('test.format_string').format_luav(v))
  488. found = found + 1
  489. end
  490. end
  491. eq(1, found)
  492. end)
  493. it('does not leak when no append is performed due to too many marks', function()
  494. wshada(
  495. '\007\002\018\131\162mX\195\161f\196\006'
  496. .. mock_file_path
  497. .. 'a\161n0'
  498. .. '\007\002\018\131\162mX\195\161f\196\006'
  499. .. mock_file_path
  500. .. 'b\161n1'
  501. .. '\007\002\018\131\162mX\195\161f\196\006'
  502. .. mock_file_path
  503. .. 'c\161n2'
  504. .. '\007\002\018\131\162mX\195\161f\196\006'
  505. .. mock_file_path
  506. .. 'd\161n3'
  507. .. '\007\002\018\131\162mX\195\161f\196\006'
  508. .. mock_file_path
  509. .. 'e\161n4'
  510. .. '\007\002\018\131\162mX\195\161f\196\006'
  511. .. mock_file_path
  512. .. 'f\161n5'
  513. .. '\007\002\018\131\162mX\195\161f\196\006'
  514. .. mock_file_path
  515. .. 'g\161n6'
  516. .. '\007\002\018\131\162mX\195\161f\196\006'
  517. .. mock_file_path
  518. .. 'h\161n7'
  519. .. '\007\002\018\131\162mX\195\161f\196\006'
  520. .. mock_file_path
  521. .. 'i\161n8'
  522. .. '\007\002\018\131\162mX\195\161f\196\006'
  523. .. mock_file_path
  524. .. 'j\161n9'
  525. .. '\007\001\018\131\162mX\195\161f\196\006'
  526. .. mock_file_path
  527. .. 'k\161n9'
  528. )
  529. eq(0, exc_exec(sdrcmd()))
  530. eq(0, exc_exec('wshada ' .. shada_fname))
  531. local found = {}
  532. for _, v in ipairs(read_shada_file(shada_fname)) do
  533. if v.type == 7 and v.value.f:sub(1, #mock_file_path) == mock_file_path then
  534. found[#found + 1] = v.value.f:sub(#v.value.f)
  535. end
  536. end
  537. eq({ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }, found)
  538. end)
  539. it('does not leak when last mark in file removes some of the earlier ones', function()
  540. wshada(
  541. '\007\002\018\131\162mX\195\161f\196\006'
  542. .. mock_file_path
  543. .. 'a\161n0'
  544. .. '\007\002\018\131\162mX\195\161f\196\006'
  545. .. mock_file_path
  546. .. 'b\161n1'
  547. .. '\007\002\018\131\162mX\195\161f\196\006'
  548. .. mock_file_path
  549. .. 'c\161n2'
  550. .. '\007\002\018\131\162mX\195\161f\196\006'
  551. .. mock_file_path
  552. .. 'd\161n3'
  553. .. '\007\002\018\131\162mX\195\161f\196\006'
  554. .. mock_file_path
  555. .. 'e\161n4'
  556. .. '\007\002\018\131\162mX\195\161f\196\006'
  557. .. mock_file_path
  558. .. 'f\161n5'
  559. .. '\007\002\018\131\162mX\195\161f\196\006'
  560. .. mock_file_path
  561. .. 'g\161n6'
  562. .. '\007\002\018\131\162mX\195\161f\196\006'
  563. .. mock_file_path
  564. .. 'h\161n7'
  565. .. '\007\002\018\131\162mX\195\161f\196\006'
  566. .. mock_file_path
  567. .. 'i\161n8'
  568. .. '\007\002\018\131\162mX\195\161f\196\006'
  569. .. mock_file_path
  570. .. 'j\161n9'
  571. .. '\007\003\018\131\162mX\195\161f\196\006'
  572. .. mock_file_path
  573. .. 'k\161n9'
  574. )
  575. eq(0, exc_exec(sdrcmd()))
  576. eq(0, exc_exec('wshada ' .. shada_fname))
  577. local found = {}
  578. for _, v in ipairs(read_shada_file(shada_fname)) do
  579. if v.type == 7 and v.value.f:sub(1, #mock_file_path) == mock_file_path then
  580. found[#found + 1] = v.value.f:sub(#v.value.f)
  581. end
  582. end
  583. eq({ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k' }, found)
  584. end)
  585. it('uses last A mark with gt timestamp from file when reading with !', function()
  586. wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
  587. eq(0, exc_exec(sdrcmd()))
  588. wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
  589. eq(0, exc_exec(sdrcmd(true)))
  590. nvim_command('normal! `A')
  591. eq('?', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
  592. end)
  593. it('uses last A mark with eq timestamp from instance when reading', function()
  594. wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
  595. eq(0, exc_exec(sdrcmd()))
  596. wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
  597. eq(0, exc_exec(sdrcmd()))
  598. nvim_command('normal! `A')
  599. eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
  600. end)
  601. it('uses last A mark with gt timestamp from file when reading', function()
  602. wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
  603. eq(0, exc_exec(sdrcmd()))
  604. wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
  605. eq(0, exc_exec(sdrcmd()))
  606. nvim_command('normal! `A')
  607. eq('?', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
  608. end)
  609. it('uses last A mark with gt timestamp from instance when writing', function()
  610. wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
  611. eq(0, exc_exec(sdrcmd()))
  612. wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
  613. nvim_command('normal! `A')
  614. eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
  615. eq(0, exc_exec('wshada ' .. shada_fname))
  616. local found = {}
  617. for _, v in ipairs(read_shada_file(shada_fname)) do
  618. if v.type == 7 and v.value.f == mock_file_path .. '-' then
  619. local name = ('%c'):format(v.value.n)
  620. found[name] = (found[name] or 0) + 1
  621. end
  622. end
  623. eq({ ['0'] = 1, A = 1 }, found)
  624. end)
  625. it('uses last A mark with eq timestamp from instance when writing', function()
  626. wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
  627. eq(0, exc_exec(sdrcmd()))
  628. wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
  629. nvim_command('normal! `A')
  630. eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
  631. eq(0, exc_exec('wshada ' .. shada_fname))
  632. local found = {}
  633. for _, v in ipairs(read_shada_file(shada_fname)) do
  634. if v.type == 7 and v.value.f == mock_file_path .. '-' then
  635. local name = ('%c'):format(v.value.n)
  636. found[name] = (found[name] or 0) + 1
  637. end
  638. end
  639. eq({ ['0'] = 1, A = 1 }, found)
  640. end)
  641. it('uses last A mark with gt timestamp from file when writing', function()
  642. wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
  643. eq(0, exc_exec(sdrcmd()))
  644. wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
  645. nvim_command('normal! `A')
  646. eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
  647. eq(0, exc_exec('wshada ' .. shada_fname))
  648. local found = {}
  649. for _, v in ipairs(read_shada_file(shada_fname)) do
  650. if v.type == 7 then
  651. local name = ('%c'):format(v.value.n)
  652. local _t = found[name] or {}
  653. _t[v.value.f] = (_t[v.value.f] or 0) + 1
  654. found[name] = _t
  655. end
  656. end
  657. eq({ ['0'] = { [mock_file_path .. '-'] = 1 }, A = { [mock_file_path .. '?'] = 1 } }, found)
  658. end)
  659. it('uses last a mark with gt timestamp from instance when reading', function()
  660. nvim_command('edit ' .. mock_file_path .. '-')
  661. fn.setline(1, { '-', '?' })
  662. wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
  663. eq(0, exc_exec(sdrcmd()))
  664. wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
  665. eq(0, exc_exec(sdrcmd()))
  666. nvim_command('normal! `a')
  667. eq('-', fn.getline('.'))
  668. end)
  669. it('uses last a mark with gt timestamp from file when reading with !', function()
  670. nvim_command('edit ' .. mock_file_path .. '-')
  671. fn.setline(1, { '-', '?' })
  672. wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
  673. eq(0, exc_exec(sdrcmd()))
  674. wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
  675. eq(0, exc_exec(sdrcmd(true)))
  676. nvim_command('normal! `a')
  677. eq('?', fn.getline('.'))
  678. end)
  679. it('uses last a mark with eq timestamp from instance when reading', function()
  680. nvim_command('edit ' .. mock_file_path .. '-')
  681. fn.setline(1, { '-', '?' })
  682. wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
  683. eq(0, exc_exec(sdrcmd()))
  684. wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
  685. eq(0, exc_exec(sdrcmd()))
  686. nvim_command('normal! `a')
  687. eq('-', fn.getline('.'))
  688. end)
  689. it('uses last a mark with gt timestamp from file when reading', function()
  690. nvim_command('edit ' .. mock_file_path .. '-')
  691. fn.setline(1, { '-', '?' })
  692. wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
  693. eq(0, exc_exec(sdrcmd()))
  694. wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
  695. eq(0, exc_exec(sdrcmd()))
  696. nvim_command('normal! `a')
  697. eq('?', fn.getline('.'))
  698. end)
  699. it('uses last a mark with gt timestamp from instance when writing', function()
  700. nvim_command('edit ' .. mock_file_path .. '-')
  701. fn.setline(1, { '-', '?' })
  702. wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
  703. eq(0, exc_exec(sdrcmd()))
  704. wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
  705. nvim_command('normal! `a')
  706. eq('-', fn.getline('.'))
  707. eq(0, exc_exec('wshada ' .. shada_fname))
  708. local found = 0
  709. for _, v in ipairs(read_shada_file(shada_fname)) do
  710. if
  711. v.type == 10
  712. and v.value.f == '' .. mock_file_path .. '-'
  713. and v.value.n == ('a'):byte()
  714. then
  715. eq(true, v.value.l == 1 or v.value.l == nil)
  716. found = found + 1
  717. end
  718. end
  719. eq(1, found)
  720. end)
  721. it('uses last a mark with eq timestamp from instance when writing', function()
  722. nvim_command('edit ' .. mock_file_path .. '-')
  723. fn.setline(1, { '-', '?' })
  724. wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
  725. eq(0, exc_exec(sdrcmd()))
  726. wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
  727. nvim_command('normal! `a')
  728. eq('-', fn.getline('.'))
  729. eq(0, exc_exec('wshada ' .. shada_fname))
  730. local found = 0
  731. for _, v in ipairs(read_shada_file(shada_fname)) do
  732. if
  733. v.type == 10
  734. and v.value.f == '' .. mock_file_path .. '-'
  735. and v.value.n == ('a'):byte()
  736. then
  737. eq(true, v.value.l == 1 or v.value.l == nil)
  738. found = found + 1
  739. end
  740. end
  741. eq(1, found)
  742. end)
  743. it('uses last a mark with gt timestamp from file when writing', function()
  744. nvim_command('edit ' .. mock_file_path .. '-')
  745. fn.setline(1, { '-', '?' })
  746. wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
  747. eq(0, exc_exec(sdrcmd()))
  748. wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
  749. nvim_command('normal! `a')
  750. eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
  751. eq(0, exc_exec('wshada ' .. shada_fname))
  752. local found = 0
  753. for _, v in ipairs(read_shada_file(shada_fname)) do
  754. if
  755. v.type == 10
  756. and v.value.f == '' .. mock_file_path .. '-'
  757. and v.value.n == ('a'):byte()
  758. then
  759. eq(2, v.value.l)
  760. found = found + 1
  761. end
  762. end
  763. eq(1, found)
  764. end)
  765. end)
  766. describe('ShaDa registers support code', function()
  767. before_each(reset)
  768. after_each(function()
  769. clear()
  770. os.remove(shada_fname)
  771. end)
  772. it('uses last a register with gt timestamp from instance when reading', function()
  773. wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-')
  774. eq(0, exc_exec(sdrcmd()))
  775. wshada('\005\000\015\131\161na\162rX\194\162rc\145\196\001?')
  776. eq(0, exc_exec(sdrcmd()))
  777. eq('-', fn.getreg('a'))
  778. end)
  779. it('uses last a register with gt timestamp from file when reading with !', function()
  780. wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-')
  781. eq(0, exc_exec(sdrcmd()))
  782. wshada('\005\000\015\131\161na\162rX\194\162rc\145\196\001?')
  783. eq(0, exc_exec(sdrcmd(true)))
  784. eq('?', fn.getreg('a'))
  785. end)
  786. it('uses last a register with eq timestamp from instance when reading', function()
  787. wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-')
  788. eq(0, exc_exec(sdrcmd()))
  789. wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001?')
  790. eq(0, exc_exec(sdrcmd()))
  791. eq('-', fn.getreg('a'))
  792. end)
  793. it('uses last a register with gt timestamp from file when reading', function()
  794. wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-')
  795. eq(0, exc_exec(sdrcmd()))
  796. wshada('\005\002\015\131\161na\162rX\194\162rc\145\196\001?')
  797. eq(0, exc_exec(sdrcmd()))
  798. eq('?', fn.getreg('a'))
  799. end)
  800. it('uses last a register with gt timestamp from instance when writing', function()
  801. wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-')
  802. eq(0, exc_exec(sdrcmd()))
  803. wshada('\005\000\015\131\161na\162rX\194\162rc\145\196\001?')
  804. eq('-', fn.getreg('a'))
  805. eq(0, exc_exec('wshada ' .. shada_fname))
  806. local found = 0
  807. for _, v in ipairs(read_shada_file(shada_fname)) do
  808. if v.type == 5 and v.value.n == ('a'):byte() then
  809. eq({ '-' }, v.value.rc)
  810. found = found + 1
  811. end
  812. end
  813. eq(1, found)
  814. end)
  815. it('uses last a register with eq timestamp from instance when writing', function()
  816. wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-')
  817. eq(0, exc_exec(sdrcmd()))
  818. wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001?')
  819. eq('-', fn.getreg('a'))
  820. eq(0, exc_exec('wshada ' .. shada_fname))
  821. local found = 0
  822. for _, v in ipairs(read_shada_file(shada_fname)) do
  823. if v.type == 5 and v.value.n == ('a'):byte() then
  824. eq({ '-' }, v.value.rc)
  825. found = found + 1
  826. end
  827. end
  828. eq(1, found)
  829. end)
  830. it('uses last a register with gt timestamp from file when writing', function()
  831. wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-')
  832. eq(0, exc_exec(sdrcmd()))
  833. wshada('\005\002\015\131\161na\162rX\194\162rc\145\196\001?')
  834. eq('-', fn.getreg('a'))
  835. eq(0, exc_exec('wshada ' .. shada_fname))
  836. local found = 0
  837. for _, v in ipairs(read_shada_file(shada_fname)) do
  838. if v.type == 5 and v.value.n == ('a'):byte() then
  839. eq({ '?' }, v.value.rc)
  840. found = found + 1
  841. end
  842. end
  843. eq(1, found)
  844. end)
  845. end)
  846. describe('ShaDa jumps support code', function()
  847. before_each(reset)
  848. after_each(function()
  849. clear()
  850. os.remove(shada_fname)
  851. end)
  852. it('merges jumps when reading', function()
  853. wshada(
  854. '\008\001\018\131\162mX\195\161f\196\006'
  855. .. mock_file_path
  856. .. 'c\161l\002'
  857. .. '\008\004\018\131\162mX\195\161f\196\006'
  858. .. mock_file_path
  859. .. 'd\161l\002'
  860. .. '\008\007\018\131\162mX\195\161f\196\006'
  861. .. mock_file_path
  862. .. 'e\161l\002'
  863. )
  864. eq(0, exc_exec(sdrcmd()))
  865. wshada(
  866. '\008\001\018\131\162mX\195\161f\196\006'
  867. .. mock_file_path
  868. .. 'c\161l\002'
  869. .. '\008\004\018\131\162mX\195\161f\196\006'
  870. .. mock_file_path
  871. .. 'd\161l\003'
  872. .. '\008\007\018\131\162mX\195\161f\196\006'
  873. .. mock_file_path
  874. .. 'f\161l\002'
  875. )
  876. eq(0, exc_exec(sdrcmd()))
  877. eq('', api.nvim_buf_get_name(0))
  878. eq(
  879. ' jump line col file/text\n'
  880. .. ' 5 2 0 '
  881. .. mock_file_path
  882. .. 'c\n'
  883. .. ' 4 2 0 '
  884. .. mock_file_path
  885. .. 'd\n'
  886. .. ' 3 3 0 '
  887. .. mock_file_path
  888. .. 'd\n'
  889. .. ' 2 2 0 '
  890. .. mock_file_path
  891. .. 'e\n'
  892. .. ' 1 2 0 '
  893. .. mock_file_path
  894. .. 'f\n'
  895. .. '>',
  896. exec_capture('jumps')
  897. )
  898. end)
  899. it('merges jumps when writing', function()
  900. wshada(
  901. '\008\001\018\131\162mX\195\161f\196\006'
  902. .. mock_file_path
  903. .. 'c\161l\002'
  904. .. '\008\004\018\131\162mX\195\161f\196\006'
  905. .. mock_file_path
  906. .. 'd\161l\002'
  907. .. '\008\007\018\131\162mX\195\161f\196\006'
  908. .. mock_file_path
  909. .. 'e\161l\002'
  910. )
  911. eq(0, exc_exec(sdrcmd()))
  912. wshada(
  913. '\008\001\018\131\162mX\195\161f\196\006'
  914. .. mock_file_path
  915. .. 'c\161l\002'
  916. .. '\008\004\018\131\162mX\195\161f\196\006'
  917. .. mock_file_path
  918. .. 'd\161l\003'
  919. .. '\008\007\018\131\162mX\195\161f\196\006'
  920. .. mock_file_path
  921. .. 'f\161l\002'
  922. )
  923. eq(0, exc_exec('wshada ' .. shada_fname))
  924. local jumps = {
  925. { file = '' .. mock_file_path .. 'c', line = 2 },
  926. { file = '' .. mock_file_path .. 'd', line = 2 },
  927. { file = '' .. mock_file_path .. 'd', line = 3 },
  928. { file = '' .. mock_file_path .. 'e', line = 2 },
  929. { file = '' .. mock_file_path .. 'f', line = 2 },
  930. }
  931. local found = 0
  932. for _, v in ipairs(read_shada_file(shada_fname)) do
  933. if v.type == 8 then
  934. found = found + 1
  935. eq(jumps[found].file, v.value.f)
  936. eq(jumps[found].line, v.value.l)
  937. end
  938. end
  939. eq(#jumps, found)
  940. end)
  941. it('merges JUMPLISTSIZE jumps when writing', function()
  942. local jumps = {}
  943. local shada = ''
  944. for i = 1, 100 do
  945. shada = shada
  946. .. ('\008%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c'):format(i, i)
  947. jumps[i] = { file = '' .. mock_file_path .. 'c', line = i }
  948. end
  949. wshada(shada)
  950. eq(0, exc_exec(sdrcmd()))
  951. shada = ''
  952. for i = 1, 101 do
  953. local _t = i * 2
  954. shada = shada
  955. .. ('\008\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c'):format(
  956. _t,
  957. _t
  958. )
  959. jumps[(_t > #jumps + 1) and (#jumps + 1) or _t] =
  960. { file = '' .. mock_file_path .. 'c', line = _t }
  961. end
  962. wshada(shada)
  963. eq(0, exc_exec('wshada ' .. shada_fname))
  964. local shift = #jumps - 100
  965. for i = 1, 100 do
  966. jumps[i] = jumps[i + shift]
  967. end
  968. local found = 0
  969. for _, v in ipairs(read_shada_file(shada_fname)) do
  970. if v.type == 8 then
  971. found = found + 1
  972. eq(jumps[found].file, v.value.f)
  973. eq(jumps[found].line, v.value.l)
  974. end
  975. end
  976. eq(100, found)
  977. end)
  978. end)
  979. describe('ShaDa changes support code', function()
  980. before_each(reset)
  981. after_each(function()
  982. clear()
  983. os.remove(shada_fname)
  984. end)
  985. it('merges changes when reading', function()
  986. nvim_command('edit ' .. mock_file_path .. 'c')
  987. nvim_command('keepjumps call setline(1, range(7))')
  988. wshada(
  989. '\011\001\018\131\162mX\195\161f\196\006'
  990. .. mock_file_path
  991. .. 'c\161l\001'
  992. .. '\011\004\018\131\162mX\195\161f\196\006'
  993. .. mock_file_path
  994. .. 'c\161l\002'
  995. .. '\011\007\018\131\162mX\195\161f\196\006'
  996. .. mock_file_path
  997. .. 'c\161l\003'
  998. )
  999. eq(0, exc_exec(sdrcmd()))
  1000. wshada(
  1001. '\011\001\018\131\162mX\194\161f\196\006'
  1002. .. mock_file_path
  1003. .. 'c\161l\001'
  1004. .. '\011\004\018\131\162mX\195\161f\196\006'
  1005. .. mock_file_path
  1006. .. 'c\161l\005'
  1007. .. '\011\008\018\131\162mX\195\161f\196\006'
  1008. .. mock_file_path
  1009. .. 'c\161l\004'
  1010. )
  1011. eq(0, exc_exec(sdrcmd()))
  1012. eq(
  1013. 'change line col text\n'
  1014. .. ' 5 1 0 0\n'
  1015. .. ' 4 2 0 1\n'
  1016. .. ' 3 5 0 4\n'
  1017. .. ' 2 3 0 2\n'
  1018. .. ' 1 4 0 3\n'
  1019. .. '>',
  1020. exec_capture('changes')
  1021. )
  1022. end)
  1023. it('merges changes when writing', function()
  1024. nvim_command('edit ' .. mock_file_path .. 'c')
  1025. nvim_command('keepjumps call setline(1, range(7))')
  1026. wshada(
  1027. '\011\001\018\131\162mX\195\161f\196\006'
  1028. .. mock_file_path
  1029. .. 'c\161l\001'
  1030. .. '\011\004\018\131\162mX\195\161f\196\006'
  1031. .. mock_file_path
  1032. .. 'c\161l\002'
  1033. .. '\011\007\018\131\162mX\195\161f\196\006'
  1034. .. mock_file_path
  1035. .. 'c\161l\003'
  1036. )
  1037. eq(0, exc_exec(sdrcmd()))
  1038. wshada(
  1039. '\011\001\018\131\162mX\194\161f\196\006'
  1040. .. mock_file_path
  1041. .. 'c\161l\001'
  1042. .. '\011\004\018\131\162mX\195\161f\196\006'
  1043. .. mock_file_path
  1044. .. 'c\161l\005'
  1045. .. '\011\008\018\131\162mX\195\161f\196\006'
  1046. .. mock_file_path
  1047. .. 'c\161l\004'
  1048. )
  1049. eq(0, exc_exec('wshada ' .. shada_fname))
  1050. local changes = {
  1051. { line = 1 },
  1052. { line = 2 },
  1053. { line = 5 },
  1054. { line = 3 },
  1055. { line = 4 },
  1056. }
  1057. local found = 0
  1058. for _, v in ipairs(read_shada_file(shada_fname)) do
  1059. if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then
  1060. found = found + 1
  1061. eq(changes[found].line, v.value.l or 1)
  1062. end
  1063. end
  1064. eq(#changes, found)
  1065. end)
  1066. it('merges JUMPLISTSIZE changes when writing', function()
  1067. nvim_command('edit ' .. mock_file_path .. 'c')
  1068. nvim_command('keepjumps call setline(1, range(202))')
  1069. local changes = {}
  1070. local shada = ''
  1071. for i = 1, 100 do
  1072. shada = shada
  1073. .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c'):format(i, i)
  1074. changes[i] = { line = i }
  1075. end
  1076. wshada(shada)
  1077. eq(0, exc_exec(sdrcmd()))
  1078. shada = ''
  1079. for i = 1, 101 do
  1080. local _t = i * 2
  1081. shada = shada
  1082. .. ('\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c'):format(
  1083. _t,
  1084. _t
  1085. )
  1086. changes[(_t > #changes + 1) and (#changes + 1) or _t] = { line = _t }
  1087. end
  1088. wshada(shada)
  1089. eq(0, exc_exec('wshada ' .. shada_fname))
  1090. local shift = #changes - 100
  1091. for i = 1, 100 do
  1092. changes[i] = changes[i + shift]
  1093. end
  1094. local found = 0
  1095. for _, v in ipairs(read_shada_file(shada_fname)) do
  1096. if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then
  1097. found = found + 1
  1098. eq(changes[found].line, v.value.l)
  1099. end
  1100. end
  1101. eq(100, found)
  1102. end)
  1103. it('merges JUMPLISTSIZE changes when writing, with new items between old', function()
  1104. nvim_command('edit ' .. mock_file_path .. 'c')
  1105. nvim_command('keepjumps call setline(1, range(202))')
  1106. local shada = ''
  1107. for i = 1, 101 do
  1108. local _t = i * 2
  1109. shada = shada
  1110. .. ('\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c'):format(
  1111. _t,
  1112. _t
  1113. )
  1114. end
  1115. wshada(shada)
  1116. eq(0, exc_exec(sdrcmd()))
  1117. shada = ''
  1118. for i = 1, 100 do
  1119. shada = shada
  1120. .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c'):format(i, i)
  1121. end
  1122. local changes = {}
  1123. for i = 1, 100 do
  1124. changes[i] = { line = i }
  1125. end
  1126. for i = 1, 101 do
  1127. local _t = i * 2
  1128. changes[(_t > #changes + 1) and (#changes + 1) or _t] = { line = _t }
  1129. end
  1130. wshada(shada)
  1131. eq(0, exc_exec('wshada ' .. shada_fname))
  1132. local shift = #changes - 100
  1133. for i = 1, 100 do
  1134. changes[i] = changes[i + shift]
  1135. end
  1136. local found = 0
  1137. for _, v in ipairs(read_shada_file(shada_fname)) do
  1138. if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then
  1139. found = found + 1
  1140. eq(changes[found].line, v.value.l)
  1141. end
  1142. end
  1143. eq(100, found)
  1144. end)
  1145. end)