neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

completion_spec.lua (79237B)


      1 local t = require('test.testutil')
      2 local n = require('test.functional.testnvim')()
      3 local Screen = require('test.functional.ui.screen')
      4 
      5 local assert_alive = n.assert_alive
      6 local clear, feed = n.clear, n.feed
      7 local eval, eq, ok = n.eval, t.eq, t.ok
      8 local source, expect = n.source, n.expect
      9 local fn = n.fn
     10 local command = n.command
     11 local api = n.api
     12 local poke_eventloop = n.poke_eventloop
     13 local exec_lua = n.exec_lua
     14 
     15 describe('completion', function()
     16  local screen
     17 
     18  before_each(function()
     19    clear()
     20    source([[
     21      set completeopt-=noselect
     22      " Avoid tags completion (if running test locally).
     23      set complete-=t
     24    ]])
     25    screen = Screen.new(60, 8)
     26    screen:add_extra_attr_ids {
     27      [100] = { foreground = Screen.colors.Gray0, background = Screen.colors.Yellow },
     28      [101] = { background = Screen.colors.Gray0 },
     29      [102] = { foreground = Screen.colors.SeaGreen },
     30    }
     31  end)
     32 
     33  it('ctrl-x_ctrl-f completes Windows drive letter', function()
     34    t.skip(not t.is_os('win'), 'N/A for non-Windows')
     35    feed('iblablaC:/W<C-x><C-f>')
     36    screen:expect {
     37      any = [[C:\Windows\]],
     38    }
     39  end)
     40 
     41  describe('v:completed_item', function()
     42    it('is empty dict until completion', function()
     43      eq({}, eval('v:completed_item'))
     44    end)
     45    it('is empty dict if the candidate is not inserted', function()
     46      feed('ifoo<ESC>o<C-x><C-n>')
     47      screen:expect([[
     48        foo                                                         |
     49        foo^                                                         |
     50        {1:~                                                           }|*5
     51        {5:-- Keyword Local completion (^N^P) The only match}           |
     52      ]])
     53      feed('<C-e>')
     54      screen:expect([[
     55        foo                                                         |
     56        ^                                                            |
     57        {1:~                                                           }|*5
     58        {5:-- INSERT --}                                                |
     59      ]])
     60      feed('<ESC>')
     61      eq({}, eval('v:completed_item'))
     62    end)
     63    it('returns expected dict in normal completion', function()
     64      feed('ifoo<ESC>o<C-x><C-n>')
     65      eq('foo', eval('getline(2)'))
     66      eq(
     67        { word = 'foo', abbr = '', menu = '', info = '', kind = '', user_data = '' },
     68        eval('v:completed_item')
     69      )
     70    end)
     71    it('is readonly', function()
     72      screen:try_resize(80, 8)
     73      feed('ifoo<ESC>o<C-x><C-n><ESC>')
     74      t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.word = "bar"'))
     75      t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.abbr = "bar"'))
     76      t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.menu = "bar"'))
     77      t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.info = "bar"'))
     78      t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.kind = "bar"'))
     79      t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.user_data = "bar"'))
     80    end)
     81    it('returns expected dict in omni completion', function()
     82      source([[
     83      function! TestOmni(findstart, base) abort
     84        return a:findstart ? 0 : [{'word': 'foo', 'abbr': 'bar',
     85        \ 'menu': 'baz', 'info': 'foobar', 'kind': 'foobaz'},
     86        \ {'word': 'word', 'abbr': 'abbr', 'menu': 'menu',
     87        \  'info': 'info', 'kind': 'kind'}]
     88      endfunction
     89      setlocal omnifunc=TestOmni
     90      ]])
     91      feed('i<C-x><C-o>')
     92      eq('foo', eval('getline(1)'))
     93      screen:expect([[
     94        foo^                                                         |
     95        {12:bar  foobaz baz  }{1:                                           }|
     96        {4:abbr kind   menu }{1:                                           }|
     97        {1:~                                                           }|*4
     98        {5:-- Omni completion (^O^N^P) }{6:match 1 of 2}                    |
     99      ]])
    100      eq({
    101        word = 'foo',
    102        abbr = 'bar',
    103        menu = 'baz',
    104        info = 'foobar',
    105        kind = 'foobaz',
    106        user_data = '',
    107      }, eval('v:completed_item'))
    108    end)
    109  end)
    110 
    111  describe('completeopt', function()
    112    before_each(function()
    113      source([[
    114      function! TestComplete() abort
    115        call complete(1, ['foo'])
    116        return ''
    117      endfunction
    118      ]])
    119    end)
    120 
    121    it('inserts the first candidate if default', function()
    122      command('set completeopt+=menuone')
    123      feed('ifoo<ESC>o')
    124      screen:expect([[
    125        foo                                                         |
    126        ^                                                            |
    127        {1:~                                                           }|*5
    128        {5:-- INSERT --}                                                |
    129      ]])
    130      feed('<C-x>')
    131      -- the ^X prompt, only test this once
    132      screen:expect([[
    133        foo                                                         |
    134        ^                                                            |
    135        {1:~                                                           }|*5
    136        {5:-- ^X mode (^]^D^E^F^I^K^L^N^O^P^Rs^U^V^Y)}                  |
    137      ]])
    138      feed('<C-n>')
    139      screen:expect([[
    140        foo                                                         |
    141        foo^                                                         |
    142        {12:foo            }{1:                                             }|
    143        {1:~                                                           }|*4
    144        {5:-- Keyword Local completion (^N^P) The only match}           |
    145      ]])
    146      feed('bar<ESC>')
    147      eq('foobar', eval('getline(2)'))
    148      feed('o<C-r>=TestComplete()<CR>')
    149      screen:expect([[
    150        foo                                                         |
    151        foobar                                                      |
    152        foo^                                                         |
    153        {12:foo            }{1:                                             }|
    154        {1:~                                                           }|*3
    155        {5:-- INSERT --}                                                |
    156      ]])
    157      eq('foo', eval('getline(3)'))
    158    end)
    159    it('selects the first candidate if noinsert', function()
    160      command('set completeopt+=menuone,noinsert')
    161      feed('ifoo<ESC>o<C-x><C-n>')
    162      screen:expect([[
    163        foo                                                         |
    164        ^                                                            |
    165        {12:foo            }{1:                                             }|
    166        {1:~                                                           }|*4
    167        {5:-- Keyword Local completion (^N^P) The only match}           |
    168      ]])
    169      feed('<C-y>')
    170      screen:expect([[
    171        foo                                                         |
    172        foo^                                                         |
    173        {1:~                                                           }|*5
    174        {5:-- INSERT --}                                                |
    175      ]])
    176      feed('<ESC>')
    177      eq('foo', eval('getline(2)'))
    178      feed('o<C-r>=TestComplete()<CR>')
    179      screen:expect([[
    180        foo                                                         |*2
    181        ^                                                            |
    182        {12:foo            }{1:                                             }|
    183        {1:~                                                           }|*3
    184        {5:-- INSERT --}                                                |
    185      ]])
    186      feed('<C-y><ESC>')
    187      eq('foo', eval('getline(3)'))
    188    end)
    189    it('does not insert the first candidate if noselect', function()
    190      command('set completeopt+=menuone,noselect')
    191      feed('ifoo<ESC>o<C-x><C-n>')
    192      screen:expect([[
    193        foo                                                         |
    194        ^                                                            |
    195        {4:foo            }{1:                                             }|
    196        {1:~                                                           }|*4
    197        {5:-- Keyword Local completion (^N^P) }{19:Back at original}         |
    198      ]])
    199      feed('b')
    200      screen:expect([[
    201        foo                                                         |
    202        b^                                                           |
    203        {1:~                                                           }|*5
    204        {5:-- Keyword Local completion (^N^P) }{19:Back at original}         |
    205      ]])
    206      feed('ar<ESC>')
    207      eq('bar', eval('getline(2)'))
    208      feed('o<C-r>=TestComplete()<CR>')
    209      screen:expect([[
    210        foo                                                         |
    211        bar                                                         |
    212        ^                                                            |
    213        {4:foo            }{1:                                             }|
    214        {1:~                                                           }|*3
    215        {5:-- INSERT --}                                                |
    216      ]])
    217      feed('bar<ESC>')
    218      eq('bar', eval('getline(3)'))
    219    end)
    220    it('does not select/insert the first candidate if noselect and noinsert', function()
    221      command('set completeopt+=menuone,noselect,noinsert')
    222      feed('ifoo<ESC>o<C-x><C-n>')
    223      screen:expect([[
    224        foo                                                         |
    225        ^                                                            |
    226        {4:foo            }{1:                                             }|
    227        {1:~                                                           }|*4
    228        {5:-- Keyword Local completion (^N^P) }{19:Back at original}         |
    229      ]])
    230      feed('<ESC>')
    231      screen:expect([[
    232        foo                                                         |
    233        ^                                                            |
    234        {1:~                                                           }|*5
    235                                                                    |
    236      ]])
    237      eq('', eval('getline(2)'))
    238      feed('o<C-r>=TestComplete()<CR>')
    239      screen:expect([[
    240        foo                                                         |
    241                                                                    |
    242        ^                                                            |
    243        {4:foo            }{1:                                             }|
    244        {1:~                                                           }|*3
    245        {5:-- INSERT --}                                                |
    246      ]])
    247      feed('<ESC>')
    248      screen:expect([[
    249        foo                                                         |
    250                                                                    |
    251        ^                                                            |
    252        {1:~                                                           }|*4
    253                                                                    |
    254      ]])
    255      eq('', eval('getline(3)'))
    256    end)
    257    it('does not change modified state if noinsert', function()
    258      command('set completeopt+=menuone,noinsert')
    259      command('setlocal nomodified')
    260      feed('i<C-r>=TestComplete()<CR><ESC>')
    261      eq(0, eval('&l:modified'))
    262    end)
    263    it('does not change modified state if noselect', function()
    264      command('set completeopt+=menuone,noselect')
    265      command('setlocal nomodified')
    266      feed('i<C-r>=TestComplete()<CR><ESC>')
    267      eq(0, eval('&l:modified'))
    268    end)
    269  end)
    270 
    271  describe('completeopt+=noinsert does not add blank undo items', function()
    272    before_each(function()
    273      source([[
    274      function! TestComplete() abort
    275        call complete(1, ['foo', 'bar'])
    276        return ''
    277      endfunction
    278      ]])
    279      command('set completeopt+=noselect,noinsert')
    280      command('inoremap <right> <c-r>=TestComplete()<cr>')
    281    end)
    282 
    283    local tests = {
    284      ['<up>, <down>, <cr>'] = { '<down><cr>', '<up><cr>' },
    285      ['<c-n>, <c-p>, <c-y>'] = { '<c-n><c-y>', '<c-p><c-y>' },
    286    }
    287 
    288    for name, seq in pairs(tests) do
    289      it('using ' .. name, function()
    290        feed('iaaa<esc>')
    291        feed('A<right>' .. seq[1] .. '<esc>')
    292        feed('A<right><esc>A<right><esc>')
    293        feed('A<cr>bbb<esc>')
    294        feed('A<right>' .. seq[2] .. '<esc>')
    295        feed('A<right><esc>A<right><esc>')
    296        feed('A<cr>ccc<esc>')
    297        feed('A<right>' .. seq[1] .. '<esc>')
    298        feed('A<right><esc>A<right><esc>')
    299 
    300        local expected = {
    301          { 'foo', 'bar', 'foo' },
    302          { 'foo', 'bar', 'ccc' },
    303          { 'foo', 'bar' },
    304          { 'foo', 'bbb' },
    305          { 'foo' },
    306          { 'aaa' },
    307          { '' },
    308        }
    309 
    310        for i = 1, #expected do
    311          if i > 1 then
    312            feed('u')
    313          end
    314          eq(expected[i], eval('getline(1, "$")'))
    315        end
    316 
    317        for i = #expected, 1, -1 do
    318          if i < #expected then
    319            feed('<c-r>')
    320          end
    321          eq(expected[i], eval('getline(1, "$")'))
    322        end
    323      end)
    324    end
    325  end)
    326 
    327  describe('with refresh:always and noselect', function()
    328    before_each(function()
    329      source([[
    330        function! TestCompletion(findstart, base) abort
    331          if a:findstart
    332            let line = getline('.')
    333            let start = col('.') - 1
    334            while start > 0 && line[start - 1] =~ '\a'
    335              let start -= 1
    336            endwhile
    337            return start
    338          else
    339            let ret = []
    340            for m in split("January February March April May June July August September October November December")
    341              if m =~ a:base  " match by regex
    342                call add(ret, m)
    343              endif
    344            endfor
    345            return {'words':ret, 'refresh':'always'}
    346          endif
    347        endfunction
    348 
    349        set completeopt=menuone,noselect
    350        set completefunc=TestCompletion
    351      ]])
    352    end)
    353 
    354    it('completes on each input char', function()
    355      feed('i<C-x><C-u>')
    356      screen:expect([[
    357        ^                                                            |
    358        {4:January        }{101: }{1:                                            }|
    359        {4:February       }{101: }{1:                                            }|
    360        {4:March          }{101: }{1:                                            }|
    361        {4:April          }{12: }{1:                                            }|
    362        {4:May            }{12: }{1:                                            }|
    363        {4:June           }{12: }{1:                                            }|
    364        {5:-- User defined completion (^U^N^P) }{19:Back at original}        |
    365      ]])
    366      feed('u')
    367      screen:expect([[
    368        u^                                                           |
    369        {4:January        }{1:                                             }|
    370        {4:February       }{1:                                             }|
    371        {4:June           }{1:                                             }|
    372        {4:July           }{1:                                             }|
    373        {4:August         }{1:                                             }|
    374        {1:~                                                           }|
    375        {5:-- User defined completion (^U^N^P) }{19:Back at original}        |
    376      ]])
    377      feed('g')
    378      screen:expect([[
    379        ug^                                                          |
    380        {4:August         }{1:                                             }|
    381        {1:~                                                           }|*5
    382        {5:-- User defined completion (^U^N^P) }{19:Back at original}        |
    383      ]])
    384      feed('<Down>')
    385      screen:expect([[
    386        ug^                                                          |
    387        {12:August         }{1:                                             }|
    388        {1:~                                                           }|*5
    389        {5:-- User defined completion (^U^N^P) The only match}          |
    390      ]])
    391      feed('<C-y>')
    392      screen:expect([[
    393        August^                                                      |
    394        {1:~                                                           }|*6
    395        {5:-- INSERT --}                                                |
    396      ]])
    397      expect('August')
    398    end)
    399 
    400    it('repeats correctly after backspace #2674', function()
    401      feed('o<C-x><C-u>Ja')
    402      screen:expect([[
    403                                                                    |
    404        Ja^                                                          |
    405        {4:January        }{1:                                             }|
    406        {1:~                                                           }|*4
    407        {5:-- User defined completion (^U^N^P) }{19:Back at original}        |
    408      ]])
    409      feed('<BS>')
    410      screen:expect([[
    411                                                                    |
    412        J^                                                           |
    413        {4:January        }{1:                                             }|
    414        {4:June           }{1:                                             }|
    415        {4:July           }{1:                                             }|
    416        {1:~                                                           }|*2
    417        {5:-- User defined completion (^U^N^P) }{19:Back at original}        |
    418      ]])
    419      feed('<C-n>')
    420      screen:expect([[
    421                                                                    |
    422        January^                                                     |
    423        {12:January        }{1:                                             }|
    424        {4:June           }{1:                                             }|
    425        {4:July           }{1:                                             }|
    426        {1:~                                                           }|*2
    427        {5:-- User defined completion (^U^N^P) }{6:match 1 of 3}            |
    428      ]])
    429      feed('<C-n>')
    430      screen:expect([[
    431                                                                    |
    432        June^                                                        |
    433        {4:January        }{1:                                             }|
    434        {12:June           }{1:                                             }|
    435        {4:July           }{1:                                             }|
    436        {1:~                                                           }|*2
    437        {5:-- User defined completion (^U^N^P) }{6:match 2 of 3}            |
    438      ]])
    439      feed('<Esc>')
    440      screen:expect([[
    441                                                                    |
    442        Jun^e                                                        |
    443        {1:~                                                           }|*5
    444                                                                    |
    445      ]])
    446      feed('.')
    447      screen:expect([[
    448                                                                    |
    449        June                                                        |
    450        Jun^e                                                        |
    451        {1:~                                                           }|*4
    452                                                                    |
    453      ]])
    454      expect([[
    455 
    456        June
    457        June]])
    458    end)
    459 
    460    it('Enter inserts newline at original text after adding leader', function()
    461      feed('iJ<C-x><C-u>')
    462      poke_eventloop()
    463      feed('u')
    464      poke_eventloop()
    465      feed('<CR>')
    466      expect([[
    467        Ju
    468        ]])
    469      feed('J<C-x><C-u>')
    470      poke_eventloop()
    471      feed('<CR>')
    472      expect([[
    473        Ju
    474        J
    475        ]])
    476    end)
    477  end)
    478 
    479  describe('with noselect but not refresh:always', function()
    480    before_each(function()
    481      source([[
    482        function! TestCompletion(findstart, base) abort
    483          if a:findstart
    484            let line = getline('.')
    485            let start = col('.') - 1
    486            while start > 0 && line[start - 1] =~ '\a'
    487              let start -= 1
    488            endwhile
    489            return start
    490          else
    491            let ret = []
    492            for m in split("January February March April May June July August September October November December")
    493              if m =~ a:base  " match by regex
    494                call add(ret, m)
    495              endif
    496            endfor
    497            return {'words':ret}
    498          endif
    499        endfunction
    500 
    501        set completeopt=menuone,noselect
    502        set completefunc=TestCompletion
    503      ]])
    504    end)
    505 
    506    it('Enter inserts newline at original text after adding leader', function()
    507      feed('iJ<C-x><C-u>')
    508      poke_eventloop()
    509      feed('u')
    510      poke_eventloop()
    511      feed('<CR>')
    512      expect([[
    513        Ju
    514        ]])
    515      feed('<Esc>')
    516      poke_eventloop()
    517      -- The behavior should be the same when completion has been interrupted,
    518      -- which can happen interactively if the completion function is slow.
    519      feed('ggVGSJ<C-x><C-u>u<CR>')
    520      expect([[
    521        Ju
    522        ]])
    523    end)
    524  end)
    525 
    526  describe('with a lot of items', function()
    527    before_each(function()
    528      source([[
    529      function! TestComplete() abort
    530        call complete(1, map(range(0,100), "string(v:val)"))
    531        return ''
    532      endfunction
    533      ]])
    534      command('set completeopt=menuone,noselect')
    535    end)
    536 
    537    it('works', function()
    538      feed('i<C-r>=TestComplete()<CR>')
    539      screen:expect([[
    540        ^                                                            |
    541        {4:0              }{101: }{1:                                            }|
    542        {4:1              }{12: }{1:                                            }|
    543        {4:2              }{12: }{1:                                            }|
    544        {4:3              }{12: }{1:                                            }|
    545        {4:4              }{12: }{1:                                            }|
    546        {4:5              }{12: }{1:                                            }|
    547        {5:-- INSERT --}                                                |
    548      ]])
    549      feed('7')
    550      screen:expect([[
    551        7^                                                           |
    552        {4:7              }{101: }{1:                                            }|
    553        {4:70             }{101: }{1:                                            }|
    554        {4:71             }{101: }{1:                                            }|
    555        {4:72             }{12: }{1:                                            }|
    556        {4:73             }{12: }{1:                                            }|
    557        {4:74             }{12: }{1:                                            }|
    558        {5:-- INSERT --}                                                |
    559      ]])
    560      feed('<c-n>')
    561      screen:expect([[
    562        7^                                                           |
    563        {12:7              }{101: }{1:                                            }|
    564        {4:70             }{101: }{1:                                            }|
    565        {4:71             }{101: }{1:                                            }|
    566        {4:72             }{12: }{1:                                            }|
    567        {4:73             }{12: }{1:                                            }|
    568        {4:74             }{12: }{1:                                            }|
    569        {5:-- INSERT --}                                                |
    570      ]])
    571      feed('<c-n>')
    572      screen:expect([[
    573        70^                                                          |
    574        {4:7              }{101: }{1:                                            }|
    575        {12:70             }{101: }{1:                                            }|
    576        {4:71             }{101: }{1:                                            }|
    577        {4:72             }{12: }{1:                                            }|
    578        {4:73             }{12: }{1:                                            }|
    579        {4:74             }{12: }{1:                                            }|
    580        {5:-- INSERT --}                                                |
    581      ]])
    582    end)
    583 
    584    it('can be navigated with <PageDown>, <PageUp>', function()
    585      feed('i<C-r>=TestComplete()<CR>')
    586      screen:expect([[
    587        ^                                                            |
    588        {4:0              }{101: }{1:                                            }|
    589        {4:1              }{12: }{1:                                            }|
    590        {4:2              }{12: }{1:                                            }|
    591        {4:3              }{12: }{1:                                            }|
    592        {4:4              }{12: }{1:                                            }|
    593        {4:5              }{12: }{1:                                            }|
    594        {5:-- INSERT --}                                                |
    595      ]])
    596      feed('<PageDown>')
    597      screen:expect([[
    598        ^                                                            |
    599        {4:0              }{101: }{1:                                            }|
    600        {4:1              }{12: }{1:                                            }|
    601        {4:2              }{12: }{1:                                            }|
    602        {12:3               }{1:                                            }|
    603        {4:4              }{12: }{1:                                            }|
    604        {4:5              }{12: }{1:                                            }|
    605        {5:-- INSERT --}                                                |
    606      ]])
    607      feed('<PageDown>')
    608      screen:expect([[
    609        ^                                                            |
    610        {4:5              }{101: }{1:                                            }|
    611        {4:6              }{12: }{1:                                            }|
    612        {12:7               }{1:                                            }|
    613        {4:8              }{12: }{1:                                            }|
    614        {4:9              }{12: }{1:                                            }|
    615        {4:10             }{12: }{1:                                            }|
    616        {5:-- INSERT --}                                                |
    617      ]])
    618      feed('<Down>')
    619      screen:expect([[
    620        ^                                                            |
    621        {4:5              }{101: }{1:                                            }|
    622        {4:6              }{12: }{1:                                            }|
    623        {4:7              }{12: }{1:                                            }|
    624        {12:8               }{1:                                            }|
    625        {4:9              }{12: }{1:                                            }|
    626        {4:10             }{12: }{1:                                            }|
    627        {5:-- INSERT --}                                                |
    628      ]])
    629      feed('<PageUp>')
    630      screen:expect([[
    631        ^                                                            |
    632        {4:2              }{101: }{1:                                            }|
    633        {4:3              }{12: }{1:                                            }|
    634        {12:4               }{1:                                            }|
    635        {4:5              }{12: }{1:                                            }|
    636        {4:6              }{12: }{1:                                            }|
    637        {4:7              }{12: }{1:                                            }|
    638        {5:-- INSERT --}                                                |
    639      ]])
    640      feed('<PageUp>') -- stop on first item
    641      screen:expect([[
    642        ^                                                            |
    643        {12:0              }{101: }{1:                                            }|
    644        {4:1              }{12: }{1:                                            }|
    645        {4:2              }{12: }{1:                                            }|
    646        {4:3              }{12: }{1:                                            }|
    647        {4:4              }{12: }{1:                                            }|
    648        {4:5              }{12: }{1:                                            }|
    649        {5:-- INSERT --}                                                |
    650      ]])
    651      feed('<PageUp>') -- when on first item, unselect
    652      screen:expect([[
    653        ^                                                            |
    654        {4:0              }{101: }{1:                                            }|
    655        {4:1              }{12: }{1:                                            }|
    656        {4:2              }{12: }{1:                                            }|
    657        {4:3              }{12: }{1:                                            }|
    658        {4:4              }{12: }{1:                                            }|
    659        {4:5              }{12: }{1:                                            }|
    660        {5:-- INSERT --}                                                |
    661      ]])
    662      feed('<PageUp>') -- when unselected, select last item
    663      screen:expect([[
    664        ^                                                            |
    665        {4:95             }{12: }{1:                                            }|
    666        {4:96             }{12: }{1:                                            }|
    667        {4:97             }{12: }{1:                                            }|
    668        {4:98             }{12: }{1:                                            }|
    669        {4:99             }{12: }{1:                                            }|
    670        {12:100            }{101: }{1:                                            }|
    671        {5:-- INSERT --}                                                |
    672      ]])
    673      feed('<PageUp>')
    674      screen:expect([[
    675        ^                                                            |
    676        {4:94             }{12: }{1:                                            }|
    677        {4:95             }{12: }{1:                                            }|
    678        {12:96              }{1:                                            }|
    679        {4:97             }{12: }{1:                                            }|
    680        {4:98             }{12: }{1:                                            }|
    681        {4:99             }{101: }{1:                                            }|
    682        {5:-- INSERT --}                                                |
    683      ]])
    684      feed('<cr>')
    685      screen:expect([[
    686        96^                                                          |
    687        {1:~                                                           }|*6
    688        {5:-- INSERT --}                                                |
    689      ]])
    690    end)
    691  end)
    692 
    693  it('does not indent until an item is selected #8345', function()
    694    -- Indents on "ind", unindents on "unind".
    695    source([[
    696      function! TestIndent()
    697        let line = getline(v:lnum)
    698        if (line =~ '^\s*ind')
    699          return indent(v:lnum-1) + shiftwidth()
    700        elseif (line =~ '^\s*unind')
    701          return indent(v:lnum-1) - shiftwidth()
    702        else
    703          return indent(v:lnum-1)
    704        endif
    705      endfunction
    706      set indentexpr=TestIndent()
    707      set indentkeys=o,O,!^F,=ind,=unind
    708      set completeopt+=menuone
    709    ]])
    710 
    711    -- Give some words to complete.
    712    feed('iinc uninc indent unindent<CR>')
    713 
    714    -- Does not indent when "ind" is typed.
    715    feed('in<C-X><C-N>')
    716    -- Completion list is generated incorrectly if we send everything at once
    717    -- via nvim_input().  So poke_eventloop() before sending <BS>. #8480
    718    poke_eventloop()
    719    feed('<BS>d')
    720 
    721    screen:expect([[
    722      inc uninc indent unindent                                   |
    723      ind^                                                         |
    724      {12:indent         }{1:                                             }|
    725      {1:~                                                           }|*4
    726      {5:-- Keyword Local completion (^N^P) }{6:match 1 of 2}             |
    727    ]])
    728 
    729    -- Indents when the item is selected
    730    feed('<C-Y>')
    731    screen:expect([[
    732      inc uninc indent unindent                                   |
    733              indent^                                              |
    734      {1:~                                                           }|*5
    735      {5:-- INSERT --}                                                |
    736    ]])
    737    -- Indents when completion is exited using ESC.
    738    feed('<CR>in<C-N><BS>d<Esc>')
    739    screen:expect([[
    740      inc uninc indent unindent                                   |
    741              indent                                              |
    742                      in^d                                         |
    743      {1:~                                                           }|*4
    744                                                                  |
    745    ]])
    746    -- Works for unindenting too.
    747    feed('ounin<C-X><C-N>')
    748    poke_eventloop()
    749    feed('<BS>d')
    750    screen:expect([[
    751      inc uninc indent unindent                                   |
    752              indent                                              |
    753                      ind                                         |
    754                      unind^                                       |
    755      {1:~              }{12: unindent       }{1:                             }|
    756      {1:~                                                           }|*2
    757      {5:-- Keyword Local completion (^N^P) }{6:match 1 of 2}             |
    758    ]])
    759    -- Works when going back and forth.
    760    feed('<BS>c')
    761    screen:expect([[
    762      inc uninc indent unindent                                   |
    763              indent                                              |
    764                      ind                                         |
    765                      uninc^                                       |
    766      {1:~              }{12: uninc          }{1:                             }|
    767      {1:~                                                           }|*2
    768      {5:-- Keyword Local completion (^N^P) }{6:match 1 of 2}             |
    769    ]])
    770    feed('<BS>d')
    771    screen:expect([[
    772      inc uninc indent unindent                                   |
    773              indent                                              |
    774                      ind                                         |
    775                      unind^                                       |
    776      {1:~              }{12: unindent       }{1:                             }|
    777      {1:~                                                           }|*2
    778      {5:-- Keyword Local completion (^N^P) }{6:match 1 of 2}             |
    779    ]])
    780    feed('<C-N><C-N><C-Y><Esc>')
    781    screen:expect([[
    782      inc uninc indent unindent                                   |
    783              indent                                              |
    784                      ind                                         |
    785              uninden^t                                            |
    786      {1:~                                                           }|*3
    787                                                                  |
    788    ]])
    789  end)
    790 
    791  it('disables folding during completion', function()
    792    command('set foldmethod=indent')
    793    feed('i<Tab>foo<CR><Tab>bar<Esc>gg')
    794    screen:expect([[
    795              ^foo                                                 |
    796              bar                                                 |
    797      {1:~                                                           }|*5
    798                                                                  |
    799    ]])
    800    feed('A<C-x><C-l>')
    801    screen:expect([[
    802              foo^                                                 |
    803              bar                                                 |
    804      {1:~                                                           }|*5
    805      {5:-- Whole line completion (^L^N^P) }{9:Pattern not found}         |
    806    ]])
    807    eq(-1, eval('foldclosed(1)'))
    808  end)
    809 
    810  it('popupmenu is not interrupted by events', function()
    811    command('set complete=.')
    812 
    813    feed('ifoobar fooegg<cr>f<c-p>')
    814    screen:expect([[
    815      foobar fooegg                                               |
    816      fooegg^                                                      |
    817      {4:foobar         }{1:                                             }|
    818      {12:fooegg         }{1:                                             }|
    819      {1:~                                                           }|*3
    820      {5:-- Keyword completion (^N^P) }{6:match 1 of 2}                   |
    821    ]])
    822 
    823    assert_alive()
    824    -- popupmenu still visible
    825    screen:expect {
    826      grid = [[
    827      foobar fooegg                                               |
    828      fooegg^                                                      |
    829      {4:foobar         }{1:                                             }|
    830      {12:fooegg         }{1:                                             }|
    831      {1:~                                                           }|*3
    832      {5:-- Keyword completion (^N^P) }{6:match 1 of 2}                   |
    833    ]],
    834      unchanged = true,
    835    }
    836 
    837    feed('<c-p>')
    838    -- Didn't restart completion: old matches still used
    839    screen:expect([[
    840      foobar fooegg                                               |
    841      foobar^                                                      |
    842      {12:foobar         }{1:                                             }|
    843      {4:fooegg         }{1:                                             }|
    844      {1:~                                                           }|*3
    845      {5:-- Keyword completion (^N^P) }{6:match 2 of 2}                   |
    846    ]])
    847  end)
    848 
    849  describe('lua completion', function()
    850    it('expands when there is only one match', function()
    851      feed(':lua CURRENT_TESTING_VAR = 1<CR>')
    852      feed(':lua CURRENT_TESTING_<TAB>')
    853      screen:expect {
    854        grid = [[
    855                                                                    |
    856        {1:~                                                           }|*6
    857        :lua CURRENT_TESTING_VAR^                                    |
    858      ]],
    859      }
    860    end)
    861 
    862    it('expands when there is only one match', function()
    863      feed(':lua CURRENT_TESTING_FOO = 1<CR>')
    864      feed(':lua CURRENT_TESTING_BAR = 1<CR>')
    865      feed(':lua CURRENT_TESTING_<TAB>')
    866      screen:expect {
    867        grid = [[
    868                                                                    |
    869        {1:~                                                           }|*5
    870        {100:CURRENT_TESTING_BAR}{3:  CURRENT_TESTING_FOO                    }|
    871        :lua CURRENT_TESTING_BAR^                                    |
    872      ]],
    873        unchanged = true,
    874      }
    875    end)
    876 
    877    it('prefix is not included in completion for cmdline mode', function()
    878      feed(':lua math.a<Tab>')
    879      screen:expect([[
    880                                                                    |
    881        {1:~                                                           }|*5
    882        {100:abs}{3:  acos  asin  atan  atan2                                }|
    883        :lua math.abs^                                               |
    884      ]])
    885      feed('<Tab>')
    886      screen:expect([[
    887                                                                    |
    888        {1:~                                                           }|*5
    889        {3:abs  }{100:acos}{3:  asin  atan  atan2                                }|
    890        :lua math.acos^                                              |
    891      ]])
    892    end)
    893 
    894    it('prefix is not included in completion for i_CTRL-X_CTRL-V #19623', function()
    895      feed('ilua math.a<C-X><C-V>')
    896      screen:expect([[
    897        lua math.abs^                                                |
    898        {1:~       }{12: abs            }{1:                                    }|
    899        {1:~       }{4: acos           }{1:                                    }|
    900        {1:~       }{4: asin           }{1:                                    }|
    901        {1:~       }{4: atan           }{1:                                    }|
    902        {1:~       }{4: atan2          }{1:                                    }|
    903        {1:~                                                           }|
    904        {5:-- Command-line completion (^V^N^P) }{6:match 1 of 5}            |
    905      ]])
    906      feed('<C-V>')
    907      screen:expect([[
    908        lua math.acos^                                               |
    909        {1:~       }{4: abs            }{1:                                    }|
    910        {1:~       }{12: acos           }{1:                                    }|
    911        {1:~       }{4: asin           }{1:                                    }|
    912        {1:~       }{4: atan           }{1:                                    }|
    913        {1:~       }{4: atan2          }{1:                                    }|
    914        {1:~                                                           }|
    915        {5:-- Command-line completion (^V^N^P) }{6:match 2 of 5}            |
    916      ]])
    917    end)
    918 
    919    it('works when cursor is in the middle of cmdline #29586', function()
    920      feed(':lua math.a(); 1<Left><Left><Left><Left><Left><Tab>')
    921      screen:expect([[
    922                                                                    |
    923        {1:~                                                           }|*5
    924        {100:abs}{3:  acos  asin  atan  atan2                                }|
    925        :lua math.abs^(); 1                                          |
    926      ]])
    927    end)
    928 
    929    it('provides completion from `getcompletion()`', function()
    930      eq({ 'vim' }, fn.getcompletion('vi', 'lua'))
    931      eq({ 'api' }, fn.getcompletion('vim.ap', 'lua'))
    932      eq({ 'tbl_filter' }, fn.getcompletion('vim.tbl_fil', 'lua'))
    933      eq({ 'vim' }, fn.getcompletion('print(vi', 'lua'))
    934      eq({ 'abs', 'acos', 'asin', 'atan', 'atan2' }, fn.getcompletion('math.a', 'lua'))
    935      eq({ 'abs', 'acos', 'asin', 'atan', 'atan2' }, fn.getcompletion('lua math.a', 'cmdline'))
    936      -- fuzzy completion is not supported, so the result should be the same
    937      command('set wildoptions+=fuzzy')
    938      eq({ 'vim' }, fn.getcompletion('vi', 'lua'))
    939    end)
    940 
    941    it('completes _defer_require() modules', function()
    942      -- vim.lsp.c<tab> -> vim.lsp.completion
    943      ok(vim.tbl_contains(fn.getcompletion('lua vim.lsp.c', 'cmdline'), 'completion'))
    944      -- vim.lsp.completion.g<tab> -> vim.lsp.completion.get
    945      ok(vim.tbl_contains(fn.getcompletion('lua vim.lsp.completion.g', 'cmdline'), 'get'))
    946    end)
    947  end)
    948 
    949  it('cmdline completion supports various string options', function()
    950    eq('auto', fn.getcompletion('set foldcolumn=', 'cmdline')[2])
    951    eq({ 'nosplit', 'split' }, fn.getcompletion('set inccommand=', 'cmdline'))
    952    eq({ 'ver:3,hor:6', 'hor:', 'ver:' }, fn.getcompletion('set mousescroll=', 'cmdline'))
    953    eq('BS', fn.getcompletion('set termpastefilter=', 'cmdline')[2])
    954    eq('SpecialKey', fn.getcompletion('set winhighlight=', 'cmdline')[1])
    955    eq('SpecialKey', fn.getcompletion('set winhighlight=NonText:', 'cmdline')[1])
    956  end)
    957 
    958  it('cmdline completion for -complete does not contain spaces', function()
    959    for _, str in ipairs(fn.getcompletion('command -complete=', 'cmdline')) do
    960      ok(not str:find(' '), 'string without spaces', str)
    961    end
    962  end)
    963 
    964  it('cmdline completion for :restart', function()
    965    eq('qall', fn.getcompletion('restart +qa', 'cmdline')[1])
    966    eq('edit', fn.getcompletion('restart +qall ed', 'cmdline')[1])
    967    eq('edit', fn.getcompletion('restart ed', 'cmdline')[1])
    968  end)
    969 
    970  describe('from the commandline window', function()
    971    it('is cleared after CTRL-C', function()
    972      feed('q:')
    973      feed('ifoo faa fee f')
    974      screen:expect([[
    975                                                                    |
    976        {2:[No Name]                                                   }|
    977        {1::}foo faa fee f^                                              |
    978        {1:~                                                           }|*3
    979        {3:[Command Line]                                              }|
    980        {5:-- INSERT --}                                                |
    981      ]])
    982      feed('<c-x><c-n>')
    983      screen:expect([[
    984                                                                    |
    985        {2:[No Name]                                                   }|
    986        {1::}foo faa fee foo^                                            |
    987        {1:~           }{12: foo            }{1:                                }|
    988        {1:~           }{4: faa            }{1:                                }|
    989        {1:~           }{4: fee            }{1:                                }|
    990        {3:[Command Line]                                              }|
    991        {5:-- Keyword Local completion (^N^P) }{6:match 1 of 3}             |
    992      ]])
    993      feed('<c-c>')
    994      screen:expect([[
    995                                                                    |
    996        {2:[No Name]                                                   }|
    997        {1::}foo faa fee foo                                            |
    998        {1:~                                                           }|*3
    999        {3:[Command Line]                                              }|
   1000        :foo faa fee foo^                                            |
   1001      ]])
   1002    end)
   1003  end)
   1004 
   1005  describe('with numeric items', function()
   1006    before_each(function()
   1007      source([[
   1008        function! TestComplete() abort
   1009          call complete(1, g:_complist)
   1010          return ''
   1011        endfunction
   1012      ]])
   1013      api.nvim_set_option_value('completeopt', 'menuone,noselect', {})
   1014      api.nvim_set_var('_complist', {
   1015        {
   1016          word = 0,
   1017          abbr = 1,
   1018          menu = 2,
   1019          kind = 3,
   1020          info = 4,
   1021          icase = 5,
   1022          dup = 6,
   1023          empty = 7,
   1024        },
   1025      })
   1026    end)
   1027 
   1028    it('shows correct variant as word', function()
   1029      feed('i<C-r>=TestComplete()<CR>')
   1030      screen:expect([[
   1031        ^                                                            |
   1032        {4:1 3 2          }{1:                                             }|
   1033        {1:~                                                           }|*5
   1034        {5:-- INSERT --}                                                |
   1035      ]])
   1036    end)
   1037  end)
   1038 
   1039  it("'ignorecase' 'infercase' CTRL-X CTRL-N #6451", function()
   1040    command('set ignorecase infercase')
   1041    command('edit runtime/doc/credits.txt')
   1042    feed('oX<C-X><C-N>')
   1043    screen:expect {
   1044      grid = [[
   1045      *credits.txt*          Nvim                                 |
   1046      Xvi^                                                         |
   1047      {12:Xvi            }{101: }                                            |
   1048      {4:Xvim           }{101: }                                            |
   1049      {4:X11            }{12: }     NVIM REFERENCE MANUAL                  |
   1050      {4:Xnull          }{12: }                                            |
   1051      {4:Xoxomoon       }{12: }                                            |
   1052      {5:-- Keyword Local completion (^N^P) }{6:match 1 of 10}            |
   1053    ]],
   1054    }
   1055  end)
   1056 
   1057  it('CompleteChanged autocommand', function()
   1058    api.nvim_buf_set_lines(0, 0, 1, false, { 'foo', 'bar', 'foobar', '' })
   1059    source([[
   1060      set complete=. completeopt=noinsert,noselect,menuone
   1061      function! OnPumChange()
   1062        let g:event = copy(v:event)
   1063        let g:item = get(v:event, 'completed_item', {})
   1064        let g:word = get(g:item, 'word', v:null)
   1065      endfunction
   1066      autocmd! CompleteChanged * :call OnPumChange()
   1067      call cursor(4, 1)
   1068    ]])
   1069 
   1070    -- v:event.size should be set with ext_popupmenu #20646
   1071    screen:set_option('ext_popupmenu', true)
   1072    feed('Sf<C-N>')
   1073    screen:expect({
   1074      grid = [[
   1075      foo                                                         |
   1076      bar                                                         |
   1077      foobar                                                      |
   1078      f^                                                           |
   1079      {1:~                                                           }|*3
   1080      {5:-- Keyword completion (^N^P) }{19:Back at original}               |
   1081    ]],
   1082      popupmenu = {
   1083        anchor = { 1, 3, 0 },
   1084        items = { { 'foo', '', '', '' }, { 'foobar', '', '', '' } },
   1085        pos = -1,
   1086      },
   1087    })
   1088    eq(
   1089      { completed_item = {}, width = 0, height = 2, size = 2, col = 0, row = 4, scrollbar = false },
   1090      eval('g:event')
   1091    )
   1092    feed('oob')
   1093    screen:expect({
   1094      grid = [[
   1095      foo                                                         |
   1096      bar                                                         |
   1097      foobar                                                      |
   1098      foob^                                                        |
   1099      {1:~                                                           }|*3
   1100      {5:-- Keyword completion (^N^P) }{19:Back at original}               |
   1101    ]],
   1102      popupmenu = {
   1103        anchor = { 1, 3, 0 },
   1104        items = { { 'foobar', '', '', '' } },
   1105        pos = -1,
   1106      },
   1107    })
   1108    eq(
   1109      { completed_item = {}, width = 0, height = 1, size = 1, col = 0, row = 4, scrollbar = false },
   1110      eval('g:event')
   1111    )
   1112    feed('<Esc>')
   1113    screen:set_option('ext_popupmenu', false)
   1114 
   1115    feed('Sf<C-N>')
   1116    screen:expect([[
   1117      foo                                                         |
   1118      bar                                                         |
   1119      foobar                                                      |
   1120      f^                                                           |
   1121      {4:foo            }{1:                                             }|
   1122      {4:foobar         }{1:                                             }|
   1123      {1:~                                                           }|
   1124      {5:-- Keyword completion (^N^P) }{19:Back at original}               |
   1125    ]])
   1126    eq(
   1127      { completed_item = {}, width = 15, height = 2, size = 2, col = 0, row = 4, scrollbar = false },
   1128      eval('g:event')
   1129    )
   1130    feed('<C-N>')
   1131    screen:expect([[
   1132      foo                                                         |
   1133      bar                                                         |
   1134      foobar                                                      |
   1135      foo^                                                         |
   1136      {12:foo            }{1:                                             }|
   1137      {4:foobar         }{1:                                             }|
   1138      {1:~                                                           }|
   1139      {5:-- Keyword completion (^N^P) }{6:match 1 of 2}                   |
   1140    ]])
   1141    eq('foo', eval('g:word'))
   1142    feed('<C-N>')
   1143    screen:expect([[
   1144      foo                                                         |
   1145      bar                                                         |
   1146      foobar                                                      |
   1147      foobar^                                                      |
   1148      {4:foo            }{1:                                             }|
   1149      {12:foobar         }{1:                                             }|
   1150      {1:~                                                           }|
   1151      {5:-- Keyword completion (^N^P) }{6:match 2 of 2}                   |
   1152    ]])
   1153    eq('foobar', eval('g:word'))
   1154    feed('<up>')
   1155    screen:expect([[
   1156      foo                                                         |
   1157      bar                                                         |
   1158      foobar                                                      |
   1159      foobar^                                                      |
   1160      {12:foo            }{1:                                             }|
   1161      {4:foobar         }{1:                                             }|
   1162      {1:~                                                           }|
   1163      {5:-- Keyword completion (^N^P) }{6:match 1 of 2}                   |
   1164    ]])
   1165    eq('foo', eval('g:word'))
   1166    feed('<down>')
   1167    screen:expect([[
   1168      foo                                                         |
   1169      bar                                                         |
   1170      foobar                                                      |
   1171      foobar^                                                      |
   1172      {4:foo            }{1:                                             }|
   1173      {12:foobar         }{1:                                             }|
   1174      {1:~                                                           }|
   1175      {5:-- Keyword completion (^N^P) }{6:match 2 of 2}                   |
   1176    ]])
   1177    eq('foobar', eval('g:word'))
   1178    feed('<esc>')
   1179  end)
   1180 
   1181  it('is stopped by :stopinsert from timer #12976', function()
   1182    screen:try_resize(32, 14)
   1183    command([[call setline(1, ['hello', 'hullo', 'heeee', ''])]])
   1184    feed('Gah<c-x><c-n>')
   1185    screen:expect([[
   1186      hello                           |
   1187      hullo                           |
   1188      heeee                           |
   1189      hello^                           |
   1190      {12:hello          }{1:                 }|
   1191      {4:hullo          }{1:                 }|
   1192      {4:heeee          }{1:                 }|
   1193      {1:~                               }|*6
   1194      {5:-- }{6:match 1 of 3}                 |
   1195    ]])
   1196    command([[call timer_start(100, { -> execute('stopinsert') })]])
   1197    vim.uv.sleep(200)
   1198    feed('k') -- cursor should move up in Normal mode
   1199    screen:expect([[
   1200      hello                           |
   1201      hullo                           |
   1202      heee^e                           |
   1203      hello                           |
   1204      {1:~                               }|*9
   1205                                      |
   1206    ]])
   1207  end)
   1208 
   1209  -- oldtest: Test_complete_changed_complete_info()
   1210  it('no crash calling complete_info() in CompleteChanged', function()
   1211    source([[
   1212      set completeopt=menuone
   1213      autocmd CompleteChanged * call complete_info(['items'])
   1214      call feedkeys("iii\<cr>\<c-p>")
   1215    ]])
   1216    screen:expect([[
   1217      ii                                                          |
   1218      ii^                                                          |
   1219      {12:ii             }{1:                                             }|
   1220      {1:~                                                           }|*4
   1221      {5:-- Keyword completion (^N^P) The only match}                 |
   1222    ]])
   1223    assert_alive()
   1224  end)
   1225 
   1226  it('no crash if text changed by first call to complete function #17489', function()
   1227    source([[
   1228      func Complete(findstart, base) abort
   1229        if a:findstart
   1230          let col = col('.')
   1231          call complete_add('#')
   1232          return col - 1
   1233        else
   1234          return []
   1235        endif
   1236      endfunc
   1237 
   1238      set completeopt=longest
   1239      set completefunc=Complete
   1240    ]])
   1241    feed('ifoo#<C-X><C-U>')
   1242    assert_alive()
   1243  end)
   1244 
   1245  it('no crash using i_CTRL-X_CTRL-V to complete non-existent colorscheme', function()
   1246    feed('icolorscheme NOSUCHCOLORSCHEME<C-X><C-V>')
   1247    expect('colorscheme NOSUCHCOLORSCHEME')
   1248    assert_alive()
   1249  end)
   1250 
   1251  it('complete with f flag #25598', function()
   1252    screen:try_resize(20, 9)
   1253    command('set complete+=f | edit foo | edit bar |edit foa |edit .hidden')
   1254    feed('i<C-n>')
   1255    screen:expect {
   1256      grid = [[
   1257      foo^                 |
   1258      {12:foo            }{1:     }|
   1259      {4:bar            }{1:     }|
   1260      {4:foa            }{1:     }|
   1261      {4:.hidden        }{1:     }|
   1262      {1:~                   }|*3
   1263      {5:-- }{6:match 1 of 4}     |
   1264    ]],
   1265    }
   1266    feed('<Esc>ccf<C-n>')
   1267    screen:expect {
   1268      grid = [[
   1269      foo^                 |
   1270      {12:foo            }{1:     }|
   1271      {4:foa            }{1:     }|
   1272      {1:~                   }|*5
   1273      {5:-- }{6:match 1 of 2}     |
   1274    ]],
   1275    }
   1276  end)
   1277 
   1278  it('restores extmarks if original text is restored #23653', function()
   1279    screen:try_resize(screen._width, 4)
   1280    command([[
   1281      call setline(1, ['aaaa'])
   1282      let ns_id = nvim_create_namespace('extmark')
   1283      let mark_id = nvim_buf_set_extmark(0, ns_id, 0, 0, { 'end_col':2, 'hl_group':'Error' })
   1284      let mark = nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })
   1285      inoremap <C-x> <C-r>=Complete()<CR>
   1286      function Complete() abort
   1287        call complete(1, [{ 'word': 'aaaaa' }])
   1288        return ''
   1289      endfunction
   1290    ]])
   1291    feed('A<C-X><C-E><Esc>')
   1292    eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
   1293    feed('A<C-N>')
   1294    eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
   1295    feed('<Esc>0Yppia<Esc>ggI<C-N>')
   1296    screen:expect([[
   1297      aaaa{9:^aa}aa                                                    |
   1298      {12:aaaa           }                                             |
   1299      {4:aaaaa          }                                             |
   1300      {5:-- Keyword completion (^N^P) }{6:match 1 of 2}                   |
   1301    ]])
   1302    feed('<C-N><C-N><Esc>')
   1303    eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
   1304    feed('A<C-N>')
   1305    eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })"))
   1306    feed('<C-N>')
   1307    screen:expect([[
   1308      aaaaa^                                                       |
   1309      {4:aaaa           }                                             |
   1310      {12:aaaaa          }                                             |
   1311      {5:-- Keyword completion (^N^P) }{6:match 2 of 2}                   |
   1312    ]])
   1313    feed('<C-E>')
   1314    screen:expect([[
   1315      {9:aa}aa^                                                        |
   1316      aaaa                                                        |
   1317      aaaaa                                                       |
   1318      {5:-- INSERT --}                                                |
   1319    ]])
   1320    -- Also when completion leader is changed #31384
   1321    feed('<Esc>hi<C-N><C-P>a')
   1322    screen:expect({
   1323      grid = [[
   1324        {9:aa}a^aa                                                       |
   1325        {4:aaaa           }                                             |
   1326        {4:aaaaa          }                                             |
   1327        {5:-- Keyword completion (^N^P) }{19:Back at original}               |
   1328      ]],
   1329    })
   1330    -- But still grows with end_right_gravity #31437
   1331    command(
   1332      "call nvim_buf_set_extmark(0, ns_id, 1, 0, { 'end_col':2, 'hl_group':'Error', 'end_right_gravity': 1 })"
   1333    )
   1334    feed('<Esc>ji<C-N>a')
   1335    screen:expect({
   1336      grid = [[
   1337        {9:aa}aaa                                                       |
   1338        {9:aaa}^aa                                                       |
   1339        aaaaa                                                       |
   1340        {5:-- INSERT --}                                                |
   1341      ]],
   1342    })
   1343  end)
   1344 
   1345  describe('nvim__complete_set', function()
   1346    it("fails when 'completeopt' does not include popup", function()
   1347      exec_lua([[
   1348        function _G.omni_test(findstart, base)
   1349          if findstart == 1 then
   1350            return vim.fn.col('.') - 1
   1351          end
   1352          return { { word = 'one' } }
   1353        end
   1354        vim.api.nvim_create_autocmd('CompleteChanged', {
   1355          callback = function()
   1356            local ok, err = pcall(vim.api.nvim__complete_set, 0, { info = '1info' })
   1357            if not ok then
   1358              vim.g.err_msg = err
   1359            end
   1360          end,
   1361        })
   1362        vim.opt.completeopt = 'menu,menuone'
   1363        vim.opt.omnifunc = 'v:lua.omni_test'
   1364      ]])
   1365      feed('S<C-X><C-O>')
   1366      eq('completeopt option does not include popup', api.nvim_get_var('err_msg'))
   1367    end)
   1368  end)
   1369 
   1370  it([[does not include buffer from non-focusable window for 'complete' "w"]], function()
   1371    local buf = api.nvim_create_buf(false, true)
   1372    local cfg = { focusable = false, relative = 'win', bufpos = { 1, 0 }, width = 1, height = 1 }
   1373    local win = api.nvim_open_win(buf, false, cfg)
   1374    api.nvim_buf_set_lines(buf, 0, -1, false, { 'foo' })
   1375    feed('i<C-N>')
   1376    screen:expect([[
   1377      ^                                                            |
   1378      {4:f}{1:                                                           }|
   1379      {1:~                                                           }|*5
   1380      {5:-- Keyword completion (^N^P) }{9:Pattern not found}              |
   1381    ]])
   1382    api.nvim_win_set_config(win, { focusable = true })
   1383    feed('<Esc>i<C-N>')
   1384    screen:expect([[
   1385      foo^                                                         |
   1386      {4:f}{1:                                                           }|
   1387      {1:~                                                           }|*5
   1388      {5:-- Keyword completion (^N^P) The only match}                 |
   1389    ]])
   1390  end)
   1391 
   1392  -- oldtest: Test_shortmess()
   1393  it('shortmess+=c turns off completion messages', function()
   1394    command('set ruler')
   1395    command([[call setline(1, ['hello', 'hullo', 'heee'])]])
   1396    feed('Goh<C-N>')
   1397    screen:expect([[
   1398      hello                                                       |
   1399      hullo                                                       |
   1400      heee                                                        |
   1401      hello^                                                       |
   1402      {12:hello          }{1:                                             }|
   1403      {4:hullo          }{1:                                             }|
   1404      {4:heee           }{1:                                             }|
   1405      {5:-- Keyword completion (^N^P) }{6:match 1 of 3}                   |
   1406    ]])
   1407    feed('<Esc>')
   1408    command('set shm+=c')
   1409    feed('Sh<C-N>')
   1410    screen:expect([[
   1411      hello                                                       |
   1412      hullo                                                       |
   1413      heee                                                        |
   1414      hello^                                                       |
   1415      {12:hello          }{1:                                             }|
   1416      {4:hullo          }{1:                                             }|
   1417      {4:heee           }{1:                                             }|
   1418      {5:-- INSERT --}                              4,6           All |
   1419    ]])
   1420  end)
   1421 
   1422  -- oldtest: Test_autocompletedelay()
   1423  it("'autocompletedelay' option", function()
   1424    screen:try_resize(60, 10)
   1425    source([[
   1426      call setline(1, ['foo', 'foobar', 'foobarbaz'])
   1427      setlocal autocomplete
   1428    ]])
   1429    screen:expect([[
   1430      ^foo                                                         |
   1431      foobar                                                      |
   1432      foobarbaz                                                   |
   1433      {1:~                                                           }|*6
   1434                                                                  |
   1435    ]])
   1436    screen.timeout = 400
   1437 
   1438    feed('Gof')
   1439    screen:expect([[
   1440      foo                                                         |
   1441      foobar                                                      |
   1442      foobarbaz                                                   |
   1443      f^                                                           |
   1444      {4:foobarbaz      }{1:                                             }|
   1445      {4:foobar         }{1:                                             }|
   1446      {4:foo            }{1:                                             }|
   1447      {1:~                                                           }|*2
   1448      {5:-- INSERT --}                                                |
   1449    ]])
   1450 
   1451    feed('<Esc>')
   1452    command('set autocompletedelay=500')
   1453    feed('Sf')
   1454    screen:expect([[
   1455      foo                                                         |
   1456      foobar                                                      |
   1457      foobarbaz                                                   |
   1458      f^                                                           |
   1459      {1:~                                                           }|*5
   1460      {5:-- INSERT --}                                                |
   1461    ]])
   1462    feed('o')
   1463    screen:expect([[
   1464      foo                                                         |
   1465      foobar                                                      |
   1466      foobarbaz                                                   |
   1467      fo^                                                          |
   1468      {1:~                                                           }|*5
   1469      {5:-- INSERT --}                                                |
   1470    ]])
   1471    vim.uv.sleep(500)
   1472    screen:expect([[
   1473      foo                                                         |
   1474      foobar                                                      |
   1475      foobarbaz                                                   |
   1476      fo^                                                          |
   1477      {4:foobarbaz      }{1:                                             }|
   1478      {4:foobar         }{1:                                             }|
   1479      {4:foo            }{1:                                             }|
   1480      {1:~                                                           }|*2
   1481      {5:-- INSERT --}                                                |
   1482    ]])
   1483    feed('<BS>')
   1484    screen:expect([[
   1485      foo                                                         |
   1486      foobar                                                      |
   1487      foobarbaz                                                   |
   1488      f^                                                           |
   1489      {1:~                                                           }|*5
   1490      {5:-- INSERT --}                                                |
   1491    ]])
   1492    vim.uv.sleep(500)
   1493    screen:expect([[
   1494      foo                                                         |
   1495      foobar                                                      |
   1496      foobarbaz                                                   |
   1497      f^                                                           |
   1498      {4:foobarbaz      }{1:                                             }|
   1499      {4:foobar         }{1:                                             }|
   1500      {4:foo            }{1:                                             }|
   1501      {1:~                                                           }|*2
   1502      {5:-- INSERT --}                                                |
   1503    ]])
   1504 
   1505    -- During delay wait, user can open menu using CTRL_N completion
   1506    feed('<Esc>')
   1507    command('set completeopt=menuone')
   1508    feed('Sf<C-N>')
   1509    screen:expect([[
   1510      foo                                                         |
   1511      foobar                                                      |
   1512      foobarbaz                                                   |
   1513      foo^                                                         |
   1514      {12:foo            }{1:                                             }|
   1515      {4:foobar         }{1:                                             }|
   1516      {4:foobarbaz      }{1:                                             }|
   1517      {1:~                                                           }|*2
   1518      {5:-- Keyword completion (^N^P) }{6:match 1 of 3}                   |
   1519    ]])
   1520 
   1521    -- After the menu is open, ^N/^P and Up/Down should not delay
   1522    feed('<Esc>')
   1523    command('set completeopt=menu')
   1524    feed('Sf')
   1525    screen:expect([[
   1526      foo                                                         |
   1527      foobar                                                      |
   1528      foobarbaz                                                   |
   1529      f^                                                           |
   1530      {1:~                                                           }|*5
   1531      {5:-- INSERT --}                                                |
   1532    ]])
   1533    vim.uv.sleep(500)
   1534    screen:expect([[
   1535      foo                                                         |
   1536      foobar                                                      |
   1537      foobarbaz                                                   |
   1538      f^                                                           |
   1539      {4:foobarbaz      }{1:                                             }|
   1540      {4:foobar         }{1:                                             }|
   1541      {4:foo            }{1:                                             }|
   1542      {1:~                                                           }|*2
   1543      {5:-- INSERT --}                                                |
   1544    ]])
   1545    feed('<C-N>')
   1546    screen:expect([[
   1547      foo                                                         |
   1548      foobar                                                      |
   1549      foobarbaz                                                   |
   1550      foobarbaz^                                                   |
   1551      {12:foobarbaz      }{1:                                             }|
   1552      {4:foobar         }{1:                                             }|
   1553      {4:foo            }{1:                                             }|
   1554      {1:~                                                           }|*2
   1555      {5:-- INSERT --}                                                |
   1556    ]])
   1557    feed('<Down>')
   1558    screen:expect([[
   1559      foo                                                         |
   1560      foobar                                                      |
   1561      foobarbaz                                                   |
   1562      foobarbaz^                                                   |
   1563      {4:foobarbaz      }{1:                                             }|
   1564      {12:foobar         }{1:                                             }|
   1565      {4:foo            }{1:                                             }|
   1566      {1:~                                                           }|*2
   1567      {5:-- INSERT --}                                                |
   1568    ]])
   1569 
   1570    -- When menu is not open Up/Down moves cursor to different line
   1571    feed('<Esc>Sf')
   1572    screen:expect([[
   1573      foo                                                         |
   1574      foobar                                                      |
   1575      foobarbaz                                                   |
   1576      f^                                                           |
   1577      {1:~                                                           }|*5
   1578      {5:-- INSERT --}                                                |
   1579    ]])
   1580    feed('<Up>')
   1581    screen:expect([[
   1582      foo                                                         |
   1583      foobar                                                      |
   1584      f^oobarbaz                                                   |
   1585      f                                                           |
   1586      {1:~                                                           }|*5
   1587      {5:-- INSERT --}                                                |
   1588    ]])
   1589    feed('<Down>')
   1590    screen:expect([[
   1591      foo                                                         |
   1592      foobar                                                      |
   1593      foobarbaz                                                   |
   1594      f^                                                           |
   1595      {1:~                                                           }|*5
   1596      {5:-- INSERT --}                                                |
   1597    ]])
   1598 
   1599    feed('<esc>')
   1600  end)
   1601 
   1602  -- oldtest: Test_fuzzy_select_item_when_acl()
   1603  it([[first item isn't selected with "fuzzy" and 'acl']], function()
   1604    screen:try_resize(60, 10)
   1605    source([[
   1606      call setline(1, ["v", "vi", "vim"])
   1607      set autocomplete completeopt=menuone,noinsert,fuzzy autocompletedelay=300
   1608    ]])
   1609 
   1610    feed('Govi')
   1611    screen:expect([[
   1612      v                                                           |
   1613      vi                                                          |
   1614      vim                                                         |
   1615      vi^                                                          |
   1616      {4:vi             }{1:                                             }|
   1617      {4:vim            }{1:                                             }|
   1618      {1:~                                                           }|*3
   1619      {5:-- INSERT --}                                                |
   1620    ]])
   1621 
   1622    feed('<Esc>Sv')
   1623    screen:expect([[
   1624      v                                                           |
   1625      vi                                                          |
   1626      vim                                                         |
   1627      v^                                                           |
   1628      {4:v              }{1:                                             }|
   1629      {4:vi             }{1:                                             }|
   1630      {4:vim            }{1:                                             }|
   1631      {1:~                                                           }|*2
   1632      {5:-- INSERT --}                                                |
   1633    ]])
   1634    feed('i')
   1635    screen:expect([[
   1636      v                                                           |
   1637      vi                                                          |
   1638      vim                                                         |
   1639      vi^                                                          |
   1640      {4:vi             }{1:                                             }|
   1641      {4:vim            }{1:                                             }|
   1642      {1:~                                                           }|*3
   1643      {5:-- INSERT --}                                                |
   1644    ]])
   1645  end)
   1646 
   1647  -- oldtest: Test_autocompletedelay_longest_preinsert()
   1648  it("'autocompletedelay' with 'completeopt' longest/preinsert", function()
   1649    source([[
   1650      call setline(1, ['autocomplete', 'autocomxxx'])
   1651      set autocomplete completeopt+=longest autocompletedelay=500
   1652    ]])
   1653    screen:expect([[
   1654      ^autocomplete                                                |
   1655      autocomxxx                                                  |
   1656      {1:~                                                           }|*5
   1657                                                                  |
   1658    ]])
   1659    screen.timeout = 400
   1660 
   1661    -- No spurious characters when autocompletedelay is in effect
   1662    feed('Goau')
   1663    screen:expect([[
   1664      autocomplete                                                |
   1665      autocomxxx                                                  |
   1666      au{102:^tocom}                                                     |
   1667      {1:~                                                           }|*4
   1668      {5:-- INSERT --}                                                |
   1669    ]])
   1670    feed('toc')
   1671    screen:expect([[
   1672      autocomplete                                                |
   1673      autocomxxx                                                  |
   1674      autoc{102:^om}                                                     |
   1675      {1:~                                                           }|*4
   1676      {5:-- INSERT --}                                                |
   1677    ]])
   1678    vim.uv.sleep(500)
   1679    screen:expect([[
   1680      autocomplete                                                |
   1681      autocomxxx                                                  |
   1682      autoc{102:^om}                                                     |
   1683      {4:autocomxxx     }{1:                                             }|
   1684      {4:autocomplete   }{1:                                             }|
   1685      {1:~                                                           }|*2
   1686      {5:-- INSERT --}                                                |
   1687    ]])
   1688 
   1689    -- Deleting a char should still show longest text
   1690    feed('<Esc>Saut')
   1691    screen:expect([[
   1692      autocomplete                                                |
   1693      autocomxxx                                                  |
   1694      aut{102:^ocom}                                                     |
   1695      {1:~                                                           }|*4
   1696      {5:-- INSERT --}                                                |
   1697    ]])
   1698    feed('<BS>')
   1699    screen:expect([[
   1700      autocomplete                                                |
   1701      autocomxxx                                                  |
   1702      au{102:^tocom}                                                     |
   1703      {1:~                                                           }|*4
   1704      {5:-- INSERT --}                                                |
   1705    ]])
   1706    vim.uv.sleep(500)
   1707    screen:expect([[
   1708      autocomplete                                                |
   1709      autocomxxx                                                  |
   1710      au{102:^tocom}                                                     |
   1711      {4:autocomxxx     }{1:                                             }|
   1712      {4:autocomplete   }{1:                                             }|
   1713      {1:~                                                           }|*2
   1714      {5:-- INSERT --}                                                |
   1715    ]])
   1716 
   1717    -- Preinsert
   1718    command('set completeopt& completeopt+=preinsert')
   1719 
   1720    -- Show preinserted text right away but display popup later
   1721    feed('<Esc>Sau')
   1722    screen:expect([[
   1723      autocomplete                                                |
   1724      autocomxxx                                                  |
   1725      au{102:^tocomplete}                                                |
   1726      {1:~                                                           }|*4
   1727      {5:-- INSERT --}                                                |
   1728    ]])
   1729    vim.uv.sleep(500)
   1730    screen:expect([[
   1731      autocomplete                                                |
   1732      autocomxxx                                                  |
   1733      au{102:^tocomplete}                                                |
   1734      {12:autocomplete   }{1:                                             }|
   1735      {4:autocomxxx     }{1:                                             }|
   1736      {1:~                                                           }|*2
   1737      {5:-- INSERT --}                                                |
   1738    ]])
   1739  end)
   1740 
   1741  -- oldtest: Test_fuzzy_filenames_compl_autocompl()
   1742  it('fuzzy file name does not crash with autocomplete', function()
   1743    feed('iset ac cot=fuzzy,longest<Esc>')
   1744    command('source')
   1745    feed('o')
   1746    poke_eventloop()
   1747    feed('.')
   1748    poke_eventloop()
   1749    feed('n')
   1750    poke_eventloop()
   1751    feed('a')
   1752    poke_eventloop()
   1753    feed('<C-X><C-F>') -- this used to cause segfault
   1754    screen:expect([[
   1755      set ac cot=fuzzy,longest                                    |
   1756      .na^                                                         |
   1757      {1:~                                                           }|*5
   1758      {5:-- File name completion (^F^N^P) }{9:Pattern not found}          |
   1759    ]])
   1760  end)
   1761 end)