Как выполнить поиск по содержимому файла (grep/ag/rg) с помощью FZF?

Как выполнить поиск по содержимому файла (grep/ag/rg) с помощью FZF?

Когда я запускаю поиск по всему проекту (по нескольким файлам) черезФЗФ, результаты переполнены строками, чьиПуть к файлусоответствует запросу, вытесняя более релевантные результаты, где файлсодержаниесовпало.

Например, запускПример Ag из вики,

ag --nobreak --nonumbers --noheading . | fzf

Я сделаю запрос searchи получу что-то вроде этого,

  plugin/keybindings.vim:cnoremap <expr> <C-Y> refract#if_incsearch("\<C-L>", "\<C-Y>")
  plugin/keybindings.vim:cmap            <C-P> <Plug>(refract_incsearch_prev)
  plugin/coherent.vim:set incsearch
  plugin/coherent.vim:setg tags+=./tags;~  " search for tags recursively upwards until ~
  plugin/search.vim:" use it for tab-completion instead depending on context of cmdline
  plugin/search.vim:  autocmd User Hint,listical_next,listical_prev Latitude
  plugin/search.vim:  autocmd User Grepper call hint#prepare_highlights()
  plugin/search.vim:let g:fzf_colors =
  plugin/search.vim:" let g:grepper =
  plugin/search.vim:\   <q-args>,
  plugin/search.vim:\   <bang>0)
  plugin/search.vim:augroup END
  plugin/search.vim:  autocmd!
  plugin/search.vim:
  plugin/search.vim:
  plugin/search.vim:
  plugin/search.vim:
> plugin/search.vim:
  41/517
> search

Что я делаю не так? Когда я запускаю аналогичный запрос Ag без FZF, я получаю только те результаты, где мой запрос встречался в содержимом файла (что мне и нужно).

решение1

Я неправильно понял взаимодействие между ag и fzf, думая, что введенный мной запрос каким-то образом прошел через ag перед передачей в fzf. Оглядываясь назад, я понимаю, что это была глупая ошибка, поскольку фильтрация — это именно то, что делает fzf, а ag используется просто как способ генерации множества осмысленных строк.

Чтобы получить то, что я хотел, я посмотрел на формат строк, которые сгенерировал ag, например

plugin/coherent.vim:set incsearch

Сообщите fzf, что его следует рассматривать :как разделитель полей и что он должен ограничить область поиска полями 2, 3, 4,...

ag --nobreak --nonumbers --noheading . | fzf --delimiter=: --nth=2..

Это приведет к сбою, если какой-либо из обработанных файлов будет содержать :в своем имени символ , но я не ожидаю, что это будет происходить слишком часто.

решение2

Для тех, кто ищет скрипт ripgrep, вот что я придумал:

FZF_EDITOR="gvim"

# Fuzzy Ripgrep Ignoring-case
frgi() {
  local result
  IFS=$'\n' result="$(rg -i --line-number "$@" | fzf --no-sort --tac --delimiter=: --nth=2..)"

  local filename
  local lineno
  local _
  if [[ -n "$result" ]]
  then
    IFS=':' read -r filename lineno _ <<< "$result"
    # Vim can accept line-number with +99
    # But if your editor cannot, then you had better remove the + argument
    verbosely "$FZF_EDITOR" +"$lineno" "$filename"
  fi
}

Связанный контент