Make search toggleable

- `--phony` renamed to `--disabled` for consistency
    - `--no-phony` is now `--enabled`
- Added `enable-search`, `disable-search`, and `toggle-search` actions
  for `--bind`
- Added `--color` options: `query` and `disabled`

Close #2303
This commit is contained in:
Junegunn Choi 2021-01-03 00:00:40 +09:00
parent fd8858f8c9
commit d779ff7e6d
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
10 changed files with 132 additions and 49 deletions

View File

@ -1,7 +1,7 @@
CHANGELOG CHANGELOG
========= =========
0.24.5 0.25.0
------ ------
- Text attributes set in `--color` are not reset when fzf sees another - Text attributes set in `--color` are not reset when fzf sees another
`--color` option for the same element. This allows you to put custom text `--color` option for the same element. This allows you to put custom text
@ -23,6 +23,13 @@ CHANGELOG
# Write "regular" if you want to clear the attributes # Write "regular" if you want to clear the attributes
fzf --color hl:176:regular,hl+:177:regular fzf --color hl:176:regular,hl+:177:regular
``` ```
- Renamed `--phony` to `--disabled`
- You can dynamically enable and disable the search functionality using the
new `enable-search`, `disable-search`, and `toggle-search` actions
- You can assign a different color to the query string for when search is disabled
```sh
fzf --color query:#ffffff,disabled:#999999 --bind space:toggle-search
```
- Added `last` action to move the cursor to the last match - Added `last` action to move the cursor to the last match
- The opposite action `top` is renamed to `first`, but `top` is still - The opposite action `top` is renamed to `first`, but `top` is still
recognized as a synonym for backward compatibility recognized as a synonym for backward compatibility

View File

@ -171,19 +171,23 @@ list:
- `element` is an fzf element to apply a color to: - `element` is an fzf element to apply a color to:
| Element | Description | | Element | Description |
| --- | --- | | --- | --- |
| `fg` / `bg` / `hl` | Item (foreground / background / highlight) | | `fg` / `bg` / `hl` | Item (foreground / background / highlight) |
| `fg+` / `bg+` / `hl+` | Current item (foreground / background / highlight) | | `fg+` / `bg+` / `hl+` | Current item (foreground / background / highlight) |
| `hl` / `hl+` | Highlighted substrings (normal / current) | | `preview-fg` / `preview-bg` | Preview window text and background |
| `gutter` | Background of the gutter on the left | | `hl` / `hl+` | Highlighted substrings (normal / current) |
| `pointer` | Pointer to the current line (`>`) | | `gutter` | Background of the gutter on the left |
| `marker` | Multi-select marker (`>`) | | `pointer` | Pointer to the current line (`>`) |
| `border` | Border around the window (`--border` and `--preview`) | | `marker` | Multi-select marker (`>`) |
| `header` | Header (`--header` or `--header-lines`) | | `border` | Border around the window (`--border` and `--preview`) |
| `info` | Info line (match counters) | | `header` | Header (`--header` or `--header-lines`) |
| `spinner` | Streaming input indicator | | `info` | Info line (match counters) |
| `prompt` | Prompt before query (`> `) | | `spinner` | Streaming input indicator |
| `query` | Query string |
| `disabled` | Query string when search is disabled |
| `prompt` | Prompt before query (`> `) |
| `pointer` | Pointer to the current line (`>`) |
- `component` specifies the component (`fg` / `bg`) from which to extract the - `component` specifies the component (`fg` / `bg`) from which to extract the
color when considering each of the following highlight groups color when considering each of the following highlight groups

View File

