Add horizontal separator after info panel (counter)

Close #3029
This commit is contained in:
Junegunn Choi 2022-10-30 16:28:58 +09:00
parent e61585f2f3
commit b9ca1fe830
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
5 changed files with 60 additions and 21 deletions

View File

@ -24,6 +24,11 @@ CHANGELOG
# Right-aligned (negative integer)
fzf --height=10 --border-label="╢ $label ╟" --border=bottom --border-label-pos=-3 --color=label:italic:black
```
- Info panel (counter) will be followed by a horizontal separator by default
- The color of the separator can be customized via `--color=separator:...`
- Separator can be disabled by adding `:nosep` to `--info`
- `--info=nosep`
- `--info=inline:nosep`
0.34.0
------

View File

@ -394,6 +394,7 @@ color mappings.
\fBquery \fRQuery string
\fBdisabled \fRQuery string when search is disabled
\fBinfo \fRInfo line (match counters)
\fBseparator \fRHorizontal separator on info line (match counters)
\fBborder \fRBorder around the window (\fB--border\fR and \fB--preview\fR)
\fBlabel \fRBorder label (\fB--border-label\fR)
\fBprompt \fRPrompt

View File

@ -69,7 +69,7 @@ const usage = `usage: fzf [options]
NEGATIVE_INTEGER: columns from right] (default: 0)
--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|inline|hidden]
--info=STYLE Finder info style [default|inline|hidden[:nosep]]
--prompt=STR Input prompt (default: '> ')
--pointer=STR Pointer to the current line (default: '>')
--marker=STR Multi-select marker (default: '>')
@ -169,10 +169,14 @@ const (
layoutReverseList
)
type infoStyle int
type infoLayout int
type infoStyle struct {
layout infoLayout
separator bool
}
const (
infoDefault infoStyle = iota
infoDefault infoLayout = iota
infoInline
infoHidden
)
@ -310,7 +314,7 @@ func defaultOptions() *Options {
HscrollOff: 10,
ScrollOff: 0,
FileWord: false,
InfoStyle: infoDefault,
InfoStyle: infoStyle{layout: infoDefault, separator: true},
JumpLabels: defaultJumpLabels,
Prompt: "> ",
Pointer: ">",
@ -813,6 +817,8 @@ func parseTheme(defaultTheme *tui.ColorTheme, str string) *tui.ColorTheme {
mergeAttr(&theme.CurrentMatch)
case "border":
mergeAttr(&theme.Border)
case "separator":
mergeAttr(&theme.Separator)
case "label":
mergeAttr(&theme.BorderLabel)
case "prompt":
@ -1214,17 +1220,26 @@ func parseLayout(str string) layoutType {
}
func parseInfoStyle(str string) infoStyle {
switch str {
layout := infoDefault
separator := true
for _, token := range regexp.MustCompile("[,:]").Split(strings.ToLower(str), -1) {
switch token {
case "default":
return infoDefault
layout = infoDefault
case "inline":
return infoInline
layout = infoInline
case "hidden":
return infoHidden
layout = infoHidden
case "nosep":
separator = false
case "sep":
separator = true
default:
errorExit("invalid info style (expected: default / inline / hidden)")
errorExit("invalid info style (expected: default|inline|hidden[:nosep])")
}
return infoDefault
}
return infoStyle{layout: layout, separator: separator}
}
func parsePreviewWindow(opts *previewOpts, input string) {
@ -1486,11 +1501,11 @@ func parseOptions(opts *Options, allArgs []string) {
opts.InfoStyle = parseInfoStyle(
nextString(allArgs, &i, "info style required"))
case "--no-info":
opts.InfoStyle = infoHidden
opts.InfoStyle.layout = infoHidden
case "--inline-info":
opts.InfoStyle = infoInline
opts.InfoStyle.layout = infoInline
case "--no-inline-info":
opts.InfoStyle = infoDefault
opts.InfoStyle.layout = infoDefault
case "--jump-labels":
opts.JumpLabels = nextString(allArgs, &i, "label characters required")
validateJumpLabels = true

View File

@ -495,7 +495,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
if previewBox != nil && opts.Preview.aboveOrBelow() {
effectiveMinHeight += 1 + borderLines(opts.Preview.border)
}
if opts.InfoStyle != infoDefault {
if opts.InfoStyle.layout != infoDefault {
effectiveMinHeight--
}
effectiveMinHeight += borderLines(opts.BorderShape)
@ -677,7 +677,7 @@ func (t *Terminal) parsePrompt(prompt string) (func(), int) {
}
func (t *Terminal) noInfoLine() bool {
return t.infoStyle != infoDefault
return t.infoStyle.layout != infoDefault
}
// Input returns current query string
@ -1153,7 +1153,7 @@ func (t *Terminal) trimMessage(message string, maxWidth int) string {
func (t *Terminal) printInfo() {
pos := 0
line := t.promptLine()
switch t.infoStyle {
switch t.infoStyle.layout {
case infoDefault:
t.move(line+1, 0, true)
if t.reading {
@ -1202,8 +1202,17 @@ func (t *Terminal) printInfo() {
if t.failed != nil && t.count == 0 {
output = fmt.Sprintf("[Command failed: %s]", *t.failed)
}
output = t.trimMessage(output, t.window.Width()-pos)
maxWidth := t.window.Width() - pos
output = t.trimMessage(output, maxWidth)
t.window.CPrint(tui.ColInfo, output)
if t.infoStyle.separator && len(output) < maxWidth-2 {
bar := "─"
if !t.unicode {
bar = "-"
}
t.window.CPrint(tui.ColSeparator, " "+strings.Repeat(bar, maxWidth-len(output)-2))
}
}
func (t *Terminal) printHeader() {

View File

@ -267,6 +267,7 @@ type ColorTheme struct {
Cursor ColorAttr
Selected ColorAttr
Header ColorAttr
Separator ColorAttr
Border ColorAttr
BorderLabel ColorAttr
}
@ -439,6 +440,7 @@ var (
ColSpinner ColorPair
ColInfo ColorPair
ColHeader ColorPair
ColSeparator ColorPair
ColBorder ColorPair
ColPreview ColorPair
ColPreviewBorder ColorPair
@ -465,6 +467,7 @@ func EmptyTheme() *ColorTheme {
Cursor: ColorAttr{colUndefined, AttrUndefined},
Selected: ColorAttr{colUndefined, AttrUndefined},
Header: ColorAttr{colUndefined, AttrUndefined},
Separator: ColorAttr{colUndefined, AttrUndefined},
Border: ColorAttr{colUndefined, AttrUndefined},
BorderLabel: ColorAttr{colUndefined, AttrUndefined},
}
@ -490,6 +493,7 @@ func NoColorTheme() *ColorTheme {
Cursor: ColorAttr{colDefault, AttrRegular},
Selected: ColorAttr{colDefault, AttrRegular},
Header: ColorAttr{colDefault, AttrRegular},
Separator: ColorAttr{colDefault, AttrRegular},
Border: ColorAttr{colDefault, AttrRegular},
BorderLabel: ColorAttr{colDefault, AttrRegular},
}
@ -520,6 +524,7 @@ func init() {
Cursor: ColorAttr{colRed, AttrUndefined},
Selected: ColorAttr{colMagenta, AttrUndefined},
Header: ColorAttr{colCyan, AttrUndefined},
Separator: ColorAttr{colBlack, AttrUndefined},
Border: ColorAttr{colBlack, AttrUndefined},
BorderLabel: ColorAttr{colWhite, AttrUndefined},
}
@ -542,6 +547,7 @@ func init() {
Cursor: ColorAttr{161, AttrUndefined},
Selected: ColorAttr{168, AttrUndefined},
Header: ColorAttr{109, AttrUndefined},
Separator: ColorAttr{59, AttrUndefined},
Border: ColorAttr{59, AttrUndefined},
BorderLabel: ColorAttr{145, AttrUndefined},
}
@ -564,6 +570,7 @@ func init() {
Cursor: ColorAttr{161, AttrUndefined},
Selected: ColorAttr{168, AttrUndefined},
Header: ColorAttr{31, AttrUndefined},
Separator: ColorAttr{145, AttrUndefined},
Border: ColorAttr{145, AttrUndefined},
BorderLabel: ColorAttr{59, AttrUndefined},
}
@ -601,6 +608,7 @@ func initTheme(theme *ColorTheme, baseTheme *ColorTheme, forceBlack bool) {
theme.Cursor = o(baseTheme.Cursor, theme.Cursor)
theme.Selected = o(baseTheme.Selected, theme.Selected)
theme.Header = o(baseTheme.Header, theme.Header)
theme.Separator = o(baseTheme.Separator, theme.Separator)
theme.Border = o(baseTheme.Border, theme.Border)
theme.BorderLabel = o(baseTheme.BorderLabel, theme.BorderLabel)
@ -634,6 +642,7 @@ func initPalette(theme *ColorTheme) {
ColSpinner = pair(theme.Spinner, theme.Bg)
ColInfo = pair(theme.Info, theme.Bg)
ColHeader = pair(theme.Header, theme.Bg)
ColSeparator = pair(theme.Separator, theme.Bg)
ColBorder = pair(theme.Border, theme.Bg)
ColBorderLabel = pair(theme.BorderLabel, theme.Bg)
ColPreview = pair(theme.PreviewFg, theme.PreviewBg)