Compare commits

..

9 Commits

Author SHA1 Message Date
Junegunn Choi
d471067e3f 0.42.0 2023-06-15 00:37:41 +09:00
Junegunn Choi
d0b7780239 Add --info=right
Related: #3322
2023-06-11 16:09:15 +09:00
Junegunn Choi
e627ca6bd7 Add --info=inline-right
Close #3322
2023-06-10 23:11:05 +09:00
Junegunn Choi
c97172bdd4 Fix background color of spinner on the preview window 2023-06-10 14:48:47 +09:00
Mike
ce8a745fb4 Add new border style: 'thinblock' (#3327)
Co-authored-by: Junegunn Choi <junegunn.c@gmail.com>
2023-06-10 14:48:29 +09:00
Junegunn Choi
3e9efd1401 [vim] Only prepend --border option in $FZF_DEFAULT_OPTS
Fix #3318
2023-06-03 09:03:04 +09:00
Junegunn Choi
20340190b5 [fzf-tmux] Pass $BAT_THEME
This may anger some purists, but bat is widely used as the previewer so
I think it's worth it.
2023-05-31 20:16:30 +09:00
Junegunn Choi
265040a78c [vim] Respect --border optin in $FZF_DEFAULT_OPTS 2023-05-31 20:09:14 +09:00
Junegunn Choi
448d7e0c5a Update test case 2023-05-27 16:01:30 +09:00
15 changed files with 181 additions and 36 deletions

View File

@@ -1,6 +1,22 @@
CHANGELOG CHANGELOG
========= =========
0.42.0
------
- Added new info style: `--info=right`
- Added new info style: `--info=inline-right`
- Added new border style `thinblock` which uses symbols for legacy computing
[one eighth block elements](https://en.wikipedia.org/wiki/Symbols_for_Legacy_Computing)
- Similarly to `block`, this style is suitable when using a different
background color because the window is completely contained within the border.
```sh
BAT_THEME=GitHub fzf --info=right --border=thinblock --preview-window=border-thinblock \
--margin=3 --scrollbar=▏▕ --preview='bat --color=always --style=numbers {}' \
--color=light,query:238,fg:238,bg:251,bg+:249,gutter:251,border:248,preview-bg:253
```
- This style may not render correctly depending on the font and the
terminal emulator.
0.41.1 0.41.1
------ ------
- Fixed a bug where preview window is not updated when `--disabled` is set and - Fixed a bug where preview window is not updated when `--disabled` is set and

View File

@@ -192,6 +192,7 @@ if [[ "$opt" =~ "-E" ]]; then
fi fi
[[ -n "$FZF_DEFAULT_OPTS" ]] && envs="$envs FZF_DEFAULT_OPTS=$(printf %q "$FZF_DEFAULT_OPTS")" [[ -n "$FZF_DEFAULT_OPTS" ]] && envs="$envs FZF_DEFAULT_OPTS=$(printf %q "$FZF_DEFAULT_OPTS")"
[[ -n "$FZF_DEFAULT_COMMAND" ]] && envs="$envs FZF_DEFAULT_COMMAND=$(printf %q "$FZF_DEFAULT_COMMAND")" [[ -n "$FZF_DEFAULT_COMMAND" ]] && envs="$envs FZF_DEFAULT_COMMAND=$(printf %q "$FZF_DEFAULT_COMMAND")"
[[ -n "$BAT_THEME" ]] && envs="$envs BAT_THEME=$(printf %q "$BAT_THEME")"
echo "$envs;" > "$argsf" echo "$envs;" > "$argsf"
# Build arguments to fzf # Build arguments to fzf

View File

@@ -2,7 +2,7 @@
set -u set -u
version=0.41.1 version=0.42.0
auto_completion= auto_completion=
key_bindings= key_bindings=
update_config=2 update_config=2

View File

@@ -1,4 +1,4 @@
$version="0.41.1" $version="0.42.0"
$fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition $fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition

View File

@@ -5,7 +5,7 @@ import (
"github.com/junegunn/fzf/src/protector" "github.com/junegunn/fzf/src/protector"
) )
var version string = "0.41" var version string = "0.42"
var revision string = "devel" var revision string = "devel"
func main() { func main() {

View File

@@ -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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
.. ..
.TH fzf-tmux 1 "May 2023" "fzf 0.41.1" "fzf-tmux - open fzf in tmux split pane" .TH fzf-tmux 1 "Jun 2023" "fzf 0.42.0" "fzf-tmux - open fzf in tmux split pane"
.SH NAME .SH NAME
fzf-tmux - open fzf in tmux split pane fzf-tmux - open fzf in tmux split pane

View File

@@ -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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
.. ..
.TH fzf 1 "May 2023" "fzf 0.41.1" "fzf - a command-line fuzzy finder" .TH fzf 1 "Jun 2023" "fzf 0.42.0" "fzf - a command-line fuzzy finder"
.SH NAME .SH NAME
fzf - a command-line fuzzy finder fzf - a command-line fuzzy finder
@@ -228,6 +228,10 @@ Draw border around the finder
.br .br
.BR double " Border with double lines" .BR double " Border with double lines"
.br .br
.BR block " Border using block elements; suitable when using different background colors"
.br
.BR thinblock " Border using legacy computing symbols; may not be displayed on some terminals"
.br
.BR horizontal " Horizontal lines above and below the finder" .BR horizontal " Horizontal lines above and below the finder"
.br .br
.BR vertical " Vertical lines on each side of the finder" .BR vertical " Vertical lines on each side of the finder"
@@ -357,6 +361,8 @@ Determines the display style of finder info (match counters).
.br .br
.BR inline:SEPARATOR " Display on the same line with a non-default separator" .BR inline:SEPARATOR " Display on the same line with a non-default separator"
.br .br
.BR inline-right " Display on the right end of the same line
.br
.BR hidden " Do not display finder info" .BR hidden " Do not display finder info"
.br .br
@@ -599,6 +605,10 @@ Should be used with one of the following \fB--preview-window\fR options.
.br .br
.B * border-double .B * border-double
.br .br
.B * border-block
.br
.B * border-thinblock
.br
.B * border-horizontal .B * border-horizontal
.br .br
.B * border-top .B * border-top

View File

@@ -456,6 +456,30 @@ function! s:writefile(...)
endif endif
endfunction endfunction
function! s:extract_option(opts, name)
let opt = ''
let expect = 0
" There are a few cases where this function doesn't work as expected.
" Let's just assume such cases are extremely unlikely in real world.
" e.g. --query --border
for word in split(a:opts)
if expect && word !~ '^"\=-'
let opt = opt . ' ' . word
let expect = 0
elseif word == '--no-'.a:name
let opt = ''
elseif word =~ '^--'.a:name.'='
let opt = word
elseif word =~ '^--'.a:name.'$'
let opt = word
let expect = 1
elseif expect
let expect = 0
endif
endfor
return opt
endfunction
function! fzf#run(...) abort function! fzf#run(...) abort
try try
let [shell, shellslash, shellcmdflag, shellxquote] = s:use_sh() let [shell, shellslash, shellcmdflag, shellxquote] = s:use_sh()
@@ -511,8 +535,8 @@ try
let height = s:calc_size(&lines, dict.down, dict) let height = s:calc_size(&lines, dict.down, dict)
let optstr .= ' --height='.height let optstr .= ' --height='.height
endif endif
" Respect --border option given in 'options' " Respect --border option given in $FZF_DEFAULT_OPTS and 'options'
let optstr = join([s:border_opt(get(dict, 'window', 0)), optstr]) let optstr = join([s:border_opt(get(dict, 'window', 0)), s:extract_option($FZF_DEFAULT_OPTS, 'border'), optstr])
let prev_default_command = $FZF_DEFAULT_COMMAND let prev_default_command = $FZF_DEFAULT_COMMAND
if len(source_command) if len(source_command)
let $FZF_DEFAULT_COMMAND = source_command let $FZF_DEFAULT_COMMAND = source_command

View File

@@ -23,10 +23,10 @@ func randResult() Result {
} }
func TestEmptyMerger(t *testing.T) { func TestEmptyMerger(t *testing.T) {
assert(t, EmptyMerger.Length() == 0, "Not empty") assert(t, EmptyMerger(0).Length() == 0, "Not empty")
assert(t, EmptyMerger.count == 0, "Invalid count") assert(t, EmptyMerger(0).count == 0, "Invalid count")
assert(t, len(EmptyMerger.lists) == 0, "Invalid lists") assert(t, len(EmptyMerger(0).lists) == 0, "Invalid lists")
assert(t, len(EmptyMerger.merged) == 0, "Invalid merged list") assert(t, len(EmptyMerger(0).merged) == 0, "Invalid merged list")
} }
func buildLists(partiallySorted bool) ([][]Result, []Result) { func buildLists(partiallySorted bool) ([][]Result, []Result) {

View File

@@ -63,7 +63,7 @@ const usage = `usage: fzf [options]
(default: 10) (default: 10)
--layout=LAYOUT Choose layout: [default|reverse|reverse-list] --layout=LAYOUT Choose layout: [default|reverse|reverse-list]
--border[=STYLE] Draw border around the finder --border[=STYLE] Draw border around the finder
[rounded|sharp|bold|block|double|horizontal|vertical| [rounded|sharp|bold|block|thinblock|double|horizontal|vertical|
top|bottom|left|right|none] (default: rounded) top|bottom|left|right|none] (default: rounded)
--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
@@ -72,7 +72,8 @@ const usage = `usage: fzf [options]
(default: 0 or center) (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|hidden|inline|inline:SEPARATOR] --info=STYLE Finder info style
[default|right|hidden|inline[:SEPARATOR]|inline-right]
--separator=STR String to form horizontal separator on info line --separator=STR String to form horizontal separator on info line
--no-separator Hide info line separator --no-separator Hide info line separator
--scrollbar[=C1[C2]] Scrollbar character(s) (each for main and preview window) --scrollbar[=C1[C2]] Scrollbar character(s) (each for main and preview window)
@@ -194,10 +195,16 @@ type infoStyle int
const ( const (
infoDefault infoStyle = iota infoDefault infoStyle = iota
infoRight
infoInline infoInline
infoInlineRight
infoHidden infoHidden
) )
func (s infoStyle) noExtraLine() bool {
return s == infoInline || s == infoInlineRight || s == infoHidden
}
type labelOpts struct { type labelOpts struct {
label string label string
column int column int
@@ -546,6 +553,8 @@ func parseBorder(str string, optional bool) tui.BorderShape {
return tui.BorderBold return tui.BorderBold
case "block": case "block":
return tui.BorderBlock return tui.BorderBlock
case "thinblock":
return tui.BorderThinBlock
case "double": case "double":
return tui.BorderDouble return tui.BorderDouble
case "horizontal": case "horizontal":
@@ -566,7 +575,7 @@ func parseBorder(str string, optional bool) tui.BorderShape {
if optional && str == "" { if optional && str == "" {
return tui.DefaultBorderShape return tui.DefaultBorderShape
} }
errorExit("invalid border style (expected: rounded|sharp|bold|block|double|horizontal|vertical|top|bottom|left|right|none)") errorExit("invalid border style (expected: rounded|sharp|bold|block|thinblock|double|horizontal|vertical|top|bottom|left|right|none)")
} }
return tui.BorderNone return tui.BorderNone
} }
@@ -1374,8 +1383,12 @@ func parseInfoStyle(str string) (infoStyle, string) {
switch str { switch str {
case "default": case "default":
return infoDefault, "" return infoDefault, ""
case "right":
return infoRight, ""
case "inline": case "inline":
return infoInline, defaultInfoSep return infoInline, defaultInfoSep
case "inline-right":
return infoInlineRight, ""
case "hidden": case "hidden":
return infoHidden, "" return infoHidden, ""
default: default:
@@ -1383,7 +1396,7 @@ func parseInfoStyle(str string) (infoStyle, string) {
if strings.HasPrefix(str, prefix) { if strings.HasPrefix(str, prefix) {
return infoInline, strings.ReplaceAll(str[len(prefix):], "\n", " ") return infoInline, strings.ReplaceAll(str[len(prefix):], "\n", " ")
} }
errorExit("invalid info style (expected: default|hidden|inline|inline:SEPARATOR)") errorExit("invalid info style (expected: default|right|hidden|inline[:SEPARATOR]|inline-right)")
} }
return infoDefault, "" return infoDefault, ""
} }
@@ -1438,6 +1451,8 @@ func parsePreviewWindowImpl(opts *previewOpts, input string, exit func(string))
opts.border = tui.BorderBold opts.border = tui.BorderBold
case "border-block": case "border-block":
opts.border = tui.BorderBlock opts.border = tui.BorderBlock
case "border-thinblock":
opts.border = tui.BorderThinBlock
case "border-double": case "border-double":
opts.border = tui.BorderDouble opts.border = tui.BorderDouble
case "noborder", "border-none": case "noborder", "border-none":

View File

@@ -565,7 +565,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.noExtraLine() {
effectiveMinHeight-- effectiveMinHeight--
} }
effectiveMinHeight += borderLines(opts.BorderShape) effectiveMinHeight += borderLines(opts.BorderShape)
@@ -727,7 +727,7 @@ func (t *Terminal) environ() []string {
func borderLines(shape tui.BorderShape) int { func borderLines(shape tui.BorderShape) int {
switch shape { switch shape {
case tui.BorderHorizontal, tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderBlock, tui.BorderDouble: case tui.BorderHorizontal, tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderBlock, tui.BorderThinBlock, tui.BorderDouble:
return 2 return 2
case tui.BorderTop, tui.BorderBottom: case tui.BorderTop, tui.BorderBottom:
return 1 return 1
@@ -845,7 +845,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.noExtraLine()
} }
func getScrollbar(total int, height int, offset int) (int, int) { func getScrollbar(total int, height int, offset int) (int, int) {
@@ -1085,7 +1085,7 @@ func (t *Terminal) adjustMarginAndPadding() (int, int, [4]int, [4]int) {
if idx == 3 { if idx == 3 {
extraMargin[idx] += 1 + bw extraMargin[idx] += 1 + bw
} }
case tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderBlock, tui.BorderDouble: case tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderBlock, tui.BorderThinBlock, tui.BorderDouble:
extraMargin[idx] += 1 + bw*(idx%2) extraMargin[idx] += 1 + bw*(idx%2)
} }
marginInt[idx] = sizeSpecToInt(idx, sizeSpec) + extraMargin[idx] marginInt[idx] = sizeSpecToInt(idx, sizeSpec) + extraMargin[idx]
@@ -1178,7 +1178,7 @@ func (t *Terminal) resizeWindows(forcePreview bool) {
t.border = t.tui.NewWindow( t.border = t.tui.NewWindow(
marginInt[0], marginInt[3], width+(1+bw), height, marginInt[0], marginInt[3], width+(1+bw), height,
false, tui.MakeBorderStyle(tui.BorderRight, t.unicode)) false, tui.MakeBorderStyle(tui.BorderRight, t.unicode))
case tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderBlock, tui.BorderDouble: case tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderBlock, tui.BorderThinBlock, tui.BorderDouble:
t.border = t.tui.NewWindow( t.border = t.tui.NewWindow(
marginInt[0]-1, marginInt[3]-(1+bw), width+(1+bw)*2, height+2, marginInt[0]-1, marginInt[3]-(1+bw), width+(1+bw)*2, height+2,
false, tui.MakeBorderStyle(t.borderShape, t.unicode)) false, tui.MakeBorderStyle(t.borderShape, t.unicode))
@@ -1212,7 +1212,7 @@ func (t *Terminal) resizeWindows(forcePreview bool) {
} }
t.pborder = t.tui.NewWindow(y, x, w, h, true, previewBorder) t.pborder = t.tui.NewWindow(y, x, w, h, true, previewBorder)
switch previewOpts.border { switch previewOpts.border {
case tui.BorderSharp, tui.BorderRounded, tui.BorderBold, tui.BorderBlock, tui.BorderDouble: case tui.BorderSharp, tui.BorderRounded, tui.BorderBold, tui.BorderBlock, tui.BorderThinBlock, tui.BorderDouble:
pwidth -= (1 + bw) * 2 pwidth -= (1 + bw) * 2
pheight -= 2 pheight -= 2
x += 1 + bw x += 1 + bw
@@ -1356,7 +1356,7 @@ func (t *Terminal) printLabel(window tui.Window, render labelPrinter, opts label
} }
switch borderShape { switch borderShape {
case tui.BorderHorizontal, tui.BorderTop, tui.BorderBottom, tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderBlock, tui.BorderDouble: case tui.BorderHorizontal, tui.BorderTop, tui.BorderBottom, tui.BorderRounded, tui.BorderSharp, tui.BorderBold, tui.BorderBlock, tui.BorderThinBlock, tui.BorderDouble:
if redrawBorder { if redrawBorder {
window.DrawHBorder() window.DrawHBorder()
} }
@@ -1464,9 +1464,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 { printSpinner := func() {
case infoDefault:
t.move(line+1, 0, t.separatorLen == 0)
if t.reading { if t.reading {
duration := int64(spinnerDuration) duration := int64(spinnerDuration)
idx := (time.Now().UnixNano() % (duration * int64(len(t.spinner)))) / duration idx := (time.Now().UnixNano() % (duration * int64(len(t.spinner)))) / duration
@@ -1474,8 +1472,18 @@ func (t *Terminal) printInfo() {
} else { } else {
t.window.Print(" ") // Clear spinner t.window.Print(" ") // Clear spinner
} }
}
switch t.infoStyle {
case infoDefault:
t.move(line+1, 0, t.separatorLen == 0)
printSpinner()
t.move(line+1, 2, false) t.move(line+1, 2, false)
pos = 2 pos = 2
case infoRight:
t.move(line+1, 0, false)
case infoInlineRight:
pos = t.promptLen + t.queryLen[0] + t.queryLen[1] + 1
t.move(line, pos, true)
case infoInline: case infoInline:
pos = t.promptLen + t.queryLen[0] + t.queryLen[1] + 1 pos = t.promptLen + t.queryLen[0] + t.queryLen[1] + 1
str := t.infoSep str := t.infoSep
@@ -1523,14 +1531,55 @@ 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)
} }
printSeparator := func(fillLength int, pad bool) {
// --------_
if t.separatorLen > 0 {
t.separator(t.window, fillLength)
t.window.Print(" ")
} else if pad {
t.window.Print(strings.Repeat(" ", fillLength+1))
}
}
if t.infoStyle == infoRight {
maxWidth := t.window.Width()
if t.reading {
// Need space for spinner and a margin column
maxWidth -= 2
}
output = t.trimMessage(output, maxWidth)
fillLength := t.window.Width() - len(output) - 2
if t.reading {
if fillLength >= 2 {
printSeparator(fillLength-2, true)
}
printSpinner()
t.window.Print(" ")
} else if fillLength >= 0 {
printSeparator(fillLength, true)
}
t.window.CPrint(tui.ColInfo, output)
return
}
if t.infoStyle == infoInlineRight {
pos = util.Max(pos, t.window.Width()-util.StringWidth(output)-3)
if pos >= t.window.Width() {
return
}
t.move(line, pos, false)
printSpinner()
t.window.Print(" ")
pos += 2
}
maxWidth := t.window.Width() - pos maxWidth := t.window.Width() - pos
output = t.trimMessage(output, maxWidth) output = t.trimMessage(output, maxWidth)
t.window.CPrint(tui.ColInfo, output) t.window.CPrint(tui.ColInfo, output)
fillLength := maxWidth - len(output) - 2 fillLength := maxWidth - len(output) - 2
if t.separatorLen > 0 && fillLength > 0 { if fillLength > 0 {
t.window.CPrint(tui.ColSeparator, " ") t.window.CPrint(tui.ColSeparator, " ")
t.separator(t.window, fillLength) printSeparator(fillLength, false)
} }
} }
@@ -1823,7 +1872,7 @@ func (t *Terminal) renderPreviewSpinner() {
if !t.previewer.scrollable { if !t.previewer.scrollable {
if maxWidth > 0 { if maxWidth > 0 {
t.pwindow.Move(0, maxWidth-1) t.pwindow.Move(0, maxWidth-1)
t.pwindow.CPrint(tui.ColSpinner, spin) t.pwindow.CPrint(tui.ColPreviewSpinner, spin)
} }
} else { } else {
offsetString := fmt.Sprintf("%d/%d", t.previewer.offset+1, numLines) offsetString := fmt.Sprintf("%d/%d", t.previewer.offset+1, numLines)
@@ -1835,7 +1884,7 @@ func (t *Terminal) renderPreviewSpinner() {
pos := maxWidth - t.displayWidth(offsetRunes) pos := maxWidth - t.displayWidth(offsetRunes)
t.pwindow.Move(0, pos) t.pwindow.Move(0, pos)
if maxWidth > 0 { if maxWidth > 0 {
t.pwindow.CPrint(tui.ColSpinner, spin) t.pwindow.CPrint(tui.ColPreviewSpinner, spin)
t.pwindow.CPrint(tui.ColInfo.WithAttr(tui.Reverse), string(offsetRunes)) t.pwindow.CPrint(tui.ColInfo.WithAttr(tui.Reverse), string(offsetRunes))
} }
} }

View File

@@ -757,7 +757,7 @@ func (w *LightWindow) DrawHBorder() {
func (w *LightWindow) drawBorder(onlyHorizontal bool) { func (w *LightWindow) drawBorder(onlyHorizontal bool) {
switch w.border.shape { switch w.border.shape {
case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderDouble: case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderThinBlock, BorderDouble:
w.drawBorderAround(onlyHorizontal) w.drawBorderAround(onlyHorizontal)
case BorderHorizontal: case BorderHorizontal:
w.drawBorderHorizontal(true, true) w.drawBorderHorizontal(true, true)

View File

@@ -715,7 +715,7 @@ func (w *TcellWindow) drawBorder(onlyHorizontal bool) {
hw := runewidth.RuneWidth(w.borderStyle.top) hw := runewidth.RuneWidth(w.borderStyle.top)
switch shape { switch shape {
case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderDouble, BorderHorizontal, BorderTop: case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderThinBlock, BorderDouble, BorderHorizontal, BorderTop:
max := right - 2*hw max := right - 2*hw
if shape == BorderHorizontal || shape == BorderTop { if shape == BorderHorizontal || shape == BorderTop {
max = right - hw max = right - hw
@@ -730,7 +730,7 @@ func (w *TcellWindow) drawBorder(onlyHorizontal bool) {
} }
} }
switch shape { switch shape {
case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderDouble, BorderHorizontal, BorderBottom: case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderThinBlock, BorderDouble, BorderHorizontal, BorderBottom:
max := right - 2*hw max := right - 2*hw
if shape == BorderHorizontal || shape == BorderBottom { if shape == BorderHorizontal || shape == BorderBottom {
max = right - hw max = right - hw
@@ -741,13 +741,13 @@ func (w *TcellWindow) drawBorder(onlyHorizontal bool) {
} }
if !onlyHorizontal { if !onlyHorizontal {
switch shape { switch shape {
case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderDouble, BorderVertical, BorderLeft: case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderThinBlock, BorderDouble, BorderVertical, BorderLeft:
for y := top; y < bot; y++ { for y := top; y < bot; y++ {
_screen.SetContent(left, y, w.borderStyle.left, nil, style) _screen.SetContent(left, y, w.borderStyle.left, nil, style)
} }
} }
switch shape { switch shape {
case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderDouble, BorderVertical, BorderRight: case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderThinBlock, BorderDouble, BorderVertical, BorderRight:
vw := runewidth.RuneWidth(w.borderStyle.right) vw := runewidth.RuneWidth(w.borderStyle.right)
for y := top; y < bot; y++ { for y := top; y < bot; y++ {
_screen.SetContent(right-vw, y, w.borderStyle.right, nil, style) _screen.SetContent(right-vw, y, w.borderStyle.right, nil, style)
@@ -755,7 +755,7 @@ func (w *TcellWindow) drawBorder(onlyHorizontal bool) {
} }
} }
switch shape { switch shape {
case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderDouble: case BorderRounded, BorderSharp, BorderBold, BorderBlock, BorderThinBlock, BorderDouble:
_screen.SetContent(left, top, w.borderStyle.topLeft, nil, style) _screen.SetContent(left, top, w.borderStyle.topLeft, nil, style)
_screen.SetContent(right-runewidth.RuneWidth(w.borderStyle.topRight), top, w.borderStyle.topRight, nil, style) _screen.SetContent(right-runewidth.RuneWidth(w.borderStyle.topRight), top, w.borderStyle.topRight, nil, style)
_screen.SetContent(left, bot-1, w.borderStyle.bottomLeft, nil, style) _screen.SetContent(left, bot-1, w.borderStyle.bottomLeft, nil, style)

View File

@@ -315,6 +315,7 @@ const (
BorderSharp BorderSharp
BorderBold BorderBold
BorderBlock BorderBlock
BorderThinBlock
BorderDouble BorderDouble
BorderHorizontal BorderHorizontal
BorderVertical BorderVertical
@@ -408,6 +409,23 @@ func MakeBorderStyle(shape BorderShape, unicode bool) BorderStyle {
bottomLeft: '▙', bottomLeft: '▙',
bottomRight: '▟', bottomRight: '▟',
} }
case BorderThinBlock:
// 🭽▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔🭾
// ▏ ▕
// 🭼▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁🭿
return BorderStyle{
shape: shape,
top: '▔',
bottom: '▁',
left: '▏',
right: '▕',
topLeft: '🭽',
topRight: '🭾',
bottomLeft: '🭼',
bottomRight: '🭿',
}
case BorderDouble: case BorderDouble:
return BorderStyle{ return BorderStyle{
shape: shape, shape: shape,
@@ -538,6 +556,7 @@ var (
ColBorderLabel ColorPair ColBorderLabel ColorPair
ColPreviewLabel ColorPair ColPreviewLabel ColorPair
ColPreviewScrollbar ColorPair ColPreviewScrollbar ColorPair
ColPreviewSpinner ColorPair
) )
func EmptyTheme() *ColorTheme { func EmptyTheme() *ColorTheme {
@@ -769,4 +788,5 @@ func initPalette(theme *ColorTheme) {
ColPreview = pair(theme.PreviewFg, theme.PreviewBg) ColPreview = pair(theme.PreviewFg, theme.PreviewBg)
ColPreviewBorder = pair(theme.PreviewBorder, theme.PreviewBg) ColPreviewBorder = pair(theme.PreviewBorder, theme.PreviewBg)
ColPreviewScrollbar = pair(theme.PreviewScrollbar, theme.PreviewBg) ColPreviewScrollbar = pair(theme.PreviewScrollbar, theme.PreviewBg)
ColPreviewSpinner = pair(theme.Spinner, theme.PreviewBg)
} }

View File

@@ -2707,6 +2707,16 @@ class TestGoFZF < TestBase
tmux.until { assert(_1[-2] == ' 1/100') } tmux.until { assert(_1[-2] == ' 1/100') }
end end
def test_info_right
tmux.send_keys "#{FZF} --info=right --separator x --bind 'start:reload:seq 100; sleep 10'", :Enter
tmux.until { assert_match(%r{xxx [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏] 100/100}, _1[-2]) }
end
def test_info_inline_right
tmux.send_keys "#{FZF} --info=inline-right --bind 'start:reload:seq 100; sleep 10'", :Enter
tmux.until { assert_match(%r{[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏] 100/100}, _1[-1]) }
end
def test_prev_next_selected def test_prev_next_selected
tmux.send_keys 'seq 10 | fzf --multi --bind ctrl-n:next-selected,ctrl-p:prev-selected', :Enter tmux.send_keys 'seq 10 | fzf --multi --bind ctrl-n:next-selected,ctrl-p:prev-selected', :Enter
tmux.until { |lines| assert_equal 10, lines.item_count } tmux.until { |lines| assert_equal 10, lines.item_count }