Fzf: Print Nth field index expression when pressing <Enter>

Created on 27 Jun 2018  路  9Comments  路  Source: junegunn/fzf

  • Category

    • [x ] fzf binary

    • [ ] fzf-tmux script

    • [x] Key bindings

    • [ ] Completion

    • [ ] Vim

    • [ ] Neovim

    • [ ] Etc.

  • OS

    • [ ] Linux

    • [ ] Mac OS X

    • [ ] Windows

    • [ ] Windows Subsystem for Linux

    • [ ] Etc.

  • Shell

    • [ ] bash

    • [ ] zsh

    • [ ] fish

It would be nice if there was an option to format the output when pressing <Enter>. For example, I use ripgrep to search for files by their contents. When pressing <Enter> I would like to get the filename rather than the filename:linenumber:contents.

question

Most helpful comment

@junegunn Sure, for example:

git log --pretty=oneline --all \
    | fzf --ansi --delimiter=' ' --no-multi --preview='git show --color=always {1}' --with-nth=2.. \
    | cut --delimiter=' ' --field=1

Here as you see we're taking the git log lines like <SHA> <Subject>, using only the <Subject> for display, but taking the <SHA> as argument to git show for the preview.

The result is then also the <SHA> (which I use for a range of other commands - I call this one fzsha, and use it to wrap others that expect a SHA/ref) - but it's unfortunate IMO that we need to use cut for this, necessitating specifying the same delimiter again.

All 9 comments

We can easily post-process the output using cut or awk or whatever, and I think it's good enough.

echo 'a:b:c' | cut -d: -f1

Would you reconsider this issue @junegunn?

Your previous response is also true of --preview, we _could_ just do:

--preview='echo {} | cut -d: -f1 | cmd -'

but it's certainly nicer that we can do:

--delimiter=: --preview='cmd {1}'

(especially when it gets more complicated, such as more than one field used, or one used in multiple places.)

It just seems weird when scripting fzf --delimiter=: already for preview/nth/with-nth to have to pipe to cut --delimiter=: if the output needs to be transformed too, IMO.

@OJFord Can you give a more concrete example of what you're trying to accomplish with the new option you're proposing?

@junegunn Sure, for example:

git log --pretty=oneline --all \
    | fzf --ansi --delimiter=' ' --no-multi --preview='git show --color=always {1}' --with-nth=2.. \
    | cut --delimiter=' ' --field=1

Here as you see we're taking the git log lines like <SHA> <Subject>, using only the <Subject> for display, but taking the <SHA> as argument to git show for the preview.

The result is then also the <SHA> (which I use for a range of other commands - I call this one fzsha, and use it to wrap others that expect a SHA/ref) - but it's unfortunate IMO that we need to use cut for this, necessitating specifying the same delimiter again.

I too think this feature would be incredibly useful. fzf is a lot smarter than cut when it comes to finding field expressions. Moreover, there is no guarantee that cut will produce the same field as fzf.

It does seem incomplete that fzf supports --preview and --with-nth, but doesn't support --output.

Here's another simple case where it helps avoid some calls to awk/cut:

# fuzzy killing of processes
fkill() {
    ps -Arc -opid=,user=,pcpu=,rss=,command= | fzf --with-nth 2.. --multi --tiebreak=index --output-nth 1 | xargs kill "$@" --
}

I made a couple of proofs of concepts (not PR material) to demonstrate some possible integrations:

  1. Provide a template with --output (matches --preview semantics) (branch: experimental/output )
$ echo $'a b c d e f\nx y z' | fzf --multi --output "test {1} {3..}"
test 'x' 'z'
test 'a' 'c d e f'
  1. Provide an "nth" with --output-nth (matches --nth and --with-nth semantics) (branch experimental/output-nth)
$ echo $'a b c d e f\nx y z' | fzf --multi --output-nth "1,3.."
x z
a c d e f

Personally I'm leaning more towards option 2. It's less complex, less surprising (no quotes are added), and should cover the majority of use cases. Thoughts?

Currently these branches just redefine the opts.Printer function to modify the output. This means it ignores --print0/--no-print0 and will also attempt to format the query if --print-query is used. Definitely not a good way of doing it.

I'm up for fixing this and doing it right, but is this something that you would merge @junegunn ?

I'm a newbie in fzf but I was really surprised when I found out that fzf can transform input presentation but cannot produce already (internally) transformed output with something like --output-nth.

I'm also surprised. I ran into this today while trying to get '~' to show in the fzf cd widget. I could alter the display using the FZF_ALT_C_COMMAND and --with-nth, but I could not change the output to cd. That means the only solution is to duplicate the entire fzf cd widget function. (See: https://github.com/junegunn/fzf/issues/1430)

In general, I think another justification for including --output and --output-nth (in addition to the great examples above) is as a hook for users to modify all of the 3rd party tools and libraries that have included it, without having to modify those tools' source code.

another useCase found for this would something along the lines of

kubectl get pods -A | fzf --no-sort --header-lines=1 

Being able to directly only output e.g. the pod name (== --output-nth=2) would also spare me the hassle of having to cut this out with cut or awk - especially since fzf already knows the fields...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ahmedelgabri picture ahmedelgabri  路  3Comments

leonklingele picture leonklingele  路  3Comments

asilvadesigns picture asilvadesigns  路  3Comments

jan-warchol picture jan-warchol  路  3Comments

erusev picture erusev  路  3Comments