diff options
| author | Junegunn Choi <junegunn.c@gmail.com> | 2023-01-22 01:56:29 +0900 |
|---|---|---|
| committer | Junegunn Choi <junegunn.c@gmail.com> | 2023-01-22 02:18:19 +0900 |
| commit | d51980a3f50dfa8ce43b01a3dce216afb8a0bd8f (patch) | |
| tree | 6041fc67bd7108153363a155b0c05348e65ee11d /src | |
| parent | c3d73e7ecbe56358949400f5314fee2d6976885a (diff) | |
| download | fzf-d51980a3f50dfa8ce43b01a3dce216afb8a0bd8f.tar.gz | |
Add 'transform-border-label' and 'transform-preview-label'
Diffstat (limited to 'src')
| -rw-r--r-- | src/options.go | 14 | ||||
| -rw-r--r-- | src/terminal.go | 86 | ||||
| -rw-r--r-- | src/tui/light.go | 37 | ||||
| -rw-r--r-- | src/tui/tcell.go | 30 | ||||
| -rw-r--r-- | src/tui/tui.go | 1 |
5 files changed, 111 insertions, 57 deletions
diff --git a/src/options.go b/src/options.go index f22e767a..fa238d7e 100644 --- a/src/options.go +++ b/src/options.go @@ -912,7 +912,7 @@ const ( func init() { executeRegexp = regexp.MustCompile( - `(?si)[:+](execute(?:-multi|-silent)?|reload(?:-sync)?|preview|(?:change|transform)-(?:query|prompt)|change-preview-window|change-preview-label|change-border-label|change-preview|(?:re|un)bind|pos|put)`) + `(?si)[:+](execute(?:-multi|-silent)?|reload(?:-sync)?|preview|(?:change|transform)-(?:query|prompt|border-label|preview-label)|change-preview-window|change-preview|(?:re|un)bind|pos|put)`) splitRegexp = regexp.MustCompile("[,:]+") actionNameRegexp = regexp.MustCompile("(?i)^[a-z-]+") } @@ -1220,16 +1220,16 @@ func isExecuteAction(str string) actionType { return actRebind case "preview": return actPreview + case "change-border-label": + return actChangeBorderLabel + case "change-preview-label": + return actChangePreviewLabel case "change-preview-window": return actChangePreviewWindow case "change-preview": return actChangePreview - case "change-preview-label": - return actChangePreviewLabel case "change-prompt": return actChangePrompt - case "change-border-label": - return actChangeBorderLabel case "change-query": return actChangeQuery case "pos": @@ -1242,6 +1242,10 @@ func isExecuteAction(str string) actionType { return actExecuteMulti case "put": return actPut + case "transform-border-label": + return actTransformBorderLabel + case "transform-preview-label": + return actTransformPreviewLabel case "transform-prompt": return actTransformPrompt case "transform-query": diff --git a/src/terminal.go b/src/terminal.go index 5b03f6d7..b2a99134 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -276,6 +276,8 @@ const ( reqRefresh reqReinit reqFullRedraw + reqRedrawBorderLabel + reqRedrawPreviewLabel reqClose reqPrintQuery reqPreviewEnqueue @@ -349,6 +351,8 @@ const ( actToggleSort actTogglePreview actTogglePreviewWrap + actTransformBorderLabel + actTransformPreviewLabel actTransformPrompt actTransformQuery actPreview @@ -1252,37 +1256,41 @@ func (t *Terminal) resizeWindows(forcePreview bool) { } // Print border label - printLabel := func(window tui.Window, render labelPrinter, opts labelOpts, length int, borderShape tui.BorderShape) { - if window == nil || render == nil { - return - } - - switch borderShape { - case tui.BorderHorizontal, tui.BorderTop, tui.BorderBottom, tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderDouble: - var col int - if opts.column == 0 { - col = util.Max(0, (window.Width()-length)/2) - } else if opts.column < 0 { - col = util.Max(0, window.Width()+opts.column+1-length) - } else { - col = util.Min(opts.column-1, window.Width()-length) - } - row := 0 - if borderShape == tui.BorderBottom || opts.bottom { - row = window.Height() - 1 - } - window.Move(row, col) - render(window, window.Width()) - } - } - printLabel(t.border, t.borderLabel, t.borderLabelOpts, t.borderLabelLen, t.borderShape) - printLabel(t.pborder, t.previewLabel, t.previewLabelOpts, t.previewLabelLen, t.previewOpts.border) + t.printLabel(t.border, t.borderLabel, t.borderLabelOpts, t.borderLabelLen, t.borderShape, false) + t.printLabel(t.pborder, t.previewLabel, t.previewLabelOpts, t.previewLabelLen, t.previewOpts.border, false) for i := 0; i < t.window.Height(); i++ { t.window.MoveAndClear(i, 0) } } +func (t *Terminal) printLabel(window tui.Window, render labelPrinter, opts labelOpts, length int, borderShape tui.BorderShape, redrawBorder bool) { + if window == nil || render == nil { + return + } + + switch borderShape { + case tui.BorderHorizontal, tui.BorderTop, tui.BorderBottom, tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderDouble: + if redrawBorder { + window.DrawHBorder() + } + var col int + if opts.column == 0 { + col = util.Max(0, (window.Width()-length)/2) + } else if opts.column < 0 { + col = util.Max(0, window.Width()+opts.column+1-length) + } else { + col = util.Min(opts.column-1, window.Width()-length) + } + row := 0 + if borderShape == tui.BorderBottom || opts.bottom { + row = window.Height() - 1 + } + window.Move(row, col) + render(window, window.Width()) + } +} + func (t *Terminal) move(y int, x int, clear bool) { h := t.window.Height() @@ -2659,6 +2667,10 @@ func (t *Terminal) Loop() { t.printHeader() case reqRefresh: t.suppress = false + case reqRedrawBorderLabel: + t.printLabel(t.border, t.borderLabel, t.borderLabelOpts, t.borderLabelLen, t.borderShape, true) + case reqRedrawPreviewLabel: + t.printLabel(t.pborder, t.previewLabel, t.previewLabelOpts, t.previewLabelLen, t.previewOpts.border, true) case reqReinit: t.tui.Resume(t.fullscreen, t.sigstop) t.redraw() @@ -2912,11 +2924,27 @@ func (t *Terminal) Loop() { t.input = []rune(a.a) t.cx = len(t.input) case actChangeBorderLabel: - t.borderLabel, t.borderLabelLen = t.ansiLabelPrinter(a.a, &tui.ColBorderLabel, false) - req(reqFullRedraw) + if t.border != nil { + t.borderLabel, t.borderLabelLen = t.ansiLabelPrinter(a.a, &tui.ColBorderLabel, false) + req(reqRedrawBorderLabel) + } case actChangePreviewLabel: - t.previewLabel, t.previewLabelLen = t.ansiLabelPrinter(a.a, &tui.ColPreviewLabel, false) - req(reqFullRedraw) + if t.pborder != nil { + t.previewLabel, t.previewLabelLen = t.ansiLabelPrinter(a.a, &tui.ColPreviewLabel, false) + req(reqRedrawPreviewLabel) + } + case actTransformBorderLabel: + if t.border != nil { + label := t.executeCommand(a.a, false, true, true) + t.borderLabel, t.borderLabelLen = t.ansiLabelPrinter(label, &tui.ColBorderLabel, false) + req(reqRedrawBorderLabel) + } + case actTransformPreviewLabel: + if t.pborder != nil { + label := t.executeCommand(a.a, false, true, true) + t.previewLabel, t.previewLabelLen = t.ansiLabelPrinter(label, &tui.ColPreviewLabel, false) + req(reqRedrawPreviewLabel) + } case actChangePrompt: t.prompt, t.promptLen = t.parsePrompt(a.a) req(reqPrompt) diff --git a/src/tui/light.go b/src/tui/light.go index a336cac0..3ff4ded7 100644 --- a/src/tui/light.go +++ b/src/tui/light.go @@ -719,25 +719,38 @@ func (r *LightRenderer) NewWindow(top int, left int, width int, height int, prev w.fg = r.theme.Fg.Color w.bg = r.theme.Bg.Color } - w.drawBorder() + w.drawBorder(false) return w } -func (w *LightWindow) drawBorder() { +func (w *LightWindow) DrawHBorder() { + w.drawBorder(true) +} + +func (w *LightWindow) drawBorder(onlyHorizontal bool) { switch w.border.shape { case BorderRounded, BorderSharp, BorderBold, BorderDouble: - w.drawBorderAround() + w.drawBorderAround(onlyHorizontal) case BorderHorizontal: w.drawBorderHorizontal(true, true) case BorderVertical: + if onlyHorizontal { + return + } w.drawBorderVertical(true, true) case BorderTop: w.drawBorderHorizontal(true, false) case BorderBottom: w.drawBorderHorizontal(false, true) case BorderLeft: + if onlyHorizontal { + return + } w.drawBorderVertical(true, false) case BorderRight: + if onlyHorizontal { + return + } w.drawBorderVertical(false, true) } } @@ -779,23 +792,25 @@ func (w *LightWindow) drawBorderVertical(left, right bool) { } } -func (w *LightWindow) drawBorderAround() { +func (w *LightWindow) drawBorderAround(onlyHorizontal bool) { w.Move(0, 0) color := ColBorder if w.preview { color = ColPreviewBorder } hw := runewidth.RuneWidth(w.border.horizontal) - vw := runewidth.RuneWidth(w.border.vertical) tcw := runewidth.RuneWidth(w.border.topLeft) + runewidth.RuneWidth(w.border.topRight) bcw := runewidth.RuneWidth(w.border.bottomLeft) + runewidth.RuneWidth(w.border.bottomRight) rem := (w.width - tcw) % hw w.CPrint(color, string(w.border.topLeft)+repeat(w.border.horizontal, (w.width-tcw)/hw)+repeat(' ', rem)+string(w.border.topRight)) - for y := 1; y < w.height-1; y++ { - w.Move(y, 0) - w.CPrint(color, string(w.border.vertical)) - w.CPrint(color, repeat(' ', w.width-vw*2)) - w.CPrint(color, string(w.border.vertical)) + if !onlyHorizontal { + vw := runewidth.RuneWidth(w.border.vertical) + for y := 1; y < w.height-1; y++ { + w.Move(y, 0) + w.CPrint(color, string(w.border.vertical)) + w.CPrint(color, repeat(' ', w.width-vw*2)) + w.CPrint(color, string(w.border.vertical)) + } } w.Move(w.height-1, 0) rem = (w.width - bcw) % hw @@ -1040,7 +1055,7 @@ func (w *LightWindow) FinishFill() { } func (w *LightWindow) Erase() { - w.drawBorder() + w.drawBorder(false) // We don't erase the window here to avoid flickering during scroll w.Move(0, 0) } diff --git a/src/tui/tcell.go b/src/tui/tcell.go index 366cb775..ad0182cf 100644 --- a/src/tui/tcell.go +++ b/src/tui/tcell.go @@ -512,7 +512,7 @@ func (r *FullscreenRenderer) NewWindow(top int, left int, width int, height int, height: height, normal: normal, borderStyle: borderStyle} - w.drawBorder() + w.drawBorder(false) return w } @@ -670,7 +670,11 @@ func (w *TcellWindow) CFill(fg Color, bg Color, a Attr, str string) FillReturn { return w.fillString(str, NewColorPair(fg, bg, a)) } -func (w *TcellWindow) drawBorder() { +func (w *TcellWindow) DrawHBorder() { + w.drawBorder(true) +} + +func (w *TcellWindow) drawBorder(onlyHorizontal bool) { shape := w.borderStyle.shape if shape == BorderNone { return @@ -718,17 +722,19 @@ func (w *TcellWindow) drawBorder() { _screen.SetContent(x, bot-1, w.borderStyle.horizontal, nil, style) } } - switch shape { - case BorderRounded, BorderSharp, BorderBold, BorderDouble, BorderVertical, BorderLeft: - for y := top; y < bot; y++ { - _screen.SetContent(left, y, w.borderStyle.vertical, nil, style) + if !onlyHorizontal { + switch shape { + case BorderRounded, BorderSharp, BorderBold, BorderDouble, BorderVertical, BorderLeft: + for y := top; y < bot; y++ { + _screen.SetContent(left, y, w.borderStyle.vertical, nil, style) + } } - } - switch shape { - case BorderRounded, BorderSharp, BorderBold, BorderDouble, BorderVertical, BorderRight: - vw := runewidth.RuneWidth(w.borderStyle.vertical) - for y := top; y < bot; y++ { - _screen.SetContent(right-vw, y, w.borderStyle.vertical, nil, style) + switch shape { + case BorderRounded, BorderSharp, BorderBold, BorderDouble, BorderVertical, BorderRight: + vw := runewidth.RuneWidth(w.borderStyle.vertical) + for y := top; y < bot; y++ { + _screen.SetContent(right-vw, y, w.borderStyle.vertical, nil, style) + } } } switch shape { diff --git a/src/tui/tui.go b/src/tui/tui.go index 5a86453b..203da76c 100644 --- a/src/tui/tui.go +++ b/src/tui/tui.go @@ -426,6 +426,7 @@ type Window interface { Width() int Height() int + DrawHBorder() Refresh() FinishFill() Close() |
