I have the following function that runs eslint project wise:

function! EslintProject()
  " Allows using eslint --format compact output with quickfix list
  set errorformat+=%f:\ line\ %l\\,\ col\ %c\\,\ %trror\ -\ '%*[^']'\ %m
  set errorformat+=%f:\ line\ %l\\,\ col\ %c\\,\ %tarning\ -\ '%*[^']'\ %m
  " Is lines which don't match the format
  set errorformat+=%-G%.%#

  if executable('yarn')
    !yarn run --silent eslint . --ext .js,.jsx,.ts,.tsx,.vue --no-color -f compact
  elseif executable('npm')
    !npm run --silent eslint . --ext .js,.jsx,.ts,.tsx,.vue --no-color -f compact
    echoerr 'No ESLint found'

  " Restore values
  set errorformat-=%f:\ line\ %l\\,\ col\ %c\\,\ %trror\ -\ '%*[^']'\ %m
  set errorformat-=%f:\ line\ %l\\,\ col\ %c\\,\ %tarning\ -\ '%*[^']'\ %m
  set errorformat-=%-G%.%#

I'm trying to define a command for that:

command! -bar EslintProject call EslintProject() | cexpr | cw | redraw!

However, the quickfix list is not populated.

Is there a way of populating the quickfix list from a function call which executes external commands?


Try this:

com -bar EslintProject call EslintProject()

fu EslintProject() abort
  if executable('yarn')
    let cmd = 'yarn run --silent eslint . --ext .js,.jsx,.ts,.tsx,.vue --no-color -f compact'
  elseif executable('npm')
    let cmd = 'npm run --silent eslint . --ext .js,.jsx,.ts,.tsx,.vue --no-color -f compact'
    echoerr 'No ESLint found'

  let efm = &efm
  let efm ..= ',%f: line %l\, col %c\, %trror - ''%*[^'']'' %m'
  let efm ..= ',%f: line %l\, col %c\, %tarning - ''%*[^'']'' %m'
  let efm ..= ',%-G%.%#'

  sil let qfl = getqflist({'lines': systemlist(cmd), 'efm': efm})
  call setqflist(get(qfl, 'items', []))

If the error format doesn't work as expected, visit this site to build a better one.

You can get a quickfix list resulting from the parsing of the output of an arbitrary shell command, with an arbitrary error format, with this expression:

getqflist({'lines': systemlist('my shell command'), 'efm': 'my error format'})

As an example, this snippet should populate a valid quickfix list with all the files in /etc whose name end with .conf:

let qfl = getqflist({'lines': systemlist('find /etc/ -name "*.conf"'), 'efm': '%f'})
call setqflist(get(qfl, 'items', []))

For more info, see:

:h getqflist()
:h setqflist()
:h getqflist-examples
  • Awesome! Thanks a lot @user938271... Works if I set let efm = '%f: line %l\, col %c\, %trror - ''%*[^'']'' %m' instead of appending the pattern. If I copy and paste exacltly as your example, it complains about having too many %f arguments. I guess that's because my efm is not empty. Apr 30 '20 at 1:29
  • I think that's because I forgot a comma; I updated the code.
    – user938271
    Apr 30 '20 at 1:36
  • Yeah, but since this efm is only used inside the function and the function only uses eslint format, I see no reason to mix it with the global efm. But it works as well... Thank you very much. I've been a Vimer for almost 8 years and only now I'm trying to dive into vimscript. It's harder than I though :'D Apr 30 '20 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.