mirror of
https://github.com/junegunn/fzf.git
synced 2025-11-12 21:33:49 -05:00
Add 'multi' event triggered on multi-selection changes
This commit is contained in:
@@ -1,13 +1,18 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
0.63.1
|
0.64.0
|
||||||
------
|
------
|
||||||
|
- Added `multi` event that is triggered when the multi-selection has changed.
|
||||||
|
```sh
|
||||||
|
fzf --multi --bind 'multi:transform-footer:(( FZF_SELECT_COUNT )) && echo "Selected: $FZF_SELECT_COUNT item(s)"'
|
||||||
|
```
|
||||||
- [Halfwidth and fullwidth alphanumeric and punctuation characters](https://en.wikipedia.org/wiki/Halfwidth_and_Fullwidth_Forms_(Unicode_block)) are now internally normalized to their ASCII equivalents to allow matching with ASCII queries.
|
- [Halfwidth and fullwidth alphanumeric and punctuation characters](https://en.wikipedia.org/wiki/Halfwidth_and_Fullwidth_Forms_(Unicode_block)) are now internally normalized to their ASCII equivalents to allow matching with ASCII queries.
|
||||||
```sh
|
```sh
|
||||||
echo ABC| fzf -q abc
|
echo ABC| fzf -q abc
|
||||||
```
|
```
|
||||||
- Fixed a bug which caused fzf to abort due to incorrect update ordering.
|
- Fixed a bug which caused fzf to abort due to incorrect update ordering.
|
||||||
|
- Renamed `clear-selection` action to `clear-multi` for consistency.
|
||||||
|
|
||||||
0.63.0
|
0.63.0
|
||||||
------
|
------
|
||||||
|
|||||||
@@ -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 "Jun 2025" "fzf 0.63.0" "fzf - a command-line fuzzy finder"
|
.TH fzf 1 "Jul 2025" "fzf 0.64.0" "fzf - a command-line fuzzy finder"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fzf - a command-line fuzzy finder
|
fzf - a command-line fuzzy finder
|
||||||
@@ -1609,6 +1609,10 @@ e.g.
|
|||||||
# Beware not to introduce an infinite loop
|
# Beware not to introduce an infinite loop
|
||||||
seq 10 | fzf \-\-bind 'focus:up' \-\-cycle\fR
|
seq 10 | fzf \-\-bind 'focus:up' \-\-cycle\fR
|
||||||
.RE
|
.RE
|
||||||
|
\fImulti\fR
|
||||||
|
.RS
|
||||||
|
Triggered when the multi\-selection has changed.
|
||||||
|
.RE
|
||||||
|
|
||||||
\fIone\fR
|
\fIone\fR
|
||||||
.RS
|
.RS
|
||||||
@@ -1711,7 +1715,7 @@ A key or an event can be bound to one or more of the following actions.
|
|||||||
\fBchange\-prompt(...)\fR (change prompt to the given string)
|
\fBchange\-prompt(...)\fR (change prompt to the given string)
|
||||||
\fBchange\-query(...)\fR (change query string to the given string)
|
\fBchange\-query(...)\fR (change query string to the given string)
|
||||||
\fBclear\-screen\fR \fIctrl\-l\fR
|
\fBclear\-screen\fR \fIctrl\-l\fR
|
||||||
\fBclear\-selection\fR (clear multi\-selection)
|
\fBclear\-multi\fR (clear multi\-selection)
|
||||||
\fBclose\fR (close preview window if open, abort fzf otherwise)
|
\fBclose\fR (close preview window if open, abort fzf otherwise)
|
||||||
\fBclear\-query\fR (clear query string)
|
\fBclear\-query\fR (clear query string)
|
||||||
\fBdelete\-char\fR \fIdel\fR
|
\fBdelete\-char\fR \fIdel\fR
|
||||||
|
|||||||
@@ -1008,6 +1008,8 @@ func parseKeyChordsImpl(str string, message string) (map[tui.Event]string, error
|
|||||||
add(tui.JumpCancel)
|
add(tui.JumpCancel)
|
||||||
case "click-header":
|
case "click-header":
|
||||||
add(tui.ClickHeader)
|
add(tui.ClickHeader)
|
||||||
|
case "multi":
|
||||||
|
add(tui.Multi)
|
||||||
case "alt-enter", "alt-return":
|
case "alt-enter", "alt-return":
|
||||||
chords[tui.CtrlAltKey('m')] = key
|
chords[tui.CtrlAltKey('m')] = key
|
||||||
case "alt-space":
|
case "alt-space":
|
||||||
@@ -1561,7 +1563,7 @@ func parseActionList(masked string, original string, prevActions []*action, putA
|
|||||||
appendAction(actCancel)
|
appendAction(actCancel)
|
||||||
case "clear-query":
|
case "clear-query":
|
||||||
appendAction(actClearQuery)
|
appendAction(actClearQuery)
|
||||||
case "clear-selection":
|
case "clear-multi", "clear-selection":
|
||||||
appendAction(actClearSelection)
|
appendAction(actClearSelection)
|
||||||
case "forward-char":
|
case "forward-char":
|
||||||
appendAction(actForwardChar)
|
appendAction(actForwardChar)
|
||||||
|
|||||||
@@ -5399,6 +5399,7 @@ func (t *Terminal) Loop() error {
|
|||||||
}
|
}
|
||||||
previousInput := t.input
|
previousInput := t.input
|
||||||
previousCx := t.cx
|
previousCx := t.cx
|
||||||
|
previousVersion := t.version
|
||||||
t.lastKey = event.KeyName()
|
t.lastKey = event.KeyName()
|
||||||
updatePreviewWindow := func(forcePreview bool) {
|
updatePreviewWindow := func(forcePreview bool) {
|
||||||
t.resizeWindows(forcePreview, false)
|
t.resizeWindows(forcePreview, false)
|
||||||
@@ -6656,6 +6657,9 @@ func (t *Terminal) Loop() error {
|
|||||||
if onEOFs, prs := t.keymap[tui.BackwardEOF.AsEvent()]; beof && prs && !doActions(onEOFs) {
|
if onEOFs, prs := t.keymap[tui.BackwardEOF.AsEvent()]; beof && prs && !doActions(onEOFs) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if onMultis, prs := t.keymap[tui.Multi.AsEvent()]; t.version != previousVersion && prs && !doActions(onMultis) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
jumpEvent := tui.JumpCancel
|
jumpEvent := tui.JumpCancel
|
||||||
if event.Type == tui.Rune {
|
if event.Type == tui.Rune {
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ const (
|
|||||||
Jump
|
Jump
|
||||||
JumpCancel
|
JumpCancel
|
||||||
ClickHeader
|
ClickHeader
|
||||||
|
Multi
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t EventType) AsEvent() Event {
|
func (t EventType) AsEvent() Event {
|
||||||
|
|||||||
@@ -1988,4 +1988,15 @@ class TestCore < TestInteractive
|
|||||||
tmux.until { assert it.any_include?('boom') }
|
tmux.until { assert it.any_include?('boom') }
|
||||||
tmux.until { assert it.any_include?('bam') }
|
tmux.until { assert it.any_include?('bam') }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_multi_event
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --multi --bind 'multi:transform-footer:(( FZF_SELECT_COUNT )) && echo "Selected $FZF_SELECT_COUNT item(s)"'), :Enter
|
||||||
|
tmux.until { assert_equal 100, it.match_count }
|
||||||
|
tmux.send_keys :Tab
|
||||||
|
tmux.until { assert_equal 1, it.select_count }
|
||||||
|
tmux.until { assert it.any_include?('Selected 1 item(s)') }
|
||||||
|
tmux.send_keys :Tab
|
||||||
|
tmux.until { assert_equal 0, it.select_count }
|
||||||
|
tmux.until { refute it.any_include?('Selected') }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user