mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-25 17:33:50 -07:00
Add --no-input to hide the input section (#4210)
Close #2890 Close #1396 You can't type in queries in this mode, and the only way to trigger an fzf search is to use `search(...)` action. # Click header to trigger search fzf --header '[src] [test]' --no-input --layout reverse \ --header-border bottom --input-border \ --bind 'click-header:transform-search:echo ${FZF_CLICK_HEADER_WORD:1:-1}'
This commit is contained in:
@@ -28,6 +28,13 @@ CHANGELOG
|
|||||||
```
|
```
|
||||||
- `$FZF_KEY` was updated to expose the type of the click. e.g. `click`, `ctrl-click`, etc. You can use it to implement a more sophisticated behavior.
|
- `$FZF_KEY` was updated to expose the type of the click. e.g. `click`, `ctrl-click`, etc. You can use it to implement a more sophisticated behavior.
|
||||||
- `kill` completion for bash and zsh were updated to use this feature
|
- `kill` completion for bash and zsh were updated to use this feature
|
||||||
|
- Added `--no-input` option to completely disable and hide the input section
|
||||||
|
```sh
|
||||||
|
# Click header to trigger search
|
||||||
|
fzf --header '[src] [test]' --no-input --layout reverse \
|
||||||
|
--header-border bottom --input-border \
|
||||||
|
--bind 'click-header:transform-search:echo ${FZF_CLICK_HEADER_WORD:1:-1}'
|
||||||
|
```
|
||||||
- Extended `{q}` placeholder to support ranges. e.g. `{q:1}`, `{q:2..}`, etc.
|
- Extended `{q}` placeholder to support ranges. e.g. `{q:1}`, `{q:2..}`, etc.
|
||||||
- Added `search(...)` and `transform-search(...)` action to trigger an fzf search with an arbitrary query string. This can be used to extend the search syntax of fzf. In the following example, fzf will use the first word of the query to trigger ripgrep search, and use the rest of the query to perform fzf search within the result.
|
- Added `search(...)` and `transform-search(...)` action to trigger an fzf search with an arbitrary query string. This can be used to extend the search syntax of fzf. In the following example, fzf will use the first word of the query to trigger ripgrep search, and use the rest of the query to perform fzf search within the result.
|
||||||
```sh
|
```sh
|
||||||
|
@@ -620,6 +620,11 @@ Position of the list label
|
|||||||
|
|
||||||
.SS INPUT SECTION
|
.SS INPUT SECTION
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B "\-\-no\-input"
|
||||||
|
Disable and hide the input section. You can no longer type in queries. To
|
||||||
|
trigger a search, use \fBsearch\fR action.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI "\-\-prompt=" "STR"
|
.BI "\-\-prompt=" "STR"
|
||||||
Input prompt (default: '> ')
|
Input prompt (default: '> ')
|
||||||
|
@@ -127,6 +127,7 @@ Usage: fzf [options]
|
|||||||
(default: 0 or center)
|
(default: 0 or center)
|
||||||
|
|
||||||
INPUT SECTION
|
INPUT SECTION
|
||||||
|
--no-input Disable and hide the input section
|
||||||
--prompt=STR Input prompt (default: '> ')
|
--prompt=STR Input prompt (default: '> ')
|
||||||
--info=STYLE Finder info style
|
--info=STYLE Finder info style
|
||||||
[default|right|hidden|inline[-right][:PREFIX]]
|
[default|right|hidden|inline[-right][:PREFIX]]
|
||||||
@@ -538,6 +539,7 @@ type Options struct {
|
|||||||
Scheme string
|
Scheme string
|
||||||
Extended bool
|
Extended bool
|
||||||
Phony bool
|
Phony bool
|
||||||
|
Inputless bool
|
||||||
Case Case
|
Case Case
|
||||||
Normalize bool
|
Normalize bool
|
||||||
Nth []Range
|
Nth []Range
|
||||||
@@ -659,6 +661,7 @@ func defaultOptions() *Options {
|
|||||||
Scheme: "", // Unknown
|
Scheme: "", // Unknown
|
||||||
Extended: true,
|
Extended: true,
|
||||||
Phony: false,
|
Phony: false,
|
||||||
|
Inputless: false,
|
||||||
Case: CaseSmart,
|
Case: CaseSmart,
|
||||||
Normalize: true,
|
Normalize: true,
|
||||||
Nth: make([]Range, 0),
|
Nth: make([]Range, 0),
|
||||||
@@ -2315,6 +2318,8 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
|||||||
opts.Phony = false
|
opts.Phony = false
|
||||||
case "--disabled", "--phony":
|
case "--disabled", "--phony":
|
||||||
opts.Phony = true
|
opts.Phony = true
|
||||||
|
case "--no-input":
|
||||||
|
opts.Inputless = true
|
||||||
case "--tiebreak":
|
case "--tiebreak":
|
||||||
str, err := nextString("sort criterion required")
|
str, err := nextString("sort criterion required")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -3064,6 +3069,9 @@ func noSeparatorLine(style infoStyle, separator bool) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (opts *Options) noSeparatorLine() bool {
|
func (opts *Options) noSeparatorLine() bool {
|
||||||
|
if opts.Inputless {
|
||||||
|
return true
|
||||||
|
}
|
||||||
sep := opts.Separator == nil && !opts.InputBorderShape.Visible() || opts.Separator != nil && len(*opts.Separator) > 0
|
sep := opts.Separator == nil && !opts.InputBorderShape.Visible() || opts.Separator != nil && len(*opts.Separator) > 0
|
||||||
return noSeparatorLine(opts.InfoStyle, sep)
|
return noSeparatorLine(opts.InfoStyle, sep)
|
||||||
}
|
}
|
||||||
@@ -3235,7 +3243,13 @@ func postProcessOptions(opts *Options) error {
|
|||||||
|
|
||||||
// Sets --min-height automatically
|
// Sets --min-height automatically
|
||||||
if opts.Height.size > 0 && opts.Height.percent && opts.MinHeight < 0 {
|
if opts.Height.size > 0 && opts.Height.percent && opts.MinHeight < 0 {
|
||||||
opts.MinHeight = -opts.MinHeight + 1 + borderLines(opts.BorderShape) + borderLines(opts.ListBorderShape) + borderLines(opts.InputBorderShape)
|
opts.MinHeight = -opts.MinHeight + borderLines(opts.BorderShape) + borderLines(opts.ListBorderShape)
|
||||||
|
if !opts.Inputless {
|
||||||
|
opts.MinHeight += 1 + borderLines(opts.InputBorderShape)
|
||||||
|
if !opts.noSeparatorLine() {
|
||||||
|
opts.MinHeight++
|
||||||
|
}
|
||||||
|
}
|
||||||
if len(opts.Header) > 0 {
|
if len(opts.Header) > 0 {
|
||||||
opts.MinHeight += borderLines(opts.HeaderBorderShape) + len(opts.Header)
|
opts.MinHeight += borderLines(opts.HeaderBorderShape) + len(opts.Header)
|
||||||
}
|
}
|
||||||
@@ -3246,9 +3260,6 @@ func postProcessOptions(opts *Options) error {
|
|||||||
}
|
}
|
||||||
opts.MinHeight += borderLines(borderShape) + opts.HeaderLines
|
opts.MinHeight += borderLines(borderShape) + opts.HeaderLines
|
||||||
}
|
}
|
||||||
if !opts.noSeparatorLine() {
|
|
||||||
opts.MinHeight++
|
|
||||||
}
|
|
||||||
if len(opts.Preview.command) > 0 && (opts.Preview.position == posUp || opts.Preview.position == posDown) && opts.Preview.Visible() && opts.Preview.position == posUp {
|
if len(opts.Preview.command) > 0 && (opts.Preview.position == posUp || opts.Preview.position == posDown) && opts.Preview.Visible() && opts.Preview.position == posUp {
|
||||||
borderShape := opts.Preview.border
|
borderShape := opts.Preview.border
|
||||||
if opts.Preview.border == tui.BorderLine {
|
if opts.Preview.border == tui.BorderLine {
|
||||||
|
@@ -324,6 +324,7 @@ type Terminal struct {
|
|||||||
cleanExit bool
|
cleanExit bool
|
||||||
executor *util.Executor
|
executor *util.Executor
|
||||||
paused bool
|
paused bool
|
||||||
|
inputless bool
|
||||||
border tui.Window
|
border tui.Window
|
||||||
window tui.Window
|
window tui.Window
|
||||||
inputWindow tui.Window
|
inputWindow tui.Window
|
||||||
@@ -810,6 +811,9 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if opts.Inputless {
|
||||||
|
renderer.HideCursor()
|
||||||
|
}
|
||||||
wordRubout := "[^\\pL\\pN][\\pL\\pN]"
|
wordRubout := "[^\\pL\\pN][\\pL\\pN]"
|
||||||
wordNext := "[\\pL\\pN][^\\pL\\pN]|(.$)"
|
wordNext := "[\\pL\\pN][^\\pL\\pN]|(.$)"
|
||||||
if opts.FileWord {
|
if opts.FileWord {
|
||||||
@@ -887,6 +891,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
|
|||||||
cleanExit: opts.ClearOnExit,
|
cleanExit: opts.ClearOnExit,
|
||||||
executor: executor,
|
executor: executor,
|
||||||
paused: opts.Phony,
|
paused: opts.Phony,
|
||||||
|
inputless: opts.Inputless,
|
||||||
cycle: opts.Cycle,
|
cycle: opts.Cycle,
|
||||||
highlightLine: opts.CursorLine,
|
highlightLine: opts.CursorLine,
|
||||||
headerVisible: true,
|
headerVisible: true,
|
||||||
@@ -1124,9 +1129,15 @@ func (t *Terminal) visibleHeaderLinesInList() int {
|
|||||||
|
|
||||||
// Extra number of lines needed to display fzf
|
// Extra number of lines needed to display fzf
|
||||||
func (t *Terminal) extraLines() int {
|
func (t *Terminal) extraLines() int {
|
||||||
extra := 1
|
extra := 0
|
||||||
if t.inputBorderShape.Visible() {
|
if !t.inputless {
|
||||||
extra += borderLines(t.inputBorderShape)
|
extra++
|
||||||
|
if !t.noSeparatorLine() {
|
||||||
|
extra++
|
||||||
|
}
|
||||||
|
if t.inputBorderShape.Visible() {
|
||||||
|
extra += borderLines(t.inputBorderShape)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if t.listBorderShape.Visible() {
|
if t.listBorderShape.Visible() {
|
||||||
extra += borderLines(t.listBorderShape)
|
extra += borderLines(t.listBorderShape)
|
||||||
@@ -1141,9 +1152,6 @@ func (t *Terminal) extraLines() int {
|
|||||||
}
|
}
|
||||||
extra += t.headerLines
|
extra += t.headerLines
|
||||||
}
|
}
|
||||||
if !t.noSeparatorLine() {
|
|
||||||
extra++
|
|
||||||
}
|
|
||||||
return extra
|
return extra
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1265,7 +1273,7 @@ func (t *Terminal) parsePrompt(prompt string) (func(), int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) noSeparatorLine() bool {
|
func (t *Terminal) noSeparatorLine() bool {
|
||||||
return noSeparatorLine(t.infoStyle, t.separatorLen > 0)
|
return t.inputless || noSeparatorLine(t.infoStyle, t.separatorLen > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getScrollbar(perLine int, total int, height int, offset int) (int, int) {
|
func getScrollbar(perLine int, total int, height int, offset int) (int, int) {
|
||||||
@@ -1350,7 +1358,10 @@ func (t *Terminal) Input() (bool, []rune) {
|
|||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
paused := t.paused
|
paused := t.paused
|
||||||
src := t.input
|
var src []rune
|
||||||
|
if !t.inputless {
|
||||||
|
src = t.input
|
||||||
|
}
|
||||||
if t.inputOverride != nil {
|
if t.inputOverride != nil {
|
||||||
paused = false
|
paused = false
|
||||||
src = *t.inputOverride
|
src = *t.inputOverride
|
||||||
@@ -1635,8 +1646,11 @@ func (t *Terminal) adjustMarginAndPadding() (int, int, [4]int, [4]int) {
|
|||||||
|
|
||||||
minAreaWidth := minWidth
|
minAreaWidth := minWidth
|
||||||
minAreaHeight := minHeight
|
minAreaHeight := minHeight
|
||||||
|
if t.inputless {
|
||||||
|
minAreaHeight--
|
||||||
|
}
|
||||||
if t.noSeparatorLine() {
|
if t.noSeparatorLine() {
|
||||||
minAreaHeight -= 1
|
minAreaHeight--
|
||||||
}
|
}
|
||||||
if t.needPreviewWindow() {
|
if t.needPreviewWindow() {
|
||||||
minPreviewWidth, minPreviewHeight := t.minPreviewSize(t.activePreviewOpts)
|
minPreviewWidth, minPreviewHeight := t.minPreviewSize(t.activePreviewOpts)
|
||||||
@@ -1756,7 +1770,7 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
|
|||||||
shrink := 0
|
shrink := 0
|
||||||
hasHeaderWindow := t.hasHeaderWindow()
|
hasHeaderWindow := t.hasHeaderWindow()
|
||||||
hasHeaderLinesWindow := t.hasHeaderLinesWindow()
|
hasHeaderLinesWindow := t.hasHeaderLinesWindow()
|
||||||
hasInputWindow := t.inputBorderShape.Visible() || hasHeaderWindow || hasHeaderLinesWindow
|
hasInputWindow := !t.inputless && (t.inputBorderShape.Visible() || hasHeaderWindow || hasHeaderLinesWindow)
|
||||||
if hasInputWindow {
|
if hasInputWindow {
|
||||||
inputWindowHeight := 2
|
inputWindowHeight := 2
|
||||||
if t.noSeparatorLine() {
|
if t.noSeparatorLine() {
|
||||||
@@ -1873,6 +1887,9 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
|
|||||||
switch previewOpts.position {
|
switch previewOpts.position {
|
||||||
case posUp, posDown:
|
case posUp, posDown:
|
||||||
minWindowHeight := minHeight
|
minWindowHeight := minHeight
|
||||||
|
if t.inputless {
|
||||||
|
minWindowHeight--
|
||||||
|
}
|
||||||
if t.noSeparatorLine() {
|
if t.noSeparatorLine() {
|
||||||
minWindowHeight--
|
minWindowHeight--
|
||||||
}
|
}
|
||||||
@@ -2227,6 +2244,9 @@ func (t *Terminal) promptLine() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) placeCursor() {
|
func (t *Terminal) placeCursor() {
|
||||||
|
if t.inputless {
|
||||||
|
return
|
||||||
|
}
|
||||||
if t.inputWindow != nil {
|
if t.inputWindow != nil {
|
||||||
y := t.inputWindow.Height() - 1
|
y := t.inputWindow.Height() - 1
|
||||||
if t.layout == layoutReverse {
|
if t.layout == layoutReverse {
|
||||||
@@ -2239,6 +2259,9 @@ func (t *Terminal) placeCursor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) printPrompt() {
|
func (t *Terminal) printPrompt() {
|
||||||
|
if t.inputless {
|
||||||
|
return
|
||||||
|
}
|
||||||
w := t.window
|
w := t.window
|
||||||
if t.inputWindow != nil {
|
if t.inputWindow != nil {
|
||||||
w = t.inputWindow
|
w = t.inputWindow
|
||||||
@@ -2266,6 +2289,9 @@ func (t *Terminal) trimMessage(message string, maxWidth int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) printInfo() {
|
func (t *Terminal) printInfo() {
|
||||||
|
if t.inputless {
|
||||||
|
return
|
||||||
|
}
|
||||||
t.withWindow(t.inputWindow, func() { t.printInfoImpl() })
|
t.withWindow(t.inputWindow, func() { t.printInfoImpl() })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2509,7 +2535,7 @@ func (t *Terminal) headerIndent(borderShape tui.BorderShape) int {
|
|||||||
|
|
||||||
func (t *Terminal) printHeaderImpl(window tui.Window, borderShape tui.BorderShape, lines1 []string, lines2 []string) {
|
func (t *Terminal) printHeaderImpl(window tui.Window, borderShape tui.BorderShape, lines1 []string, lines2 []string) {
|
||||||
max := t.window.Height()
|
max := t.window.Height()
|
||||||
if t.inputWindow == nil && window == nil && t.headerFirst {
|
if !t.inputless && t.inputWindow == nil && window == nil && t.headerFirst {
|
||||||
max--
|
max--
|
||||||
if !t.noSeparatorLine() {
|
if !t.noSeparatorLine() {
|
||||||
max--
|
max--
|
||||||
@@ -2539,7 +2565,7 @@ func (t *Terminal) printHeaderImpl(window tui.Window, borderShape tui.BorderShap
|
|||||||
if needReverse && idx < len(lines1) {
|
if needReverse && idx < len(lines1) {
|
||||||
line = len(lines1) - idx - 1
|
line = len(lines1) - idx - 1
|
||||||
}
|
}
|
||||||
if t.inputWindow == nil && window == nil && !t.headerFirst {
|
if !t.inputless && t.inputWindow == nil && window == nil && !t.headerFirst {
|
||||||
line++
|
line++
|
||||||
if !t.noSeparatorLine() {
|
if !t.noSeparatorLine() {
|
||||||
line++
|
line++
|
||||||
@@ -5681,7 +5707,7 @@ func (t *Terminal) Loop() error {
|
|||||||
// Header
|
// Header
|
||||||
numLines := t.visibleHeaderLinesInList()
|
numLines := t.visibleHeaderLinesInList()
|
||||||
lineOffset := 0
|
lineOffset := 0
|
||||||
if t.inputWindow == nil && !t.headerFirst {
|
if !t.inputless && t.inputWindow == nil && !t.headerFirst {
|
||||||
// offset for info line
|
// offset for info line
|
||||||
if t.noSeparatorLine() {
|
if t.noSeparatorLine() {
|
||||||
lineOffset = 1
|
lineOffset = 1
|
||||||
@@ -5829,7 +5855,13 @@ func (t *Terminal) Loop() error {
|
|||||||
} else if !doActions(actions) {
|
} else if !doActions(actions) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
t.truncateQuery()
|
if t.inputless {
|
||||||
|
// Always just discard the change
|
||||||
|
t.input = previousInput
|
||||||
|
t.cx = len(t.input)
|
||||||
|
} else {
|
||||||
|
t.truncateQuery()
|
||||||
|
}
|
||||||
queryChanged = string(previousInput) != string(t.input)
|
queryChanged = string(previousInput) != string(t.input)
|
||||||
if queryChanged {
|
if queryChanged {
|
||||||
t.inputOverride = nil
|
t.inputOverride = nil
|
||||||
@@ -6016,6 +6048,9 @@ func (t *Terminal) vset(o int) bool {
|
|||||||
|
|
||||||
// Number of prompt lines in the list window
|
// Number of prompt lines in the list window
|
||||||
func (t *Terminal) promptLines() int {
|
func (t *Terminal) promptLines() int {
|
||||||
|
if t.inputless {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
if t.inputWindow != nil {
|
if t.inputWindow != nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@@ -45,6 +45,7 @@ func (r *FullscreenRenderer) Clear() {}
|
|||||||
func (r *FullscreenRenderer) NeedScrollbarRedraw() bool { return false }
|
func (r *FullscreenRenderer) NeedScrollbarRedraw() bool { return false }
|
||||||
func (r *FullscreenRenderer) ShouldEmitResizeEvent() bool { return false }
|
func (r *FullscreenRenderer) ShouldEmitResizeEvent() bool { return false }
|
||||||
func (r *FullscreenRenderer) Bell() {}
|
func (r *FullscreenRenderer) Bell() {}
|
||||||
|
func (r *FullscreenRenderer) HideCursor() {}
|
||||||
func (r *FullscreenRenderer) Refresh() {}
|
func (r *FullscreenRenderer) Refresh() {}
|
||||||
func (r *FullscreenRenderer) Close() {}
|
func (r *FullscreenRenderer) Close() {}
|
||||||
func (r *FullscreenRenderer) Size() TermSize { return TermSize{} }
|
func (r *FullscreenRenderer) Size() TermSize { return TermSize{} }
|
||||||
|
@@ -77,7 +77,13 @@ func (r *LightRenderer) csi(code string) string {
|
|||||||
|
|
||||||
func (r *LightRenderer) flush() {
|
func (r *LightRenderer) flush() {
|
||||||
if r.queued.Len() > 0 {
|
if r.queued.Len() > 0 {
|
||||||
r.flushRaw("\x1b[?7l\x1b[?25l" + r.queued.String() + "\x1b[?25h\x1b[?7h")
|
raw := "\x1b[?7l\x1b[?25l" + r.queued.String()
|
||||||
|
if r.showCursor {
|
||||||
|
raw += "\x1b[?25h\x1b[?7h"
|
||||||
|
} else {
|
||||||
|
raw += "\x1b[?7h"
|
||||||
|
}
|
||||||
|
r.flushRaw(raw)
|
||||||
r.queued.Reset()
|
r.queued.Reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,6 +116,7 @@ type LightRenderer struct {
|
|||||||
y int
|
y int
|
||||||
x int
|
x int
|
||||||
maxHeightFunc func(int) int
|
maxHeightFunc func(int) int
|
||||||
|
showCursor bool
|
||||||
|
|
||||||
// Windows only
|
// Windows only
|
||||||
ttyinChannel chan byte
|
ttyinChannel chan byte
|
||||||
@@ -152,7 +159,8 @@ func NewLightRenderer(ttyin *os.File, theme *ColorTheme, forceBlack bool, mouse
|
|||||||
tabstop: tabstop,
|
tabstop: tabstop,
|
||||||
fullscreen: fullscreen,
|
fullscreen: fullscreen,
|
||||||
upOneLine: false,
|
upOneLine: false,
|
||||||
maxHeightFunc: maxHeightFunc}
|
maxHeightFunc: maxHeightFunc,
|
||||||
|
showCursor: true}
|
||||||
return &r, nil
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -759,6 +767,9 @@ func (r *LightRenderer) Close() {
|
|||||||
} else if !r.fullscreen {
|
} else if !r.fullscreen {
|
||||||
r.csi("u")
|
r.csi("u")
|
||||||
}
|
}
|
||||||
|
if !r.showCursor {
|
||||||
|
r.csi("?25h")
|
||||||
|
}
|
||||||
r.disableMouse()
|
r.disableMouse()
|
||||||
r.flush()
|
r.flush()
|
||||||
r.closePlatform()
|
r.closePlatform()
|
||||||
@@ -1214,3 +1225,7 @@ func (w *LightWindow) Erase() {
|
|||||||
func (w *LightWindow) EraseMaybe() bool {
|
func (w *LightWindow) EraseMaybe() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *LightRenderer) HideCursor() {
|
||||||
|
r.showCursor = false
|
||||||
|
}
|
||||||
|
@@ -52,6 +52,7 @@ type TcellWindow struct {
|
|||||||
borderStyle BorderStyle
|
borderStyle BorderStyle
|
||||||
uri *string
|
uri *string
|
||||||
params *string
|
params *string
|
||||||
|
showCursor bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *TcellWindow) Top() int {
|
func (w *TcellWindow) Top() int {
|
||||||
@@ -72,7 +73,9 @@ func (w *TcellWindow) Height() int {
|
|||||||
|
|
||||||
func (w *TcellWindow) Refresh() {
|
func (w *TcellWindow) Refresh() {
|
||||||
if w.moveCursor {
|
if w.moveCursor {
|
||||||
_screen.ShowCursor(w.left+w.lastX, w.top+w.lastY)
|
if w.showCursor {
|
||||||
|
_screen.ShowCursor(w.left+w.lastX, w.top+w.lastY)
|
||||||
|
}
|
||||||
w.moveCursor = false
|
w.moveCursor = false
|
||||||
}
|
}
|
||||||
w.lastX = 0
|
w.lastX = 0
|
||||||
@@ -104,6 +107,10 @@ func (r *FullscreenRenderer) Bell() {
|
|||||||
_screen.Beep()
|
_screen.Beep()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *FullscreenRenderer) HideCursor() {
|
||||||
|
r.showCursor = false
|
||||||
|
}
|
||||||
|
|
||||||
func (r *FullscreenRenderer) PassThrough(str string) {
|
func (r *FullscreenRenderer) PassThrough(str string) {
|
||||||
// No-op
|
// No-op
|
||||||
// https://github.com/gdamore/tcell/pull/650#issuecomment-1806442846
|
// https://github.com/gdamore/tcell/pull/650#issuecomment-1806442846
|
||||||
@@ -168,6 +175,9 @@ func (r *FullscreenRenderer) getScreen() (tcell.Screen, error) {
|
|||||||
if e != nil {
|
if e != nil {
|
||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
|
if !r.showCursor {
|
||||||
|
s.HideCursor()
|
||||||
|
}
|
||||||
_screen = s
|
_screen = s
|
||||||
}
|
}
|
||||||
return _screen, nil
|
return _screen, nil
|
||||||
@@ -590,7 +600,8 @@ func (r *FullscreenRenderer) NewWindow(top int, left int, width int, height int,
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
normal: normal,
|
normal: normal,
|
||||||
borderStyle: borderStyle}
|
borderStyle: borderStyle,
|
||||||
|
showCursor: r.showCursor}
|
||||||
w.Erase()
|
w.Erase()
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
@@ -615,6 +615,7 @@ type Renderer interface {
|
|||||||
NeedScrollbarRedraw() bool
|
NeedScrollbarRedraw() bool
|
||||||
ShouldEmitResizeEvent() bool
|
ShouldEmitResizeEvent() bool
|
||||||
Bell()
|
Bell()
|
||||||
|
HideCursor()
|
||||||
|
|
||||||
GetChar() Event
|
GetChar() Event
|
||||||
|
|
||||||
@@ -662,6 +663,7 @@ type FullscreenRenderer struct {
|
|||||||
forceBlack bool
|
forceBlack bool
|
||||||
prevDownTime time.Time
|
prevDownTime time.Time
|
||||||
clicks [][2]int
|
clicks [][2]int
|
||||||
|
showCursor bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFullscreenRenderer(theme *ColorTheme, forceBlack bool, mouse bool) Renderer {
|
func NewFullscreenRenderer(theme *ColorTheme, forceBlack bool, mouse bool) Renderer {
|
||||||
@@ -670,7 +672,8 @@ func NewFullscreenRenderer(theme *ColorTheme, forceBlack bool, mouse bool) Rende
|
|||||||
mouse: mouse,
|
mouse: mouse,
|
||||||
forceBlack: forceBlack,
|
forceBlack: forceBlack,
|
||||||
prevDownTime: time.Unix(0, 0),
|
prevDownTime: time.Unix(0, 0),
|
||||||
clicks: [][2]int{}}
|
clicks: [][2]int{},
|
||||||
|
showCursor: true}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -876,4 +876,19 @@ class TestLayout < TestInteractive
|
|||||||
BLOCK
|
BLOCK
|
||||||
tmux.until { assert_block(block, _1) }
|
tmux.until { assert_block(block, _1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_min_height_auto_no_input
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --style full:sharp --no-input --height 1% --min-height 5+), :Enter
|
||||||
|
|
||||||
|
block = <<~BLOCK
|
||||||
|
┌─────────
|
||||||
|
│ 5
|
||||||
|
│ 4
|
||||||
|
│ 3
|
||||||
|
│ 2
|
||||||
|
│ > 1
|
||||||
|
└─────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user