Search code examples
vimviml

Vim Script command-complete: pressing tab reload the list


I'm currently trying to write a script allowing to call a Vim command, which in turns calls an external command. I want to enable auto-completion with results within a list of files having a specific extension (see code below).

The completion actually circles through the list of files with the given extension, but when I start typing something and press tab, the completion is cycle is repeated from the start of the list, regardless of what's being entered (instead of actually completing the rest of the file name given in input). The code is the following:

call CreateEditCommand('EComponent', 'ComponentFiles')

function! CreateEditCommand(command, listFunction)
  silent execute 'command! -nargs=1 -complete=customlist,'. a:listFunction . ' ' . a:command . ' call EditFile(<f-args>)'
endfunction

function! ComponentFiles(A,L,P)
  return Files('component.ts')
endfunction

function! Files(extension)
  let paths = split(globpath('.', '**/*.' . a:extension), "\n")
  let idx = range(0, len(paths)-1)
  let g:global_paths = {}
  for i in idx
    let g:global_paths[fnamemodify(paths[i], ':t:r')] = paths[i]
  endfor
  call map(paths, 'fnamemodify(v:val, ":t:r")')
  return paths
endfunction

function! EditFile(file)
  execute 'edit' g:global_paths[a:file]
endfunction

For instance, if I have: app.component.ts, and test.component.ts and I type

:EComponent test

and press tab, the completed command will is the following

:EComponent app.component.ts

instead of:

:EComponent test.component.ts

Thanks in advance for your help on this.


Solution

  • ComponentFiles() is supposed to filter the list of files based on the characters before the cursor (ArgLead) but you always return the same list so that function does nothing useful.

    The custom completion function below returns only the items in ls that match the characters before the cursor:

    function! MyComp(ArgLead, CmdLine, CursorPos)
        return filter(systemlist("ls"), 'v:val =~ a:ArgLead')
    endfunction
    
    function! MyFunc(arg)
        execute "edit " . a:arg
    endfunction
    
    command! -nargs=1 -complete=customlist,MyComp MyEdit call MyFunc(<f-args>)
    

    See :help :command-completion-customlist.