Closed digitalsignalperson closed 2 years ago
This should work.
fzf --preview='fzf -f {q} < /dev/tty'
Or something like this
ls | fzf --preview='ls | fzf -f {q}'
Explanation:
With --preview
, you're starting an fzf process in a non-interactive environment where the standard input of it is not attached to a TTY device (i.e. keyboard input). When the standard input is a TTY device, fzf will use the default find command (or $FZF_DEFAULT_COMMAND
) to populate the list of candidates. This is to allow fzf without explicit input.
# STDIN is not a TTY device, so fzf just reads the output of `find .`
find . | fzf
# It can be tedious to always have to write `find . |` before fzf, so let's provide a shortcut.
# In this case, STDIN is a TTY device, which means fzf is probably not attached to an input process,
# so instead of reading STDIN, fzf starts a child process to populate the input list
export FZF_DEFAULT_COMMAND='find .'
fzf
Ah thank you for the explanation! I'll share some of my results below in case it benefits anyone else.
Here's one way to see the concatenated results:
fzf --preview='tail -n +1 (fzf -f {q} < /dev/tty)'
I tried piping that into less with a pattern option to jump to current line, but realize it's not interactive to use that way. E.g.
fzf --preview='tail -n +1 (fzf -f {q} < /dev/tty) | less --pattern={}'
Ideally I could scroll to a specific point in the preview based on the current line, and it almost seems possible with --preview-window
scroll option, but still scratching my head on that one. I don't know how to get the line number it would need.
This is a stopgap solution that approximately does it:
ls | fzf --reverse --no-sort --preview='tail -n +1 (fzf -f {q} < /dev/tty | sort | grep -A5000 \'\b{}\b\')'
What it's doing
--reverse
to show the candidates in the same order, top to bottom, with the one at the top initially selectedExample of running the full command:
> ╭───────────────────────────────────╮
4/4 │ ==> hey.txt <== 1/59 │
> hey.txt │ hey │
hi.txt │ │
large_hey.txt │ ==> hi.txt <== │
yo.txt │ hi │
│ │
│ ==> large_hey.txt <== │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
╰───────────────────────────────────╯
press down arrow to "scroll down" in the concatenated document (see lines reduce from 59 to 56 and we've "scrolled" down to "hi.txt". Can further use mouse to scroll down in right panel, but obviously can't scroll up to see "hey.txt" contents again. For that press up arrow.
> ╭───────────────────────────────────╮
4/4 │ ==> hi.txt <== 1/56 │
hey.txt │ hi │
> hi.txt │ │
large_hey.txt │ ==> large_hey.txt <== │
yo.txt │ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
│ hey │
╰───────────────────────────────────╯
above example after scrolled down with mouse wheel
> ╭───────────────────────────────────╮
4/4 │ hey 48/56 │
hey.txt │ hey │
> hi.txt │ hey │
large_hey.txt │ hey │
yo.txt │ hey │
│ │
│ │
│ ==> yo.txt <== │
│ yo │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────────╯
My use case or at least idea for this is for a sort of zettelkasten system. Imagining
--multi --bind "enter:select-all+accept"
can further take this discovered note sequence for a viewable report, or for refactoring the set of notes into a cleaner summary
man fzf
)Info
Problem / Steps to reproduce
Problem
I'm trying to achieve seeing a preview of the items currently matching the query all concatenated together:
fzf --preview='head (fzf -f "{q}")'
or even better
--preview='head (fzf -f "{q}") | less -p{}'
to jump to the section of the current line in the pagerBut using
fzf -f "{q}"
doesn't work when called from the preview function.Steps to reproduce:
First create some files in an empty folder
The output of
fzf -f h
is as expected:The output of
head (fzf -f h)
is as expected:And that is what I expected to see in the preview window after I type "h" as my query with the command
fzf --preview='head (fzf -f "{q}")'
. But the preview window is empty.If I do
fzf --preview='fzf -f "{q}"'
, the preview is empty regardless of the query. If I dofzf --preview='echo "{q}" && fzf -f "{q}"'
I can indeed see the query in the panel, so puzzled why no result from fzf.If I create a preview.sh to try and debug this, I can see it is working in the current directory, but the
fzf -f
output always returns 1 (no result) even if I hard code a query.Tried both bash and fish. Also tried wrapping the preview's fzf call in like
env -i bash -l -c 'fzf -f {q}'
in case some funky environment thing is happening, but no luck.Further discussion
For the available substitutions for preview, there is no "list of currently filtered items". The closest thing is the list of selected items
{+}
. Theoretically I can get the "list of currently filtered items" viafzf -f {q}
or feeding the query to fzf in script mode.My use case would also probably also include
--multi --bind "enter:select-all+accept"
since my goal is to output the list of files matching the query after I'm satisfied with the preview.While I could also do
--preview='head {+}'
, I'd have to select all first, maybe with some keybinding like ctrl+a, but it breaks the real-time flow of seeing the concatenated view change as I change the query. I also noticed if I did ctrl+a then modified the query the original items are still selected. I'd rather just use the current matches to the query, like if a{q}
option existed.