Support ANSI escape sequence for clearing display in preview window

fzf --preview 'for i in $(seq 100000); do
    (( i % 200 == 0 )) && printf "\033[2J"
    echo "$i"
    sleep 0.01
  done'
This commit is contained in:
Junegunn Choi 2020-10-23 21:37:20 +09:00
parent e2b87e0d74
commit a4d9b0b468
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
4 changed files with 45 additions and 2 deletions

View File

@ -3,9 +3,27 @@ CHANGELOG
0.24.0 0.24.0
------ ------
- fzf can render preview window before the command completes - Real-time rendering of preview window
```sh ```sh
# fzf can render preview window before the command completes
fzf --preview 'sleep 1; for i in $(seq 100); do echo $i; sleep 0.01; done' fzf --preview 'sleep 1; for i in $(seq 100); do echo $i; sleep 0.01; done'
# Preview window can process ANSI escape sequence (CSI 2 J) for clearing the display
fzf --preview 'for i in $(seq 100000); do
(( i % 200 == 0 )) && printf "\033[2J"
echo "$i"
sleep 0.01
done'
```
- To indicate if `--multi` mode is enabled, fzf will print the number of
selected items even when no item is selected
```sh
seq 100 | fzf
# 100/100
seq 100 | fzf --multi
# 100/100 (0)
seq 100 | fzf --multi 5
# 100/100 (0/5)
``` ```
0.23.1 0.23.1

View File

@ -379,6 +379,18 @@ Note that you can escape a placeholder pattern by prepending a backslash.
Preview window will be updated even when there is no match for the current Preview window will be updated even when there is no match for the current
query if any of the placeholder expressions evaluates to a non-empty string. query if any of the placeholder expressions evaluates to a non-empty string.
Since 0.24.0, fzf can render partial preview content before the preview command
completes. ANSI escape sequence for clearing the display (\fBCSI 2 J\fR) is
supported, so you can use it to implement preview window that is constantly
updating.
e.g.
\fBfzf --preview 'for i in $(seq 100000); do
(( i % 200 == 0 )) && printf "\\033[2J"
echo "$i"
sleep 0.01
done'\fR
.RE .RE
.TP .TP
.BI "--preview-window=" "[POSITION][:SIZE[%]][:rounded|sharp|noborder][:[no]wrap][:[no]cycle][:[no]hidden][:+SCROLL[-OFFSET]][:default]" .BI "--preview-window=" "[POSITION][:SIZE[%]][:rounded|sharp|noborder][:[no]wrap][:[no]cycle][:[no]hidden][:+SCROLL[-OFFSET]][:default]"
@ -389,7 +401,6 @@ query if any of the placeholder expressions evaluates to a non-empty string.
\fBdown \fBdown
\fBleft \fBleft
\fBright \fBright
.RE
\fRDetermines the layout of the preview window. If the argument contains \fRDetermines the layout of the preview window. If the argument contains
\fB:hidden\fR, the preview window will be hidden by default until \fB:hidden\fR, the preview window will be hidden by default until

View File

@ -26,6 +26,7 @@ var numericPrefix *regexp.Regexp
var activeTempFiles []string var activeTempFiles []string
const ellipsis string = ".." const ellipsis string = ".."
const clearCode string = "\x1b[2J"
func init() { func init() {
placeholder = regexp.MustCompile(`\\?(?:{[+sf]*[0-9,-.]*}|{q}|{\+?f?nf?})`) placeholder = regexp.MustCompile(`\\?(?:{[+sf]*[0-9,-.]*}|{q}|{\+?f?nf?})`)
@ -1834,6 +1835,13 @@ func (t *Terminal) Loop() {
line := eachLine.line line := eachLine.line
err := eachLine.err err := eachLine.err
if len(line) > 0 { if len(line) > 0 {
clearIndex := strings.Index(line, clearCode)
if clearIndex >= 0 {
lines = []string{}
line = line[clearIndex+len(clearCode):]
version--
offset = 0
}
lines = append(lines, line) lines = append(lines, line)
} }
if err != nil { if err != nil {

View File

@ -1817,6 +1817,12 @@ class TestGoFZF < TestBase
assert_equal %w[A Á], `#{echoes} | #{FZF} -f A`.lines.map(&:chomp) assert_equal %w[A Á], `#{echoes} | #{FZF} -f A`.lines.map(&:chomp)
assert_equal %w[Á], `#{echoes} | #{FZF} -f Á`.lines.map(&:chomp) assert_equal %w[Á], `#{echoes} | #{FZF} -f Á`.lines.map(&:chomp)
end end
def test_preview_clear_screen
tmux.send_keys %{seq 100 | #{FZF} --preview 'for i in $(seq 300); do (( i % 200 == 0 )) && printf "\\033[2J"; echo "[$i]"; sleep 0.001; done'}, :Enter
tmux.until { |lines| lines.item_count == 100 }
tmux.until { |lines| lines[1]&.include?('[200]') }
end
end end
module TestShell module TestShell