Display header lines at the top in 'reverse-list' layout

This commit is contained in:
Junegunn Choi committed 2025-02-01 17:03:59 +09:00
1 parent e84afe196a
commit 18cbb4a84d
5 files changed
+189 -97

No files matched your search

+1
View File
@@ -70,6 +70,7 @@ CHANGELOG
fzf --style full --height 1% --min-height 3+ fzf --style full --height 1% --min-height 3+
``` ```
- Shell integration scripts were updated to use `--min-height 20+` by default - Shell integration scripts were updated to use `--min-height 20+` by default
- `--header-lines` will be displayed at the top in `reverse-list` layout
- Added `bell` action to ring the terminal bell - Added `bell` action to ring the terminal bell
```sh ```sh
# Press CTRL-Y to copy the current line to the clipboard and ring the bell # Press CTRL-Y to copy the current line to the clipboard and ring the bell
+8 -1
View File
@@ -3110,7 +3110,14 @@ func postProcessOptions(opts *Options) error {
if opts.HeaderLinesShape == tui.BorderNone { if opts.HeaderLinesShape == tui.BorderNone {
opts.HeaderLinesShape = tui.BorderPhantom opts.HeaderLinesShape = tui.BorderPhantom
} else if opts.HeaderLinesShape == tui.BorderUndefined { } else if opts.HeaderLinesShape == tui.BorderUndefined {
opts.HeaderLinesShape = tui.BorderNone // In reverse-list layout, header lines should be at the top, while
// ordinary header should be at the bottom. So let's use a separate
// window for the header lines.
if opts.Layout == layoutReverseList {
opts.HeaderLinesShape = tui.BorderPhantom
} else {
opts.HeaderLinesShape = tui.BorderNone
}
} }
if opts.Pointer == nil { if opts.Pointer == nil {
+58 -29
View File
@@ -1138,6 +1138,16 @@ func (t *Terminal) visibleHeaderLinesInList() int {
return t.visibleHeaderLines() return t.visibleHeaderLines()
} }
func (t *Terminal) visibleInputLinesInList() int {
if t.inputWindow != nil || t.inputless {
return 0
}
if t.noSeparatorLine() {
return 1
}
return 2
}
// Extra number of lines needed to display fzf // Extra number of lines needed to display fzf
func (t *Terminal) extraLines() int { func (t *Terminal) extraLines() int {
extra := 0 extra := 0
@@ -1817,7 +1827,7 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
headerLinesHeight := 0 headerLinesHeight := 0
if hasHeaderLinesWindow { if hasHeaderLinesWindow {
headerLinesHeight = util.Min(availableLines, borderLines(t.headerLinesShape)+t.headerLines) headerLinesHeight = util.Min(availableLines, borderLines(t.headerLinesShape)+t.headerLines)
if t.layout == layoutReverse { if t.layout != layoutDefault {
shift += headerLinesHeight shift += headerLinesHeight
shrink += headerLinesHeight shrink += headerLinesHeight
} else { } else {
@@ -2078,12 +2088,16 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
if hasHeaderWindow && t.headerFirst { if hasHeaderWindow && t.headerFirst {
if t.layout == layoutReverse { if t.layout == layoutReverse {
btop = w.Top() - inputBorderHeight - headerLinesHeight btop = w.Top() - inputBorderHeight - headerLinesHeight
} else if t.layout == layoutReverseList {
btop = w.Top() + w.Height()
} else { } else {
btop = w.Top() + w.Height() + headerLinesHeight btop = w.Top() + w.Height() + headerLinesHeight
} }
} else { } else {
if t.layout == layoutReverse { if t.layout == layoutReverse {
btop = w.Top() - shrink btop = w.Top() - shrink
} else if t.layout == layoutReverseList {
btop = w.Top() + w.Height() + headerBorderHeight
} else { } else {
btop = w.Top() + w.Height() + headerBorderHeight + headerLinesHeight btop = w.Top() + w.Height() + headerBorderHeight + headerLinesHeight
} }
@@ -2112,12 +2126,16 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
if hasInputWindow && t.headerFirst { if hasInputWindow && t.headerFirst {
if t.layout == layoutReverse { if t.layout == layoutReverse {
btop = w.Top() - shrink btop = w.Top() - shrink
} else if t.layout == layoutReverseList {
btop = w.Top() + w.Height() + inputBorderHeight
} else { } else {
btop = w.Top() + w.Height() + inputBorderHeight + headerLinesHeight btop = w.Top() + w.Height() + inputBorderHeight + headerLinesHeight
} }
} else { } else {
if t.layout == layoutReverse { if t.layout == layoutReverse {
btop = w.Top() - headerBorderHeight - headerLinesHeight btop = w.Top() - headerBorderHeight - headerLinesHeight
} else if t.layout == layoutReverseList {
btop = w.Top() + w.Height()
} else { } else {
btop = w.Top() + w.Height() + headerLinesHeight btop = w.Top() + w.Height() + headerLinesHeight
} }
@@ -2133,7 +2151,7 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
// Set up header lines border // Set up header lines border
if hasHeaderLinesWindow { if hasHeaderLinesWindow {
var btop int var btop int
if t.layout == layoutReverse { if t.layout != layoutDefault {
btop = w.Top() - headerLinesHeight btop = w.Top() - headerLinesHeight
} else { } else {
btop = w.Top() + w.Height() btop = w.Top() + w.Height()
@@ -2195,17 +2213,28 @@ func (t *Terminal) move(y int, x int, clear bool) {
case layoutDefault: case layoutDefault:
y = h - y - 1 y = h - y - 1
case layoutReverseList: case layoutReverseList:
n := t.visibleHeaderLinesInList() if t.window == t.inputWindow || t.window == t.headerWindow {
if !t.inputless { // From bottom to top
n++
}
if !t.noSeparatorLine() {
n++
}
if y < n {
y = h - y - 1 y = h - y - 1
} else { } else {
y -= n /*
* List 1
* List 2
* Header 1
* Header 2
* Input 2
* Input 1
*/
i := t.visibleInputLinesInList()
n := t.visibleHeaderLinesInList()
if i > 0 && y < i {
y = h - y - 1
} else if n > 0 && y < i+n {
y = h - y - 1
} else {
// Top to bottom
y -= n + i
}
} }
} }
@@ -4145,13 +4174,13 @@ func (t *Terminal) addClickHeaderWord(env []string) []string {
/* /*
* echo $'HL1\nHL2' | fzf --header-lines 3 --header $'H1\nH2' --header-lines-border --bind 'click-header:preview:env | grep FZF_CLICK' * echo $'HL1\nHL2' | fzf --header-lines 3 --header $'H1\nH2' --header-lines-border --bind 'click-header:preview:env | grep FZF_CLICK'
* *
* REVERSE DEFAULT * REVERSE DEFAULT REVERSE-LIST
* H1 1 1 * H1 1 1 HL1 1
* H2 2 HL2 2 * H2 2 HL2 2 HL2 2
* ------- HL1 3 * ------- HL1 3 3
* HL1 3 ------- * HL1 3 ------- -------
* HL2 4 H1 4 * HL2 4 H1 4 H1 4
* 5 H2 5 * 5 H2 5 H2 5
*/ */
lineNum := t.clickHeaderLine - 1 lineNum := t.clickHeaderLine - 1
if lineNum < 0 { if lineNum < 0 {
@@ -4159,20 +4188,20 @@ func (t *Terminal) addClickHeaderWord(env []string) []string {
return env return env
} }
// NOTE: t.header is padded with empty strings so that its size is equal to t.headerLines
var line string var line string
headers := [2][]string{t.header, t.header0}
if t.layout == layoutReverse { if t.layout == layoutReverse {
if lineNum < len(t.header0) { headers[0], headers[1] = headers[1], headers[0]
line = t.header0[lineNum] }
} else if lineNum-len(t.header0) < len(t.header) { if lineNum < len(headers[0]) {
line = t.header[lineNum-len(t.header0)] index := lineNum
} if t.layout == layoutDefault {
} else { index = len(headers[0]) - index - 1
// NOTE: t.header is padded with empty strings so that its size is equal to t.headerLines
if lineNum < len(t.header) {
line = t.header[len(t.header)-lineNum-1]
} else if lineNum-len(t.header) < len(t.header0) {
line = t.header0[lineNum-len(t.header)]
} }
line = headers[0][index]
} else if lineNum-len(headers[0]) < len(headers[1]) {
line = headers[1][lineNum-len(headers[0])]
} }
if len(line) == 0 { if len(line) == 0 {
return env return env
+4 -4
View File
@@ -576,9 +576,9 @@ class TestCore < TestInteractive
tmux.send_keys "seq 100 | #{fzf('--header-lines=10 -q 5 --layout=reverse-list')}", :Enter tmux.send_keys "seq 100 | #{fzf('--header-lines=10 -q 5 --layout=reverse-list')}", :Enter
2.times do 2.times do
tmux.until do |lines| tmux.until do |lines|
assert_equal '> 50', lines[0] assert_equal ' 9', lines[8]
assert_equal ' 2', lines[-4] assert_equal ' 10', lines[9]
assert_equal ' 1', lines[-3] assert_equal '> 50', lines[10]
assert_equal ' 18/90', lines[-2] assert_equal ' 18/90', lines[-2]
end end
tmux.send_keys :Up tmux.send_keys :Up
@@ -665,7 +665,7 @@ class TestCore < TestInteractive
tmux.until do |lines| tmux.until do |lines|
assert_equal ' 90/90', lines[-2] assert_equal ' 90/90', lines[-2]
assert_equal header.map { |line| " #{line}".rstrip }, lines[-7...-2] assert_equal header.map { |line| " #{line}".rstrip }, lines[-7...-2]
assert_equal (' 1'..' 10').to_a.reverse, lines[-17...-7] assert_equal (' 1'..' 10').to_a, lines.take(10)
end end
end end
+118 -63
View File
@@ -6,9 +6,9 @@ require_relative 'lib/common'
class TestLayout < TestInteractive class TestLayout < TestInteractive
def assert_block(expected, lines) def assert_block(expected, lines)
cols = expected.lines.map { it.chomp.length }.max cols = expected.lines.map { it.chomp.length }.max
top = lines.take(expected.lines.length).map { _1[0, cols].rstrip + "\n" }.join top = lines.take(expected.lines.length).map { it[0, cols].rstrip + "\n" }.join.chomp
bottom = lines.reverse.take(expected.lines.length).reverse.map { _1[0, cols].rstrip + "\n" }.join bottom = lines.reverse.take(expected.lines.length).reverse.map { it[0, cols].rstrip + "\n" }.join.chomp
assert_includes [top, bottom], expected assert_includes [top, bottom], expected.chomp
end end
def test_vanilla def test_vanilla
@@ -19,7 +19,7 @@ class TestLayout < TestInteractive
100000/100000 100000/100000
> >
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
# Testing basic key bindings # Testing basic key bindings
tmux.send_keys '99', 'C-a', '1', 'C-f', '3', 'C-b', 'C-h', 'C-u', 'C-e', 'C-y', 'C-k', 'Tab', 'BTab' tmux.send_keys '99', 'C-a', '1', 'C-f', '3', 'C-b', 'C-h', 'C-u', 'C-e', 'C-y', 'C-k', 'Tab', 'BTab'
@@ -29,7 +29,7 @@ class TestLayout < TestInteractive
856/100000 856/100000
> 391 > 391
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
tmux.send_keys :Enter tmux.send_keys :Enter
assert_equal '3910', fzf_output assert_equal '3910', fzf_output
@@ -46,7 +46,7 @@ class TestLayout < TestInteractive
1 1
foobar foobar
OUTPUT OUTPUT
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_header_first_reverse def test_header_first_reverse
@@ -59,7 +59,7 @@ class TestLayout < TestInteractive
> < 997/997 > < 997/997
> 4 > 4
OUTPUT OUTPUT
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_change_and_transform_header def test_change_and_transform_header
@@ -76,7 +76,7 @@ class TestLayout < TestInteractive
1/1 1/1
> >
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
tmux.send_keys :Space tmux.send_keys :Space
expected = <<~OUTPUT expected = <<~OUTPUT
> 3 > 3
@@ -89,7 +89,7 @@ class TestLayout < TestInteractive
1/1 1/1
> >
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
next unless i.zero? next unless i.zero?
teardown teardown
@@ -107,7 +107,7 @@ class TestLayout < TestInteractive
1/1 1/1
> >
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
tmux.send_keys :Space tmux.send_keys :Space
expected = <<~OUTPUT expected = <<~OUTPUT
> 3 > 3
@@ -120,7 +120,7 @@ class TestLayout < TestInteractive
1/1 1/1
> >
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
end end
def test_reload_and_change_cache def test_reload_and_change_cache
@@ -130,7 +130,7 @@ class TestLayout < TestInteractive
1/1 1/1
> >
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
tmux.send_keys :z tmux.send_keys :z
expected = <<~OUTPUT expected = <<~OUTPUT
> foo > foo
@@ -138,7 +138,7 @@ class TestLayout < TestInteractive
1/1 1/1
> >
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
end end
def test_toggle_header def test_toggle_header
@@ -155,7 +155,7 @@ class TestLayout < TestInteractive
│ foo │ foo
╰─────── ╰───────
OUTPUT OUTPUT
tmux.until { assert_block(before, _1) } tmux.until { assert_block(before, it) }
tmux.send_keys :Space tmux.send_keys :Space
after = <<~OUTPUT after = <<~OUTPUT
╭─────── ╭───────
@@ -169,9 +169,9 @@ class TestLayout < TestInteractive
│ > │ >
╰─────── ╰───────
OUTPUT OUTPUT
tmux.until { assert_block(after, _1) } tmux.until { assert_block(after, it) }
tmux.send_keys :Space tmux.send_keys :Space
tmux.until { assert_block(before, _1) } tmux.until { assert_block(before, it) }
end end
def test_height_range_fit def test_height_range_fit
@@ -184,7 +184,7 @@ class TestLayout < TestInteractive
│ > < 3/3 │ > < 3/3
╰────────── ╰──────────
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
end end
def test_height_range_fit_preview_above def test_height_range_fit_preview_above
@@ -203,7 +203,7 @@ class TestLayout < TestInteractive
│ > < 3/3 │ > < 3/3
╰────────── ╰──────────
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
end end
def test_height_range_fit_preview_above_alternative def test_height_range_fit_preview_above_alternative
@@ -224,7 +224,7 @@ class TestLayout < TestInteractive
│ │
└───────── └─────────
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
end end
def test_height_range_fit_preview_left def test_height_range_fit_preview_left
@@ -240,7 +240,7 @@ class TestLayout < TestInteractive
│ │ > │ │ >
│ │
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
end end
def test_height_range_overflow def test_height_range_overflow
@@ -252,7 +252,7 @@ class TestLayout < TestInteractive
│ > < 100/100 │ > < 100/100
╰────────────── ╰──────────────
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
end end
def test_no_extra_newline_issue_3209 def test_no_extra_newline_issue_3209
@@ -269,7 +269,7 @@ class TestLayout < TestInteractive
100/100 ─ 100/100 ─
> >
OUTPUT OUTPUT
tmux.until { assert_block(expected, _1) } tmux.until { assert_block(expected, it) }
end end
def test_fzf_multi_line def test_fzf_multi_line
@@ -286,7 +286,7 @@ class TestLayout < TestInteractive
│ > │ >
╰─────────── ╰───────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
tmux.send_keys :Up, :Up tmux.send_keys :Up, :Up
block = <<~BLOCK block = <<~BLOCK
╭─────── ╭───────
@@ -294,7 +294,7 @@ class TestLayout < TestInteractive
│ >┃2 │ >┃2
│ >┃3 │ >┃3
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
block = <<~BLOCK block = <<~BLOCK
│ >┃ │ >┃
@@ -302,7 +302,7 @@ class TestLayout < TestInteractive
│ > │ >
╰─── ╰───
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_fzf_multi_line_reverse def test_fzf_multi_line_reverse
@@ -318,7 +318,7 @@ class TestLayout < TestInteractive
│ ┃2 │ ┃2
│ ┃3 │ ┃3
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_fzf_multi_line_no_pointer_and_marker def test_fzf_multi_line_no_pointer_and_marker
@@ -334,7 +334,7 @@ class TestLayout < TestInteractive
│ 2 │ 2
│ 3 │ 3
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_gap def test_gap
@@ -351,7 +351,7 @@ class TestLayout < TestInteractive
│ ┈┈┈┈┈┈┈┈┈┈┈┈┈┈ │ ┈┈┈┈┈┈┈┈┈┈┈┈┈┈
│ 4 │ 4
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_gap_2 def test_gap_2
@@ -368,7 +368,7 @@ class TestLayout < TestInteractive
│ xyzxyzxyzxyzxy │ xyzxyzxyzxyzxy
│ 3 │ 3
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_list_border_and_label def test_list_border_and_label
@@ -385,7 +385,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_input_border_and_label def test_input_border_and_label
@@ -403,7 +403,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_input_border_and_label_header_first def test_input_border_and_label_header_first
@@ -421,7 +421,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_list_input_border_and_label def test_list_input_border_and_label
@@ -444,7 +444,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
tmux.send_keys :Space tmux.send_keys :Space
block = <<~BLOCK block = <<~BLOCK
│ ║ 11 │ ║ 11
@@ -460,7 +460,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_list_input_border_and_label_header_first def test_list_input_border_and_label_header_first
@@ -483,7 +483,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
tmux.send_keys :Space tmux.send_keys :Space
block = <<~BLOCK block = <<~BLOCK
│ ║ 11 │ ║ 11
@@ -499,7 +499,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_header_border_and_label def test_header_border_and_label
@@ -518,7 +518,7 @@ class TestLayout < TestInteractive
│ │
╰──────────── ╰────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_header_border_toggle def test_header_border_toggle
@@ -533,7 +533,7 @@ class TestLayout < TestInteractive
│ > │ >
╰──────────── ╰────────────
BLOCK BLOCK
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
tmux.send_keys :Space tmux.send_keys :Space
block2 = <<~BLOCK block2 = <<~BLOCK
@@ -547,10 +547,10 @@ class TestLayout < TestInteractive
100/100 ─ 100/100 ─
> >
BLOCK BLOCK
tmux.until { assert_block(block2, _1) } tmux.until { assert_block(block2, it) }
tmux.send_keys :Enter tmux.send_keys :Enter
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
end end
def test_header_border_toggle_with_header_lines def test_header_border_toggle_with_header_lines
@@ -567,7 +567,7 @@ class TestLayout < TestInteractive
98/98 ─ 98/98 ─
> >
BLOCK BLOCK
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
tmux.send_keys :Space tmux.send_keys :Space
block2 = <<~BLOCK block2 = <<~BLOCK
@@ -582,10 +582,10 @@ class TestLayout < TestInteractive
98/98 ─ 98/98 ─
> >
BLOCK BLOCK
tmux.until { assert_block(block2, _1) } tmux.until { assert_block(block2, it) }
tmux.send_keys :Enter tmux.send_keys :Enter
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
end end
def test_header_border_toggle_with_header_lines_header_first def test_header_border_toggle_with_header_lines_header_first
@@ -602,7 +602,7 @@ class TestLayout < TestInteractive
│ 1 │ 1
╰────────── ╰──────────
BLOCK BLOCK
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
tmux.send_keys :Space tmux.send_keys :Space
block2 = <<~BLOCK block2 = <<~BLOCK
@@ -617,10 +617,10 @@ class TestLayout < TestInteractive
│ hello │ hello
╰────────── ╰──────────
BLOCK BLOCK
tmux.until { assert_block(block2, _1) } tmux.until { assert_block(block2, it) }
tmux.send_keys :Enter tmux.send_keys :Enter
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
end end
def test_header_border_toggle_with_header_lines_header_lines_border def test_header_border_toggle_with_header_lines_header_lines_border
@@ -637,7 +637,7 @@ class TestLayout < TestInteractive
98/98 ─ 98/98 ─
> >
BLOCK BLOCK
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
tmux.send_keys :Space tmux.send_keys :Space
block2 = <<~BLOCK block2 = <<~BLOCK
@@ -653,10 +653,10 @@ class TestLayout < TestInteractive
98/98 ─ 98/98 ─
> >
BLOCK BLOCK
tmux.until { assert_block(block2, _1) } tmux.until { assert_block(block2, it) }
tmux.send_keys :Enter tmux.send_keys :Enter
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
end end
def test_header_border_toggle_with_header_lines_header_first_header_lines_border def test_header_border_toggle_with_header_lines_header_first_header_lines_border
@@ -673,7 +673,7 @@ class TestLayout < TestInteractive
98/98 ─ 98/98 ─
> >
BLOCK BLOCK
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
tmux.send_keys :Space tmux.send_keys :Space
block2 = <<~BLOCK block2 = <<~BLOCK
@@ -689,10 +689,10 @@ class TestLayout < TestInteractive
│ hello │ hello
╰────────── ╰──────────
BLOCK BLOCK
tmux.until { assert_block(block2, _1) } tmux.until { assert_block(block2, it) }
tmux.send_keys :Enter tmux.send_keys :Enter
tmux.until { assert_block(block1, _1) } tmux.until { assert_block(block1, it) }
end end
def test_header_border_and_label_header_first def test_header_border_and_label_header_first
@@ -711,7 +711,7 @@ class TestLayout < TestInteractive
│ │
╰──────────── ╰────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_header_border_and_label_with_list_border def test_header_border_and_label_with_list_border
@@ -731,7 +731,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_header_border_and_label_with_list_border_header_first def test_header_border_and_label_with_list_border_header_first
@@ -751,7 +751,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_all_borders def test_all_borders
@@ -773,7 +773,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_all_borders_header_first def test_all_borders_header_first
@@ -795,7 +795,7 @@ class TestLayout < TestInteractive
│ │
╰────────────── ╰──────────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_style_full_adaptive_height def test_style_full_adaptive_height
@@ -811,7 +811,7 @@ class TestLayout < TestInteractive
│ > │ >
╰──────── ╰────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_style_full_adaptive_height_double def test_style_full_adaptive_height_double
@@ -829,7 +829,7 @@ class TestLayout < TestInteractive
║ ╚════════ ║ ╚════════
╚══════════ ╚══════════
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_preview_window_noinfo def test_preview_window_noinfo
@@ -856,7 +856,7 @@ class TestLayout < TestInteractive
│ └───── │ └─────
└─────── └───────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_min_height_auto def test_min_height_auto
@@ -874,7 +874,7 @@ class TestLayout < TestInteractive
│ > │ >
└───────── └─────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_min_height_auto_no_input def test_min_height_auto_no_input
@@ -889,7 +889,7 @@ class TestLayout < TestInteractive
│ > 1 │ > 1
└───────── └─────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end end
def test_min_height_auto_no_input_reverse_list def test_min_height_auto_no_input_reverse_list
@@ -904,6 +904,61 @@ class TestLayout < TestInteractive
│ 5 │ 5
└───────── └─────────
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, it) }
end
def test_layout_reverse_list
prefix = "seq 5 | #{FZF} --layout reverse-list --no-list-border --height ~100% --border sharp "
suffixes = [
%[],
%[--header "$(seq 101 103)"],
%[--header "$(seq 101 103)" --header-first],
%[--header "$(seq 101 103)" --header-lines 3],
%[--header "$(seq 101 103)" --header-lines 3 --header-first],
%[--header "$(seq 101 103)" --header-border sharp],
%[--header "$(seq 101 103)" --header-border sharp --header-first],
%[--header "$(seq 101 103)" --header-border sharp --header-lines 3],
%[--header "$(seq 101 103)" --header-border sharp --header-lines 3 --header-lines-border sharp],
%[--header "$(seq 101 103)" --header-border sharp --header-lines 3 --header-lines-border sharp --header-first],
%[--header "$(seq 101 103)" --header-border sharp --header-lines 3 --header-lines-border sharp --header-first --input-border sharp],
%[--header "$(seq 101 103)" --header-border sharp --header-lines 3 --header-lines-border sharp --header-first --no-input],
%[--header "$(seq 101 103)" --input-border sharp],
%[--header "$(seq 101 103)" --style full:sharp],
%[--header "$(seq 101 103)" --style full:sharp --header-first],
]
output = <<~BLOCK
┌──────── ┌──────── ┌──────── ┌──────── ┌──────── ┌──────── ┌──────── ┌──────── ┌──────── ┌──────── ┌───────── ┌─────── ┌───────── ┌───────── ┌─────────
│ > 1 │ > 1 │ > 1 │ 1 │ 1 │ > 1 │ > 1 │ 1 │ ┌────── │ ┌────── │ ┌─────── │ ┌───── │ > 1 │ ┌─────── │ ┌───────
│ 2 │ 2 │ 2 │ 2 │ 2 │ 2 │ 2 │ 2 │ │ 1 │ │ 1 │ │ 1 │ │ 1 │ 2 │ │ > 1 │ │ > 1
│ 3 │ 3 │ 3 │ 3 │ 3 │ 3 │ 3 │ 3 │ │ 2 │ │ 2 │ │ 2 │ │ 2 │ 3 │ │ 2 │ │ 2
│ 4 │ 4 │ 4 │ > 4 │ > 4 │ 4 │ 4 │ > 4 │ │ 3 │ │ 3 │ │ 3 │ │ 3 │ 4 │ │ 3 │ │ 3
│ 5 │ 5 │ 5 │ 5 │ 5 │ 5 │ 5 │ 5 │ └────── │ └────── │ └─────── │ └───── │ 5 │ │ 4 │ │ 4
│ 5/5 ─ │ 101 │ 5/5 ─ │ 101 │ 2/2 ─ │ ┌────── │ 5/5 ─ │ ┌────── │ > 4 │ > 4 │ > 4 │ > 4 │ 101 │ │ 5 │ │ 5
│ > │ 102 │ > │ 102 │ > │ │ 101 │ > │ │ 101 │ 5 │ 5 │ 5 │ 5 │ 102 │ └─────── │ └───────
└──────── │ 103 │ 101 │ 103 │ 101 │ │ 102 │ ┌────── │ │ 102 │ ┌────── │ 2/2 ─ │ ┌─────── │ ┌───── │ 103 │ ┌─────── │ ┌───────
│ 5/5 ─ │ 102 │ 2/2 ─ │ 102 │ │ 103 │ │ 101 │ │ 103 │ │ 101 │ > │ │ 2/2 │ │ 101 │ ┌─────── │ │ 101 │ │ >
│ > │ 103 │ > │ 103 │ └────── │ │ 102 │ └────── │ │ 102 │ ┌────── │ │ > │ │ 102 │ │ 5/5 │ │ 102 │ └───────
└──────── └──────── └──────── └──────── │ 5/5 ─ │ │ 103 │ 2/2 ─ │ │ 103 │ │ 101 │ └─────── │ │ 103 │ │ > │ │ 103 │ ┌───────
│ > │ └────── │ > │ └────── │ │ 102 │ ┌─────── │ └───── │ └─────── │ └─────── │ │ 101
└──────── └──────── └──────── │ 2/2 ─ │ │ 103 │ │ 101 └─────── └───────── │ ┌─────── │ │ 102
│ > │ └────── │ │ 102 │ │ > │ │ 103
└──────── └──────── │ │ 103 │ └─────── │ └───────
│ └─────── └───────── └─────────
└─────────
BLOCK
expects = []
output.each_line.first.scan(/\S+/) do
offset = Regexp.last_match.offset(0)
expects << output.lines.filter_map { it[offset[0]...offset[1]]&.strip }.take_while { !it.empty? }.join("\n")
end
suffixes.zip(expects).each do |suffix, block|
tmux.send_keys(prefix + suffix, :Enter)
tmux.until { assert_block(block, it) }
teardown
setup
end
end end
end end