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) # Right-aligned (negative integer)
fzf --height=10 --border-label="╢ $label ╟" --border=bottom --border-label-pos=-3 --color=label:italic:black 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 0.34.0
------ ------

View File

@ -394,6 +394,7 @@ color mappings.
\fBquery \fRQuery string \fBquery \fRQuery string
\fBdisabled \fRQuery string when search is disabled \fBdisabled \fRQuery string when search is disabled
\fBinfo \fRInfo line (match counters) \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) \fBborder \fRBorder around the window (\fB--border\fR and \fB--preview\fR)
\fBlabel \fRBorder label (\fB--border-label\fR) \fBlabel \fRBorder label (\fB--border-label\fR)
\fBprompt \fRPrompt \fBprompt \fRPrompt

View File

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

View File

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

View File

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