mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-11-29 00:06:29 +00:00
parent
27d1f5e0a8
commit
c3cc378d89
@ -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.
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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),
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user