mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-10 17:51:58 -07:00
Add more --border options; default changed to "rounded"
--border option now takes an optional argument that defines the style - rounded (new default) - sharp - horizontal (previous default)
This commit is contained in:
@@ -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
|
||||
THE SOFTWARE.
|
||||
..
|
||||
.TH fzf 1 "Feb 2020" "fzf 0.21.0" "fzf - a command-line fuzzy finder"
|
||||
.TH fzf 1 "Mar 2020" "fzf 0.21.0" "fzf - a command-line fuzzy finder"
|
||||
|
||||
.SH NAME
|
||||
fzf - a command-line fuzzy finder
|
||||
@@ -178,8 +178,16 @@ Choose the layout (default: default)
|
||||
A synonym for \fB--layout=reverse\fB
|
||||
|
||||
.TP
|
||||
.B "--border"
|
||||
Draw border above and below the finder
|
||||
.BI "--border" [=STYLE]
|
||||
Draw border around the finder
|
||||
|
||||
.br
|
||||
.BR rounded " Border with rounded corners (default)"
|
||||
.br
|
||||
.BR sharp " Border with sharp corners"
|
||||
.br
|
||||
.BR horizontal " Horizontal lines above and below the finder"
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B "--no-unicode"
|
||||
|
@@ -57,7 +57,8 @@ const usage = `usage: fzf [options]
|
||||
--min-height=HEIGHT Minimum height when --height is given in percent
|
||||
(default: 10)
|
||||
--layout=LAYOUT Choose layout: [default|reverse|reverse-list]
|
||||
--border Draw border above and below the finder
|
||||
--border[=STYLE] Draw border around the finder
|
||||
[rounded|sharp|horizontal] (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: '> ')
|
||||
@@ -212,7 +213,7 @@ type Options struct {
|
||||
Header []string
|
||||
HeaderLines int
|
||||
Margin [4]sizeSpec
|
||||
Bordered bool
|
||||
BorderShape tui.BorderShape
|
||||
Unicode bool
|
||||
Tabstop int
|
||||
ClearOnExit bool
|
||||
@@ -301,12 +302,12 @@ func nextString(args []string, i *int, message string) string {
|
||||
return args[*i]
|
||||
}
|
||||
|
||||
func optionalNextString(args []string, i *int) string {
|
||||
if len(args) > *i+1 && !strings.HasPrefix(args[*i+1], "-") {
|
||||
func optionalNextString(args []string, i *int) (bool, string) {
|
||||
if len(args) > *i+1 && !strings.HasPrefix(args[*i+1], "-") && !strings.HasPrefix(args[*i+1], "+") {
|
||||
*i++
|
||||
return args[*i]
|
||||
return true, args[*i]
|
||||
}
|
||||
return ""
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func atoi(str string) int {
|
||||
@@ -400,6 +401,23 @@ func parseAlgo(str string) algo.Algo {
|
||||
return algo.FuzzyMatchV2
|
||||
}
|
||||
|
||||
func parseBorder(str string, optional bool) tui.BorderShape {
|
||||
switch str {
|
||||
case "rounded":
|
||||
return tui.BorderRounded
|
||||
case "sharp":
|
||||
return tui.BorderSharp
|
||||
case "horizontal":
|
||||
return tui.BorderHorizontal
|
||||
default:
|
||||
if optional && str == "" {
|
||||
return tui.BorderRounded
|
||||
}
|
||||
errorExit("invalid border style (expected: rounded|sharp|horizontal)")
|
||||
}
|
||||
return tui.BorderNone
|
||||
}
|
||||
|
||||
func parseKeyChords(str string, message string) map[int]string {
|
||||
if len(str) == 0 {
|
||||
errorExit(message)
|
||||
@@ -1098,7 +1116,7 @@ func parseOptions(opts *Options, allArgs []string) {
|
||||
case "--bind":
|
||||
parseKeymap(opts.Keymap, nextString(allArgs, &i, "bind expression required"))
|
||||
case "--color":
|
||||
spec := optionalNextString(allArgs, &i)
|
||||
_, spec := optionalNextString(allArgs, &i)
|
||||
if len(spec) == 0 {
|
||||
opts.Theme = tui.EmptyTheme()
|
||||
} else {
|
||||
@@ -1246,9 +1264,10 @@ func parseOptions(opts *Options, allArgs []string) {
|
||||
case "--no-margin":
|
||||
opts.Margin = defaultMargin()
|
||||
case "--no-border":
|
||||
opts.Bordered = false
|
||||
opts.BorderShape = tui.BorderNone
|
||||
case "--border":
|
||||
opts.Bordered = true
|
||||
hasArg, arg := optionalNextString(allArgs, &i)
|
||||
opts.BorderShape = parseBorder(arg, !hasArg)
|
||||
case "--no-unicode":
|
||||
opts.Unicode = false
|
||||
case "--unicode":
|
||||
@@ -1273,6 +1292,8 @@ func parseOptions(opts *Options, allArgs []string) {
|
||||
opts.Filter = &value
|
||||
} else if match, value := optString(arg, "-d", "--delimiter="); match {
|
||||
opts.Delimiter = delimiterRegexp(value)
|
||||
} else if match, value := optString(arg, "--border="); match {
|
||||
opts.BorderShape = parseBorder(value, false)
|
||||
} else if match, value := optString(arg, "--prompt="); match {
|
||||
opts.Prompt = value
|
||||
} else if match, value := optString(arg, "--pointer="); match {
|
||||
|
@@ -100,7 +100,7 @@ type Terminal struct {
|
||||
margin [4]sizeSpec
|
||||
strong tui.Attr
|
||||
unicode bool
|
||||
bordered bool
|
||||
borderShape tui.BorderShape
|
||||
cleanExit bool
|
||||
border tui.Window
|
||||
window tui.Window
|
||||
@@ -370,9 +370,9 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
||||
effectiveMinHeight *= 2
|
||||
}
|
||||
if opts.InfoStyle != infoDefault {
|
||||
effectiveMinHeight -= 1
|
||||
effectiveMinHeight--
|
||||
}
|
||||
if opts.Bordered {
|
||||
if opts.BorderShape != tui.BorderNone {
|
||||
effectiveMinHeight += 2
|
||||
}
|
||||
return util.Min(termHeight, util.Max(maxHeight, effectiveMinHeight))
|
||||
@@ -418,7 +418,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
||||
history: opts.History,
|
||||
margin: opts.Margin,
|
||||
unicode: opts.Unicode,
|
||||
bordered: opts.Bordered,
|
||||
borderShape: opts.BorderShape,
|
||||
cleanExit: opts.ClearOnExit,
|
||||
strong: strongAttr,
|
||||
cycle: opts.Cycle,
|
||||
@@ -595,8 +595,11 @@ func (t *Terminal) resizeWindows() {
|
||||
} else {
|
||||
marginInt[idx] = int(sizeSpec.size)
|
||||
}
|
||||
if t.bordered && idx%2 == 0 {
|
||||
marginInt[idx] += 1
|
||||
switch t.borderShape {
|
||||
case tui.BorderHorizontal:
|
||||
marginInt[idx] += 1 - idx%2
|
||||
case tui.BorderRounded, tui.BorderSharp:
|
||||
marginInt[idx] += 1 + idx%2
|
||||
}
|
||||
}
|
||||
adjust := func(idx1 int, idx2 int, max int, min int) {
|
||||
@@ -636,18 +639,26 @@ func (t *Terminal) resizeWindows() {
|
||||
|
||||
width := screenWidth - marginInt[1] - marginInt[3]
|
||||
height := screenHeight - marginInt[0] - marginInt[2]
|
||||
if t.bordered {
|
||||
switch t.borderShape {
|
||||
case tui.BorderHorizontal:
|
||||
t.border = t.tui.NewWindow(
|
||||
marginInt[0]-1,
|
||||
marginInt[3],
|
||||
width,
|
||||
height+2,
|
||||
false, tui.MakeBorderStyle(tui.BorderHorizontal, t.unicode))
|
||||
case tui.BorderRounded, tui.BorderSharp:
|
||||
t.border = t.tui.NewWindow(
|
||||
marginInt[0]-1,
|
||||
marginInt[3]-2,
|
||||
width+4,
|
||||
height+2,
|
||||
false, tui.MakeBorderStyle(t.borderShape, t.unicode))
|
||||
}
|
||||
noBorder := tui.MakeBorderStyle(tui.BorderNone, t.unicode)
|
||||
if previewVisible {
|
||||
createPreviewWindow := func(y int, x int, w int, h int) {
|
||||
previewBorder := tui.MakeBorderStyle(tui.BorderAround, t.unicode)
|
||||
previewBorder := tui.MakeBorderStyle(tui.BorderRounded, t.unicode)
|
||||
if !t.preview.border {
|
||||
previewBorder = tui.MakeTransparentBorder()
|
||||
}
|
||||
@@ -1146,7 +1157,7 @@ func (t *Terminal) refresh() {
|
||||
t.placeCursor()
|
||||
if !t.suppress {
|
||||
windows := make([]tui.Window, 0, 4)
|
||||
if t.bordered {
|
||||
if t.borderShape != tui.BorderNone {
|
||||
windows = append(windows, t.border)
|
||||
}
|
||||
if t.hasPreviewWindow() {
|
||||
|
@@ -105,6 +105,7 @@ type LightRenderer struct {
|
||||
type LightWindow struct {
|
||||
renderer *LightRenderer
|
||||
colored bool
|
||||
preview bool
|
||||
border BorderStyle
|
||||
top int
|
||||
left int
|
||||
@@ -681,6 +682,7 @@ func (r *LightRenderer) NewWindow(top int, left int, width int, height int, prev
|
||||
w := &LightWindow{
|
||||
renderer: r,
|
||||
colored: r.theme != nil,
|
||||
preview: preview,
|
||||
border: borderStyle,
|
||||
top: top,
|
||||
left: left,
|
||||
@@ -704,7 +706,7 @@ func (r *LightRenderer) NewWindow(top int, left int, width int, height int, prev
|
||||
|
||||
func (w *LightWindow) drawBorder() {
|
||||
switch w.border.shape {
|
||||
case BorderAround:
|
||||
case BorderRounded, BorderSharp:
|
||||
w.drawBorderAround()
|
||||
case BorderHorizontal:
|
||||
w.drawBorderHorizontal()
|
||||
@@ -720,16 +722,20 @@ func (w *LightWindow) drawBorderHorizontal() {
|
||||
|
||||
func (w *LightWindow) drawBorderAround() {
|
||||
w.Move(0, 0)
|
||||
w.CPrint(ColPreviewBorder, AttrRegular,
|
||||
color := ColBorder
|
||||
if w.preview {
|
||||
color = ColPreviewBorder
|
||||
}
|
||||
w.CPrint(color, AttrRegular,
|
||||
string(w.border.topLeft)+repeat(w.border.horizontal, w.width-2)+string(w.border.topRight))
|
||||
for y := 1; y < w.height-1; y++ {
|
||||
w.Move(y, 0)
|
||||
w.CPrint(ColPreviewBorder, AttrRegular, string(w.border.vertical))
|
||||
w.CPrint(ColPreviewBorder, AttrRegular, repeat(' ', w.width-2))
|
||||
w.CPrint(ColPreviewBorder, AttrRegular, string(w.border.vertical))
|
||||
w.CPrint(color, AttrRegular, string(w.border.vertical))
|
||||
w.CPrint(color, AttrRegular, repeat(' ', w.width-2))
|
||||
w.CPrint(color, AttrRegular, string(w.border.vertical))
|
||||
}
|
||||
w.Move(w.height-1, 0)
|
||||
w.CPrint(ColPreviewBorder, AttrRegular,
|
||||
w.CPrint(color, AttrRegular,
|
||||
string(w.border.bottomLeft)+repeat(w.border.horizontal, w.width-2)+string(w.border.bottomRight))
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,7 @@ type Attr tcell.Style
|
||||
|
||||
type TcellWindow struct {
|
||||
color bool
|
||||
preview bool
|
||||
top int
|
||||
left int
|
||||
width int
|
||||
@@ -418,6 +419,7 @@ func (r *FullscreenRenderer) NewWindow(top int, left int, width int, height int,
|
||||
}
|
||||
return &TcellWindow{
|
||||
color: r.theme != nil,
|
||||
preview: preview,
|
||||
top: top,
|
||||
left: left,
|
||||
width: width,
|
||||
@@ -591,7 +593,7 @@ func (w *TcellWindow) drawBorder() {
|
||||
|
||||
var style tcell.Style
|
||||
if w.color {
|
||||
if w.borderStyle.shape == BorderAround {
|
||||
if w.preview {
|
||||
style = ColPreviewBorder.style()
|
||||
} else {
|
||||
style = ColBorder.style()
|
||||
@@ -605,7 +607,7 @@ func (w *TcellWindow) drawBorder() {
|
||||
_screen.SetContent(x, bot-1, w.borderStyle.horizontal, nil, style)
|
||||
}
|
||||
|
||||
if w.borderStyle.shape == BorderAround {
|
||||
if w.borderStyle.shape != BorderHorizontal {
|
||||
for y := top; y < bot; y++ {
|
||||
_screen.SetContent(left, y, w.borderStyle.vertical, nil, style)
|
||||
_screen.SetContent(right-1, y, w.borderStyle.vertical, nil, style)
|
||||
|
@@ -210,7 +210,8 @@ type BorderShape int
|
||||
|
||||
const (
|
||||
BorderNone BorderShape = iota
|
||||
BorderAround
|
||||
BorderRounded
|
||||
BorderSharp
|
||||
BorderHorizontal
|
||||
)
|
||||
|
||||
@@ -228,6 +229,7 @@ type BorderCharacter int
|
||||
|
||||
func MakeBorderStyle(shape BorderShape, unicode bool) BorderStyle {
|
||||
if unicode {
|
||||
if shape == BorderRounded {
|
||||
return BorderStyle{
|
||||
shape: shape,
|
||||
horizontal: '─',
|
||||
@@ -238,6 +240,16 @@ func MakeBorderStyle(shape BorderShape, unicode bool) BorderStyle {
|
||||
bottomRight: '╯',
|
||||
}
|
||||
}
|
||||
return BorderStyle{
|
||||
shape: shape,
|
||||
horizontal: '─',
|
||||
vertical: '│',
|
||||
topLeft: '┌',
|
||||
topRight: '┐',
|
||||
bottomLeft: '└',
|
||||
bottomRight: '┘',
|
||||
}
|
||||
}
|
||||
return BorderStyle{
|
||||
shape: shape,
|
||||
horizontal: '-',
|
||||
@@ -251,7 +263,7 @@ func MakeBorderStyle(shape BorderShape, unicode bool) BorderStyle {
|
||||
|
||||
func MakeTransparentBorder() BorderStyle {
|
||||
return BorderStyle{
|
||||
shape: BorderAround,
|
||||
shape: BorderRounded,
|
||||
horizontal: ' ',
|
||||
vertical: ' ',
|
||||
topLeft: ' ',
|
||||
|
Reference in New Issue
Block a user