summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2020-10-26 22:33:41 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2020-10-26 22:51:22 +0900
commit2e8e63fb0b3b62e89472eebe9e86578598e1a541 (patch)
tree8c10978de92b685df67ae4624e13daddbf65c711
parent874f7dd416a4098d657dce7f307b60485993eea1 (diff)
Add more --border options
Instead of drawing the window border in Vim using an extra window, extend the --border option so that we do can it natively. Close #2223 Fix #2184
-rw-r--r--CHANGELOG.md2
-rw-r--r--man/man1/fzf.110
-rw-r--r--plugin/fzf.vim64
-rw-r--r--src/options.go15
-rw-r--r--src/terminal.go50
-rw-r--r--src/tui/light.go43
-rw-r--r--src/tui/tcell.go30
-rw-r--r--src/tui/tui.go5
8 files changed, 154 insertions, 65 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ecbade6b..ed6c9ce9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,6 +27,8 @@ CHANGELOG
--color pointer:reverse,prompt:reverse,input:159 \
--pointer ' '
```
+- More `--border` options
+ - `vertical`, `top`, `bottom`, `left`, `right`
- To indicate if `--multi` mode is enabled, fzf will print the number of
selected items even when no item is selected
```sh
diff --git a/man/man1/fzf.1 b/man/man1/fzf.1
index da2642eb..9f2051ff 100644
--- a/man/man1/fzf.1
+++ b/man/man1/fzf.1
@@ -192,6 +192,16 @@ Draw border around the finder
.br
.BR horizontal " Horizontal lines above and below the finder"
.br
+.BR vertical " Vertical lines on each side of the finder"
+.br
+.BR top
+.br
+.BR bottom
+.br
+.BR left
+.br
+.BR right
+.br
.TP
.B "--no-unicode"
diff --git a/plugin/fzf.vim b/plugin/fzf.vim
index 83e1cef5..065ac156 100644
--- a/plugin/fzf.vim
+++ b/plugin/fzf.vim
@@ -432,6 +432,7 @@ try
elseif use_term
let optstr .= ' --no-height'
endif
+ let optstr .= s:border_opt(get(dict, 'window', 0))
let command = prefix.(use_tmux ? s:fzf_tmux(dict) : fzf_exec).' '.optstr.' > '.temps.result
if use_term
@@ -656,6 +657,27 @@ function! s:getpos()
return {'tab': tabpagenr(), 'win': winnr(), 'winid': win_getid(), 'cnt': winnr('$'), 'tcnt': tabpagenr('$')}
endfunction
+function! s:border_opt(window)
+ if type(a:window) != type({})
+ return ''
+ endif
+
+ " Border style
+ let style = tolower(get(a:window, 'border', 'rounded'))
+ if !has_key(a:window, 'border') && !get(a:window, 'rounded', 1)
+ let style = 'sharp'
+ endif
+
+ let opt = ' --border=' . style
+ if has_key(a:window, 'highlight')
+ let color = s:get_color('fg', a:window.highlight)
+ if len(color)
+ let opt .= ' --color=border:' . color
+ endif
+ endif
+ return opt
+endfunction
+
function! s:split(dict)
let directions = {
\ 'up': ['topleft', 'resize', &lines],
@@ -869,12 +891,8 @@ else
endif
function! s:popup(opts) abort
- " Support ambiwidth == 'double'
- let ambidouble = &ambiwidth == 'double' ? 2 : 1
-
" Size and position
let width = min([max([8, a:opts.width > 1 ? a:opts.width : float2nr(&columns * a:opts.width)]), &columns])
- let width += width % ambidouble
let height = min([max([4, a:opts.height > 1 ? a:opts.height : float2nr(&lines * a:opts.height)]), &lines - has('nvim')])
let row = float2nr(get(a:opts, 'yoffset', 0.5) * (&lines - height))
let col = float2nr(get(a:opts, 'xoffset', 0.5) * (&columns - width))
@@ -885,45 +903,9 @@ function! s:popup(opts) abort
let row += !has('nvim')
let col += !has('nvim')
- " Border style
- let style = tolower(get(a:opts, 'border', 'rounded'))
- if !has_key(a:opts, 'border') && !get(a:opts, 'rounded', 1)
- let style = 'sharp'
- endif
-
- if style =~ 'vertical\|left\|right'
- let mid = style == 'vertical' ? '│' .. repeat(' ', width - 2 * ambidouble) .. '│' :
- \ style == 'left' ? '│' .. repeat(' ', width - 1 * ambidouble)
- \ : repeat(' ', width - 1 * ambidouble) .. '│'
- let border = repeat([mid], height)
- let shift = { 'row': 0, 'col': style == 'right' ? 0 : 2, 'width': style == 'vertical' ? -4 : -2, 'height': 0 }
- elseif style =~ 'horizontal\|top\|bottom'
- let hor = repeat('─', width / ambidouble)
- let mid = repeat(' ', width)
- let border = style == 'horizontal' ? [hor] + repeat([mid], height - 2) + [hor] :
- \ style == 'top' ? [hor] + repeat([mid], height - 1)
- \ : repeat([mid], height - 1) + [hor]
- let shift = { 'row': style == 'bottom' ? 0 : 1, 'col': 0, 'width': 0, 'height': style == 'horizontal' ? -2 : -1 }
- else
- let edges = style == 'sharp' ? ['┌', '┐', '└', '┘'] : ['╭', '╮', '╰', '╯']
- let bar = repeat('─', width / ambidouble - 2)
- let top = edges[0] .. bar .. edges[1]
- let mid = '│' .. repeat(' ', width - 2 * ambidouble) .. '│'
- let bot = edges[2] .. bar .. edges[3]
- let border = [top] + repeat([mid], height - 2) + [bot]
- let shift = { 'row': 1, 'col': 2, 'width': -4, 'height': -2 }
- endif
-
- let highlight = get(a:opts, 'highlight', 'Comment')
- let frame = s:create_popup(highlight, {
- \ 'row': row, 'col': col, 'width': width, 'height': height, 'border': border
- \ })
call s:create_popup('Normal', {
- \ 'row': row + shift.row, 'col': col + shift.col, 'width': width + shift.width, 'height': height + shift.height
+ \ 'row': row, 'col': col, 'width': width, 'height': height
\ })
- if has('nvim')
- execute 'autocmd BufWipeout <buffer> bwipeout '..frame
- endif
endfunction
let s:default_action = {
diff --git a/src/options.go b/src/options.go
index ce000a03..ab5ae27a 100644
--- a/src/options.go
+++ b/src/options.go
@@ -58,7 +58,8 @@ const usage = `usage: fzf [options]
(default: 10)
--layout=LAYOUT Choose layout: [default|reverse|reverse-list]
--border[=STYLE] Draw border around the finder
- [rounded|sharp|horizontal] (default: rounded)
+ [rounded|sharp|horizontal|vertical|
+ top|bottom|left|right] (default: rounded)
--margin=MARGIN Screen margin (TRBL / TB,RL / T,RL,B / T,R,B,L)
--info=STYLE Finder info style [default|inline|hidden]
--prompt=STR Input prompt (default: '> ')
@@ -421,11 +422,21 @@ func parseBorder(str string, optional bool) tui.BorderShape {
return tui.BorderSharp
case "horizontal":
return tui.BorderHorizontal
+ case "vertical":
+ return tui.BorderVertical
+ case "top":
+ return tui.BorderTop
+ case "bottom":
+ return tui.BorderBottom
+ case "left":
+ return tui.BorderLeft
+ case "right":
+ return tui.BorderRight
default:
if optional && str == "" {
return tui.BorderRounded
}
- errorExit("invalid border style (expected: rounded|sharp|horizontal)")
+ errorExit("invalid border style (expected: rounded|sharp|horizontal|vertical|top|bottom|left|right)")
}
return tui.BorderNone
}
diff --git a/src/terminal.go b/src/terminal.go
index d896d1de..85001c7d 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -670,7 +670,7 @@ 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{}
+ marginInt := [4]int{} // TRBL
t.prevLines = make([]itemLine, screenHeight)
for idx, sizeSpec := range t.margin {
if sizeSpec.percent {
@@ -687,6 +687,24 @@ func (t *Terminal) resizeWindows() {
switch t.borderShape {
case tui.BorderHorizontal:
marginInt[idx] += 1 - idx%2
+ case tui.BorderVertical:
+ marginInt[idx] += 2 * (idx % 2)
+ case tui.BorderTop:
+ if idx == 0 {
+ marginInt[idx]++
+ }
+ case tui.BorderRight:
+ if idx == 1 {
+ marginInt[idx] += 2
+ }
+ case tui.BorderBottom:
+ if idx == 2 {
+ marginInt[idx]++
+ }
+ case tui.BorderLeft:
+ if idx == 3 {
+ marginInt[idx] += 2
+ }
case tui.BorderRounded, tui.BorderSharp:
marginInt[idx] += 1 + idx%2
}
@@ -735,17 +753,31 @@ func (t *Terminal) resizeWindows() {
switch t.borderShape {
case tui.BorderHorizontal:
t.border = t.tui.NewWindow(
- marginInt[0]-1,
- marginInt[3],
- width,
- height+2,
+ marginInt[0]-1, marginInt[3], width, height+2,
false, tui.MakeBorderStyle(tui.BorderHorizontal, t.unicode))
+ case tui.BorderVertical:
+ t.border = t.tui.NewWindow(
+ marginInt[0], marginInt[3]-2, width+4, height,
+ false, tui.MakeBorderStyle(tui.BorderVertical, t.unicode))
+ case tui.BorderTop:
+ t.border = t.tui.NewWindow(
+ marginInt[0]-1, marginInt[3], width, height+1,
+ false, tui.MakeBorderStyle(tui.BorderTop, t.unicode))
+ case tui.BorderBottom:
+ t.border = t.tui.NewWindow(
+ marginInt[0], marginInt[3], width, height+1,
+ false, tui.MakeBorderStyle(tui.BorderBottom, t.unicode))
+ case tui.BorderLeft:
+ t.border = t.tui.NewWindow(
+ marginInt[0], marginInt[3]-2, width+2, height,
+ false, tui.MakeBorderStyle(tui.BorderLeft, t.unicode))
+ case tui.BorderRight:
+ t.border = t.tui.NewWindow(
+ marginInt[0], marginInt[3], width+2, height,
+ false, tui.MakeBorderStyle(tui.BorderRight, t.unicode))
case tui.BorderRounded, tui.BorderSharp:
t.border = t.tui.NewWindow(
- marginInt[0]-1,
- marginInt[3]-2,
- width+4,
- height+2,
+ marginInt[0]-1, marginInt[3]-2, width+4, height+2,
false, tui.MakeBorderStyle(t.borderShape, t.unicode))
}
noBorder := tui.MakeBorderStyle(tui.BorderNone, t.unicode)
diff --git a/src/tui/light.go b/src/tui/light.go
index 6bd08216..ad536f6d 100644
--- a/src/tui/light.go
+++ b/src/tui/light.go
@@ -653,15 +653,46 @@ func (w *LightWindow) drawBorder() {
case BorderRounded, BorderSharp:
w.drawBorderAround()
case BorderHorizontal:
- w.drawBorderHorizontal()
+ w.drawBorderHorizontal(true, true)
+ case BorderVertical:
+ w.drawBorderVertical(true, true)
+ case BorderTop:
+ w.drawBorderHorizontal(true, false)
+ case BorderBottom:
+ w.drawBorderHorizontal(false, true)
+ case BorderLeft:
+ w.drawBorderVertical(true, false)
+ case BorderRight:
+ w.drawBorderVertical(false, true)
}
}
-func (w *LightWindow) drawBorderHorizontal() {
- w.Move(0, 0)
- w.CPrint(ColBorder, repeat(w.border.horizontal, w.width))
- w.Move(w.height-1, 0)
- w.CPrint(ColBorder, repeat(w.border.horizontal, w.width))
+func (w *LightWindow) drawBorderHorizontal(top, bottom bool) {
+ if top {
+ w.Move(0, 0)
+ w.CPrint(ColBorder, repeat(w.border.horizontal, w.width))
+ }
+ if bottom {
+ w.Move(w.height-1, 0)
+ w.CPrint(ColBorder, repeat(w.border.horizontal, w.width))
+ }
+}
+
+func (w *LightWindow) drawBorderVertical(left, right bool) {
+ width := w.width - 2
+ if !left || !right {
+ width++
+ }
+ for y := 0; y < w.height; y++ {
+ w.Move(y, 0)
+ if left {
+ w.CPrint(ColBorder, string(w.border.vertical))
+ }
+ w.CPrint(ColBorder, repeat(' ', width))
+ if right {
+ w.CPrint(ColBorder, string(w.border.vertical))
+ }
+ }
}
func (w *LightWindow) drawBorderAround() {
diff --git a/src/tui/tcell.go b/src/tui/tcell.go
index 0ad1488f..4f80d069 100644
--- a/src/tui/tcell.go
+++ b/src/tui/tcell.go
@@ -583,7 +583,8 @@ func (w *TcellWindow) CFill(fg Color, bg Color, a Attr, str string) FillReturn {
}
func (w *TcellWindow) drawBorder() {
- if w.borderStyle.shape == BorderNone {
+ shape := w.borderStyle.shape
+ if shape == BorderNone {
return
}
@@ -603,17 +604,32 @@ func (w *TcellWindow) drawBorder() {
style = w.normal.style()
}
- for x := left; x < right; x++ {
- _screen.SetContent(x, top, w.borderStyle.horizontal, nil, style)
- _screen.SetContent(x, bot-1, w.borderStyle.horizontal, nil, style)
+ switch shape {
+ case BorderRounded, BorderSharp, BorderHorizontal, BorderTop:
+ for x := left; x < right; x++ {
+ _screen.SetContent(x, top, w.borderStyle.horizontal, nil, style)
+ }
}
-
- if w.borderStyle.shape != BorderHorizontal {
+ switch shape {
+ case BorderRounded, BorderSharp, BorderHorizontal, BorderBottom:
+ for x := left; x < right; x++ {
+ _screen.SetContent(x, bot-1, w.borderStyle.horizontal, nil, style)
+ }
+ }
+ switch shape {
+ case BorderRounded, BorderSharp, BorderVertical, BorderLeft:
for y := top; y < bot; y++ {
_screen.SetContent(left, y, w.borderStyle.vertical, nil, style)
+ }
+ }
+ switch shape {
+ case BorderRounded, BorderSharp, BorderVertical, BorderRight:
+ for y := top; y < bot; y++ {
_screen.SetContent(right-1, y, w.borderStyle.vertical, nil, style)
}
-
+ }
+ switch shape {
+ case BorderRounded, BorderSharp:
_screen.SetContent(left, top, w.borderStyle.topLeft, nil, style)
_screen.SetContent(right-1, top, w.borderStyle.topRight, nil, style)
_screen.SetContent(left, bot-1, w.borderStyle.bottomLeft, nil, style)
diff --git a/src/tui/tui.go b/src/tui/tui.go
index 40c75112..3cade215 100644
--- a/src/tui/tui.go
+++ b/src/tui/tui.go
@@ -259,6 +259,11 @@ const (
BorderRounded
BorderSharp
BorderHorizontal
+ BorderVertical
+ BorderTop
+ BorderBottom
+ BorderLeft
+ BorderRight
)
type BorderStyle struct {