Allow putting border label on the bottom line

Related #3022
This commit is contained in:
Junegunn Choi 2022-10-31 00:22:41 +09:00
parent 31bbaad06e
commit c09ec8e4d1
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
4 changed files with 229 additions and 177 deletions

View File

@ -16,15 +16,18 @@ CHANGELOG
label=$(curl -s http://metaphorpsum.com/sentences/1 | lolcat -f) label=$(curl -s http://metaphorpsum.com/sentences/1 | lolcat -f)
# Border label at the center # Border label at the center
fzf --height=10 --border-label="╢ $label ╟" --border --color=label:italic:black fzf --height=10 --border --border-label="╢ $label ╟" --color=label:italic:black
# Left-aligned (positive integer) # Left-aligned (positive integer)
fzf --height=10 --border-label="╢ $label ╟" --border=top --border-label-pos=3 --color=label:italic:black fzf --height=10 --border --border-label="╢ $label ╟" --border-label-pos=3 --color=label:italic:black
# Right-aligned (negative integer) # Right-aligned (negative integer) on the bottom line (:bottom)
fzf --height=10 --border-label="╢ $label ╟" --border=bottom --border-label-pos=-3 --color=label:italic:black fzf --height=10 --border --border-label="╢ $label ╟" --border-label-pos=-3:bottom --color=label:italic:black
``` ```
- Also added `--preview-label` and `--preview-label-pos` for the border of the - Also added `--preview-label` and `--preview-label-pos` for the border of the
```sh
fzf --preview 'cat {}' --border --preview-label=' Preview ' --preview-label-pos=2
```
preview window preview window
- Info panel (counter) will be followed by a horizontal separator by default - Info panel (counter) will be followed by a horizontal separator by default
- The color of the separator can be customized via `--color=separator:...` - The color of the separator can be customized via `--color=separator:...`

View File

@ -250,20 +250,21 @@ e.g.
label=$(curl -s http://metaphorpsum.com/sentences/1 | lolcat -f) label=$(curl -s http://metaphorpsum.com/sentences/1 | lolcat -f)
# Border label at the center # Border label at the center
fzf --height=10 --border-label="╢ $label ╟" --border --color=label:italic:black fzf --height=10 --border --border-label="╢ $label ╟" --color=label:italic:black
# Left-aligned (positive integer) # Left-aligned (positive integer)
fzf --height=10 --border-label="╢ $label ╟" --border=top --border-label-pos=3 --color=label:italic:black fzf --height=10 --border --border-label="╢ $label ╟" --border-label-pos=3 --color=label:italic:black
# Right-aligned (negative integer) # Right-aligned (negative integer) on the bottom line (:bottom)
fzf --height=10 --border-label="╢ $label ╟" --border=bottom --border-label-pos=-3 --color=label:italic:black\fR fzf --height=10 --border --border-label="╢ $label ╟" --border-label-pos=-3:bottom --color=label:italic:black\fR
.TP .TP
.BI "--border-label-pos" [=COL] .BI "--border-label-pos" [=N[:top|bottom]]
Horizontal position of the border label on the border line. Specify a positive Position of the border label on the border line. Specify a positive integer as
integer as the column position from the left. Specify a negative integer to the column position from the left. Specify a negative integer to right-align
right-align the label. The default value 0 (or \fBcenter\fR) will put the label. Label is printed on the top border line by default, add
the label at the center of the border line. \fB:bottom\fR to put it on the border line on the bottom. The default value
\fB0 (or \fBcenter\fR) will put the label at the center of the border line.
.TP .TP
.B "--no-unicode" .B "--no-unicode"
@ -396,7 +397,7 @@ color mappings.
\fBinfo \fRInfo line (match counters) \fBinfo \fRInfo line (match counters)
\fBseparator \fRHorizontal separator on info 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 and \fB--preview-label\fR)
\fBprompt \fRPrompt \fBprompt \fRPrompt
\fBpointer \fRPointer to the current line \fBpointer \fRPointer to the current line
\fBmarker \fRMulti-select marker \fBmarker \fRMulti-select marker
@ -527,6 +528,33 @@ e.g.
sleep 0.01 sleep 0.01
done'\fR done'\fR
.RE .RE
.TP
.BI "--preview-label" [=LABEL]
Label to print on the horizontal border line of the preview window.
Should be used with one of the following \fB--preview-window\fR options.
.br
.B * border-rounded (default)
.br
.B * border-sharp
.br
.B * border-horizontal
.br
.B * border-top
.br
.B * border-bottom
.br
.TP
.BI "--preview-label-pos" [=N[:top|bottom]]
Position of the border label on the border line of the preview window. Specify
a positive integer as the column position from the left. Specify a negative
integer to right-align the label. Label is printed on the top border line by
default, add \fB:bottom\fR to put it on the border line on the bottom. The
default value 0 (or \fBcenter\fR) will put the label at the center of the
border line.
.TP .TP
.BI "--preview-window=" "[POSITION][,SIZE[%]][,border-BORDER_OPT][,[no]wrap][,[no]follow][,[no]cycle][,[no]hidden][,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES][,default][,<SIZE_THRESHOLD(ALTERNATIVE_LAYOUT)]" .BI "--preview-window=" "[POSITION][,SIZE[%]][,border-BORDER_OPT][,[no]wrap][,[no]follow][,[no]cycle][,[no]hidden][,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES][,default][,<SIZE_THRESHOLD(ALTERNATIVE_LAYOUT)]"

View File

@ -66,7 +66,8 @@ const usage = `usage: fzf [options]
--border-label=LABEL Label to print on the border --border-label=LABEL Label to print on the border
--border-label-pos=COL Position of the border label --border-label-pos=COL Position of the border label
[POSITIVE_INTEGER: columns from left| [POSITIVE_INTEGER: columns from left|
NEGATIVE_INTEGER: columns from right] (default: 0) NEGATIVE_INTEGER: columns from right][:bottom]
(default: 0 or center)
--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[:nosep]] --info=STYLE Finder info style [default|inline|hidden[:nosep]]
@ -97,7 +98,8 @@ const usage = `usage: fzf [options]
[,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES] [,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES]
[,default][,<SIZE_THRESHOLD(ALTERNATIVE_LAYOUT)] [,default][,<SIZE_THRESHOLD(ALTERNATIVE_LAYOUT)]
--preview-label=LABEL --preview-label=LABEL
--preview-label-pos=COL --preview-label-pos=N Same as --border-label and --border-label-pos,
but for preview window
Scripting Scripting
-q, --query=STR Start the finder with the given query -q, --query=STR Start the finder with the given query
@ -183,6 +185,12 @@ const (
infoHidden infoHidden
) )
type labelOpts struct {
label string
column int
bottom bool
}
type previewOpts struct { type previewOpts struct {
command string command string
position windowPosition position windowPosition
@ -198,11 +206,21 @@ type previewOpts struct {
alternative *previewOpts alternative *previewOpts
} }
func parseLabelPosition(arg string) int { func parseLabelPosition(opts *labelOpts, arg string) {
if strings.ToLower(arg) == "center" { opts.column = 0
return 0 opts.bottom = false
for _, token := range splitRegexp.Split(strings.ToLower(arg), -1) {
switch token {
case "center":
opts.column = 0
case "bottom":
opts.bottom = true
case "top":
opts.bottom = false
default:
opts.column = atoi(token)
}
} }
return atoi(arg)
} }
func (a previewOpts) aboveOrBelow() bool { func (a previewOpts) aboveOrBelow() bool {
@ -221,68 +239,66 @@ func (a previewOpts) sameContentLayout(b previewOpts) bool {
// Options stores the values of command-line options // Options stores the values of command-line options
type Options struct { type Options struct {
Fuzzy bool Fuzzy bool
FuzzyAlgo algo.Algo FuzzyAlgo algo.Algo
Scheme string Scheme string
Extended bool Extended bool
Phony bool Phony bool
Case Case Case Case
Normalize bool Normalize bool
Nth []Range Nth []Range
WithNth []Range WithNth []Range
Delimiter Delimiter Delimiter Delimiter
Sort int Sort int
Tac bool Tac bool
Criteria []criterion Criteria []criterion
Multi int Multi int
Ansi bool Ansi bool
Mouse bool Mouse bool
Theme *tui.ColorTheme Theme *tui.ColorTheme
Black bool Black bool
Bold bool Bold bool
Height heightSpec Height heightSpec
MinHeight int MinHeight int
Layout layoutType Layout layoutType
Cycle bool Cycle bool
KeepRight bool KeepRight bool
Hscroll bool Hscroll bool
HscrollOff int HscrollOff int
ScrollOff int ScrollOff int
FileWord bool FileWord bool
InfoStyle infoStyle InfoStyle infoStyle
JumpLabels string JumpLabels string
Prompt string Prompt string
Pointer string Pointer string
Marker string Marker string
Query string Query string
Select1 bool Select1 bool
Exit0 bool Exit0 bool
Filter *string Filter *string
ToggleSort bool ToggleSort bool
Expect map[tui.Event]string Expect map[tui.Event]string
Keymap map[tui.Event][]*action Keymap map[tui.Event][]*action
Preview previewOpts Preview previewOpts
PrintQuery bool PrintQuery bool
ReadZero bool ReadZero bool
Printer func(string) Printer func(string)
PrintSep string PrintSep string
Sync bool Sync bool
History *History History *History
Header []string Header []string
HeaderLines int HeaderLines int
HeaderFirst bool HeaderFirst bool
Ellipsis string Ellipsis string
Margin [4]sizeSpec Margin [4]sizeSpec
Padding [4]sizeSpec Padding [4]sizeSpec
BorderShape tui.BorderShape BorderShape tui.BorderShape
Label string BorderLabel labelOpts
LabelPos int PreviewLabel labelOpts
PLabel string Unicode bool
PLabelPos int Tabstop int
Unicode bool ClearOnExit bool
Tabstop int Version bool
ClearOnExit bool
Version bool
} }
func defaultPreviewOpts(command string) previewOpts { func defaultPreviewOpts(command string) previewOpts {
@ -291,66 +307,64 @@ func defaultPreviewOpts(command string) previewOpts {
func defaultOptions() *Options { func defaultOptions() *Options {
return &Options{ return &Options{
Fuzzy: true, Fuzzy: true,
FuzzyAlgo: algo.FuzzyMatchV2, FuzzyAlgo: algo.FuzzyMatchV2,
Scheme: "default", Scheme: "default",
Extended: true, Extended: true,
Phony: false, Phony: false,
Case: CaseSmart, Case: CaseSmart,
Normalize: true, Normalize: true,
Nth: make([]Range, 0), Nth: make([]Range, 0),
WithNth: make([]Range, 0), WithNth: make([]Range, 0),
Delimiter: Delimiter{}, Delimiter: Delimiter{},
Sort: 1000, Sort: 1000,
Tac: false, Tac: false,
Criteria: []criterion{byScore, byLength}, Criteria: []criterion{byScore, byLength},
Multi: 0, Multi: 0,
Ansi: false, Ansi: false,
Mouse: true, Mouse: true,
Theme: tui.EmptyTheme(), Theme: tui.EmptyTheme(),
Black: false, Black: false,
Bold: true, Bold: true,
MinHeight: 10, MinHeight: 10,
Layout: layoutDefault, Layout: layoutDefault,
Cycle: false, Cycle: false,
KeepRight: false, KeepRight: false,
Hscroll: true, Hscroll: true,
HscrollOff: 10, HscrollOff: 10,
ScrollOff: 0, ScrollOff: 0,
FileWord: false, FileWord: false,
InfoStyle: infoStyle{layout: infoDefault, separator: true}, InfoStyle: infoStyle{layout: infoDefault, separator: true},
JumpLabels: defaultJumpLabels, JumpLabels: defaultJumpLabels,
Prompt: "> ", Prompt: "> ",
Pointer: ">", Pointer: ">",
Marker: ">", Marker: ">",
Query: "", Query: "",
Select1: false, Select1: false,
Exit0: false, Exit0: false,
Filter: nil, Filter: nil,
ToggleSort: false, ToggleSort: false,
Expect: make(map[tui.Event]string), Expect: make(map[tui.Event]string),
Keymap: make(map[tui.Event][]*action), Keymap: make(map[tui.Event][]*action),
Preview: defaultPreviewOpts(""), Preview: defaultPreviewOpts(""),
PrintQuery: false, PrintQuery: false,
ReadZero: false, ReadZero: false,
Printer: func(str string) { fmt.Println(str) }, Printer: func(str string) { fmt.Println(str) },
PrintSep: "\n", PrintSep: "\n",
Sync: false, Sync: false,
History: nil, History: nil,
Header: make([]string, 0), Header: make([]string, 0),
HeaderLines: 0, HeaderLines: 0,
HeaderFirst: false, HeaderFirst: false,
Ellipsis: "..", Ellipsis: "..",
Margin: defaultMargin(), Margin: defaultMargin(),
Padding: defaultMargin(), Padding: defaultMargin(),
Unicode: true, Unicode: true,
Tabstop: 8, Tabstop: 8,
Label: "", BorderLabel: labelOpts{},
LabelPos: 0, PreviewLabel: labelOpts{},
PLabel: "", ClearOnExit: true,
PLabelPos: 0, Version: false}
ClearOnExit: true,
Version: false}
} }
func help(code int) { func help(code int) {
@ -847,7 +861,10 @@ func parseTheme(defaultTheme *tui.ColorTheme, str string) *tui.ColorTheme {
return theme return theme
} }
var executeRegexp *regexp.Regexp var (
executeRegexp *regexp.Regexp
splitRegexp *regexp.Regexp
)
func firstKey(keymap map[tui.Event]string) tui.Event { func firstKey(keymap map[tui.Event]string) tui.Event {
for k := range keymap { for k := range keymap {
@ -867,6 +884,7 @@ func init() {
// "~!@#$%^&*;/|".each_char.map { |c| Regexp.escape(c) }.map { |c| "#{c}[^#{c}]*#{c}" }.join('|') // "~!@#$%^&*;/|".each_char.map { |c| Regexp.escape(c) }.map { |c| "#{c}[^#{c}]*#{c}" }.join('|')
executeRegexp = regexp.MustCompile( executeRegexp = regexp.MustCompile(
`(?si)[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt|change-preview-window|change-preview|(?:re|un)bind):.+|[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt|change-preview-window|change-preview|(?:re|un)bind)(\([^)]*\)|\[[^\]]*\]|~[^~]*~|![^!]*!|@[^@]*@|\#[^\#]*\#|\$[^\$]*\$|%[^%]*%|\^[^\^]*\^|&[^&]*&|\*[^\*]*\*|;[^;]*;|/[^/]*/|\|[^\|]*\|)`) `(?si)[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt|change-preview-window|change-preview|(?:re|un)bind):.+|[:+](execute(?:-multi|-silent)?|reload|preview|change-prompt|change-preview-window|change-preview|(?:re|un)bind)(\([^)]*\)|\[[^\]]*\]|~[^~]*~|![^!]*!|@[^@]*@|\#[^\#]*\#|\$[^\$]*\$|%[^%]*%|\^[^\^]*\^|&[^&]*&|\*[^\*]*\*|;[^;]*;|/[^/]*/|\|[^\|]*\|)`)
splitRegexp = regexp.MustCompile("[,:]+")
} }
func parseKeymap(keymap map[tui.Event][]*action, str string) { func parseKeymap(keymap map[tui.Event][]*action, str string) {
@ -1229,7 +1247,7 @@ func parseInfoStyle(str string) infoStyle {
layout := infoDefault layout := infoDefault
separator := true separator := true
for _, token := range regexp.MustCompile("[,:]").Split(strings.ToLower(str), -1) { for _, token := range splitRegexp.Split(strings.ToLower(str), -1) {
switch token { switch token {
case "default": case "default":
layout = infoDefault layout = infoDefault
@ -1594,16 +1612,20 @@ func parseOptions(opts *Options, allArgs []string) {
case "--border": case "--border":
hasArg, arg := optionalNextString(allArgs, &i) hasArg, arg := optionalNextString(allArgs, &i)
opts.BorderShape = parseBorder(arg, !hasArg) opts.BorderShape = parseBorder(arg, !hasArg)
case "--no-border-label":
opts.BorderLabel.label = ""
case "--border-label": case "--border-label":
opts.Label = nextString(allArgs, &i, "label required") opts.BorderLabel.label = nextString(allArgs, &i, "label required")
case "--border-label-pos": case "--border-label-pos":
pos := nextString(allArgs, &i, "label position required (positive or negative integer or 'center')") pos := nextString(allArgs, &i, "label position required (positive or negative integer or 'center')")
opts.LabelPos = parseLabelPosition(pos) parseLabelPosition(&opts.BorderLabel, pos)
case "--no-preview-label":
opts.PreviewLabel.label = ""
case "--preview-label": case "--preview-label":
opts.PLabel = nextString(allArgs, &i, "preview label required") opts.PreviewLabel.label = nextString(allArgs, &i, "preview label required")
case "--preview-label-pos": case "--preview-label-pos":
pos := nextString(allArgs, &i, "preview label position required (positive or negative integer or 'center')") pos := nextString(allArgs, &i, "preview label position required (positive or negative integer or 'center')")
opts.PLabelPos = parseLabelPosition(pos) parseLabelPosition(&opts.PreviewLabel, pos)
case "--no-unicode": case "--no-unicode":
opts.Unicode = false opts.Unicode = false
case "--unicode": case "--unicode":
@ -1640,13 +1662,13 @@ func parseOptions(opts *Options, allArgs []string) {
} else if match, value := optString(arg, "--border="); match { } else if match, value := optString(arg, "--border="); match {
opts.BorderShape = parseBorder(value, false) opts.BorderShape = parseBorder(value, false)
} else if match, value := optString(arg, "--border-label="); match { } else if match, value := optString(arg, "--border-label="); match {
opts.Label = value opts.BorderLabel.label = value
} else if match, value := optString(arg, "--border-label-pos="); match { } else if match, value := optString(arg, "--border-label-pos="); match {
opts.LabelPos = parseLabelPosition(value) parseLabelPosition(&opts.BorderLabel, value)
} else if match, value := optString(arg, "--preview-label="); match { } else if match, value := optString(arg, "--preview-label="); match {
opts.PLabel = value opts.PreviewLabel.label = value
} else if match, value := optString(arg, "--preview-label-pos="); match { } else if match, value := optString(arg, "--preview-label-pos="); match {
opts.PLabelPos = parseLabelPosition(value) parseLabelPosition(&opts.PreviewLabel, value)
} else if match, value := optString(arg, "--prompt="); match { } else if match, value := optString(arg, "--prompt="); match {
opts.Prompt = value opts.Prompt = value
} else if match, value := optString(arg, "--pointer="); match { } else if match, value := optString(arg, "--pointer="); match {

View File

@ -114,12 +114,12 @@ type Terminal struct {
spinner []string spinner []string
prompt func() prompt func()
promptLen int promptLen int
borderLabel func() borderLabel func(tui.Window)
borderLabelLen int borderLabelLen int
borderLabelPos int borderLabelOpts labelOpts
previewLabel func() previewLabel func(tui.Window)
previewLabelLen int previewLabelLen int
previewLabelPos int previewLabelOpts labelOpts
pointer string pointer string
pointerLen int pointerLen int
pointerEmpty string pointerEmpty string
@ -551,9 +551,9 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
unicode: opts.Unicode, unicode: opts.Unicode,
borderShape: opts.BorderShape, borderShape: opts.BorderShape,
borderLabel: nil, borderLabel: nil,
borderLabelPos: opts.LabelPos, borderLabelOpts: opts.BorderLabel,
previewLabel: nil, previewLabel: nil,
previewLabelPos: opts.PLabelPos, previewLabelOpts: opts.PreviewLabel,
cleanExit: opts.ClearOnExit, cleanExit: opts.ClearOnExit,
paused: opts.Phony, paused: opts.Phony,
strong: strongAttr, strong: strongAttr,
@ -597,12 +597,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
// Pre-calculated empty pointer and marker signs // Pre-calculated empty pointer and marker signs
t.pointerEmpty = strings.Repeat(" ", t.pointerLen) t.pointerEmpty = strings.Repeat(" ", t.pointerLen)
t.markerEmpty = strings.Repeat(" ", t.markerLen) t.markerEmpty = strings.Repeat(" ", t.markerLen)
if len(opts.Label) > 0 { t.borderLabel, t.borderLabelLen = t.parseBorderLabel(opts.BorderLabel.label)
t.borderLabel, t.borderLabelLen = t.parseBorderLabel(opts.Label) t.previewLabel, t.previewLabelLen = t.parseBorderLabel(opts.PreviewLabel.label)
}
if len(opts.PLabel) > 0 {
t.previewLabel, t.previewLabelLen = t.parseBorderLabel(opts.PLabel)
}
return &t return &t
} }
@ -633,20 +629,23 @@ func (t *Terminal) MaxFitAndPad(opts *Options) (int, int) {
return fit, padHeight return fit, padHeight
} }
func (t *Terminal) parseBorderLabel(borderLabel string) (func(), int) { func (t *Terminal) parseBorderLabel(borderLabel string) (func(tui.Window), int) {
if len(borderLabel) == 0 {
return nil, 0
}
text, colors, _ := extractColor(borderLabel, nil, nil) text, colors, _ := extractColor(borderLabel, nil, nil)
runes := []rune(text) runes := []rune(text)
item := &Item{text: util.RunesToChars(runes), colors: colors} item := &Item{text: util.RunesToChars(runes), colors: colors}
result := Result{item: item} result := Result{item: item}
var offsets []colorOffset var offsets []colorOffset
borderLabelFn := func() { borderLabelFn := func(window tui.Window) {
if offsets == nil { if offsets == nil {
// tui.Col* are not initialized until renderer.Init() // tui.Col* are not initialized until renderer.Init()
offsets = result.colorOffsets(nil, t.theme, tui.ColBorderLabel, tui.ColBorderLabel, false) offsets = result.colorOffsets(nil, t.theme, tui.ColBorderLabel, tui.ColBorderLabel, false)
} }
text, _ := t.trimRight(runes, t.border.Width()) text, _ := t.trimRight(runes, window.Width())
t.printColoredString(t.border, text, offsets, tui.ColBorderLabel) t.printColoredString(window, text, offsets, tui.ColBorderLabel)
} }
borderLabelLen := runewidth.StringWidth(text) borderLabelLen := runewidth.StringWidth(text)
return borderLabelFn, borderLabelLen return borderLabelFn, borderLabelLen
@ -1052,7 +1051,7 @@ func (t *Terminal) resizeWindows() {
} }
// Print border label // Print border label
printLabel := func(window tui.Window, render func(), pos int, length int, borderShape tui.BorderShape) { printLabel := func(window tui.Window, render func(tui.Window), opts labelOpts, length int, borderShape tui.BorderShape) {
if window == nil || render == nil { if window == nil || render == nil {
return return
} }
@ -1060,23 +1059,23 @@ func (t *Terminal) resizeWindows() {
switch borderShape { switch borderShape {
case tui.BorderHorizontal, tui.BorderTop, tui.BorderBottom, tui.BorderRounded, tui.BorderSharp: case tui.BorderHorizontal, tui.BorderTop, tui.BorderBottom, tui.BorderRounded, tui.BorderSharp:
var col int var col int
if pos == 0 { if opts.column == 0 {
col = util.Max(0, (window.Width()-length)/2) col = util.Max(0, (window.Width()-length)/2)
} else if pos < 0 { } else if opts.column < 0 {
col = util.Max(0, window.Width()+pos+1-length) col = util.Max(0, window.Width()+opts.column+1-length)
} else { } else {
col = util.Min(pos-1, window.Width()-length) col = util.Min(opts.column-1, window.Width()-length)
} }
row := 0 row := 0
if borderShape == tui.BorderBottom { if borderShape == tui.BorderBottom || opts.bottom {
row = window.Height() - 1 row = window.Height() - 1
} }
window.Move(row, col) window.Move(row, col)
render() render(window)
} }
} }
printLabel(t.border, t.borderLabel, t.borderLabelPos, t.borderLabelLen, t.borderShape) printLabel(t.border, t.borderLabel, t.borderLabelOpts, t.borderLabelLen, t.borderShape)
printLabel(t.pborder, t.previewLabel, t.previewLabelPos, t.previewLabelLen, t.previewOpts.border) printLabel(t.pborder, t.previewLabel, t.previewLabelOpts, t.previewLabelLen, t.previewOpts.border)
for i := 0; i < t.window.Height(); i++ { for i := 0; i < t.window.Height(); i++ {
t.window.MoveAndClear(i, 0) t.window.MoveAndClear(i, 0)