diff --git a/CHANGELOG.md b/CHANGELOG.md index 337d026..d7b5a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,15 @@ CHANGELOG ``` - `$FZF_INFO` is set to the original info text - ANSI color codes are supported +- Pointer and marker signs can be set to empty strings + ```sh + # Minimal style + fzf --pointer '' --marker '' --info hidden + + # When --read0 is specified, there can be multi-line entries, + # so you need to set --marker-multi-line to an empty string + find . -print0 | fzf --read0 --pointer '' --marker-multi-line '' --info hidden + ``` - Better cache management and improved rendering for `--tail` - Improved `--sync` behavior - When `--sync` is provided, fzf will not render the interface until the initial filtering and the associated actions (bound to any of `start`, `load`, `result`, or `focus`) are complete. diff --git a/src/options.go b/src/options.go index 31f32b3..fdf5f8d 100644 --- a/src/options.go +++ b/src/options.go @@ -450,7 +450,7 @@ type Options struct { Prompt string Pointer *string Marker *string - MarkerMulti [3]string + MarkerMulti *[3]string Query string Select1 bool Exit0 bool @@ -555,6 +555,7 @@ func defaultOptions() *Options { Prompt: "> ", Pointer: nil, Marker: nil, + MarkerMulti: nil, Query: "", Select1: false, Exit0: false, @@ -1862,7 +1863,10 @@ func parseMargin(opt string, margin string) ([4]sizeSpec, error) { return [4]sizeSpec{}, errors.New("invalid " + opt + ": " + margin) } -func parseMarkerMultiLine(str string) ([3]string, error) { +func parseMarkerMultiLine(str string) (*[3]string, error) { + if str == "" { + return &[3]string{}, nil + } gr := uniseg.NewGraphemes(str) parts := []string{} totalWidth := 0 @@ -1874,7 +1878,7 @@ func parseMarkerMultiLine(str string) ([3]string, error) { result := [3]string{} if totalWidth != 3 && totalWidth != 6 { - return result, fmt.Errorf("invalid total marker width: %d (expected: 3 or 6)", totalWidth) + return &result, fmt.Errorf("invalid total marker width: %d (expected: 0, 3 or 6)", totalWidth) } expected := totalWidth / 3 @@ -1890,7 +1894,7 @@ func parseMarkerMultiLine(str string) ([3]string, error) { break } } - return result, nil + return &result, nil } func parseOptions(index *int, opts *Options, allArgs []string) error { @@ -2699,9 +2703,6 @@ func parseOptions(index *int, opts *Options, allArgs []string) error { } func validateSign(sign string, signOptName string) error { - if sign == "" { - return fmt.Errorf("%v cannot be empty", signOptName) - } if uniseg.StringWidth(sign) > 2 { return fmt.Errorf("%v display width should be up to 2", signOptName) } @@ -2768,34 +2769,45 @@ func postProcessOptions(opts *Options) error { opts.Pointer = &defaultPointer } + multiLine := opts.MultiLine && opts.ReadZero markerLen := 1 if opts.Marker == nil { - // "▎" looks better, but not all terminals render it correctly - defaultMarker := "┃" - if !opts.Unicode { - defaultMarker = ">" + if multiLine && opts.MarkerMulti != nil && opts.MarkerMulti[0] == "" { + empty := "" + opts.Marker = &empty + markerLen = 0 + } else { + // "▎" looks better, but not all terminals render it correctly + defaultMarker := "┃" + if !opts.Unicode { + defaultMarker = ">" + } + opts.Marker = &defaultMarker } - opts.Marker = &defaultMarker } else { markerLen = uniseg.StringWidth(*opts.Marker) } markerMultiLen := 1 - if len(opts.MarkerMulti[0]) == 0 { - if opts.Unicode { - opts.MarkerMulti = [3]string{"╻", "┃", "╹"} + if opts.MarkerMulti == nil { + if !multiLine && *opts.Marker == "" { + opts.MarkerMulti = &[3]string{} + markerMultiLen = 0 + } else if opts.Unicode { + opts.MarkerMulti = &[3]string{"╻", "┃", "╹"} } else { - opts.MarkerMulti = [3]string{".", "|", "'"} + opts.MarkerMulti = &[3]string{".", "|", "'"} } } else { markerMultiLen = uniseg.StringWidth(opts.MarkerMulti[0]) } - if markerMultiLen > markerLen { - padded := *opts.Marker + " " + diff := markerMultiLen - markerLen + if diff > 0 { + padded := *opts.Marker + strings.Repeat(" ", diff) opts.Marker = &padded - } else if markerMultiLen < markerLen { + } else if diff < 0 { for idx := range opts.MarkerMulti { - opts.MarkerMulti[idx] += " " + opts.MarkerMulti[idx] += strings.Repeat(" ", -diff) } } diff --git a/src/terminal.go b/src/terminal.go index 480fb31..f131f1d 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -771,7 +771,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor pointerLen: uniseg.StringWidth(*opts.Pointer), marker: *opts.Marker, markerLen: uniseg.StringWidth(*opts.Marker), - markerMultiLine: opts.MarkerMulti, + markerMultiLine: *opts.MarkerMulti, wordRubout: wordRubout, wordNext: wordNext, cx: len(input), diff --git a/test/test_go.rb b/test/test_go.rb index 42d526a..fdef78f 100755 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -3340,6 +3340,22 @@ class TestGoFZF < TestBase BLOCK tmux.until { assert_block(block, _1) } end + + def test_fzf_multi_line_no_pointer_and_marker + tmux.send_keys %[(echo -en '0\\0'; echo -en '1\\n2\\0'; seq 1000) | fzf --read0 --multi --bind load:select-all --border rounded --reverse --pointer '' --marker '' --marker-multi-line ''], :Enter + block = <<~BLOCK + ╭─────────── + │ > + │ 3/3 (3) + │ 0 + │ 1 + │ 2 + │ 1 + │ 2 + │ 3 + BLOCK + tmux.until { assert_block(block, _1) } + end end module TestShell