mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-11-12 08:26:27 +00:00
Add --no-unicode option to draw borders in ASCII characters
Close ##1533
This commit is contained in:
parent
e7d60aac9c
commit
75972d59a8
@ -174,6 +174,11 @@ A synonym for \fB--layout=reverse\fB
|
|||||||
.TP
|
.TP
|
||||||
.B "--border"
|
.B "--border"
|
||||||
Draw border above and below the finder
|
Draw border above and below the finder
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B "--no-unicode"
|
||||||
|
Use ASCII characters instead of Unicode box drawing characters to draw border
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI "--margin=" MARGIN
|
.BI "--margin=" MARGIN
|
||||||
Comma-separated expression for margins around the finder.
|
Comma-separated expression for margins around the finder.
|
||||||
|
@ -195,6 +195,7 @@ type Options struct {
|
|||||||
HeaderLines int
|
HeaderLines int
|
||||||
Margin [4]sizeSpec
|
Margin [4]sizeSpec
|
||||||
Bordered bool
|
Bordered bool
|
||||||
|
Unicode bool
|
||||||
Tabstop int
|
Tabstop int
|
||||||
ClearOnExit bool
|
ClearOnExit bool
|
||||||
Version bool
|
Version bool
|
||||||
@ -244,6 +245,7 @@ func defaultOptions() *Options {
|
|||||||
Header: make([]string, 0),
|
Header: make([]string, 0),
|
||||||
HeaderLines: 0,
|
HeaderLines: 0,
|
||||||
Margin: defaultMargin(),
|
Margin: defaultMargin(),
|
||||||
|
Unicode: true,
|
||||||
Tabstop: 8,
|
Tabstop: 8,
|
||||||
ClearOnExit: true,
|
ClearOnExit: true,
|
||||||
Version: false}
|
Version: false}
|
||||||
@ -1152,6 +1154,10 @@ func parseOptions(opts *Options, allArgs []string) {
|
|||||||
opts.Bordered = false
|
opts.Bordered = false
|
||||||
case "--border":
|
case "--border":
|
||||||
opts.Bordered = true
|
opts.Bordered = true
|
||||||
|
case "--no-unicode":
|
||||||
|
opts.Unicode = false
|
||||||
|
case "--unicode":
|
||||||
|
opts.Unicode = true
|
||||||
case "--margin":
|
case "--margin":
|
||||||
opts.Margin = parseMargin(
|
opts.Margin = parseMargin(
|
||||||
nextString(allArgs, &i, "margin required (TRBL / TB,RL / T,RL,B / T,R,B,L)"))
|
nextString(allArgs, &i, "margin required (TRBL / TB,RL / T,RL,B / T,R,B,L)"))
|
||||||
|
@ -88,6 +88,7 @@ type Terminal struct {
|
|||||||
tabstop int
|
tabstop int
|
||||||
margin [4]sizeSpec
|
margin [4]sizeSpec
|
||||||
strong tui.Attr
|
strong tui.Attr
|
||||||
|
unicode bool
|
||||||
bordered bool
|
bordered bool
|
||||||
cleanExit bool
|
cleanExit bool
|
||||||
border tui.Window
|
border tui.Window
|
||||||
@ -391,6 +392,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
|||||||
printQuery: opts.PrintQuery,
|
printQuery: opts.PrintQuery,
|
||||||
history: opts.History,
|
history: opts.History,
|
||||||
margin: opts.Margin,
|
margin: opts.Margin,
|
||||||
|
unicode: opts.Unicode,
|
||||||
bordered: opts.Bordered,
|
bordered: opts.Bordered,
|
||||||
cleanExit: opts.ClearOnExit,
|
cleanExit: opts.ClearOnExit,
|
||||||
strong: strongAttr,
|
strong: strongAttr,
|
||||||
@ -600,11 +602,12 @@ func (t *Terminal) resizeWindows() {
|
|||||||
marginInt[0]-1,
|
marginInt[0]-1,
|
||||||
marginInt[3],
|
marginInt[3],
|
||||||
width,
|
width,
|
||||||
height+2, tui.BorderHorizontal)
|
height+2, tui.MakeBorderStyle(tui.BorderHorizontal, t.unicode))
|
||||||
}
|
}
|
||||||
|
noBorder := tui.MakeBorderStyle(tui.BorderNone, t.unicode)
|
||||||
if previewVisible {
|
if previewVisible {
|
||||||
createPreviewWindow := func(y int, x int, w int, h int) {
|
createPreviewWindow := func(y int, x int, w int, h int) {
|
||||||
t.pborder = t.tui.NewWindow(y, x, w, h, tui.BorderAround)
|
t.pborder = t.tui.NewWindow(y, x, w, h, tui.MakeBorderStyle(tui.BorderAround, t.unicode))
|
||||||
pwidth := w - 4
|
pwidth := w - 4
|
||||||
// ncurses auto-wraps the line when the cursor reaches the right-end of
|
// ncurses auto-wraps the line when the cursor reaches the right-end of
|
||||||
// the window. To prevent unintended line-wraps, we use the width one
|
// the window. To prevent unintended line-wraps, we use the width one
|
||||||
@ -612,28 +615,28 @@ func (t *Terminal) resizeWindows() {
|
|||||||
if !t.preview.wrap && t.tui.DoesAutoWrap() {
|
if !t.preview.wrap && t.tui.DoesAutoWrap() {
|
||||||
pwidth += 1
|
pwidth += 1
|
||||||
}
|
}
|
||||||
t.pwindow = t.tui.NewWindow(y+1, x+2, pwidth, h-2, tui.BorderNone)
|
t.pwindow = t.tui.NewWindow(y+1, x+2, pwidth, h-2, noBorder)
|
||||||
}
|
}
|
||||||
switch t.preview.position {
|
switch t.preview.position {
|
||||||
case posUp:
|
case posUp:
|
||||||
pheight := calculateSize(height, t.preview.size, minHeight, 3)
|
pheight := calculateSize(height, t.preview.size, minHeight, 3)
|
||||||
t.window = t.tui.NewWindow(
|
t.window = t.tui.NewWindow(
|
||||||
marginInt[0]+pheight, marginInt[3], width, height-pheight, tui.BorderNone)
|
marginInt[0]+pheight, marginInt[3], width, height-pheight, noBorder)
|
||||||
createPreviewWindow(marginInt[0], marginInt[3], width, pheight)
|
createPreviewWindow(marginInt[0], marginInt[3], width, pheight)
|
||||||
case posDown:
|
case posDown:
|
||||||
pheight := calculateSize(height, t.preview.size, minHeight, 3)
|
pheight := calculateSize(height, t.preview.size, minHeight, 3)
|
||||||
t.window = t.tui.NewWindow(
|
t.window = t.tui.NewWindow(
|
||||||
marginInt[0], marginInt[3], width, height-pheight, tui.BorderNone)
|
marginInt[0], marginInt[3], width, height-pheight, noBorder)
|
||||||
createPreviewWindow(marginInt[0]+height-pheight, marginInt[3], width, pheight)
|
createPreviewWindow(marginInt[0]+height-pheight, marginInt[3], width, pheight)
|
||||||
case posLeft:
|
case posLeft:
|
||||||
pwidth := calculateSize(width, t.preview.size, minWidth, 5)
|
pwidth := calculateSize(width, t.preview.size, minWidth, 5)
|
||||||
t.window = t.tui.NewWindow(
|
t.window = t.tui.NewWindow(
|
||||||
marginInt[0], marginInt[3]+pwidth, width-pwidth, height, tui.BorderNone)
|
marginInt[0], marginInt[3]+pwidth, width-pwidth, height, noBorder)
|
||||||
createPreviewWindow(marginInt[0], marginInt[3], pwidth, height)
|
createPreviewWindow(marginInt[0], marginInt[3], pwidth, height)
|
||||||
case posRight:
|
case posRight:
|
||||||
pwidth := calculateSize(width, t.preview.size, minWidth, 5)
|
pwidth := calculateSize(width, t.preview.size, minWidth, 5)
|
||||||
t.window = t.tui.NewWindow(
|
t.window = t.tui.NewWindow(
|
||||||
marginInt[0], marginInt[3], width-pwidth, height, tui.BorderNone)
|
marginInt[0], marginInt[3], width-pwidth, height, noBorder)
|
||||||
createPreviewWindow(marginInt[0], marginInt[3]+width-pwidth, pwidth, height)
|
createPreviewWindow(marginInt[0], marginInt[3]+width-pwidth, pwidth, height)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -641,7 +644,7 @@ func (t *Terminal) resizeWindows() {
|
|||||||
marginInt[0],
|
marginInt[0],
|
||||||
marginInt[3],
|
marginInt[3],
|
||||||
width,
|
width,
|
||||||
height, tui.BorderNone)
|
height, noBorder)
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
@ -163,9 +163,9 @@ func (r *LightRenderer) findOffset() (row int, col int) {
|
|||||||
return -1, -1
|
return -1, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func repeat(s string, times int) string {
|
func repeat(r rune, times int) string {
|
||||||
if times > 0 {
|
if times > 0 {
|
||||||
return strings.Repeat(s, times)
|
return strings.Repeat(string(r), times)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -676,7 +676,7 @@ func (r *LightRenderer) NewWindow(top int, left int, width int, height int, bord
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *LightWindow) drawBorder() {
|
func (w *LightWindow) drawBorder() {
|
||||||
switch w.border {
|
switch w.border.shape {
|
||||||
case BorderAround:
|
case BorderAround:
|
||||||
w.drawBorderAround()
|
w.drawBorderAround()
|
||||||
case BorderHorizontal:
|
case BorderHorizontal:
|
||||||
@ -686,22 +686,24 @@ func (w *LightWindow) drawBorder() {
|
|||||||
|
|
||||||
func (w *LightWindow) drawBorderHorizontal() {
|
func (w *LightWindow) drawBorderHorizontal() {
|
||||||
w.Move(0, 0)
|
w.Move(0, 0)
|
||||||
w.CPrint(ColBorder, AttrRegular, repeat("─", w.width))
|
w.CPrint(ColBorder, AttrRegular, repeat(w.border.horizontal, w.width))
|
||||||
w.Move(w.height-1, 0)
|
w.Move(w.height-1, 0)
|
||||||
w.CPrint(ColBorder, AttrRegular, repeat("─", w.width))
|
w.CPrint(ColBorder, AttrRegular, repeat(w.border.horizontal, w.width))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LightWindow) drawBorderAround() {
|
func (w *LightWindow) drawBorderAround() {
|
||||||
w.Move(0, 0)
|
w.Move(0, 0)
|
||||||
w.CPrint(ColBorder, AttrRegular, "┌"+repeat("─", w.width-2)+"┐")
|
w.CPrint(ColBorder, AttrRegular,
|
||||||
|
string(w.border.topLeft)+repeat(w.border.horizontal, w.width-2)+string(w.border.topRight))
|
||||||
for y := 1; y < w.height-1; y++ {
|
for y := 1; y < w.height-1; y++ {
|
||||||
w.Move(y, 0)
|
w.Move(y, 0)
|
||||||
w.CPrint(ColBorder, AttrRegular, "│")
|
w.CPrint(ColBorder, AttrRegular, string(w.border.vertical))
|
||||||
w.cprint2(colDefault, w.bg, AttrRegular, repeat(" ", w.width-2))
|
w.cprint2(colDefault, w.bg, AttrRegular, repeat(' ', w.width-2))
|
||||||
w.CPrint(ColBorder, AttrRegular, "│")
|
w.CPrint(ColBorder, AttrRegular, string(w.border.vertical))
|
||||||
}
|
}
|
||||||
w.Move(w.height-1, 0)
|
w.Move(w.height-1, 0)
|
||||||
w.CPrint(ColBorder, AttrRegular, "└"+repeat("─", w.width-2)+"┘")
|
w.CPrint(ColBorder, AttrRegular,
|
||||||
|
string(w.border.bottomLeft)+repeat(w.border.horizontal, w.width-2)+string(w.border.bottomRight))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LightWindow) csi(code string) {
|
func (w *LightWindow) csi(code string) {
|
||||||
@ -762,7 +764,7 @@ func (w *LightWindow) MoveAndClear(y int, x int) {
|
|||||||
w.Move(y, x)
|
w.Move(y, x)
|
||||||
// We should not delete preview window on the right
|
// We should not delete preview window on the right
|
||||||
// csi("K")
|
// csi("K")
|
||||||
w.Print(repeat(" ", w.width-x))
|
w.Print(repeat(' ', w.width-x))
|
||||||
w.Move(y, x)
|
w.Move(y, x)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -858,7 +860,7 @@ func wrapLine(input string, prefixLength int, max int, tabstop int) []wrappedLin
|
|||||||
width += w
|
width += w
|
||||||
str := string(r)
|
str := string(r)
|
||||||
if r == '\t' {
|
if r == '\t' {
|
||||||
str = repeat(" ", w)
|
str = repeat(' ', w)
|
||||||
}
|
}
|
||||||
if prefixLength+width <= max {
|
if prefixLength+width <= max {
|
||||||
line += str
|
line += str
|
||||||
|
@ -61,12 +61,8 @@ func (w *TcellWindow) Refresh() {
|
|||||||
}
|
}
|
||||||
w.lastX = 0
|
w.lastX = 0
|
||||||
w.lastY = 0
|
w.lastY = 0
|
||||||
switch w.borderStyle {
|
|
||||||
case BorderAround:
|
w.drawBorder()
|
||||||
w.drawBorder(true)
|
|
||||||
case BorderHorizontal:
|
|
||||||
w.drawBorder(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *TcellWindow) FinishFill() {
|
func (w *TcellWindow) FinishFill() {
|
||||||
@ -570,7 +566,11 @@ func (w *TcellWindow) CFill(fg Color, bg Color, a Attr, str string) FillReturn {
|
|||||||
return w.fillString(str, NewColorPair(fg, bg), a)
|
return w.fillString(str, NewColorPair(fg, bg), a)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *TcellWindow) drawBorder(around bool) {
|
func (w *TcellWindow) drawBorder() {
|
||||||
|
if w.borderStyle.shape == BorderNone {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
left := w.left
|
left := w.left
|
||||||
right := left + w.width
|
right := left + w.width
|
||||||
top := w.top
|
top := w.top
|
||||||
@ -584,19 +584,19 @@ func (w *TcellWindow) drawBorder(around bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for x := left; x < right; x++ {
|
for x := left; x < right; x++ {
|
||||||
_screen.SetContent(x, top, tcell.RuneHLine, nil, style)
|
_screen.SetContent(x, top, w.borderStyle.horizontal, nil, style)
|
||||||
_screen.SetContent(x, bot-1, tcell.RuneHLine, nil, style)
|
_screen.SetContent(x, bot-1, w.borderStyle.horizontal, nil, style)
|
||||||
}
|
}
|
||||||
|
|
||||||
if around {
|
if w.borderStyle.shape == BorderAround {
|
||||||
for y := top; y < bot; y++ {
|
for y := top; y < bot; y++ {
|
||||||
_screen.SetContent(left, y, tcell.RuneVLine, nil, style)
|
_screen.SetContent(left, y, w.borderStyle.vertical, nil, style)
|
||||||
_screen.SetContent(right-1, y, tcell.RuneVLine, nil, style)
|
_screen.SetContent(right-1, y, w.borderStyle.vertical, nil, style)
|
||||||
}
|
}
|
||||||
|
|
||||||
_screen.SetContent(left, top, tcell.RuneULCorner, nil, style)
|
_screen.SetContent(left, top, w.borderStyle.topLeft, nil, style)
|
||||||
_screen.SetContent(right-1, top, tcell.RuneURCorner, nil, style)
|
_screen.SetContent(right-1, top, w.borderStyle.topRight, nil, style)
|
||||||
_screen.SetContent(left, bot-1, tcell.RuneLLCorner, nil, style)
|
_screen.SetContent(left, bot-1, w.borderStyle.bottomLeft, nil, style)
|
||||||
_screen.SetContent(right-1, bot-1, tcell.RuneLRCorner, nil, style)
|
_screen.SetContent(right-1, bot-1, w.borderStyle.bottomRight, nil, style)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,14 +201,47 @@ type MouseEvent struct {
|
|||||||
Mod bool
|
Mod bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type BorderStyle int
|
type BorderShape int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BorderNone BorderStyle = iota
|
BorderNone BorderShape = iota
|
||||||
BorderAround
|
BorderAround
|
||||||
BorderHorizontal
|
BorderHorizontal
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type BorderStyle struct {
|
||||||
|
shape BorderShape
|
||||||
|
horizontal rune
|
||||||
|
vertical rune
|
||||||
|
topLeft rune
|
||||||
|
topRight rune
|
||||||
|
bottomLeft rune
|
||||||
|
bottomRight rune
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeBorderStyle(shape BorderShape, unicode bool) BorderStyle {
|
||||||
|
if unicode {
|
||||||
|
return BorderStyle{
|
||||||
|
shape: shape,
|
||||||
|
horizontal: '─',
|
||||||
|
vertical: '│',
|
||||||
|
topLeft: '┌',
|
||||||
|
topRight: '┐',
|
||||||
|
bottomLeft: '└',
|
||||||
|
bottomRight: '┘',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BorderStyle{
|
||||||
|
shape: shape,
|
||||||
|
horizontal: '-',
|
||||||
|
vertical: '|',
|
||||||
|
topLeft: '+',
|
||||||
|
topRight: '+',
|
||||||
|
bottomLeft: '+',
|
||||||
|
bottomRight: '+',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Renderer interface {
|
type Renderer interface {
|
||||||
Init()
|
Init()
|
||||||
Pause(clear bool)
|
Pause(clear bool)
|
||||||
|
Loading…
Reference in New Issue
Block a user