mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-01 12:42:01 -07:00
Add 'focus' event
Can we find a better name? I have considered the followings. * 'point', because "the pointer" points to the current item. * 'shift', 'switch', 'move', etc. These are not technically correct because the current item can change without cursor movement (--tac, reload, search update) * 'change' is already taken. 'change-current' feels a bit wordy and sounds wrong, 'current-changed' is wordy and doesn't go well with the other event names * 'target', not straightforward Close #3053
This commit is contained in:
14
CHANGELOG.md
14
CHANGELOG.md
@@ -3,6 +3,20 @@ CHANGELOG
|
|||||||
|
|
||||||
0.37.0
|
0.37.0
|
||||||
------
|
------
|
||||||
|
- New event
|
||||||
|
- `focus` - Triggered when the focus changes due to a vertical cursor
|
||||||
|
movement or a search result update
|
||||||
|
```sh
|
||||||
|
fzf --bind 'focus:transform-preview-label:echo [ {} ]' --border --preview 'cat {}'
|
||||||
|
|
||||||
|
# Any action bound to the event runs synchronously and thus can make the interface sluggish
|
||||||
|
# e.g. lolcat isn't one of the fastest programs, and every cursor movement in
|
||||||
|
# fzf will be noticeably affected by its execution time
|
||||||
|
fzf --bind 'focus:transform-preview-label:echo [ {} ] | lolcat -f' --border --preview 'cat {}'
|
||||||
|
|
||||||
|
# Beware not to introduce an infinite loop
|
||||||
|
seq 10 | fzf --bind 'focus:up' --cycle
|
||||||
|
```
|
||||||
- New actions
|
- New actions
|
||||||
- `change-border-label`
|
- `change-border-label`
|
||||||
- `change-preview-label`
|
- `change-preview-label`
|
||||||
|
@@ -959,6 +959,22 @@ e.g.
|
|||||||
\fB# Move cursor to the first entry whenever the query is changed
|
\fB# Move cursor to the first entry whenever the query is changed
|
||||||
fzf --bind change:first\fR
|
fzf --bind change:first\fR
|
||||||
.RE
|
.RE
|
||||||
|
\fIfocus\fR
|
||||||
|
.RS
|
||||||
|
Triggered when the focus changes due to a vertical cursor movement or a search
|
||||||
|
result update.
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
\fBfzf --bind 'focus:transform-preview-label:echo [ {} ]' --border --preview 'cat {}'
|
||||||
|
|
||||||
|
# Any action bound to the event runs synchronously and thus can make the interface sluggish
|
||||||
|
# e.g. lolcat isn't one of the fastest programs, and every cursor movement in
|
||||||
|
# fzf will be noticeably affected by its execution time
|
||||||
|
fzf --bind 'focus:transform-preview-label:echo [ {} ] | lolcat -f' --border --preview 'cat {}'
|
||||||
|
|
||||||
|
# Beware not to introduce an infinite loop
|
||||||
|
seq 10 | fzf --bind 'focus:up' --cycle\fR
|
||||||
|
.RE
|
||||||
|
|
||||||
\fIbackward-eof\fR
|
\fIbackward-eof\fR
|
||||||
.RS
|
.RS
|
||||||
@@ -983,11 +999,11 @@ A key or an event can be bound to one or more of the following actions.
|
|||||||
\fBbackward-word\fR \fIalt-b shift-left\fR
|
\fBbackward-word\fR \fIalt-b shift-left\fR
|
||||||
\fBbeginning-of-line\fR \fIctrl-a home\fR
|
\fBbeginning-of-line\fR \fIctrl-a home\fR
|
||||||
\fBcancel\fR (clear query string if not empty, abort fzf otherwise)
|
\fBcancel\fR (clear query string if not empty, abort fzf otherwise)
|
||||||
\fBchange-preview(...)\fR (change \fB--preview\fR option)
|
|
||||||
\fBchange-preview-window(...)\fR (change \fB--preview-window\fR option; rotate through the multiple option sets separated by '|')
|
|
||||||
\fBchange-preview-label(...)\fR (change \fB--preview-label\fR to the given string)
|
|
||||||
\fBchange-prompt(...)\fR (change prompt to the given string)
|
|
||||||
\fBchange-border-label(...)\fR (change \fB--border-label\fR to the given string)
|
\fBchange-border-label(...)\fR (change \fB--border-label\fR to the given string)
|
||||||
|
\fBchange-preview(...)\fR (change \fB--preview\fR option)
|
||||||
|
\fBchange-preview-label(...)\fR (change \fB--preview-label\fR to the given string)
|
||||||
|
\fBchange-preview-window(...)\fR (change \fB--preview-window\fR option; rotate through the multiple option sets separated by '|')
|
||||||
|
\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-selection\fR (clear multi-selection)
|
||||||
|
@@ -609,6 +609,8 @@ func parseKeyChordsImpl(str string, message string, exit func(string)) map[tui.E
|
|||||||
add(tui.Start)
|
add(tui.Start)
|
||||||
case "load":
|
case "load":
|
||||||
add(tui.Load)
|
add(tui.Load)
|
||||||
|
case "focus":
|
||||||
|
add(tui.Focus)
|
||||||
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":
|
||||||
|
@@ -1265,7 +1265,7 @@ func (t *Terminal) resizeWindows(forcePreview bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) printLabel(window tui.Window, render labelPrinter, opts labelOpts, length int, borderShape tui.BorderShape, redrawBorder bool) {
|
func (t *Terminal) printLabel(window tui.Window, render labelPrinter, opts labelOpts, length int, borderShape tui.BorderShape, redrawBorder bool) {
|
||||||
if window == nil || render == nil {
|
if window == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1274,6 +1274,9 @@ func (t *Terminal) printLabel(window tui.Window, render labelPrinter, opts label
|
|||||||
if redrawBorder {
|
if redrawBorder {
|
||||||
window.DrawHBorder()
|
window.DrawHBorder()
|
||||||
}
|
}
|
||||||
|
if render == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
var col int
|
var col int
|
||||||
if opts.column == 0 {
|
if opts.column == 0 {
|
||||||
col = util.Max(0, (window.Width()-length)/2)
|
col = util.Max(0, (window.Width()-length)/2)
|
||||||
@@ -2616,6 +2619,11 @@ func (t *Terminal) Loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var onFocus []*action
|
||||||
|
if actions, prs := t.keymap[tui.Focus.AsEvent()]; prs {
|
||||||
|
onFocus = actions
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
var focusedIndex int32 = minItem.Index()
|
var focusedIndex int32 = minItem.Index()
|
||||||
var version int64 = -1
|
var version int64 = -1
|
||||||
@@ -2651,7 +2659,11 @@ func (t *Terminal) Loop() {
|
|||||||
if currentItem != nil {
|
if currentItem != nil {
|
||||||
currentIndex = currentItem.Index()
|
currentIndex = currentItem.Index()
|
||||||
}
|
}
|
||||||
if focusedIndex != currentIndex || version != t.version {
|
focusChanged := focusedIndex != currentIndex
|
||||||
|
if onFocus != nil && focusChanged {
|
||||||
|
t.serverChan <- onFocus
|
||||||
|
}
|
||||||
|
if focusChanged || version != t.version {
|
||||||
version = t.version
|
version = t.version
|
||||||
focusedIndex = currentIndex
|
focusedIndex = currentIndex
|
||||||
refreshPreview(t.previewOpts.command)
|
refreshPreview(t.previewOpts.command)
|
||||||
|
@@ -92,6 +92,7 @@ const (
|
|||||||
BackwardEOF
|
BackwardEOF
|
||||||
Start
|
Start
|
||||||
Load
|
Load
|
||||||
|
Focus
|
||||||
|
|
||||||
AltBS
|
AltBS
|
||||||
|
|
||||||
|
@@ -2473,6 +2473,15 @@ class TestGoFZF < TestBase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_focus_event
|
||||||
|
tmux.send_keys 'seq 100 | fzf --bind "focus:transform-prompt(echo [[{}]])"', :Enter
|
||||||
|
tmux.until { |lines| assert_includes(lines[-1], '[[1]]') }
|
||||||
|
tmux.send_keys :Up
|
||||||
|
tmux.until { |lines| assert_includes(lines[-1], '[[2]]') }
|
||||||
|
tmux.send_keys :X
|
||||||
|
tmux.until { |lines| assert_includes(lines[-1], '[[]]') }
|
||||||
|
end
|
||||||
|
|
||||||
def test_labels_center
|
def test_labels_center
|
||||||
tmux.send_keys 'echo x | fzf --border --border-label foobar --preview : --preview-label barfoo --bind "space:change-border-label(foobarfoo)+change-preview-label(barfoobar),enter:transform-border-label(echo foo{}foo)+transform-preview-label(echo bar{}bar)"', :Enter
|
tmux.send_keys 'echo x | fzf --border --border-label foobar --preview : --preview-label barfoo --bind "space:change-border-label(foobarfoo)+change-preview-label(barfoobar),enter:transform-border-label(echo foo{}foo)+transform-preview-label(echo bar{}bar)"', :Enter
|
||||||
tmux.until do
|
tmux.until do
|
||||||
|
Reference in New Issue
Block a user