diff --git a/CHANGELOG.md b/CHANGELOG.md index 94bf57e5..bd1dd62e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ Also, fzf now offers "style presets" for quick customization, which can be activ | `minimal` | | - Style presets (#4160) - - `--style=full` + - `--style=full[:BORDER_STYLE]` - `--style=default` - `--style=minimal` - Border and label for the list section (#4148) diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index b237c110..456006d6 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -189,7 +189,7 @@ e.g. \fB# Avoid rendering both fzf instances at the same time .SS GLOBAL STYLE .TP .BI "\-\-style=" "PRESET" -Apply a style preset [default|minimal|full] +Apply a style preset [default|minimal|full[:BORDER_STYLE]] .TP .BI "\-\-color=" "[BASE_SCHEME][,COLOR_NAME[:ANSI_COLOR][:ANSI_ATTRIBUTES]]..." Color configuration. The name of the base color scheme is followed by custom diff --git a/src/options.go b/src/options.go index 3dc5d2a6..9042b6d7 100644 --- a/src/options.go +++ b/src/options.go @@ -56,7 +56,7 @@ Usage: fzf [options] --sync Synchronous search for multi-staged filtering GLOBAL STYLE - --style=PRESET Apply a style preset [default|minimal|full] + --style=PRESET Apply a style preset [default|minimal|full[:BORDER_STYLE] --color=COLSPEC Base scheme (dark|light|16|bw) and/or custom colors --no-color Disable colors --no-bold Do not use bold text @@ -214,6 +214,9 @@ Usage: fzf [options] ` +// Can be changed by --style +var defaultBorderShape tui.BorderShape = tui.DefaultBorderShape + const defaultInfoPrefix = " < " // Case denotes case-sensitivity of search @@ -628,7 +631,7 @@ func filterNonEmpty(input []string) []string { } func defaultPreviewOpts(command string) previewOpts { - return previewOpts{command, posRight, sizeSpec{50, true}, "", false, false, false, false, true, tui.DefaultBorderShape, 0, 0, nil} + return previewOpts{command, posRight, sizeSpec{50, true}, "", false, false, false, false, true, defaultBorderShape, 0, 0, nil} } func defaultOptions() *Options { @@ -842,7 +845,7 @@ func parseBorder(str string, optional bool, allowLine bool) (tui.BorderShape, er return tui.BorderNone, nil } if optional && str == "" { - return tui.DefaultBorderShape, nil + return defaultBorderShape, nil } return tui.BorderNone, errors.New("invalid border style (expected: rounded|sharp|bold|block|thinblock|double|horizontal|vertical|top|bottom|left|right|none)") } @@ -2729,7 +2732,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error { return err } case "--style": - preset, err := nextString("preset name required: [default|minimal|full]") + preset, err := nextString("preset name required: [default|minimal|full[:BORDER_STYLE]]") if err != nil { return err } @@ -2882,12 +2885,15 @@ func parseOptions(index *int, opts *Options, allArgs []string) error { } func applyPreset(opts *Options, preset string) error { + // Reset to the platform default + defaultBorderShape = tui.DefaultBorderShape + switch strings.ToLower(preset) { case "default": opts.ListBorderShape = tui.BorderUndefined opts.InputBorderShape = tui.BorderUndefined opts.HeaderBorderShape = tui.BorderUndefined - opts.Preview.border = tui.DefaultBorderShape + opts.Preview.border = defaultBorderShape opts.Preview.info = true opts.InfoStyle = infoDefault opts.Theme.Gutter = tui.NewColorAttr() @@ -2906,19 +2912,29 @@ func applyPreset(opts *Options, preset string) error { opts.Separator = &empty opts.Scrollbar = &empty opts.CursorLine = false - case "full": - opts.ListBorderShape = tui.DefaultBorderShape - opts.InputBorderShape = tui.DefaultBorderShape - opts.HeaderBorderShape = tui.DefaultBorderShape - opts.Preview.border = tui.DefaultBorderShape + default: + tokens := strings.SplitN(preset, ":", 2) + if tokens[0] != "full" { + return errors.New("unsupported style preset: " + preset) + } + if len(tokens) == 2 && len(tokens[1]) > 0 { + var err error + defaultBorderShape, err = parseBorder(tokens[1], false, false) + if err != nil { + return err + } + } + + opts.ListBorderShape = defaultBorderShape + opts.InputBorderShape = defaultBorderShape + opts.HeaderBorderShape = defaultBorderShape + opts.Preview.border = defaultBorderShape opts.Preview.info = true opts.InfoStyle = infoInlineRight opts.Theme.Gutter = tui.NewColorAttr() opts.Separator = nil opts.Scrollbar = nil opts.CursorLine = true - default: - return errors.New("unsupported style preset: " + preset) } return nil } diff --git a/src/tmux.go b/src/tmux.go index e459000a..87ea38cc 100644 --- a/src/tmux.go +++ b/src/tmux.go @@ -12,7 +12,9 @@ func runTmux(args []string, opts *Options) (int, error) { fzf, rest := args[0], args[1:] args = []string{"--bind=ctrl-z:ignore"} if !opts.Tmux.border && opts.BorderShape == tui.BorderUndefined { - args = append(args, "--border") + // We append --border option at the end, because `--style=full:STYLE` + // may have changed the default border style. + rest = append(rest, "--border") } if opts.Tmux.border && opts.Margin == defaultMargin() { args = append(args, "--margin=0,1") diff --git a/test/test_go.rb b/test/test_go.rb index f7c5b962..e782b979 100755 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -3719,6 +3719,24 @@ class TestGoFZF < TestBase tmux.until { assert_block(block, _1) } end + def test_style_full_adaptive_height_double + tmux.send_keys %(seq 1| #{FZF} --style=full:double --border --height=~100% --header-lines=1 --info=default), :Enter + block = <<~BLOCK + ╔══════════ + ║ ╔════════ + ║ ╚════════ + ║ ╔════════ + ║ ║ 1 + ║ ╚════════ + ║ ╔════════ + ║ ║ 0/0 + ║ ║ > + ║ ╚════════ + ╚══════════ + BLOCK + tmux.until { assert_block(block, _1) } + end + def test_change_nth input = [ *[''] * 1000,