diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index ec0def75..04e7fc66 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -116,6 +116,9 @@ Reverse orientation .B "--no-hscroll" Disable horizontal scroll .TP +.B "--inline-info" +Display finder info inline with the query +.TP .BI "--prompt=" "STR" Input prompt (default: '> ') .SS Scripting diff --git a/src/options.go b/src/options.go index 25dcfb3e..723c2611 100644 --- a/src/options.go +++ b/src/options.go @@ -40,6 +40,7 @@ const usage = `usage: fzf [options] --black Use black background --reverse Reverse orientation --no-hscroll Disable horizontal scroll + --inline-info Display finder info inline with the query --prompt=STR Input prompt (default: '> ') Scripting @@ -105,6 +106,7 @@ type Options struct { Black bool Reverse bool Hscroll bool + InlineInfo bool Prompt string Query string Select1 bool @@ -141,6 +143,7 @@ func defaultOptions() *Options { Black: false, Reverse: false, Hscroll: true, + InlineInfo: false, Prompt: "> ", Query: "", Select1: false, @@ -364,6 +367,10 @@ func parseOptions(opts *Options, allArgs []string) { opts.Hscroll = true case "--no-hscroll": opts.Hscroll = false + case "--inline-info": + opts.InlineInfo = true + case "--no-inline-info": + opts.InlineInfo = false case "-1", "--select-1": opts.Select1 = true case "+1", "--no-select-1": diff --git a/src/terminal.go b/src/terminal.go index a8a85da0..cae8bf7b 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -20,6 +20,7 @@ import ( // Terminal represents terminal input/output type Terminal struct { + inlineInfo bool prompt string reverse bool hscroll bool @@ -83,6 +84,7 @@ const ( func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { input := []rune(opts.Query) return &Terminal{ + inlineInfo: opts.InlineInfo, prompt: opts.Prompt, reverse: opts.Reverse, hscroll: opts.Hscroll, @@ -229,14 +231,23 @@ func (t *Terminal) printPrompt() { } func (t *Terminal) printInfo() { - t.move(1, 0, true) - if t.reading { - duration := int64(spinnerDuration) - idx := (time.Now().UnixNano() % (duration * int64(len(_spinner)))) / duration - C.CPrint(C.ColSpinner, true, _spinner[idx]) + if t.inlineInfo { + t.move(0, len(t.prompt)+displayWidth(t.input)+1, true) + if t.reading { + C.CPrint(C.ColSpinner, true, " < ") + } else { + C.CPrint(C.ColPrompt, true, " < ") + } + } else { + t.move(1, 0, true) + if t.reading { + duration := int64(spinnerDuration) + idx := (time.Now().UnixNano() % (duration * int64(len(_spinner)))) / duration + C.CPrint(C.ColSpinner, true, _spinner[idx]) + } + t.move(1, 2, false) } - t.move(1, 2, false) output := fmt.Sprintf("%d/%d", t.merger.Length(), t.count) if t.toggleSort > 0 { if t.sort { @@ -257,10 +268,16 @@ func (t *Terminal) printInfo() { func (t *Terminal) printList() { t.constrain() - maxy := maxItems() + maxy := t.maxItems() count := t.merger.Length() - t.offset for i := 0; i < maxy; i++ { - t.move(i+2, 0, true) + var line int + if t.inlineInfo { + line = i + 1 + } else { + line = i + 2 + } + t.move(line, 0, true) if i < count { t.printItem(t.merger.Get(i+t.offset), i == t.cy-t.offset) } @@ -515,6 +532,9 @@ func (t *Terminal) Loop() { switch req { case reqPrompt: t.printPrompt() + if t.inlineInfo { + t.printInfo() + } case reqInfo: t.printInfo() case reqList: @@ -659,10 +679,10 @@ func (t *Terminal) Loop() { case C.Del: t.delChar() case C.PgUp: - t.vmove(maxItems() - 1) + t.vmove(t.maxItems() - 1) req(reqList) case C.PgDn: - t.vmove(-(maxItems() - 1)) + t.vmove(-(t.maxItems() - 1)) req(reqList) case C.AltB: t.cx = findLastMatch("[^[:alnum:]][[:alnum:]]", string(t.input[:t.cx])) + 1 @@ -685,6 +705,10 @@ func (t *Terminal) Loop() { if !t.reverse { my = C.MaxY() - my - 1 } + min := 2 + if t.inlineInfo { + min = 1 + } if me.S != 0 { // Scroll if t.merger.Length() > 0 { @@ -696,8 +720,8 @@ func (t *Terminal) Loop() { } } else if me.Double { // Double-click - if my >= 2 { - if t.vset(t.offset+my-2) && t.cy < t.merger.Length() { + if my >= min { + if t.vset(t.offset+my-min) && t.cy < t.merger.Length() { req(reqClose) } } @@ -705,9 +729,9 @@ func (t *Terminal) Loop() { if my == 0 && mx >= 0 { // Prompt t.cx = mx - } else if my >= 2 { + } else if my >= min { // List - if t.vset(t.offset+my-2) && t.multi && me.Mod { + if t.vset(t.offset+my-min) && t.multi && me.Mod { toggle() } req(reqList) @@ -728,7 +752,7 @@ func (t *Terminal) Loop() { func (t *Terminal) constrain() { count := t.merger.Length() - height := C.MaxY() - 2 + height := t.maxItems() diffpos := t.cy - t.offset t.cy = util.Constrain(t.cy, 0, count-1) @@ -761,6 +785,10 @@ func (t *Terminal) vset(o int) bool { return t.cy == o } -func maxItems() int { - return C.MaxY() - 2 +func (t *Terminal) maxItems() int { + if t.inlineInfo { + return C.MaxY() - 1 + } else { + return C.MaxY() - 2 + } }