completion_spec.lua 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local Screen = require('test.functional.ui.screen')
  4. local assert_alive = n.assert_alive
  5. local clear, feed = n.clear, n.feed
  6. local eval, eq, neq, ok = n.eval, t.eq, t.neq, t.ok
  7. local feed_command, source, expect = n.feed_command, n.source, n.expect
  8. local fn = n.fn
  9. local command = n.command
  10. local api = n.api
  11. local poke_eventloop = n.poke_eventloop
  12. local exec_lua = n.exec_lua
  13. describe('completion', function()
  14. local screen
  15. before_each(function()
  16. clear()
  17. screen = Screen.new(60, 8)
  18. screen:add_extra_attr_ids {
  19. [100] = { foreground = Screen.colors.Gray0, background = Screen.colors.Yellow },
  20. [101] = { background = Screen.colors.Gray0 },
  21. }
  22. end)
  23. describe('v:completed_item', function()
  24. it('is empty dict until completion', function()
  25. eq({}, eval('v:completed_item'))
  26. end)
  27. it('is empty dict if the candidate is not inserted', function()
  28. feed('ifoo<ESC>o<C-x><C-n>')
  29. screen:expect([[
  30. foo |
  31. foo^ |
  32. {1:~ }|*5
  33. {5:-- Keyword Local completion (^N^P) The only match} |
  34. ]])
  35. feed('<C-e>')
  36. screen:expect([[
  37. foo |
  38. ^ |
  39. {1:~ }|*5
  40. {5:-- INSERT --} |
  41. ]])
  42. feed('<ESC>')
  43. eq({}, eval('v:completed_item'))
  44. end)
  45. it('returns expected dict in normal completion', function()
  46. feed('ifoo<ESC>o<C-x><C-n>')
  47. eq('foo', eval('getline(2)'))
  48. eq(
  49. { word = 'foo', abbr = '', menu = '', info = '', kind = '', user_data = '' },
  50. eval('v:completed_item')
  51. )
  52. end)
  53. it('is readonly', function()
  54. screen:try_resize(80, 8)
  55. feed('ifoo<ESC>o<C-x><C-n><ESC>')
  56. feed_command('let v:completed_item.word = "bar"')
  57. neq(nil, string.find(eval('v:errmsg'), '^E46: '))
  58. feed_command('let v:errmsg = ""')
  59. feed_command('let v:completed_item.abbr = "bar"')
  60. neq(nil, string.find(eval('v:errmsg'), '^E46: '))
  61. feed_command('let v:errmsg = ""')
  62. feed_command('let v:completed_item.menu = "bar"')
  63. neq(nil, string.find(eval('v:errmsg'), '^E46: '))
  64. feed_command('let v:errmsg = ""')
  65. feed_command('let v:completed_item.info = "bar"')
  66. neq(nil, string.find(eval('v:errmsg'), '^E46: '))
  67. feed_command('let v:errmsg = ""')
  68. feed_command('let v:completed_item.kind = "bar"')
  69. neq(nil, string.find(eval('v:errmsg'), '^E46: '))
  70. feed_command('let v:errmsg = ""')
  71. feed_command('let v:completed_item.user_data = "bar"')
  72. neq(nil, string.find(eval('v:errmsg'), '^E46: '))
  73. feed_command('let v:errmsg = ""')
  74. end)
  75. it('returns expected dict in omni completion', function()
  76. source([[
  77. function! TestOmni(findstart, base) abort
  78. return a:findstart ? 0 : [{'word': 'foo', 'abbr': 'bar',
  79. \ 'menu': 'baz', 'info': 'foobar', 'kind': 'foobaz'},
  80. \ {'word': 'word', 'abbr': 'abbr', 'menu': 'menu',
  81. \ 'info': 'info', 'kind': 'kind'}]
  82. endfunction
  83. setlocal omnifunc=TestOmni
  84. ]])
  85. feed('i<C-x><C-o>')
  86. eq('foo', eval('getline(1)'))
  87. screen:expect([[
  88. foo^ |
  89. {12:bar foobaz baz }{1: }|
  90. {4:abbr kind menu }{1: }|
  91. {1:~ }|*4
  92. {5:-- Omni completion (^O^N^P) }{6:match 1 of 2} |
  93. ]])
  94. eq({
  95. word = 'foo',
  96. abbr = 'bar',
  97. menu = 'baz',
  98. info = 'foobar',
  99. kind = 'foobaz',
  100. user_data = '',
  101. }, eval('v:completed_item'))
  102. end)
  103. end)
  104. describe('completeopt', function()
  105. before_each(function()
  106. source([[
  107. function! TestComplete() abort
  108. call complete(1, ['foo'])
  109. return ''
  110. endfunction
  111. ]])
  112. end)
  113. it('inserts the first candidate if default', function()
  114. feed_command('set completeopt+=menuone')
  115. feed('ifoo<ESC>o')
  116. screen:expect([[
  117. foo |
  118. ^ |
  119. {1:~ }|*5
  120. {5:-- INSERT --} |
  121. ]])
  122. feed('<C-x>')
  123. -- the ^X prompt, only test this once
  124. screen:expect([[
  125. foo |
  126. ^ |
  127. {1:~ }|*5
  128. {5:-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)} |
  129. ]])
  130. feed('<C-n>')
  131. screen:expect([[
  132. foo |
  133. foo^ |
  134. {12:foo }{1: }|
  135. {1:~ }|*4
  136. {5:-- Keyword Local completion (^N^P) The only match} |
  137. ]])
  138. feed('bar<ESC>')
  139. eq('foobar', eval('getline(2)'))
  140. feed('o<C-r>=TestComplete()<CR>')
  141. screen:expect([[
  142. foo |
  143. foobar |
  144. foo^ |
  145. {12:foo }{1: }|
  146. {1:~ }|*3
  147. {5:-- INSERT --} |
  148. ]])
  149. eq('foo', eval('getline(3)'))
  150. end)
  151. it('selects the first candidate if noinsert', function()
  152. feed_command('set completeopt+=menuone,noinsert')
  153. feed('ifoo<ESC>o<C-x><C-n>')
  154. screen:expect([[
  155. foo |
  156. ^ |
  157. {12:foo }{1: }|
  158. {1:~ }|*4
  159. {5:-- Keyword Local completion (^N^P) The only match} |
  160. ]])
  161. feed('<C-y>')
  162. screen:expect([[
  163. foo |
  164. foo^ |
  165. {1:~ }|*5
  166. {5:-- INSERT --} |
  167. ]])
  168. feed('<ESC>')
  169. eq('foo', eval('getline(2)'))
  170. feed('o<C-r>=TestComplete()<CR>')
  171. screen:expect([[
  172. foo |*2
  173. ^ |
  174. {12:foo }{1: }|
  175. {1:~ }|*3
  176. {5:-- INSERT --} |
  177. ]])
  178. feed('<C-y><ESC>')
  179. eq('foo', eval('getline(3)'))
  180. end)
  181. it('does not insert the first candidate if noselect', function()
  182. feed_command('set completeopt+=menuone,noselect')
  183. feed('ifoo<ESC>o<C-x><C-n>')
  184. screen:expect([[
  185. foo |
  186. ^ |
  187. {4:foo }{1: }|
  188. {1:~ }|*4
  189. {5:-- Keyword Local completion (^N^P) }{19:Back at original} |
  190. ]])
  191. feed('b')
  192. screen:expect([[
  193. foo |
  194. b^ |
  195. {1:~ }|*5
  196. {5:-- Keyword Local completion (^N^P) }{19:Back at original} |
  197. ]])
  198. feed('ar<ESC>')
  199. eq('bar', eval('getline(2)'))
  200. feed('o<C-r>=TestComplete()<CR>')
  201. screen:expect([[
  202. foo |
  203. bar |
  204. ^ |
  205. {4:foo }{1: }|
  206. {1:~ }|*3
  207. {5:-- INSERT --} |
  208. ]])
  209. feed('bar<ESC>')
  210. eq('bar', eval('getline(3)'))
  211. end)
  212. it('does not select/insert the first candidate if noselect and noinsert', function()
  213. feed_command('set completeopt+=menuone,noselect,noinsert')
  214. feed('ifoo<ESC>o<C-x><C-n>')
  215. screen:expect([[
  216. foo |
  217. ^ |
  218. {4:foo }{1: }|
  219. {1:~ }|*4
  220. {5:-- Keyword Local completion (^N^P) }{19:Back at original} |
  221. ]])
  222. feed('<ESC>')
  223. screen:expect([[
  224. foo |
  225. ^ |
  226. {1:~ }|*5
  227. |
  228. ]])
  229. eq('', eval('getline(2)'))
  230. feed('o<C-r>=TestComplete()<CR>')
  231. screen:expect([[
  232. foo |
  233. |
  234. ^ |
  235. {4:foo }{1: }|
  236. {1:~ }|*3
  237. {5:-- INSERT --} |
  238. ]])
  239. feed('<ESC>')
  240. screen:expect([[
  241. foo |
  242. |
  243. ^ |
  244. {1:~ }|*4
  245. |
  246. ]])
  247. eq('', eval('getline(3)'))
  248. end)
  249. it('does not change modified state if noinsert', function()
  250. feed_command('set completeopt+=menuone,noinsert')
  251. feed_command('setlocal nomodified')
  252. feed('i<C-r>=TestComplete()<CR><ESC>')
  253. eq(0, eval('&l:modified'))
  254. end)
  255. it('does not change modified state if noselect', function()
  256. feed_command('set completeopt+=menuone,noselect')
  257. feed_command('setlocal nomodified')
  258. feed('i<C-r>=TestComplete()<CR><ESC>')
  259. eq(0, eval('&l:modified'))
  260. end)
  261. end)
  262. describe('completeopt+=noinsert does not add blank undo items', function()
  263. before_each(function()
  264. source([[
  265. function! TestComplete() abort
  266. call complete(1, ['foo', 'bar'])
  267. return ''
  268. endfunction
  269. ]])
  270. feed_command('set completeopt+=noselect,noinsert')
  271. feed_command('inoremap <right> <c-r>=TestComplete()<cr>')
  272. end)
  273. local tests = {
  274. ['<up>, <down>, <cr>'] = { '<down><cr>', '<up><cr>' },
  275. ['<c-n>, <c-p>, <c-y>'] = { '<c-n><c-y>', '<c-p><c-y>' },
  276. }
  277. for name, seq in pairs(tests) do
  278. it('using ' .. name, function()
  279. feed('iaaa<esc>')
  280. feed('A<right>' .. seq[1] .. '<esc>')
  281. feed('A<right><esc>A<right><esc>')
  282. feed('A<cr>bbb<esc>')
  283. feed('A<right>' .. seq[2] .. '<esc>')
  284. feed('A<right><esc>A<right><esc>')
  285. feed('A<cr>ccc<esc>')
  286. feed('A<right>' .. seq[1] .. '<esc>')
  287. feed('A<right><esc>A<right><esc>')
  288. local expected = {
  289. { 'foo', 'bar', 'foo' },
  290. { 'foo', 'bar', 'ccc' },
  291. { 'foo', 'bar' },
  292. { 'foo', 'bbb' },
  293. { 'foo' },
  294. { 'aaa' },
  295. { '' },
  296. }
  297. for i = 1, #expected do
  298. if i > 1 then
  299. feed('u')
  300. end
  301. eq(expected[i], eval('getline(1, "$")'))
  302. end
  303. for i = #expected, 1, -1 do
  304. if i < #expected then
  305. feed('<c-r>')
  306. end
  307. eq(expected[i], eval('getline(1, "$")'))
  308. end
  309. end)
  310. end
  311. end)
  312. describe('with refresh:always and noselect', function()
  313. before_each(function()
  314. source([[
  315. function! TestCompletion(findstart, base) abort
  316. if a:findstart
  317. let line = getline('.')
  318. let start = col('.') - 1
  319. while start > 0 && line[start - 1] =~ '\a'
  320. let start -= 1
  321. endwhile
  322. return start
  323. else
  324. let ret = []
  325. for m in split("January February March April May June July August September October November December")
  326. if m =~ a:base " match by regex
  327. call add(ret, m)
  328. endif
  329. endfor
  330. return {'words':ret, 'refresh':'always'}
  331. endif
  332. endfunction
  333. set completeopt=menuone,noselect
  334. set completefunc=TestCompletion
  335. ]])
  336. end)
  337. it('completes on each input char', function()
  338. feed('i<C-x><C-u>')
  339. screen:expect([[
  340. ^ |
  341. {4:January }{101: }{1: }|
  342. {4:February }{101: }{1: }|
  343. {4:March }{101: }{1: }|
  344. {4:April }{12: }{1: }|
  345. {4:May }{12: }{1: }|
  346. {4:June }{12: }{1: }|
  347. {5:-- User defined completion (^U^N^P) }{19:Back at original} |
  348. ]])
  349. feed('u')
  350. screen:expect([[
  351. u^ |
  352. {4:January }{1: }|
  353. {4:February }{1: }|
  354. {4:June }{1: }|
  355. {4:July }{1: }|
  356. {4:August }{1: }|
  357. {1:~ }|
  358. {5:-- User defined completion (^U^N^P) }{19:Back at original} |
  359. ]])
  360. feed('g')
  361. screen:expect([[
  362. ug^ |
  363. {4:August }{1: }|
  364. {1:~ }|*5
  365. {5:-- User defined completion (^U^N^P) }{19:Back at original} |
  366. ]])
  367. feed('<Down>')
  368. screen:expect([[
  369. ug^ |
  370. {12:August }{1: }|
  371. {1:~ }|*5
  372. {5:-- User defined completion (^U^N^P) The only match} |
  373. ]])
  374. feed('<C-y>')
  375. screen:expect([[
  376. August^ |
  377. {1:~ }|*6
  378. {5:-- INSERT --} |
  379. ]])
  380. expect('August')
  381. end)
  382. it('repeats correctly after backspace #2674', function()
  383. feed('o<C-x><C-u>Ja')
  384. screen:expect([[
  385. |
  386. Ja^ |
  387. {4:January }{1: }|
  388. {1:~ }|*4
  389. {5:-- User defined completion (^U^N^P) }{19:Back at original} |
  390. ]])
  391. feed('<BS>')
  392. screen:expect([[
  393. |
  394. J^ |
  395. {4:January }{1: }|
  396. {4:June }{1: }|
  397. {4:July }{1: }|
  398. {1:~ }|*2
  399. {5:-- User defined completion (^U^N^P) }{19:Back at original} |
  400. ]])
  401. feed('<C-n>')
  402. screen:expect([[
  403. |
  404. January^ |
  405. {12:January }{1: }|
  406. {4:June }{1: }|
  407. {4:July }{1: }|
  408. {1:~ }|*2
  409. {5:-- User defined completion (^U^N^P) }{6:match 1 of 3} |
  410. ]])
  411. feed('<C-n>')
  412. screen:expect([[
  413. |
  414. June^ |
  415. {4:January }{1: }|
  416. {12:June }{1: }|
  417. {4:July }{1: }|
  418. {1:~ }|*2
  419. {5:-- User defined completion (^U^N^P) }{6:match 2 of 3} |
  420. ]])
  421. feed('<Esc>')
  422. screen:expect([[
  423. |
  424. Jun^e |
  425. {1:~ }|*5
  426. |
  427. ]])
  428. feed('.')
  429. screen:expect([[
  430. |
  431. June |
  432. Jun^e |
  433. {1:~ }|*4
  434. |
  435. ]])
  436. expect([[
  437. June
  438. June]])
  439. end)
  440. it('Enter does not select original text', function()
  441. feed('iJ<C-x><C-u>')
  442. poke_eventloop()
  443. feed('u')
  444. poke_eventloop()
  445. feed('<CR>')
  446. expect([[
  447. Ju
  448. ]])
  449. feed('J<C-x><C-u>')
  450. poke_eventloop()
  451. feed('<CR>')
  452. expect([[
  453. Ju
  454. J
  455. ]])
  456. end)
  457. end)
  458. describe('with noselect but not refresh:always', function()
  459. before_each(function()
  460. source([[
  461. function! TestCompletion(findstart, base) abort
  462. if a:findstart
  463. let line = getline('.')
  464. let start = col('.') - 1
  465. while start > 0 && line[start - 1] =~ '\a'
  466. let start -= 1
  467. endwhile
  468. return start
  469. else
  470. let ret = []
  471. for m in split("January February March April May June July August September October November December")
  472. if m =~ a:base " match by regex
  473. call add(ret, m)
  474. endif
  475. endfor
  476. return {'words':ret}
  477. endif
  478. endfunction
  479. set completeopt=menuone,noselect
  480. set completefunc=TestCompletion
  481. ]])
  482. end)
  483. it('Enter selects original text after adding leader', function()
  484. feed('iJ<C-x><C-u>')
  485. poke_eventloop()
  486. feed('u')
  487. poke_eventloop()
  488. feed('<CR>')
  489. expect('Ju')
  490. feed('<Esc>')
  491. poke_eventloop()
  492. -- The behavior should be the same when completion has been interrupted,
  493. -- which can happen interactively if the completion function is slow.
  494. feed('SJ<C-x><C-u>u<CR>')
  495. expect('Ju')
  496. end)
  497. end)
  498. describe('with a lot of items', function()
  499. before_each(function()
  500. source([[
  501. function! TestComplete() abort
  502. call complete(1, map(range(0,100), "string(v:val)"))
  503. return ''
  504. endfunction
  505. ]])
  506. feed_command('set completeopt=menuone,noselect')
  507. end)
  508. it('works', function()
  509. feed('i<C-r>=TestComplete()<CR>')
  510. screen:expect([[
  511. ^ |
  512. {4:0 }{101: }{1: }|
  513. {4:1 }{12: }{1: }|
  514. {4:2 }{12: }{1: }|
  515. {4:3 }{12: }{1: }|
  516. {4:4 }{12: }{1: }|
  517. {4:5 }{12: }{1: }|
  518. {5:-- INSERT --} |
  519. ]])
  520. feed('7')
  521. screen:expect([[
  522. 7^ |
  523. {4:7 }{101: }{1: }|
  524. {4:70 }{101: }{1: }|
  525. {4:71 }{101: }{1: }|
  526. {4:72 }{12: }{1: }|
  527. {4:73 }{12: }{1: }|
  528. {4:74 }{12: }{1: }|
  529. {5:-- INSERT --} |
  530. ]])
  531. feed('<c-n>')
  532. screen:expect([[
  533. 7^ |
  534. {12:7 }{101: }{1: }|
  535. {4:70 }{101: }{1: }|
  536. {4:71 }{101: }{1: }|
  537. {4:72 }{12: }{1: }|
  538. {4:73 }{12: }{1: }|
  539. {4:74 }{12: }{1: }|
  540. {5:-- INSERT --} |
  541. ]])
  542. feed('<c-n>')
  543. screen:expect([[
  544. 70^ |
  545. {4:7 }{101: }{1: }|
  546. {12:70 }{101: }{1: }|
  547. {4:71 }{101: }{1: }|
  548. {4:72 }{12: }{1: }|
  549. {4:73 }{12: }{1: }|
  550. {4:74 }{12: }{1: }|
  551. {5:-- INSERT --} |
  552. ]])
  553. end)
  554. it('can be navigated with <PageDown>, <PageUp>', function()
  555. feed('i<C-r>=TestComplete()<CR>')
  556. screen:expect([[
  557. ^ |
  558. {4:0 }{101: }{1: }|
  559. {4:1 }{12: }{1: }|
  560. {4:2 }{12: }{1: }|
  561. {4:3 }{12: }{1: }|
  562. {4:4 }{12: }{1: }|
  563. {4:5 }{12: }{1: }|
  564. {5:-- INSERT --} |
  565. ]])
  566. feed('<PageDown>')
  567. screen:expect([[
  568. ^ |
  569. {4:0 }{101: }{1: }|
  570. {4:1 }{12: }{1: }|
  571. {4:2 }{12: }{1: }|
  572. {12:3 }{1: }|
  573. {4:4 }{12: }{1: }|
  574. {4:5 }{12: }{1: }|
  575. {5:-- INSERT --} |
  576. ]])
  577. feed('<PageDown>')
  578. screen:expect([[
  579. ^ |
  580. {4:5 }{101: }{1: }|
  581. {4:6 }{12: }{1: }|
  582. {12:7 }{1: }|
  583. {4:8 }{12: }{1: }|
  584. {4:9 }{12: }{1: }|
  585. {4:10 }{12: }{1: }|
  586. {5:-- INSERT --} |
  587. ]])
  588. feed('<Down>')
  589. screen:expect([[
  590. ^ |
  591. {4:5 }{101: }{1: }|
  592. {4:6 }{12: }{1: }|
  593. {4:7 }{12: }{1: }|
  594. {12:8 }{1: }|
  595. {4:9 }{12: }{1: }|
  596. {4:10 }{12: }{1: }|
  597. {5:-- INSERT --} |
  598. ]])
  599. feed('<PageUp>')
  600. screen:expect([[
  601. ^ |
  602. {4:2 }{101: }{1: }|
  603. {4:3 }{12: }{1: }|
  604. {12:4 }{1: }|
  605. {4:5 }{12: }{1: }|
  606. {4:6 }{12: }{1: }|
  607. {4:7 }{12: }{1: }|
  608. {5:-- INSERT --} |
  609. ]])
  610. feed('<PageUp>') -- stop on first item
  611. screen:expect([[
  612. ^ |
  613. {12:0 }{101: }{1: }|
  614. {4:1 }{12: }{1: }|
  615. {4:2 }{12: }{1: }|
  616. {4:3 }{12: }{1: }|
  617. {4:4 }{12: }{1: }|
  618. {4:5 }{12: }{1: }|
  619. {5:-- INSERT --} |
  620. ]])
  621. feed('<PageUp>') -- when on first item, unselect
  622. screen:expect([[
  623. ^ |
  624. {4:0 }{101: }{1: }|
  625. {4:1 }{12: }{1: }|
  626. {4:2 }{12: }{1: }|
  627. {4:3 }{12: }{1: }|
  628. {4:4 }{12: }{1: }|
  629. {4:5 }{12: }{1: }|
  630. {5:-- INSERT --} |
  631. ]])
  632. feed('<PageUp>') -- when unselected, select last item
  633. screen:expect([[
  634. ^ |
  635. {4:95 }{12: }{1: }|
  636. {4:96 }{12: }{1: }|
  637. {4:97 }{12: }{1: }|
  638. {4:98 }{12: }{1: }|
  639. {4:99 }{12: }{1: }|
  640. {12:100 }{101: }{1: }|
  641. {5:-- INSERT --} |
  642. ]])
  643. feed('<PageUp>')
  644. screen:expect([[
  645. ^ |
  646. {4:94 }{12: }{1: }|
  647. {4:95 }{12: }{1: }|
  648. {12:96 }{1: }|
  649. {4:97 }{12: }{1: }|
  650. {4:98 }{12: }{1: }|
  651. {4:99 }{101: }{1: }|
  652. {5:-- INSERT --} |
  653. ]])
  654. feed('<cr>')
  655. screen:expect([[
  656. 96^ |
  657. {1:~ }|*6
  658. {5:-- INSERT --} |
  659. ]])
  660. end)
  661. end)
  662. it('does not indent until an item is selected #8345', function()
  663. -- Indents on "ind", unindents on "unind".
  664. source([[
  665. function! TestIndent()
  666. let line = getline(v:lnum)
  667. if (line =~ '^\s*ind')
  668. return indent(v:lnum-1) + shiftwidth()
  669. elseif (line =~ '^\s*unind')
  670. return indent(v:lnum-1) - shiftwidth()
  671. else
  672. return indent(v:lnum-1)
  673. endif
  674. endfunction
  675. set indentexpr=TestIndent()
  676. set indentkeys=o,O,!^F,=ind,=unind
  677. set completeopt+=menuone
  678. ]])
  679. -- Give some words to complete.
  680. feed('iinc uninc indent unindent<CR>')
  681. -- Does not indent when "ind" is typed.
  682. feed('in<C-X><C-N>')
  683. -- Completion list is generated incorrectly if we send everything at once
  684. -- via nvim_input(). So poke_eventloop() before sending <BS>. #8480
  685. poke_eventloop()
  686. feed('<BS>d')
  687. screen:expect([[
  688. inc uninc indent unindent |
  689. ind^ |
  690. {12:indent }{1: }|
  691. {1:~ }|*4
  692. {5:-- Keyword Local completion (^N^P) }{6:match 1 of 2} |
  693. ]])
  694. -- Indents when the item is selected
  695. feed('<C-Y>')
  696. screen:expect([[
  697. inc uninc indent unindent |
  698. indent^ |
  699. {1:~ }|*5
  700. {5:-- INSERT --} |
  701. ]])
  702. -- Indents when completion is exited using ESC.
  703. feed('<CR>in<C-N><BS>d<Esc>')
  704. screen:expect([[
  705. inc uninc indent unindent |
  706. indent |
  707. in^d |
  708. {1:~ }|*4
  709. |
  710. ]])
  711. -- Works for unindenting too.
  712. feed('ounin<C-X><C-N>')
  713. poke_eventloop()
  714. feed('<BS>d')
  715. screen:expect([[
  716. inc uninc indent unindent |
  717. indent |
  718. ind |
  719. unind^ |
  720. {1:~ }{12: unindent }{1: }|
  721. {1:~ }|*2
  722. {5:-- Keyword Local completion (^N^P) }{6:match 1 of 2} |
  723. ]])
  724. -- Works when going back and forth.
  725. feed('<BS>c')
  726. screen:expect([[
  727. inc uninc indent unindent |
  728. indent |
  729. ind |
  730. uninc^ |
  731. {1:~ }{12: uninc }{1: }|
  732. {1:~ }|*2
  733. {5:-- Keyword Local completion (^N^P) }{6:match 1 of 2} |
  734. ]])
  735. feed('<BS>d')
  736. screen:expect([[
  737. inc uninc indent unindent |
  738. indent |
  739. ind |
  740. unind^ |
  741. {1:~ }{12: unindent }{1: }|
  742. {1:~ }|*2
  743. {5:-- Keyword Local completion (^N^P) }{6:match 1 of 2} |
  744. ]])
  745. feed('<C-N><C-N><C-Y><Esc>')
  746. screen:expect([[
  747. inc uninc indent unindent |
  748. indent |
  749. ind |
  750. uninden^t |
  751. {1:~ }|*3
  752. |
  753. ]])
  754. end)
  755. it('disables folding during completion', function()
  756. feed_command('set foldmethod=indent')
  757. feed('i<Tab>foo<CR><Tab>bar<Esc>gg')
  758. screen:expect([[
  759. ^foo |
  760. bar |
  761. {1:~ }|*5
  762. |
  763. ]])
  764. feed('A<C-x><C-l>')
  765. screen:expect([[
  766. foo^ |
  767. bar |
  768. {1:~ }|*5
  769. {5:-- Whole line completion (^L^N^P) }{9:Pattern not found} |
  770. ]])
  771. eq(-1, eval('foldclosed(1)'))
  772. end)
  773. it('popupmenu is not interrupted by events', function()
  774. feed_command('set complete=.')
  775. feed('ifoobar fooegg<cr>f<c-p>')
  776. screen:expect([[
  777. foobar fooegg |
  778. fooegg^ |
  779. {4:foobar }{1: }|
  780. {12:fooegg }{1: }|
  781. {1:~ }|*3
  782. {5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
  783. ]])
  784. assert_alive()
  785. -- popupmenu still visible
  786. screen:expect {
  787. grid = [[
  788. foobar fooegg |
  789. fooegg^ |
  790. {4:foobar }{1: }|
  791. {12:fooegg }{1: }|
  792. {1:~ }|*3
  793. {5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
  794. ]],
  795. unchanged = true,
  796. }
  797. feed('<c-p>')
  798. -- Didn't restart completion: old matches still used
  799. screen:expect([[
  800. foobar fooegg |
  801. foobar^ |
  802. {12:foobar }{1: }|
  803. {4:fooegg }{1: }|
  804. {1:~ }|*3
  805. {5:-- Keyword completion (^N^P) }{6:match 2 of 2} |
  806. ]])
  807. end)
  808. describe('lua completion', function()
  809. it('expands when there is only one match', function()
  810. feed(':lua CURRENT_TESTING_VAR = 1<CR>')
  811. feed(':lua CURRENT_TESTING_<TAB>')
  812. screen:expect {
  813. grid = [[
  814. |
  815. {1:~ }|*6
  816. :lua CURRENT_TESTING_VAR^ |
  817. ]],
  818. }
  819. end)
  820. it('expands when there is only one match', function()
  821. feed(':lua CURRENT_TESTING_FOO = 1<CR>')
  822. feed(':lua CURRENT_TESTING_BAR = 1<CR>')
  823. feed(':lua CURRENT_TESTING_<TAB>')
  824. screen:expect {
  825. grid = [[
  826. |
  827. {1:~ }|*5
  828. {100:CURRENT_TESTING_BAR}{3: CURRENT_TESTING_FOO }|
  829. :lua CURRENT_TESTING_BAR^ |
  830. ]],
  831. unchanged = true,
  832. }
  833. end)
  834. it('prefix is not included in completion for cmdline mode', function()
  835. feed(':lua math.a<Tab>')
  836. screen:expect([[
  837. |
  838. {1:~ }|*5
  839. {100:abs}{3: acos asin atan atan2 }|
  840. :lua math.abs^ |
  841. ]])
  842. feed('<Tab>')
  843. screen:expect([[
  844. |
  845. {1:~ }|*5
  846. {3:abs }{100:acos}{3: asin atan atan2 }|
  847. :lua math.acos^ |
  848. ]])
  849. end)
  850. it('prefix is not included in completion for i_CTRL-X_CTRL-V #19623', function()
  851. feed('ilua math.a<C-X><C-V>')
  852. screen:expect([[
  853. lua math.abs^ |
  854. {1:~ }{12: abs }{1: }|
  855. {1:~ }{4: acos }{1: }|
  856. {1:~ }{4: asin }{1: }|
  857. {1:~ }{4: atan }{1: }|
  858. {1:~ }{4: atan2 }{1: }|
  859. {1:~ }|
  860. {5:-- Command-line completion (^V^N^P) }{6:match 1 of 5} |
  861. ]])
  862. feed('<C-V>')
  863. screen:expect([[
  864. lua math.acos^ |
  865. {1:~ }{4: abs }{1: }|
  866. {1:~ }{12: acos }{1: }|
  867. {1:~ }{4: asin }{1: }|
  868. {1:~ }{4: atan }{1: }|
  869. {1:~ }{4: atan2 }{1: }|
  870. {1:~ }|
  871. {5:-- Command-line completion (^V^N^P) }{6:match 2 of 5} |
  872. ]])
  873. end)
  874. it('works when cursor is in the middle of cmdline #29586', function()
  875. feed(':lua math.a(); 1<Left><Left><Left><Left><Left><Tab>')
  876. screen:expect([[
  877. |
  878. {1:~ }|*5
  879. {100:abs}{3: acos asin atan atan2 }|
  880. :lua math.abs^(); 1 |
  881. ]])
  882. end)
  883. it('provides completion from `getcompletion()`', function()
  884. eq({ 'vim' }, fn.getcompletion('vi', 'lua'))
  885. eq({ 'api' }, fn.getcompletion('vim.ap', 'lua'))
  886. eq({ 'tbl_filter' }, fn.getcompletion('vim.tbl_fil', 'lua'))
  887. eq({ 'vim' }, fn.getcompletion('print(vi', 'lua'))
  888. eq({ 'abs', 'acos', 'asin', 'atan', 'atan2' }, fn.getcompletion('math.a', 'lua'))
  889. eq({ 'abs', 'acos', 'asin', 'atan', 'atan2' }, fn.getcompletion('lua math.a', 'cmdline'))
  890. -- fuzzy completion is not supported, so the result should be the same
  891. command('set wildoptions+=fuzzy')
  892. eq({ 'vim' }, fn.getcompletion('vi', 'lua'))
  893. end)
  894. end)
  895. it('cmdline completion supports various string options', function()
  896. eq('auto', fn.getcompletion('set foldcolumn=', 'cmdline')[2])
  897. eq({ 'nosplit', 'split' }, fn.getcompletion('set inccommand=', 'cmdline'))
  898. eq({ 'ver:3,hor:6', 'hor:', 'ver:' }, fn.getcompletion('set mousescroll=', 'cmdline'))
  899. eq('BS', fn.getcompletion('set termpastefilter=', 'cmdline')[2])
  900. eq('SpecialKey', fn.getcompletion('set winhighlight=', 'cmdline')[1])
  901. eq('SpecialKey', fn.getcompletion('set winhighlight=NonText:', 'cmdline')[1])
  902. end)
  903. it('cmdline completion for -complete does not contain spaces', function()
  904. for _, str in ipairs(fn.getcompletion('command -complete=', 'cmdline')) do
  905. ok(not str:find(' '), 'string without spaces', str)
  906. end
  907. end)
  908. describe('from the commandline window', function()
  909. it('is cleared after CTRL-C', function()
  910. feed('q:')
  911. feed('ifoo faa fee f')
  912. screen:expect([[
  913. |
  914. {2:[No Name] }|
  915. {1::}foo faa fee f^ |
  916. {1:~ }|*3
  917. {3:[Command Line] }|
  918. {5:-- INSERT --} |
  919. ]])
  920. feed('<c-x><c-n>')
  921. screen:expect([[
  922. |
  923. {2:[No Name] }|
  924. {1::}foo faa fee foo^ |
  925. {1:~ }{12: foo }{1: }|
  926. {1:~ }{4: faa }{1: }|
  927. {1:~ }{4: fee }{1: }|
  928. {3:[Command Line] }|
  929. {5:-- Keyword Local completion (^N^P) }{6:match 1 of 3} |
  930. ]])
  931. feed('<c-c>')
  932. screen:expect([[
  933. |
  934. {2:[No Name] }|
  935. {1::}foo faa fee foo |
  936. {1:~ }|*3
  937. {3:[Command Line] }|
  938. :foo faa fee foo^ |
  939. ]])
  940. end)
  941. end)
  942. describe('with numeric items', function()
  943. before_each(function()
  944. source([[
  945. function! TestComplete() abort
  946. call complete(1, g:_complist)
  947. return ''
  948. endfunction
  949. ]])
  950. api.nvim_set_option_value('completeopt', 'menuone,noselect', {})
  951. api.nvim_set_var('_complist', {
  952. {
  953. word = 0,
  954. abbr = 1,
  955. menu = 2,
  956. kind = 3,
  957. info = 4,
  958. icase = 5,
  959. dup = 6,
  960. empty = 7,
  961. },
  962. })
  963. end)
  964. it('shows correct variant as word', function()
  965. feed('i<C-r>=TestComplete()<CR>')
  966. screen:expect([[
  967. ^ |
  968. {4:1 3 2 }{1: }|
  969. {1:~ }|*5
  970. {5:-- INSERT --} |
  971. ]])
  972. end)
  973. end)
  974. it("'ignorecase' 'infercase' CTRL-X CTRL-N #6451", function()
  975. feed_command('set ignorecase infercase')
  976. feed_command('edit runtime/doc/credits.txt')
  977. feed('oX<C-X><C-N>')
  978. screen:expect {
  979. grid = [[
  980. *credits.txt* Nvim |
  981. Xvi^ |
  982. {12:Xvi }{101: } |
  983. {4:Xvim }{101: } |
  984. {4:X11 }{12: } NVIM REFERENCE MANUAL |
  985. {4:Xnull }{12: } |
  986. {4:Xoxomoon }{12: } |
  987. {5:-- Keyword Local completion (^N^P) }{6:match 1 of 10} |
  988. ]],
  989. }
  990. end)
  991. it('CompleteChanged autocommand', function()
  992. api.nvim_buf_set_lines(0, 0, 1, false, { 'foo', 'bar', 'foobar', '' })
  993. source([[
  994. set complete=. completeopt=noinsert,noselect,menuone
  995. function! OnPumChange()
  996. let g:event = copy(v:event)
  997. let g:item = get(v:event, 'completed_item', {})
  998. let g:word = get(g:item, 'word', v:null)
  999. endfunction
  1000. autocmd! CompleteChanged * :call OnPumChange()
  1001. call cursor(4, 1)
  1002. ]])
  1003. -- v:event.size should be set with ext_popupmenu #20646
  1004. screen:set_option('ext_popupmenu', true)
  1005. feed('Sf<C-N>')
  1006. screen:expect({
  1007. grid = [[
  1008. foo |
  1009. bar |
  1010. foobar |
  1011. f^ |
  1012. {1:~ }|*3
  1013. {5:-- Keyword completion (^N^P) }{19:Back at original} |
  1014. ]],
  1015. popupmenu = {
  1016. anchor = { 1, 3, 0 },
  1017. items = { { 'foo', '', '', '' }, { 'foobar', '', '', '' } },
  1018. pos = -1,
  1019. },
  1020. })
  1021. eq(
  1022. { completed_item = {}, width = 0, height = 2, size = 2, col = 0, row = 4, scrollbar = false },
  1023. eval('g:event')
  1024. )
  1025. feed('oob')
  1026. screen:expect({
  1027. grid = [[
  1028. foo |
  1029. bar |
  1030. foobar |
  1031. foob^ |
  1032. {1:~ }|*3
  1033. {5:-- Keyword completion (^N^P) }{19:Back at original} |
  1034. ]],
  1035. popupmenu = {
  1036. anchor = { 1, 3, 0 },
  1037. items = { { 'foobar', '', '', '' } },
  1038. pos = -1,
  1039. },
  1040. })
  1041. eq(
  1042. { completed_item = {}, width = 0, height = 1, size = 1, col = 0, row = 4, scrollbar = false },
  1043. eval('g:event')
  1044. )
  1045. feed('<Esc>')
  1046. screen:set_option('ext_popupmenu', false)
  1047. feed('Sf<C-N>')
  1048. screen:expect([[
  1049. foo |
  1050. bar |
  1051. foobar |
  1052. f^ |
  1053. {4:foo }{1: }|
  1054. {4:foobar }{1: }|
  1055. {1:~ }|
  1056. {5:-- Keyword completion (^N^P) }{19:Back at original} |
  1057. ]])
  1058. eq(
  1059. { completed_item = {}, width = 15, height = 2, size = 2, col = 0, row = 4, scrollbar = false },
  1060. eval('g:event')
  1061. )
  1062. feed('<C-N>')
  1063. screen:expect([[
  1064. foo |
  1065. bar |
  1066. foobar |
  1067. foo^ |
  1068. {12:foo }{1: }|
  1069. {4:foobar }{1: }|
  1070. {1:~ }|
  1071. {5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
  1072. ]])
  1073. eq('foo', eval('g:word'))
  1074. feed('<C-N>')
  1075. screen:expect([[
  1076. foo |
  1077. bar |
  1078. foobar |
  1079. foobar^ |
  1080. {4:foo }{1: }|
  1081. {12:foobar }{1: }|
  1082. {1:~ }|
  1083. {5:-- Keyword completion (^N^P) }{6:match 2 of 2} |
  1084. ]])
  1085. eq('foobar', eval('g:word'))
  1086. feed('<up>')
  1087. screen:expect([[
  1088. foo |
  1089. bar |
  1090. foobar |
  1091. foobar^ |
  1092. {12:foo }{1: }|
  1093. {4:foobar }{1: }|
  1094. {1:~ }|
  1095. {5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
  1096. ]])
  1097. eq('foo', eval('g:word'))
  1098. feed('<down>')
  1099. screen:expect([[
  1100. foo |
  1101. bar |
  1102. foobar |
  1103. foobar^ |
  1104. {4:foo }{1: }|
  1105. {12:foobar }{1: }|
  1106. {1:~ }|
  1107. {5:-- Keyword completion (^N^P) }{6:match 2 of 2} |
  1108. ]])
  1109. eq('foobar', eval('g:word'))
  1110. feed('<esc>')
  1111. end)
  1112. it('is stopped by :stopinsert from timer #12976', function()
  1113. screen:try_resize(32, 14)
  1114. command([[call setline(1, ['hello', 'hullo', 'heeee', ''])]])
  1115. feed('Gah<c-x><c-n>')
  1116. screen:expect([[
  1117. hello |
  1118. hullo |
  1119. heeee |
  1120. hello^ |
  1121. {12:hello }{1: }|
  1122. {4:hullo }{1: }|
  1123. {4:heeee }{1: }|
  1124. {1:~ }|*6
  1125. {5:-- }{6:match 1 of 3} |
  1126. ]])
  1127. command([[call timer_start(100, { -> execute('stopinsert') })]])
  1128. vim.uv.sleep(200)
  1129. feed('k') -- cursor should move up in Normal mode
  1130. screen:expect([[
  1131. hello |
  1132. hullo |
  1133. heee^e |
  1134. hello |
  1135. {1:~ }|*9
  1136. |
  1137. ]])
  1138. end)
  1139. -- oldtest: Test_complete_changed_complete_info()
  1140. it('no crash calling complete_info() in CompleteChanged', function()
  1141. source([[
  1142. set completeopt=menuone
  1143. autocmd CompleteChanged * call complete_info(['items'])
  1144. call feedkeys("iii\<cr>\<c-p>")
  1145. ]])
  1146. screen:expect([[
  1147. ii |
  1148. ii^ |
  1149. {12:ii }{1: }|
  1150. {1:~ }|*4
  1151. {5:-- Keyword completion (^N^P) The only match} |
  1152. ]])
  1153. assert_alive()
  1154. end)
  1155. it('no crash if text changed by first call to complete function #17489', function()
  1156. source([[
  1157. func Complete(findstart, base) abort
  1158. if a:findstart
  1159. let col = col('.')
  1160. call complete_add('#')
  1161. return col - 1
  1162. else
  1163. return []
  1164. endif
  1165. endfunc
  1166. set completeopt=longest
  1167. set completefunc=Complete
  1168. ]])
  1169. feed('ifoo#<C-X><C-U>')
  1170. assert_alive()
  1171. end)
  1172. it('no crash using i_CTRL-X_CTRL-V to complete non-existent colorscheme', function()
  1173. feed('icolorscheme NOSUCHCOLORSCHEME<C-X><C-V>')
  1174. expect('colorscheme NOSUCHCOLORSCHEME')
  1175. assert_alive()
  1176. end)
  1177. it('complete with f flag #25598', function()
  1178. screen:try_resize(20, 9)
  1179. command('set complete+=f | edit foo | edit bar |edit foa |edit .hidden')
  1180. feed('i<C-n>')
  1181. screen:expect {
  1182. grid = [[
  1183. foo^ |
  1184. {12:foo }{1: }|
  1185. {4:bar }{1: }|
  1186. {4:foa }{1: }|
  1187. {4:.hidden }{1: }|
  1188. {1:~ }|*3
  1189. {5:-- }{6:match 1 of 4} |
  1190. ]],
  1191. }
  1192. feed('<Esc>ccf<C-n>')
  1193. screen:expect {
  1194. grid = [[
  1195. foo^ |
  1196. {12:foo }{1: }|
  1197. {4:foa }{1: }|
  1198. {1:~ }|*5
  1199. {5:-- }{6:match 1 of 2} |
  1200. ]],
  1201. }
  1202. end)
  1203. it('restores extmarks if original text is restored #23653', function()
  1204. screen:try_resize(screen._width, 4)
  1205. command([[
  1206. call setline(1, ['aaaa'])
  1207. let ns_id = nvim_create_namespace('extmark')
  1208. let mark_id = nvim_buf_set_extmark(0, ns_id, 0, 0, { 'end_col':2, 'hl_group':'Error' })
  1209. let mark = nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })
  1210. inoremap <C-x> <C-r>=Complete()<CR>
  1211. function Complete() abort
  1212. call complete(1, [{ 'word': 'aaaaa' }])
  1213. return ''
  1214. endfunction
  1215. ]])
  1216. feed('A<C-X><C-E><Esc>')
  1217. eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
  1218. feed('A<C-N>')
  1219. eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
  1220. feed('<Esc>0Yppia<Esc>ggI<C-N>')
  1221. screen:expect([[
  1222. aaaa{9:^aa}aa |
  1223. {12:aaaa } |
  1224. {4:aaaaa } |
  1225. {5:-- Keyword completion (^N^P) }{6:match 1 of 2} |
  1226. ]])
  1227. feed('<C-N><C-N><Esc>')
  1228. eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
  1229. feed('A<C-N>')
  1230. eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
  1231. feed('<C-N>')
  1232. screen:expect([[
  1233. aaaaa^ |
  1234. {4:aaaa } |
  1235. {12:aaaaa } |
  1236. {5:-- Keyword completion (^N^P) }{6:match 2 of 2} |
  1237. ]])
  1238. feed('<C-E>')
  1239. screen:expect([[
  1240. {9:aa}aa^ |
  1241. aaaa |
  1242. aaaaa |
  1243. {5:-- INSERT --} |
  1244. ]])
  1245. -- Also when completion leader is changed #31384
  1246. feed('<Esc>hi<C-N><C-P>a')
  1247. screen:expect({
  1248. grid = [[
  1249. {9:aa}a^aa |
  1250. {4:aaaa } |
  1251. {4:aaaaa } |
  1252. {5:-- Keyword completion (^N^P) }{19:Back at original} |
  1253. ]],
  1254. })
  1255. -- But still grows with end_right_gravity #31437
  1256. command(
  1257. "call nvim_buf_set_extmark(0, ns_id, 1, 0, { 'end_col':2, 'hl_group':'Error', 'end_right_gravity': 1 })"
  1258. )
  1259. feed('<Esc>ji<C-N>a')
  1260. screen:expect({
  1261. grid = [[
  1262. {9:aa}aaa |
  1263. {9:aaa}^aa |
  1264. aaaaa |
  1265. {5:-- INSERT --} |
  1266. ]],
  1267. })
  1268. end)
  1269. describe('nvim__complete_set', function()
  1270. it("fails when 'completeopt' does not include popup", function()
  1271. exec_lua([[
  1272. function _G.omni_test(findstart, base)
  1273. if findstart == 1 then
  1274. return vim.fn.col('.') - 1
  1275. end
  1276. return { { word = 'one' } }
  1277. end
  1278. vim.api.nvim_create_autocmd('CompleteChanged', {
  1279. callback = function()
  1280. local ok, err = pcall(vim.api.nvim__complete_set, 0, { info = '1info' })
  1281. if not ok then
  1282. vim.g.err_msg = err
  1283. end
  1284. end,
  1285. })
  1286. vim.opt.completeopt = 'menu,menuone'
  1287. vim.opt.omnifunc = 'v:lua.omni_test'
  1288. ]])
  1289. feed('S<C-X><C-O>')
  1290. eq('completeopt option does not include popup', api.nvim_get_var('err_msg'))
  1291. end)
  1292. end)
  1293. end)