diff --git a/CHANGELOG.md b/CHANGELOG.md index 3608f4e..aa5e7eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,16 @@ CHANGELOG # Put the cursor on the 10th to last item seq 100 | fzf --sync --bind 'start:pos(-10)' ``` +- Added `load` event that is triggered when the input stream is complete and + the initial processing of the list is complete. + ```sh + # Change the prompt to "loaded" when the input stream is complete + (seq 10; sleep 1; seq 11 20) | fzf --prompt 'Loading> ' --bind 'load:change-prompt:Loaded> ' + + # You can use it instead of 'start' event without `--sync` if asynchronous + # trigger is not an issue. + (seq 10; sleep 1; seq 11 20) | fzf --bind 'load:last' + ``` - Added `next-selected` and `prev-selected` actions to move between selected items ```sh diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index f5e01b6..5983dcf 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -927,6 +927,15 @@ e.g. \fB# Move cursor to the last item and select all items seq 1000 | fzf --multi --sync --bind start:last+select-all\fR .RE +\fIload\fR +.RS +Triggered when the input stream is complete and the initial processing of the +list is complete. + +e.g. + \fB# Change the prompt to "loaded" when the input stream is complete + (seq 10; sleep 1; seq 11 20) | fzf --prompt 'Loading> ' --bind 'load:change-prompt:Loaded> '\fR +.RE \fIchange\fR .RS Triggered whenever the query string is changed diff --git a/src/options.go b/src/options.go index 1288fbe..08b4825 100644 --- a/src/options.go +++ b/src/options.go @@ -590,6 +590,8 @@ func parseKeyChords(str string, message string) map[tui.Event]string { add(tui.BackwardEOF) case "start": add(tui.Start) + case "load": + add(tui.Load) case "alt-enter", "alt-return": chords[tui.CtrlAltKey('m')] = key case "alt-space": diff --git a/src/terminal.go b/src/terminal.go index 685b124..02b1a5d 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -177,6 +177,8 @@ type Terminal struct { pwindow tui.Window count int progress int + hasLoadActions bool + triggerLoad bool reading bool running bool failed *string @@ -202,6 +204,7 @@ type Terminal struct { startChan chan fitpad killChan chan int serverChan chan []*action + eventChan chan tui.Event slab *util.Slab theme *tui.ColorTheme tui tui.Renderer @@ -579,6 +582,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { ellipsis: opts.Ellipsis, ansi: opts.Ansi, tabstop: opts.Tabstop, + hasLoadActions: false, + triggerLoad: false, reading: true, running: true, failed: nil, @@ -603,6 +608,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { startChan: make(chan fitpad, 1), killChan: make(chan int), serverChan: make(chan []*action, 10), + eventChan: make(chan tui.Event, 1), tui: renderer, initFunc: func() { renderer.Init() }, executing: util.NewAtomicBool(false)} @@ -624,6 +630,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { t.separator, t.separatorLen = t.ansiLabelPrinter(bar, &tui.ColSeparator, true) } + _, t.hasLoadActions = t.keymap[tui.Load.AsEvent()] + if err := startHttpServer(t.listenPort, t.serverChan); err != nil { errorExit(err.Error()) } @@ -763,6 +771,9 @@ func (t *Terminal) Input() (bool, []rune) { func (t *Terminal) UpdateCount(cnt int, final bool, failedCommand *string) { t.mutex.Lock() t.count = cnt + if t.hasLoadActions && t.reading && final { + t.triggerLoad = true + } t.reading = !final t.failed = failedCommand t.mutex.Unlock() @@ -811,6 +822,10 @@ func (t *Terminal) UpdateList(merger *Merger, reset bool) { t.selected = make(map[int32]selectedItem) t.version++ } + if t.hasLoadActions && t.triggerLoad { + t.triggerLoad = false + t.eventChan <- tui.Load.AsEvent() + } t.mutex.Unlock() t.reqBox.Set(reqInfo, nil) t.reqBox.Set(reqList, nil) @@ -2515,13 +2530,12 @@ func (t *Terminal) Loop() { looping := true _, startEvent := t.keymap[tui.Start.AsEvent()] - eventChan := make(chan tui.Event) needBarrier := true barrier := make(chan bool) go func() { for { <-barrier - eventChan <- t.tui.GetChar() + t.eventChan <- t.tui.GetChar() } }() for looping { @@ -2540,8 +2554,8 @@ func (t *Terminal) Loop() { barrier <- true } select { - case event = <-eventChan: - needBarrier = true + case event = <-t.eventChan: + needBarrier = event != tui.Load.AsEvent() case actions = <-t.serverChan: event = tui.Invalid.AsEvent() needBarrier = false diff --git a/src/tui/tui.go b/src/tui/tui.go index 7720608..d1bb571 100644 --- a/src/tui/tui.go +++ b/src/tui/tui.go @@ -91,6 +91,7 @@ const ( Change BackwardEOF Start + Load AltBS