Allow empty pointer and marker

Close #3879
This commit is contained in:
Junegunn Choi 2024-06-20 01:45:06 +09:00
parent 27d1f5e0a8
commit c3cc378d89
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
4 changed files with 58 additions and 21 deletions

View File

@ -10,6 +10,15 @@ CHANGELOG
``` ```
- `$FZF_INFO` is set to the original info text - `$FZF_INFO` is set to the original info text
- ANSI color codes are supported - 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` - Better cache management and improved rendering for `--tail`
- Improved `--sync` behavior - 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. - 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.

View File

@ -450,7 +450,7 @@ type Options struct {
Prompt string Prompt string
Pointer *string Pointer *string
Marker *string Marker *string
MarkerMulti [3]string MarkerMulti *[3]string
Query string Query string
Select1 bool Select1 bool
Exit0 bool Exit0 bool
@ -555,6 +555,7 @@ func defaultOptions() *Options {
Prompt: "> ", Prompt: "> ",
Pointer: nil, Pointer: nil,
Marker: nil, Marker: nil,
MarkerMulti: nil,
Query: "", Query: "",
Select1: false, Select1: false,
Exit0: false, Exit0: false,
@ -1862,7 +1863,10 @@ func parseMargin(opt string, margin string) ([4]sizeSpec, error) {
return [4]sizeSpec{}, errors.New("invalid " + opt + ": " + margin) 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) gr := uniseg.NewGraphemes(str)
parts := []string{} parts := []string{}
totalWidth := 0 totalWidth := 0
@ -1874,7 +1878,7 @@ func parseMarkerMultiLine(str string) ([3]string, error) {
result := [3]string{} result := [3]string{}
if totalWidth != 3 && totalWidth != 6 { 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 expected := totalWidth / 3
@ -1890,7 +1894,7 @@ func parseMarkerMultiLine(str string) ([3]string, error) {
break break
} }
} }
return result, nil return &result, nil
} }
func parseOptions(index *int, opts *Options, allArgs []string) error { 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 { func validateSign(sign string, signOptName string) error {
if sign == "" {
return fmt.Errorf("%v cannot be empty", signOptName)
}
if uniseg.StringWidth(sign) > 2 { if uniseg.StringWidth(sign) > 2 {
return fmt.Errorf("%v display width should be up to 2", signOptName) return fmt.Errorf("%v display width should be up to 2", signOptName)
} }
@ -2768,34 +2769,45 @@ func postProcessOptions(opts *Options) error {
opts.Pointer = &defaultPointer opts.Pointer = &defaultPointer
} }
multiLine := opts.MultiLine && opts.ReadZero
markerLen := 1 markerLen := 1
if opts.Marker == nil { if opts.Marker == nil {
if multiLine && opts.MarkerMulti != nil && opts.MarkerMulti[0] == "" {
empty := ""
opts.Marker = &empty
markerLen = 0
} else {
// "▎" looks better, but not all terminals render it correctly // "▎" looks better, but not all terminals render it correctly
defaultMarker := "┃" defaultMarker := "┃"
if !opts.Unicode { if !opts.Unicode {
defaultMarker = ">" defaultMarker = ">"
} }
opts.Marker = &defaultMarker opts.Marker = &defaultMarker
}
} else { } else {
markerLen = uniseg.StringWidth(*opts.Marker) markerLen = uniseg.StringWidth(*opts.Marker)
} }
markerMultiLen := 1 markerMultiLen := 1
if len(opts.MarkerMulti[0]) == 0 { if opts.MarkerMulti == nil {
if opts.Unicode { if !multiLine && *opts.Marker == "" {
opts.MarkerMulti = [3]string{"╻", "┃", "╹"} opts.MarkerMulti = &[3]string{}
markerMultiLen = 0
} else if opts.Unicode {
opts.MarkerMulti = &[3]string{"╻", "┃", "╹"}
} else { } else {
opts.MarkerMulti = [3]string{".", "|", "'"} opts.MarkerMulti = &[3]string{".", "|", "'"}
} }
} else { } else {
markerMultiLen = uniseg.StringWidth(opts.MarkerMulti[0]) markerMultiLen = uniseg.StringWidth(opts.MarkerMulti[0])
} }
if markerMultiLen > markerLen { diff := markerMultiLen - markerLen
padded := *opts.Marker + " " if diff > 0 {
padded := *opts.Marker + strings.Repeat(" ", diff)
opts.Marker = &padded opts.Marker = &padded
} else if markerMultiLen < markerLen { } else if diff < 0 {
for idx := range opts.MarkerMulti { for idx := range opts.MarkerMulti {
opts.MarkerMulti[idx] += " " opts.MarkerMulti[idx] += strings.Repeat(" ", -diff)
} }
} }

View File

@ -771,7 +771,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
pointerLen: uniseg.StringWidth(*opts.Pointer), pointerLen: uniseg.StringWidth(*opts.Pointer),
marker: *opts.Marker, marker: *opts.Marker,
markerLen: uniseg.StringWidth(*opts.Marker), markerLen: uniseg.StringWidth(*opts.Marker),
markerMultiLine: opts.MarkerMulti, markerMultiLine: *opts.MarkerMulti,
wordRubout: wordRubout, wordRubout: wordRubout,
wordNext: wordNext, wordNext: wordNext,
cx: len(input), cx: len(input),

View File

@ -3340,6 +3340,22 @@ class TestGoFZF < TestBase
BLOCK BLOCK
tmux.until { assert_block(block, _1) } tmux.until { assert_block(block, _1) }
end 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 end
module TestShell module TestShell