mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-11-21 20:35:11 +00:00
Do not start the initial reader if 'reload*' is bound to 'start'
This commit is contained in:
parent
1525768094
commit
5b52833785
@ -32,6 +32,15 @@ CHANGELOG
|
|||||||
fzf --listen --sync --bind 'focus:transform-header:curl -s localhost:$FZF_PORT?limit=0 | jq .'
|
fzf --listen --sync --bind 'focus:transform-header:curl -s localhost:$FZF_PORT?limit=0 | jq .'
|
||||||
```
|
```
|
||||||
- Added `offset-middle` action to place the current item is in the middle of the screen
|
- Added `offset-middle` action to place the current item is in the middle of the screen
|
||||||
|
- fzf will not start the initial reader when `reload` or `reload-sync` is bound to `start` event. `fzf < /dev/null` or `: | fzf` are no longer required and extraneous `load` event will not fire due to the empty list.
|
||||||
|
```sh
|
||||||
|
# Now this will work as expected. Previously, this would print an invalid header line.
|
||||||
|
# `fzf < /dev/null` or `: | fzf` would fix the problem, but then an extraneous
|
||||||
|
# `load` event would fire and the header would be prematurely updated.
|
||||||
|
fzf --header 'Loading ...' --header-lines 1 \
|
||||||
|
--bind 'start:reload:sleep 1; ps -ef' \
|
||||||
|
--bind 'load:change-header:Loaded!'
|
||||||
|
```
|
||||||
- Fixed mouse support on Windows
|
- Fixed mouse support on Windows
|
||||||
- Fixed crash when using `--tiebreak=end` with very long items
|
- Fixed crash when using `--tiebreak=end` with very long items
|
||||||
- zsh 5.0 compatibility (thanks to @LangLangBart)
|
- zsh 5.0 compatibility (thanks to @LangLangBart)
|
||||||
|
@ -58,6 +58,7 @@ const (
|
|||||||
const (
|
const (
|
||||||
EvtReadNew util.EventType = iota
|
EvtReadNew util.EventType = iota
|
||||||
EvtReadFin
|
EvtReadFin
|
||||||
|
EvtReadNone
|
||||||
EvtSearchNew
|
EvtSearchNew
|
||||||
EvtSearchProgress
|
EvtSearchProgress
|
||||||
EvtSearchFin
|
EvtSearchFin
|
||||||
|
17
src/core.go
17
src/core.go
@ -147,13 +147,20 @@ func Run(opts *Options) (int, error) {
|
|||||||
executor := util.NewExecutor(opts.WithShell)
|
executor := util.NewExecutor(opts.WithShell)
|
||||||
|
|
||||||
// Reader
|
// Reader
|
||||||
|
reloadOnStart := opts.reloadOnStart()
|
||||||
streamingFilter := opts.Filter != nil && !sort && !opts.Tac && !opts.Sync
|
streamingFilter := opts.Filter != nil && !sort && !opts.Tac && !opts.Sync
|
||||||
var reader *Reader
|
var reader *Reader
|
||||||
if !streamingFilter {
|
if !streamingFilter {
|
||||||
reader = NewReader(func(data []byte) bool {
|
reader = NewReader(func(data []byte) bool {
|
||||||
return chunkList.Push(data)
|
return chunkList.Push(data)
|
||||||
}, eventBox, executor, opts.ReadZero, opts.Filter == nil)
|
}, eventBox, executor, opts.ReadZero, opts.Filter == nil)
|
||||||
go reader.ReadSource(opts.Input, opts.WalkerRoot, opts.WalkerOpts, opts.WalkerSkip)
|
|
||||||
|
if reloadOnStart {
|
||||||
|
// reload or reload-sync action is bound to 'start' event, no need to start the reader
|
||||||
|
eventBox.Set(EvtReadNone, nil)
|
||||||
|
} else {
|
||||||
|
go reader.ReadSource(opts.Input, opts.WalkerRoot, opts.WalkerOpts, opts.WalkerSkip)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Matcher
|
// Matcher
|
||||||
@ -227,7 +234,8 @@ func Run(opts *Options) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Synchronous search
|
// Synchronous search
|
||||||
if opts.Sync {
|
sync := opts.Sync && !reloadOnStart
|
||||||
|
if sync {
|
||||||
eventBox.Unwatch(EvtReadNew)
|
eventBox.Unwatch(EvtReadNew)
|
||||||
eventBox.WaitFor(EvtReadFin)
|
eventBox.WaitFor(EvtReadFin)
|
||||||
}
|
}
|
||||||
@ -247,7 +255,7 @@ func Run(opts *Options) (int, error) {
|
|||||||
if heightUnknown {
|
if heightUnknown {
|
||||||
maxFit, padHeight = terminal.MaxFitAndPad()
|
maxFit, padHeight = terminal.MaxFitAndPad()
|
||||||
}
|
}
|
||||||
deferred := opts.Select1 || opts.Exit0 || opts.Sync
|
deferred := opts.Select1 || opts.Exit0 || sync
|
||||||
go terminal.Loop()
|
go terminal.Loop()
|
||||||
if !deferred && !heightUnknown {
|
if !deferred && !heightUnknown {
|
||||||
// Start right away
|
// Start right away
|
||||||
@ -314,6 +322,9 @@ func Run(opts *Options) (int, error) {
|
|||||||
err = quitSignal.err
|
err = quitSignal.err
|
||||||
stop = true
|
stop = true
|
||||||
return
|
return
|
||||||
|
case EvtReadNone:
|
||||||
|
reading = false
|
||||||
|
terminal.UpdateCount(0, false, nil)
|
||||||
case EvtReadNew, EvtReadFin:
|
case EvtReadNew, EvtReadFin:
|
||||||
if evt == EvtReadFin && nextCommand != nil {
|
if evt == EvtReadFin && nextCommand != nil {
|
||||||
restart(*nextCommand, nextEnviron)
|
restart(*nextCommand, nextEnviron)
|
||||||
|
@ -2945,3 +2945,18 @@ func ParseOptions(useDefaults bool, args []string) (*Options, error) {
|
|||||||
|
|
||||||
return opts, nil
|
return opts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (opts *Options) reloadOnStart() bool {
|
||||||
|
// Not compatible with --filter
|
||||||
|
if opts.Filter != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if actions, prs := opts.Keymap[tui.Start.AsEvent()]; prs {
|
||||||
|
for _, action := range actions {
|
||||||
|
if action.t == actReload || action.t == actReloadSync {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -26,12 +26,12 @@ BASE = File.expand_path('..', __dir__)
|
|||||||
Dir.chdir(BASE)
|
Dir.chdir(BASE)
|
||||||
FZF = "FZF_DEFAULT_OPTS=\"--no-scrollbar --pointer \\> --marker \\>\" FZF_DEFAULT_COMMAND= #{BASE}/bin/fzf"
|
FZF = "FZF_DEFAULT_OPTS=\"--no-scrollbar --pointer \\> --marker \\>\" FZF_DEFAULT_COMMAND= #{BASE}/bin/fzf"
|
||||||
|
|
||||||
def wait
|
def wait(timeout = DEFAULT_TIMEOUT)
|
||||||
since = Time.now
|
since = Time.now
|
||||||
begin
|
begin
|
||||||
yield or raise Minitest::Assertion, 'Assertion failure'
|
yield or raise Minitest::Assertion, 'Assertion failure'
|
||||||
rescue Minitest::Assertion
|
rescue Minitest::Assertion
|
||||||
raise if Time.now - since > DEFAULT_TIMEOUT
|
raise if Time.now - since > timeout
|
||||||
|
|
||||||
sleep(0.05)
|
sleep(0.05)
|
||||||
retry
|
retry
|
||||||
@ -103,10 +103,10 @@ class Tmux
|
|||||||
go(%W[capture-pane -p -J -t #{win}]).map(&:rstrip).reverse.drop_while(&:empty?).reverse
|
go(%W[capture-pane -p -J -t #{win}]).map(&:rstrip).reverse.drop_while(&:empty?).reverse
|
||||||
end
|
end
|
||||||
|
|
||||||
def until(refresh = false)
|
def until(refresh = false, timeout: DEFAULT_TIMEOUT)
|
||||||
lines = nil
|
lines = nil
|
||||||
begin
|
begin
|
||||||
wait do
|
wait(timeout) do
|
||||||
lines = capture
|
lines = capture
|
||||||
class << lines
|
class << lines
|
||||||
def counts
|
def counts
|
||||||
@ -3356,6 +3356,14 @@ class TestGoFZF < TestBase
|
|||||||
BLOCK
|
BLOCK
|
||||||
tmux.until { assert_block(block, _1) }
|
tmux.until { assert_block(block, _1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_start_on_reload
|
||||||
|
tmux.send_keys %[echo foo | #{FZF} --header Loading --header-lines 1 --bind 'start:reload:sleep 2; echo bar' --bind 'load:change-header:Loaded'], :Enter
|
||||||
|
tmux.until(timeout: 1) { |lines| assert_includes lines[-3], 'Loading' }
|
||||||
|
tmux.until(timeout: 1) { |lines| refute_includes lines[-4], 'foo' }
|
||||||
|
tmux.until { |lines| assert_includes lines[-3], 'Loaded' }
|
||||||
|
tmux.until { |lines| assert_includes lines[-4], 'bar' }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module TestShell
|
module TestShell
|
||||||
|
Loading…
Reference in New Issue
Block a user