4

The plugin fzf.vim defines the following vim command here:

command!      -bang -nargs=* Ag   call fzf#vim#ag(<q-args>, <bang>0)'

the fzt#vim#ag function seems to allow passing all the ag options to the ag shell command. There is also a comment regarding this

" query, [[ag options], options]
function! fzf#vim#ag(query, ...)

However, no matter how I call it everything is passed as the first parameter query. I've added bunch of logs to the script

For example, calling

:Ag SearchString -c app

and adding following logs to the above function

" query, [[ag options], options]
function! fzf#vim#ag(query, ...)
  if type(a:query) != s:TYPE.string
    return s:warn('Invalid query argument')
  endif
  let query = empty(a:query) ? '^(?=.)' : a:query
  let args = copy(a:000)
  let ag_opts = len(args) > 1 && type(args[0]) == s:TYPE.string ? remove(args, 0) : ''
  let command = ag_opts . ' ' . fzf#shellescape(query)
  echo query
  echo ag_opts
  echo command
  return call('fzf#vim#ag_raw', insert(args, command, 0))
endfunction

would print

SearchString -c app
 'SearchString -c app'

meaning ag_opts was empty

So how to pass the other args as a query to this command?

1 Answer 1

5

TL;DR: You can't pass ag options into that command. (But jump to the bottom for a different one.)

Note the distinction between the :Ag command and the fzf#vim#ag function.

The :Ag command calls the fzf#vim#ag function passing it exactly two arguments:

  1. <q-args>: This is all the arguments that were passed to the command, passed as a single argument. (See :h <q-args>.)
  2. <bang>0: <bang> evaluates to ! if you typed an exclamation point after your command :Ag! and nothing if you didn't. (See :help <bang>.) So if you didn't type an exclamation point then 0 is passed as the second argument. And if you did, then !0 is passed, i.e. the negation of 0, i.e. 1. (Try typing :echo !0 into Vim.)

The function takes fzf#vim#ag is defined with the signature:

function! fzf#vim#ag(query, ...)

Which means that inside the function:

  • The variable a:query will contain the first argument to the function i.e. all the arguments that were passed to the command.

  • The variable a:000 will either be the list [0] or the list [1], depending on whether or not you used an exclamation point after the :Ag command.

Inside the function ag_opts is set with the lines:

let args = copy(a:000)
let ag_opts = len(args) > 1 && type(args[0]) == s:TYPE.string ? remove(args, 0) : ''

The first line just makes a copy of the list: a:000.

The second line then checks if the length of the list is greater than one. When called from the :Ag command it never is, so ag_opts is therefore always set to the empty string: ''.

Therefore, if you want to pass options to the ag executable, you cannot do it with the command you described in your question: I don't know whether the fzf plugin currently offers different commands, or whether you will need to write your own, like this one by the author of fzf:

function! s:ag_with_opts(arg, bang)
  let tokens  = split(a:arg)
  let ag_opts = join(filter(copy(tokens), 'v:val =~ "^-"'))
  let query   = join(filter(copy(tokens), 'v:val !~ "^-"'))
  call fzf#vim#ag(query, ag_opts, a:bang ? {} : {'down': '40%'})
endfunction

autocmd VimEnter * command! -nargs=* -bang Ag call s:ag_with_opts(<q-args>, <bang>0)
5
  • that should be pull request to fzf vim. awesome. just figured out what <q-args> really does and wanted to close this
    – dre-hh
    Nov 18, 2017 at 16:53
  • @dre-hh There's not really any reason I can see to close this question. Feel free to accept my answer if you feel that it has answered your question, though!
    – Rich
    Nov 20, 2017 at 13:49
  • 1
    fzf recently changed how it defined the :Ag command, it now does this: command! -bang -nargs=* Ag call fzf#vim#ag(<q-args>, s:p(<bang>0), <bang>0) It calls the function s:p() to optionally add arguments to show the preview window. anyone using a wrapper around fzf#vim#ag will not get preview windows unless they adapt their wrapper Mar 18, 2020 at 10:33
  • 1
    @PatrickZiegler Thanks for the tipoff. I'll try to incorporate the information in my answer when I get a chance (or you're welcome to make an edit).
    – Rich
    Mar 18, 2020 at 11:58
  • @Rich Unfortunately I haven't found a satisfying solution to this. Currently I just copied fzf's s:p() function verbatim Mar 18, 2020 at 13:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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