From f6269f0193e4cf5836c9e1d7c70bdf7354068124 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Mon, 9 Nov 2020 20:34:08 +0900 Subject: [PATCH] Add --padding option Close #2241 --- CHANGELOG.md | 8 +++++++ man/man1/fzf-tmux.1 | 2 +- man/man1/fzf.1 | 25 +++++++++++++++++++- src/options.go | 22 ++++++++++++++---- src/terminal.go | 56 +++++++++++++++++++++++++++++++-------------- 5 files changed, 89 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b41fd4b..a305ecc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ CHANGELOG ========= +0.24.3 +------ +- Added `--padding` option + ```sh + fzf --margin 5% --padding 5% --border --preview 'cat {}' \ + --color bg:#222222,preview-bg:#333333 + ``` + 0.24.2 ------ - Bug fixes and improvements diff --git a/man/man1/fzf-tmux.1 b/man/man1/fzf-tmux.1 index c147dde8..25465424 100644 --- a/man/man1/fzf-tmux.1 +++ b/man/man1/fzf-tmux.1 @@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .. -.TH fzf-tmux 1 "Nov 2020" "fzf 0.24.2" "fzf-tmux - open fzf in tmux split pane" +.TH fzf-tmux 1 "Nov 2020" "fzf 0.24.3" "fzf-tmux - open fzf in tmux split pane" .SH NAME fzf-tmux - open fzf in tmux split pane diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 32f54840..99147403 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .. -.TH fzf 1 "Nov 2020" "fzf 0.24.2" "fzf - a command-line fuzzy finder" +.TH fzf 1 "Nov 2020" "fzf 0.24.3" "fzf - a command-line fuzzy finder" .SH NAME fzf - a command-line fuzzy finder @@ -233,6 +233,29 @@ e.g. \fBfzf --margin 10% fzf --margin 1,5%\fR .RE +.TP +.BI "--padding=" PADDING +Comma-separated expression for padding inside the border. Padding is +distinguishable from margin only when \fB--border\fR option is used. +.br + +.br +e.g. + \fBfzf --margin 5% --padding 5% --border --preview 'cat {}' \\ + --color bg:#222222,preview-bg:#333333\fR + +.br +.RS +.BR TRBL " Same padding for top, right, bottom, and left" +.br +.BR TB,RL " Vertical, horizontal padding" +.br +.BR T,RL,B " Top, horizontal, bottom padding" +.br +.BR T,R,B,L " Top, right, bottom, left padding" +.br +.RE + .TP .BI "--info=" "STYLE" Determines the display style of finder info. diff --git a/src/options.go b/src/options.go index 797863cf..d7e1eaa6 100644 --- a/src/options.go +++ b/src/options.go @@ -60,7 +60,8 @@ const usage = `usage: fzf [options] --border[=STYLE] Draw border around the finder [rounded|sharp|horizontal|vertical| top|bottom|left|right] (default: rounded) - --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) --info=STYLE Finder info style [default|inline|hidden] --prompt=STR Input prompt (default: '> ') --pointer=STR Pointer to the current line (default: '>') @@ -221,6 +222,7 @@ type Options struct { Header []string HeaderLines int Margin [4]sizeSpec + Padding [4]sizeSpec BorderShape tui.BorderShape Unicode bool Tabstop int @@ -281,6 +283,7 @@ func defaultOptions() *Options { Header: make([]string, 0), HeaderLines: 0, Margin: defaultMargin(), + Padding: defaultMargin(), Unicode: true, Tabstop: 8, ClearOnExit: true, @@ -1076,10 +1079,10 @@ func parsePreviewWindow(opts *previewOpts, input string) { } } -func parseMargin(margin string) [4]sizeSpec { +func parseMargin(opt string, margin string) [4]sizeSpec { margins := strings.Split(margin, ",") checked := func(str string) sizeSpec { - return parseSize(str, 49, "margin") + return parseSize(str, 49, opt) } switch len(margins) { case 1: @@ -1099,7 +1102,7 @@ func parseMargin(margin string) [4]sizeSpec { checked(margins[0]), checked(margins[1]), checked(margins[2]), checked(margins[3])} default: - errorExit("invalid margin: " + margin) + errorExit("invalid " + opt + ": " + margin) } return defaultMargin() } @@ -1324,6 +1327,8 @@ func parseOptions(opts *Options, allArgs []string) { opts.Height = sizeSpec{} case "--no-margin": opts.Margin = defaultMargin() + case "--no-padding": + opts.Padding = defaultMargin() case "--no-border": opts.BorderShape = tui.BorderNone case "--border": @@ -1335,7 +1340,12 @@ func parseOptions(opts *Options, allArgs []string) { opts.Unicode = true case "--margin": opts.Margin = parseMargin( + "margin", nextString(allArgs, &i, "margin required (TRBL / TB,RL / T,RL,B / T,R,B,L)")) + case "--padding": + opts.Padding = parseMargin( + "padding", + nextString(allArgs, &i, "padding required (TRBL / TB,RL / T,RL,B / T,R,B,L)")) case "--tabstop": opts.Tabstop = nextInt(allArgs, &i, "tab stop required") case "--clear": @@ -1404,7 +1414,9 @@ func parseOptions(opts *Options, allArgs []string) { } else if match, value := optString(arg, "--preview-window="); match { parsePreviewWindow(&opts.Preview, value) } else if match, value := optString(arg, "--margin="); match { - opts.Margin = parseMargin(value) + opts.Margin = parseMargin("margin", value) + } else if match, value := optString(arg, "--padding="); match { + opts.Padding = parseMargin("padding", value) } else if match, value := optString(arg, "--tabstop="); match { opts.Tabstop = atoi(value) } else if match, value := optString(arg, "--hscroll-off="); match { diff --git a/src/terminal.go b/src/terminal.go index 10b1bac5..0a174822 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -119,6 +119,7 @@ type Terminal struct { ansi bool tabstop int margin [4]sizeSpec + padding [4]sizeSpec strong tui.Attr unicode bool borderShape tui.BorderShape @@ -472,6 +473,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { printQuery: opts.PrintQuery, history: opts.History, margin: opts.Margin, + padding: opts.Padding, unicode: opts.Unicode, borderShape: opts.BorderShape, cleanExit: opts.ClearOnExit, @@ -669,52 +671,64 @@ func calculateSize(base int, size sizeSpec, occupied int, minSize int, pad int) func (t *Terminal) resizeWindows() { screenWidth := t.tui.MaxX() screenHeight := t.tui.MaxY() - marginInt := [4]int{} // TRBL t.prevLines = make([]itemLine, screenHeight) - for idx, sizeSpec := range t.margin { - if sizeSpec.percent { + + marginInt := [4]int{} // TRBL + paddingInt := [4]int{} // TRBL + sizeSpecToInt := func(index int, spec sizeSpec) int { + if spec.percent { var max float64 - if idx%2 == 0 { + if index%2 == 0 { max = float64(screenHeight) } else { max = float64(screenWidth) } - marginInt[idx] = int(max * sizeSpec.size * 0.01) - } else { - marginInt[idx] = int(sizeSpec.size) + return int(max * spec.size * 0.01) } + return int(spec.size) + } + for idx, sizeSpec := range t.padding { + paddingInt[idx] = sizeSpecToInt(idx, sizeSpec) + } + + extraMargin := [4]int{} // TRBL + for idx, sizeSpec := range t.margin { switch t.borderShape { case tui.BorderHorizontal: - marginInt[idx] += 1 - idx%2 + extraMargin[idx] += 1 - idx%2 case tui.BorderVertical: - marginInt[idx] += 2 * (idx % 2) + extraMargin[idx] += 2 * (idx % 2) case tui.BorderTop: if idx == 0 { - marginInt[idx]++ + extraMargin[idx]++ } case tui.BorderRight: if idx == 1 { - marginInt[idx] += 2 + extraMargin[idx] += 2 } case tui.BorderBottom: if idx == 2 { - marginInt[idx]++ + extraMargin[idx]++ } case tui.BorderLeft: if idx == 3 { - marginInt[idx] += 2 + extraMargin[idx] += 2 } case tui.BorderRounded, tui.BorderSharp: - marginInt[idx] += 1 + idx%2 + extraMargin[idx] += 1 + idx%2 } + marginInt[idx] = sizeSpecToInt(idx, sizeSpec) + extraMargin[idx] } + adjust := func(idx1 int, idx2 int, max int, min int) { if max >= min { - margin := marginInt[idx1] + marginInt[idx2] + margin := marginInt[idx1] + marginInt[idx2] + paddingInt[idx1] + paddingInt[idx2] if max-margin < min { desired := max - min - marginInt[idx1] = desired * marginInt[idx1] / margin - marginInt[idx2] = desired * marginInt[idx2] / margin + paddingInt[idx1] = desired * paddingInt[idx1] / margin + paddingInt[idx2] = desired * paddingInt[idx2] / margin + marginInt[idx1] = util.Max(extraMargin[idx1], desired*marginInt[idx1]/margin) + marginInt[idx2] = util.Max(extraMargin[idx2], desired*marginInt[idx2]/margin) } } } @@ -779,6 +793,14 @@ func (t *Terminal) resizeWindows() { marginInt[0]-1, marginInt[3]-2, width+4, height+2, false, tui.MakeBorderStyle(t.borderShape, t.unicode)) } + + // Add padding + for idx, val := range paddingInt { + marginInt[idx] += val + } + width = screenWidth - marginInt[1] - marginInt[3] + height = screenHeight - marginInt[0] - marginInt[2] + noBorder := tui.MakeBorderStyle(tui.BorderNone, t.unicode) if previewVisible { createPreviewWindow := func(y int, x int, w int, h int) {