FZF を使用してファイル *contents* (grep/ag/rg) を検索するにはどうすればよいでしょうか?

FZF を使用してファイル *contents* (grep/ag/rg) を検索するにはどうすればよいでしょうか?

プロジェクト全体(複数ファイル)の検索を実行すると、FZF結果には、ファイルパスクエリに一致し、ファイルが含まれている関連性の高い結果を除外します。コンテンツ一致しました。

たとえば、ウィキからの農業の例

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

何が間違っているのでしょうか? FZF を使用せずに同様の Ag クエリを実行すると、ファイルの内容でクエリが発生した結果のみが返されます (これが必要な結果です)。

答え1

私は ag と fzf の相互作用を誤解しており、入力したクエリが fzf にパイプされる前に何らかの形で ag を通過すると考えていました。振り返ってみると、これは愚かな間違いでした。フィルタリングはまさに 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
}

関連情報