summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2024-04-04 00:05:55 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2024-04-04 00:05:55 +0900
commit8a2df7971186884b3115db68b751622f1f683481 (patch)
tree9569fdc9ea893456670cec705c3593bf60db87d8
parentc30e486b648c1540a660802a5015aeca208274fa (diff)
Do not hide separator by default on --info=inline-right|hidden
-rw-r--r--CHANGELOG.md14
-rw-r--r--man/man1/fzf.115
-rw-r--r--src/options.go33
-rw-r--r--src/terminal.go122
-rwxr-xr-xtest/test_go.rb2
5 files changed, 113 insertions, 73 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a91d7b04..70d89357 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,10 +3,14 @@ CHANGELOG
0.49.0
------
-- Performance improvements
- - Ingestion performance improved by 40%
- - `--ansi` performance improved by 50%
- - `--with-nth` performance improved by 30%
+- Ingestion performance improved by around 40% (more or less depending on options)
+- `--info=hidden` and `--info=inline-right` will no longer hide the horizontal separator by default. This gives you more flexibility in customizing the layout.
+ ```sh
+ fzf --border --info=inline-right
+ fzf --border --info=inline-right --no-separator
+ fzf --border --info=hidden
+ fzf --border --info=hidden --no-separator
+ ```
- Added two environment variables exported to the child processes
- `FZF_PREVIEW_LABEL`
- `FZF_BORDER_LABEL`
@@ -22,7 +26,7 @@ CHANGELOG
- `track` is still available as an alias
- Added `untrack-current` and `toggle-track-current` actions
- `*-current` actions are no-op when the global tracking state is set
-- Bug fixes
+- Bug fixes and minor improvements
0.48.1
------
diff --git a/man/man1/fzf.1 b/man/man1/fzf.1
index 3f8619ab..6d682ef4 100644
--- a/man/man1/fzf.1
+++ b/man/man1/fzf.1
@@ -372,20 +372,21 @@ e.g.
.TP
.BI "--info=" "STYLE"
-Determines the display style of finder info (match counters).
+Determines the display style of the finder info. (e.g. match counter, loading indicator, etc.)
+.BR default " On the left end of the horizontal separator"
.br
-.BR default " Display on the next line to the prompt"
+.BR right " On the right end of the horizontal separator"
.br
-.BR right " Display on the right end of the next line to the prompt"
+.BR hidden " Do not display finder info"
.br
-.BR inline " Display on the same line with the default separator ' < '"
+.BR inline " After the prompt with the default prefix ' < '"
.br
-.BR inline:SEPARATOR " Display on the same line with a non-default separator"
+.BR inline:PREFIX " After the prompt with a non-default prefix"
.br
-.BR inline-right " Display on the right end of the same line
+.BR inline-right " On the right end of the prompt line"
.br
-.BR hidden " Do not display finder info"
+.BR inline-right:PREFIX " On the right end of the prompt line with a custom prefix"
.br
.TP
diff --git a/src/options.go b/src/options.go
index a28e9e6f..5c73aee7 100644
--- a/src/options.go
+++ b/src/options.go
@@ -75,7 +75,7 @@ const usage = `usage: fzf [options]
--margin=MARGIN Screen margin (TRBL | TB,RL | T,RL,B | T,R,B,L)
--padding=PADDING Padding inside border (TRBL | TB,RL | T,RL,B | T,R,B,L)
--info=STYLE Finder info style
- [default|right|hidden|inline[:SEPARATOR]|inline-right]
+ [default|right|hidden|inline[-right][:PREFIX]]
--separator=STR String to form horizontal separator on info line
--no-separator Hide info line separator
--scrollbar[=C1[C2]] Scrollbar character(s) (each for main and preview window)
@@ -143,7 +143,7 @@ const usage = `usage: fzf [options]
`
-const defaultInfoSep = " < "
+const defaultInfoPrefix = " < "
// Case denotes case-sensitivity of search
type Case int
@@ -217,10 +217,6 @@ const (
infoHidden
)
-func (s infoStyle) noExtraLine() bool {
- return s == infoInline || s == infoInlineRight || s == infoHidden
-}
-
type labelOpts struct {
label string
column int
@@ -327,7 +323,7 @@ type Options struct {
ScrollOff int
FileWord bool
InfoStyle infoStyle
- InfoSep string
+ InfoPrefix string
Separator *string
JumpLabels string
Prompt string
@@ -1506,17 +1502,24 @@ func parseInfoStyle(str string) (infoStyle, string) {
case "right":
return infoRight, ""
case "inline":
- return infoInline, defaultInfoSep
+ return infoInline, defaultInfoPrefix
case "inline-right":
return infoInlineRight, ""
case "hidden":
return infoHidden, ""
default:
- prefix := "inline:"
- if strings.HasPrefix(str, prefix) {
- return infoInline, strings.ReplaceAll(str[len(prefix):], "\n", " ")
+ type infoSpec struct {
+ name string
+ style infoStyle
+ }
+ for _, spec := range []infoSpec{
+ {"inline", infoInline},
+ {"inline-right", infoInlineRight}} {
+ if strings.HasPrefix(str, spec.name+":") {
+ return spec.style, strings.ReplaceAll(str[len(spec.name)+1:], "\n", " ")
+ }
}
- errorExit("invalid info style (expected: default|right|hidden|inline[:SEPARATOR]|inline-right)")
+ errorExit("invalid info style (expected: default|right|hidden|inline[-right][:PREFIX])")
}
return infoDefault, ""
}
@@ -1807,13 +1810,13 @@ func parseOptions(opts *Options, allArgs []string) {
case "--no-filepath-word":
opts.FileWord = false
case "--info":
- opts.InfoStyle, opts.InfoSep = parseInfoStyle(
+ opts.InfoStyle, opts.InfoPrefix = parseInfoStyle(
nextString(allArgs, &i, "info style required"))
case "--no-info":
opts.InfoStyle = infoHidden
case "--inline-info":
opts.InfoStyle = infoInline
- opts.InfoSep = defaultInfoSep
+ opts.InfoPrefix = defaultInfoPrefix
case "--no-inline-info":
opts.InfoStyle = infoDefault
case "--separator":
@@ -2015,7 +2018,7 @@ func parseOptions(opts *Options, allArgs []string) {
} else if match, value := optString(arg, "--layout="); match {
opts.Layout = parseLayout(value)
} else if match, value := optString(arg, "--info="); match {
- opts.InfoStyle, opts.InfoSep = parseInfoStyle(value)
+ opts.InfoStyle, opts.InfoPrefix = parseInfoStyle(value)
} else if match, value := optString(arg, "--separator="); match {
opts.Separator = &value
} else if match, value := optString(arg, "--scrollbar="); match {
diff --git a/src/terminal.go b/src/terminal.go
index ef7ba9dd..2289a7f9 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -181,7 +181,7 @@ type Status struct {
type Terminal struct {
initDelay time.Duration
infoStyle infoStyle
- infoSep string
+ infoPrefix string
separator labelPrinter
separatorLen int
spinner []string
@@ -677,7 +677,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
if previewBox != nil && opts.Preview.aboveOrBelow() {
effectiveMinHeight += 1 + borderLines(opts.Preview.border)
}
- if opts.InfoStyle.noExtraLine() {
+ if noSeparatorLine(opts.InfoStyle, opts.Separator == nil || uniseg.StringWidth(*opts.Separator) > 0) {
effectiveMinHeight--
}
effectiveMinHeight += borderLines(opts.BorderShape)
@@ -699,7 +699,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
t := Terminal{
initDelay: delay,
infoStyle: opts.InfoStyle,
- infoSep: opts.InfoSep,
+ infoPrefix: opts.InfoPrefix,
separator: nil,
spinner: makeSpinner(opts.Unicode),
promptString: opts.Prompt,
@@ -882,7 +882,7 @@ func (t *Terminal) visibleHeaderLines() int {
// Extra number of lines needed to display fzf
func (t *Terminal) extraLines() int {
extra := t.visibleHeaderLines() + 1
- if !t.noInfoLine() {
+ if !t.noSeparatorLine() {
extra++
}
return extra
@@ -988,8 +988,18 @@ func (t *Terminal) parsePrompt(prompt string) (func(), int) {
return output, promptLen
}
-func (t *Terminal) noInfoLine() bool {
- return t.infoStyle.noExtraLine()
+func noSeparatorLine(style infoStyle, separator bool) bool {
+ switch style {
+ case infoInline:
+ return true
+ case infoHidden, infoInlineRight:
+ return !separator
+ }
+ return false
+}
+
+func (t *Terminal) noSeparatorLine() bool {
+ return noSeparatorLine(t.infoStyle, t.separatorLen > 0)
}
func getScrollbar(total int, height int, offset int) (int, int) {
@@ -1241,7 +1251,7 @@ func (t *Terminal) adjustMarginAndPadding() (int, int, [4]int, [4]int) {
minAreaWidth := minWidth
minAreaHeight := minHeight
- if t.noInfoLine() {
+ if t.noSeparatorLine() {
minAreaHeight -= 1
}
if t.needPreviewWindow() {
@@ -1522,7 +1532,7 @@ func (t *Terminal) move(y int, x int, clear bool) {
y = h - y - 1
case layoutReverseList:
n := 2 + t.visibleHeaderLines()
- if t.noInfoLine() {
+ if t.noSeparatorLine() {
n--
}
if y < n {
@@ -1562,7 +1572,7 @@ func (t *Terminal) updatePromptOffset() ([]rune, []rune) {
func (t *Terminal) promptLine() int {
if t.headerFirst {
max := t.window.Height() - 1
- if !t.noInfoLine() {
+ if !t.noSeparatorLine() {
max--
}
return util.Min(t.visibleHeaderLines(), max)
@@ -1607,20 +1617,8 @@ func (t *Terminal) printInfo() {
t.window.Print(" ") // Clear spinner
}
}
- switch t.infoStyle {
- case infoDefault:
- t.move(line+1, 0, t.separatorLen == 0)
- printSpinner()
- t.move(line+1, 2, false)
- pos = 2
- case infoRight:
- t.move(line+1, 0, false)
- case infoInlineRight:
- pos = t.promptLen + t.queryLen[0] + t.queryLen[1] + 1
- t.move(line, pos, true)
- case infoInline:
- pos = t.promptLen + t.queryLen[0] + t.queryLen[1] + 1
- str := t.infoSep
+ printInfoPrefix := func() {
+ str := t.infoPrefix
maxWidth := t.window.Width() - pos
width := util.StringWidth(str)
if width > maxWidth {
@@ -1635,7 +1633,34 @@ func (t *Terminal) printInfo() {
t.window.CPrint(tui.ColPrompt, str)
}
pos += width
+ }
+ printSeparator := func(fillLength int, pad bool) {
+ // --------_
+ if t.separatorLen > 0 {
+ t.separator(t.window, fillLength)
+ t.window.Print(" ")
+ } else if pad {
+ t.window.Print(strings.Repeat(" ", fillLength+1))
+ }
+ }
+ switch t.infoStyle {
+ case infoDefault:
+ t.move(line+1, 0, t.separatorLen == 0)
+ printSpinner()
+ t.move(line+1, 2, false)
+ pos = 2
+ case infoRight:
+ t.move(line+1, 0, false)
+ case infoInlineRight:
+ pos = t.promptLen + t.queryLen[0] + t.queryLen[1] + 1
+ case infoInline:
+ pos = t.promptLen + t.queryLen[0] + t.queryLen[1] + 1
+ printInfoPrefix()
case infoHidden:
+ if t.separatorLen > 0 {
+ t.move(line+1, 0, false)
+ printSeparator(t.window.Width()-1, false)
+ }
return
}
@@ -1669,15 +1694,6 @@ func (t *Terminal) printInfo() {
output = fmt.Sprintf("[Command failed: %s]", *t.failed)
}
- printSeparator := func(fillLength int, pad bool) {
- // --------_
- if t.separatorLen > 0 {
- t.separator(t.window, fillLength)
- t.window.Print(" ")
- } else if pad {
- t.window.Print(strings.Repeat(" ", fillLength+1))
- }
- }
if t.infoStyle == infoRight {
maxWidth := t.window.Width()
if t.reading {
@@ -1700,19 +1716,35 @@ func (t *Terminal) printInfo() {
}
if t.infoStyle == infoInlineRight {
- pos = util.Max(pos, t.window.Width()-util.StringWidth(output)-3)
- if pos >= t.window.Width() {
- return
+ if len(t.infoPrefix) == 0 {
+ pos = util.Max(pos, t.window.Width()-util.StringWidth(output)-3)
+ if pos < t.window.Width() {
+ t.move(line, pos, false)
+ printSpinner()
+ pos++
+ }
+ if pos < t.window.Width()-1 {
+ t.window.Print(" ")
+ pos++
+ }
+ } else {
+ pos = util.Max(pos, t.window.Width()-util.StringWidth(output)-util.StringWidth(t.infoPrefix)-1)
+ printInfoPrefix()
}
- t.move(line, pos, false)
- printSpinner()
- t.window.Print(" ")
- pos += 2
}
maxWidth := t.window.Width() - pos
output = t.trimMessage(output, maxWidth)
t.window.CPrint(tui.ColInfo, output)
+
+ if t.infoStyle == infoInlineRight {
+ if t.separatorLen > 0 {
+ t.move(line+1, 0, false)
+ printSeparator(t.window.Width()-1, false)
+ }
+ return
+ }
+
fillLength := maxWidth - len(output) - 2
if fillLength > 0 {
t.window.CPrint(tui.ColSeparator, " ")
@@ -1727,7 +1759,7 @@ func (t *Terminal) printHeader() {
max := t.window.Height()
if t.headerFirst {
max--
- if !t.noInfoLine() {
+ if !t.noSeparatorLine() {
max--
}
}
@@ -1744,7 +1776,7 @@ func (t *Terminal) printHeader() {
}
if !t.headerFirst {
line++
- if !t.noInfoLine() {
+ if !t.noSeparatorLine() {
line++
}
}
@@ -1776,7 +1808,7 @@ func (t *Terminal) printList() {
i = maxy - 1 - j
}
line := i + 2 + t.visibleHeaderLines()
- if t.noInfoLine() {
+ if t.noSeparatorLine() {
line--
}
if i < count {
@@ -3102,7 +3134,7 @@ func (t *Terminal) Loop() {
switch req {
case reqPrompt:
t.printPrompt()
- if t.noInfoLine() {
+ if t.infoStyle == infoInline || t.infoStyle == infoInlineRight {
t.printInfo()
}
case reqInfo:
@@ -3904,7 +3936,7 @@ func (t *Terminal) Loop() {
mx -= t.window.Left()
my -= t.window.Top()
min := 2 + t.visibleHeaderLines()
- if t.noInfoLine() {
+ if t.noSeparatorLine() {
min--
}
h := t.window.Height()
@@ -4196,7 +4228,7 @@ func (t *Terminal) vset(o int) bool {
func (t *Terminal) maxItems() int {
max := t.window.Height() - 2 - t.visibleHeaderLines()
- if t.noInfoLine() {
+ if t.noSeparatorLine() {
max++
}
return util.Max(max, 0)
diff --git a/test/test_go.rb b/test/test_go.rb
index 5c07dde2..dc4d646a 100755
--- a/test/test_go.rb
+++ b/test/test_go.rb
@@ -1719,7 +1719,7 @@ class TestGoFZF < TestBase
end
def test_info_hidden
- tmux.send_keys 'seq 10 | fzf --info=hidden', :Enter
+ tmux.send_keys 'seq 10 | fzf --info=hidden --no-separator', :Enter
tmux.until { |lines| assert_equal '> 1', lines[-2] }
end