@ -1,4 +1,4 @@
fzf.txt fzf Last change: December 31 2020 fzf.txt fzf Last change: January 2 2021
FZF - TABLE OF CONTENTS *fzf* *fzf-toc* FZF - TABLE OF CONTENTS *fzf* *fzf-toc*
============================================================================== ==============================================================================
@ -200,21 +200,25 @@ list:
< <
- `element` is an fzf element to apply a color to: - `element` is an fzf element to apply a color to:
----------------------+------------------------------------------------------ ----------------------------+------------------------------------------------------
Element | Description ~ Element | Description ~
----------------------+------------------------------------------------------ ----------------------------+------------------------------------------------------
`fg` / `bg` / `hl` | Item (foreground / background / highlight) `fg` / `bg` / `hl` | Item (foreground / background / highlight)
`fg+` / `bg+` / `hl+` | Current item (foreground / background / highlight) `fg+` / `bg+` / `hl+` | Current item (foreground / background / highlight)
`hl` / `hl+` | Highlighted substrings (normal / current) `preview-fg` / `preview-bg` | Preview window text and background
`gutter` | Background of the gutter on the left `hl` / `hl+` | Highlighted substrings (normal / current)
`pointer` | Pointer to the current line ( `>` ) `gutter` | Background of the gutter on the left
`marker` | Multi-select marker ( `>` ) `pointer` | Pointer to the current line ( `>` )
`border` | Border around the window ( `--border` and `--preview` ) `marker` | Multi-select marker ( `>` )
`header` | Header ( `--header` or `--header-lines` ) `border` | Border around the window ( `--border` and `--preview` )
`info` | Info line (match counters) `header` | Header ( `--header` or `--header-lines` )
`spinner` | Streaming input indicator `info` | Info line (match counters)
`prompt` | Prompt before query ( `>` ) `spinner` | Streaming input indicator
----------------------+------------------------------------------------------ `query` | Query string
`disabled` | Query string when search is disabled
`prompt` | Prompt before query ( `>` )
`pointer` | Pointer to the current line ( `>` )
----------------------------+------------------------------------------------------
- `component` specifies the component (`fg` / `bg`) from which to extract the - `component` specifies the component (`fg` / `bg`) from which to extract the
color when considering each of the following highlight groups color when considering each of the following highlight groups
- `group1[,group2,...]` is a list of highlight groups that are searched (in - `group1[,group2,...]` is a list of highlight groups that are searched (in

View File

@ -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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
.. ..
.TH fzf-tmux 1 "Dec 2020" "fzf 0.24.4" "fzf-tmux - open fzf in tmux split pane" .TH fzf-tmux 1 "Jan 2021" "fzf 0.25.0" "fzf-tmux - open fzf in tmux split pane"
.SH NAME .SH NAME
fzf-tmux - open fzf in tmux split pane fzf-tmux - open fzf in tmux split pane

View File

@ -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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
.. ..
.TH fzf 1 "Dec 2020" "fzf 0.24.5" "fzf - a command-line fuzzy finder" .TH fzf 1 "Jan 2021" "fzf 0.25.0" "fzf - a command-line fuzzy finder"
.SH NAME .SH NAME
fzf - a command-line fuzzy finder fzf - a command-line fuzzy finder
@ -71,9 +71,10 @@ Transform the presentation of each line using field index expressions
.BI "-d, --delimiter=" "STR" .BI "-d, --delimiter=" "STR"
Field delimiter regex for \fB--nth\fR and \fB--with-nth\fR (default: AWK-style) Field delimiter regex for \fB--nth\fR and \fB--with-nth\fR (default: AWK-style)
.TP .TP
.BI "--phony" .BI "--disabled"
Do not perform search. With this option, fzf becomes a simple selector Do not perform search. With this option, fzf becomes a simple selector
interface rather than a "fuzzy finder". interface rather than a "fuzzy finder". You can later enable the search using
\fBenable-search\fR or `\fBtoggle-search\R action.
.SS Search result .SS Search result
.TP .TP
.B "+s, --no-sort" .B "+s, --no-sort"
@ -323,6 +324,8 @@ color mappings.
\fBbg+ \fRBackground (current line) \fBbg+ \fRBackground (current line)
\fBgutter \fRGutter on the left (defaults to \fBbg+\fR) \fBgutter \fRGutter on the left (defaults to \fBbg+\fR)
\fBhl+ \fRHighlighted substrings (current line) \fBhl+ \fRHighlighted substrings (current line)
\fBquery \fRQuery string
\fBdisabled \fRQuery string when search is disabled
\fBinfo \fRInfo line (match counters) \fBinfo \fRInfo line (match counters)
\fBborder \fRBorder around the window (\fB--border\fR and \fB--preview\fR) \fBborder \fRBorder around the window (\fB--border\fR and \fB--preview\fR)
\fBprompt \fRPrompt \fBprompt \fRPrompt
@ -780,7 +783,9 @@ A key or an event can be bound to one or more of the following actions.
\fBdelete-char\fR \fIdel\fR \fBdelete-char\fR \fIdel\fR
\fBdelete-char/eof\fR \fIctrl-d\fR (same as \fBdelete-char\fR except aborts fzf if query is empty) \fBdelete-char/eof\fR \fIctrl-d\fR (same as \fBdelete-char\fR except aborts fzf if query is empty)
\fBdeselect-all\fR (deselect all matches) \fBdeselect-all\fR (deselect all matches)
\fBdisable-search\fR (disable search functionality)
\fBdown\fR \fIctrl-j ctrl-n down\fR \fBdown\fR \fIctrl-j ctrl-n down\fR
\fBenable-search\fR (enable search functionality)
\fBend-of-line\fR \fIctrl-e end\fR \fBend-of-line\fR \fIctrl-e end\fR
\fBexecute(...)\fR (see below for the details) \fBexecute(...)\fR (see below for the details)
\fBexecute-silent(...)\fR (see below for the details) \fBexecute-silent(...)\fR (see below for the details)
@ -820,6 +825,7 @@ A key or an event can be bound to one or more of the following actions.
\fBtoggle-out\fR (\fB--layout=reverse*\fR ? \fBtoggle+down\fR : \fBtoggle+up\fR) \fBtoggle-out\fR (\fB--layout=reverse*\fR ? \fBtoggle+down\fR : \fBtoggle+up\fR)
\fBtoggle-preview\fR \fBtoggle-preview\fR
\fBtoggle-preview-wrap\fR \fBtoggle-preview-wrap\fR
\fBtoggle-search\fR (toggle search functionality)
\fBtoggle-sort\fR \fBtoggle-sort\fR
\fBtoggle+up\fR \fIbtab (shift-tab)\fR \fBtoggle+up\fR \fIbtab (shift-tab)\fR
\fBunix-line-discard\fR \fIctrl-u\fR \fBunix-line-discard\fR \fIctrl-u\fR
@ -902,7 +908,7 @@ e.g.
INITIAL_QUERY="foobar" INITIAL_QUERY="foobar"
FZF_DEFAULT_COMMAND="$RG_PREFIX '$INITIAL_QUERY'" \\ FZF_DEFAULT_COMMAND="$RG_PREFIX '$INITIAL_QUERY'" \\
fzf --bind "change:reload:$RG_PREFIX {q} || true" \\ fzf --bind "change:reload:$RG_PREFIX {q} || true" \\
--ansi --phony --query "$INITIAL_QUERY"\fR --ansi --disabled --query "$INITIAL_QUERY"\fR
.SS PREVIEW BINDING .SS PREVIEW BINDING

View File

@ -237,14 +237,16 @@ func Run(opts *Options, version string, revision string) {
go reader.restart(command) go reader.restart(command)
} }
eventBox.Watch(EvtReadNew) eventBox.Watch(EvtReadNew)
query := []rune{}
for { for {
delay := true delay := true
ticks++ ticks++
input := func() []rune { input := func() []rune {
if opts.Phony { paused, input := terminal.Input()
return []rune{} if !paused {
query = input
} }
return []rune(terminal.Input()) return query
} }
eventBox.Wait(func(events *util.Events) { eventBox.Wait(func(events *util.Events) {
if _, fin := (*events)[EvtReadFin]; fin { if _, fin := (*events)[EvtReadFin]; fin {

View File

@ -33,7 +33,7 @@ const usage = `usage: fzf [options]
-d, --delimiter=STR Field delimiter regex (default: AWK-style) -d, --delimiter=STR Field delimiter regex (default: AWK-style)
+s, --no-sort Do not sort the result +s, --no-sort Do not sort the result
--tac Reverse the order of the input --tac Reverse the order of the input
--phony Do not perform search --disabled Do not perform search
--tiebreak=CRI[,..] Comma-separated list of sort criteria to apply --tiebreak=CRI[,..] Comma-separated list of sort criteria to apply
when the scores are tied [length|begin|end|index] when the scores are tied [length|begin|end|index]
(default: length) (default: length)
@ -682,8 +682,10 @@ func parseTheme(defaultTheme *tui.ColorTheme, str string) *tui.ColorTheme {
} }
} }
switch components[0] { switch components[0] {
case "input": case "query", "input":
mergeAttr(&theme.Input) mergeAttr(&theme.Input)
case "disabled":
mergeAttr(&theme.Disabled)
case "fg": case "fg":
mergeAttr(&theme.Fg) mergeAttr(&theme.Fg)
case "bg": case "bg":
@ -875,6 +877,8 @@ func parseKeymap(keymap map[tui.Event][]action, str string) {
appendAction(actToggleOut) appendAction(actToggleOut)
case "toggle-all": case "toggle-all":
appendAction(actToggleAll) appendAction(actToggleAll)
case "toggle-search":
appendAction(actToggleSearch)
case "select-all": case "select-all":
appendAction(actSelectAll) appendAction(actSelectAll)
case "deselect-all": case "deselect-all":
@ -923,6 +927,10 @@ func parseKeymap(keymap map[tui.Event][]action, str string) {
appendAction(actPreviewHalfPageUp) appendAction(actPreviewHalfPageUp)
case "preview-half-page-down": case "preview-half-page-down":
appendAction(actPreviewHalfPageDown) appendAction(actPreviewHalfPageDown)
case "enable-search":
appendAction(actEnableSearch)
case "disable-search":
appendAction(actDisableSearch)
default: default:
t := isExecuteAction(specLower) t := isExecuteAction(specLower)
if t == actIgnore { if t == actIgnore {
@ -1199,9 +1207,9 @@ func parseOptions(opts *Options, allArgs []string) {
} }
case "--no-expect": case "--no-expect":
opts.Expect = make(map[tui.Event]string) opts.Expect = make(map[tui.Event]string)
case "--no-phony": case "--enabled", "--no-phony":
opts.Phony = false opts.Phony = false
case "--phony": case "--disabled", "--phony":
opts.Phony = true opts.Phony = true
case "--tiebreak": case "--tiebreak":
opts.Criteria = parseTiebreak(nextString(allArgs, &i, "sort criterion required")) opts.Criteria = parseTiebreak(nextString(allArgs, &i, "sort criterion required"))

View File

@ -125,6 +125,7 @@ type Terminal struct {
unicode bool unicode bool
borderShape tui.BorderShape borderShape tui.BorderShape
cleanExit bool cleanExit bool
paused bool
border tui.Window border tui.Window
window tui.Window window tui.Window
pborder tui.Window pborder tui.Window
@ -233,6 +234,7 @@ const (
actSelectAll actSelectAll
actDeselectAll actDeselectAll
actToggle actToggle
actToggleSearch
actToggleAll actToggleAll
actToggleDown actToggleDown
actToggleUp actToggleUp
@ -270,6 +272,8 @@ const (
actFirst actFirst
actLast actLast
actReload actReload
actDisableSearch
actEnableSearch
) )
type placeholderFlags struct { type placeholderFlags struct {
@ -488,6 +492,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
unicode: opts.Unicode, unicode: opts.Unicode,
borderShape: opts.BorderShape, borderShape: opts.BorderShape,
cleanExit: opts.ClearOnExit, cleanExit: opts.ClearOnExit,
paused: opts.Phony,
strong: strongAttr, strong: strongAttr,
cycle: opts.Cycle, cycle: opts.Cycle,
header: header, header: header,
@ -563,10 +568,10 @@ func (t *Terminal) noInfoLine() bool {
} }
// Input returns current query string // Input returns current query string
func (t *Terminal) Input() []rune { func (t *Terminal) Input() (bool, []rune) {
t.mutex.Lock() t.mutex.Lock()
defer t.mutex.Unlock() defer t.mutex.Unlock()
return copySlice(t.input) return t.paused, copySlice(t.input)
} }
// UpdateCount updates the count information // UpdateCount updates the count information
@ -925,8 +930,12 @@ func (t *Terminal) printPrompt() {
t.prompt() t.prompt()
before, after := t.updatePromptOffset() before, after := t.updatePromptOffset()
t.window.CPrint(tui.ColInput, string(before)) color := tui.ColInput
t.window.CPrint(tui.ColInput, string(after)) if t.paused {
color = tui.ColDisabled
}
t.window.CPrint(color, string(before))
t.window.CPrint(color, string(after))
} }
func (t *Terminal) trimMessage(message string, maxWidth int) string { func (t *Terminal) trimMessage(message string, maxWidth int) string {
@ -1880,7 +1889,8 @@ func (t *Terminal) Loop() {
version++ version++
// We don't display preview window if no match // We don't display preview window if no match
if items[0] != nil { if items[0] != nil {
command := t.replacePlaceholder(commandTemplate, false, string(t.Input()), items) _, query := t.Input()
command := t.replacePlaceholder(commandTemplate, false, string(query), items)
initialOffset := 0 initialOffset := 0
cmd := util.ExecCommand(command, true) cmd := util.ExecCommand(command, true)
if pwindow != nil { if pwindow != nil {
@ -2465,6 +2475,17 @@ func (t *Terminal) Loop() {
t.input = trimQuery(t.history.next()) t.input = trimQuery(t.history.next())
t.cx = len(t.input) t.cx = len(t.input)
} }
case actToggleSearch:
t.paused = !t.paused
changed = !t.paused
req(reqPrompt)
case actEnableSearch:
t.paused = false
changed = true
req(reqPrompt)
case actDisableSearch:
t.paused = true
req(reqPrompt)
case actSigStop: case actSigStop:
p, err := os.FindProcess(os.Getpid()) p, err := os.FindProcess(os.Getpid())
if err == nil { if err == nil {

View File

@ -250,6 +250,7 @@ func (p ColorPair) MergeNonDefault(other ColorPair) ColorPair {
type ColorTheme struct { type ColorTheme struct {
Colored bool Colored bool
Input ColorAttr Input ColorAttr
Disabled ColorAttr
Fg ColorAttr Fg ColorAttr
Bg ColorAttr Bg ColorAttr
PreviewFg ColorAttr PreviewFg ColorAttr
@ -421,6 +422,7 @@ var (
ColPrompt ColorPair ColPrompt ColorPair
ColNormal ColorPair ColNormal ColorPair
ColInput ColorPair ColInput ColorPair
ColDisabled ColorPair
ColMatch ColorPair ColMatch ColorPair
ColCursor ColorPair ColCursor ColorPair
ColCursorEmpty ColorPair ColCursorEmpty ColorPair
@ -443,6 +445,7 @@ func EmptyTheme() *ColorTheme {
return &ColorTheme{ return &ColorTheme{
Colored: true, Colored: true,
Input: ColorAttr{colUndefined, AttrUndefined}, Input: ColorAttr{colUndefined, AttrUndefined},
Disabled: ColorAttr{colUndefined, AttrUndefined},
Fg: ColorAttr{colUndefined, AttrUndefined}, Fg: ColorAttr{colUndefined, AttrUndefined},
Bg: ColorAttr{colUndefined, AttrUndefined}, Bg: ColorAttr{colUndefined, AttrUndefined},
PreviewFg: ColorAttr{colUndefined, AttrUndefined}, PreviewFg: ColorAttr{colUndefined, AttrUndefined},
@ -465,6 +468,7 @@ func NoColorTheme() *ColorTheme {
return &ColorTheme{ return &ColorTheme{
Colored: false, Colored: false,
Input: ColorAttr{colDefault, AttrRegular}, Input: ColorAttr{colDefault, AttrRegular},
Disabled: ColorAttr{colDefault, AttrRegular},
Fg: ColorAttr{colDefault, AttrRegular}, Fg: ColorAttr{colDefault, AttrRegular},
Bg: ColorAttr{colDefault, AttrRegular}, Bg: ColorAttr{colDefault, AttrRegular},
PreviewFg: ColorAttr{colDefault, AttrRegular}, PreviewFg: ColorAttr{colDefault, AttrRegular},
@ -492,6 +496,7 @@ func init() {
Default16 = &ColorTheme{ Default16 = &ColorTheme{
Colored: true, Colored: true,
Input: ColorAttr{colDefault, AttrUndefined}, Input: ColorAttr{colDefault, AttrUndefined},
Disabled: ColorAttr{colUndefined, AttrUndefined},
Fg: ColorAttr{colDefault, AttrUndefined}, Fg: ColorAttr{colDefault, AttrUndefined},
Bg: ColorAttr{colDefault, AttrUndefined}, Bg: ColorAttr{colDefault, AttrUndefined},
PreviewFg: ColorAttr{colUndefined, AttrUndefined}, PreviewFg: ColorAttr{colUndefined, AttrUndefined},
@ -511,6 +516,7 @@ func init() {
Dark256 = &ColorTheme{ Dark256 = &ColorTheme{
Colored: true, Colored: true,
Input: ColorAttr{colDefault, AttrUndefined}, Input: ColorAttr{colDefault, AttrUndefined},
Disabled: ColorAttr{colUndefined, AttrUndefined},
Fg: ColorAttr{colDefault, AttrUndefined}, Fg: ColorAttr{colDefault, AttrUndefined},
Bg: ColorAttr{colDefault, AttrUndefined}, Bg: ColorAttr{colDefault, AttrUndefined},
PreviewFg: ColorAttr{colUndefined, AttrUndefined}, PreviewFg: ColorAttr{colUndefined, AttrUndefined},
@ -530,6 +536,7 @@ func init() {
Light256 = &ColorTheme{ Light256 = &ColorTheme{
Colored: true, Colored: true,
Input: ColorAttr{colDefault, AttrUndefined}, Input: ColorAttr{colDefault, AttrUndefined},
Disabled: ColorAttr{colUndefined, AttrUndefined},
Fg: ColorAttr{colDefault, AttrUndefined}, Fg: ColorAttr{colDefault, AttrUndefined},
Bg: ColorAttr{colDefault, AttrUndefined}, Bg: ColorAttr{colDefault, AttrUndefined},
PreviewFg: ColorAttr{colUndefined, AttrUndefined}, PreviewFg: ColorAttr{colUndefined, AttrUndefined},
@ -564,6 +571,7 @@ func initTheme(theme *ColorTheme, baseTheme *ColorTheme, forceBlack bool) {
return c return c
} }
theme.Input = o(baseTheme.Input, theme.Input) theme.Input = o(baseTheme.Input, theme.Input)
theme.Disabled = o(theme.Input, o(baseTheme.Disabled, theme.Disabled))
theme.Fg = o(baseTheme.Fg, theme.Fg) theme.Fg = o(baseTheme.Fg, theme.Fg)
theme.Bg = o(baseTheme.Bg, theme.Bg) theme.Bg = o(baseTheme.Bg, theme.Bg)
theme.PreviewFg = o(theme.Fg, o(baseTheme.PreviewFg, theme.PreviewFg)) theme.PreviewFg = o(theme.Fg, o(baseTheme.PreviewFg, theme.PreviewFg))
@ -597,6 +605,7 @@ func initPalette(theme *ColorTheme) {
ColPrompt = pair(theme.Prompt, theme.Bg) ColPrompt = pair(theme.Prompt, theme.Bg)
ColNormal = pair(theme.Fg, theme.Bg) ColNormal = pair(theme.Fg, theme.Bg)
ColInput = pair(theme.Input, theme.Bg) ColInput = pair(theme.Input, theme.Bg)
ColDisabled = pair(theme.Disabled, theme.Bg)
ColMatch = pair(theme.Match, theme.Bg) ColMatch = pair(theme.Match, theme.Bg)
ColCursor = pair(theme.Cursor, theme.Gutter) ColCursor = pair(theme.Cursor, theme.Gutter)
ColCursorEmpty = pair(blank, theme.Gutter) ColCursorEmpty = pair(blank, theme.Gutter)

View File

@ -1658,13 +1658,35 @@ class TestGoFZF < TestBase
tmux.until { |lines| assert_includes lines[1], ' + green ' } tmux.until { |lines| assert_includes lines[1], ' + green ' }
end end
def test_phony def test_disabled
tmux.send_keys %(seq 1000 | #{FZF} --query 333 --phony --preview 'echo {} {q}'), :Enter tmux.send_keys %(seq 1000 | #{FZF} --query 333 --disabled --bind a:enable-search,b:disable-search,c:toggle-search --preview 'echo {} {q}'), :Enter
tmux.until { |lines| assert_equal 1000, lines.match_count } tmux.until { |lines| assert_equal 1000, lines.match_count }
tmux.until { |lines| assert_includes lines[1], ' 1 333 ' } tmux.until { |lines| assert_includes lines[1], ' 1 333 ' }
tmux.send_keys 'foo' tmux.send_keys 'foo'
tmux.until { |lines| assert_equal 1000, lines.match_count } tmux.until { |lines| assert_equal 1000, lines.match_count }
tmux.until { |lines| assert_includes lines[1], ' 1 333foo ' } tmux.until { |lines| assert_includes lines[1], ' 1 333foo ' }
# Already disabled, no change
tmux.send_keys 'b'
tmux.until { |lines| assert_equal 1000, lines.match_count }
# Enable search
tmux.send_keys 'a'
tmux.until { |lines| assert_equal 0, lines.match_count }
tmux.send_keys :BSpace, :BSpace, :BSpace
tmux.until { |lines| assert_equal 1, lines.match_count }
tmux.until { |lines| assert_includes lines[1], ' 333 333 ' }
# Toggle search -> disabled again, but retains the previous result
tmux.send_keys 'c'
tmux.send_keys 'foo'
tmux.until { |lines| assert_includes lines[1], ' 333 333foo ' }
tmux.until { |lines| assert_equal 1, lines.match_count }
# Enabled, no match
tmux.send_keys 'c'
tmux.until { |lines| assert_equal 0, lines.match_count }
tmux.until { |lines| assert_includes lines[1], ' 333foo ' }
end end
def test_reload def test_reload