Fix track-current unset after a combined movement action
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled

Fix #4649
Close #4663
This commit is contained in:
Junegunn Choi
2026-01-26 11:16:59 +09:00
parent 25b2248f11
commit b389616030
3 changed files with 57 additions and 20 deletions

View File

@@ -292,14 +292,32 @@ func defaultMargin() [4]sizeSpec {
return [4]sizeSpec{}
}
type trackOption int
type trackOption struct {
enabled bool
index int32
}
const (
trackDisabled trackOption = iota
trackEnabled
trackCurrent
var (
trackDisabled = trackOption{false, minItem.Index()}
trackEnabled = trackOption{true, minItem.Index()}
)
func (t trackOption) Disabled() bool {
return !t.enabled
}
func (t trackOption) Global() bool {
return t.enabled && t.index == minItem.Index()
}
func (t trackOption) Current() bool {
return t.enabled && t.index != minItem.Index()
}
func trackCurrent(index int32) trackOption {
return trackOption{true, index}
}
type windowPosition int
const (

View File

@@ -1816,7 +1816,7 @@ func (t *Terminal) UpdateList(result MatchResult) {
if i >= 0 {
t.cy = i
t.offset = t.cy - pos
} else if t.track == trackCurrent {
} else if t.track.Current() {
t.track = trackDisabled
t.cy = pos
t.offset = 0
@@ -2886,10 +2886,9 @@ func (t *Terminal) printInfoImpl() {
output += " -S"
}
}
switch t.track {
case trackEnabled:
if t.track.Global() {
output += " +T"
case trackCurrent:
} else if t.track.Current() {
output += " +t"
}
if t.multi > 0 {
@@ -5471,11 +5470,11 @@ func (t *Terminal) Loop() error {
case reqList:
t.printList()
currentIndex := t.currentIndex()
focusChanged := focusedIndex != currentIndex
if focusChanged && focusedIndex >= 0 && t.track == trackCurrent {
if t.track.Current() && t.track.index != currentIndex {
t.track = trackDisabled
info = true
}
focusChanged := focusedIndex != currentIndex
if (t.hasFocusActions || t.infoCommand != "") && focusChanged && currentIndex != t.lastFocus {
t.lastFocus = currentIndex
t.eventChan <- tui.Focus.AsEvent()
@@ -6550,11 +6549,10 @@ func (t *Terminal) Loop() error {
}
req(reqInfo)
case actToggleTrackCurrent:
switch t.track {
case trackCurrent:
if t.track.Current() {
t.track = trackDisabled
case trackDisabled:
t.track = trackCurrent
} else if t.track.Disabled() {
t.track = trackCurrent(t.currentIndex())
}
req(reqInfo)
case actShowHeader:
@@ -6602,12 +6600,13 @@ func (t *Terminal) Loop() error {
}
req(reqList, reqInfo, reqPrompt, reqHeader)
case actTrackCurrent:
if t.track == trackDisabled {
t.track = trackCurrent
// Global tracking has higher priority
if !t.track.Global() {
t.track = trackCurrent(t.currentIndex())
}
req(reqInfo)
case actUntrackCurrent:
if t.track == trackCurrent {
if t.track.Current() {
t.track = trackDisabled
}
req(reqInfo)

View File

@@ -1588,14 +1588,16 @@ class TestCore < TestInteractive
end
def test_track_action
tmux.send_keys "seq 1000 | #{FZF} --query 555 --bind t:track", :Enter
tmux.send_keys "seq 1000 | #{FZF} --pointer x --query 555 --bind t:track,T:up+track", :Enter
tmux.until do |lines|
assert_equal 1, lines.match_count
assert_includes lines, 'x 555'
assert_includes lines, '> 555'
end
tmux.send_keys :BSpace
tmux.until do |lines|
assert_equal 28, lines.match_count
assert_includes lines, 'x 55'
assert_includes lines, '> 55'
end
tmux.send_keys :t
@@ -1605,7 +1607,8 @@ class TestCore < TestInteractive
tmux.send_keys :BSpace
tmux.until do |lines|
assert_equal 271, lines.match_count
assert_includes lines, '> 55'
assert_includes lines, 'x 55'
assert_includes lines, '> 5'
end
# Automatically disabled when the tracking item is no longer visible
@@ -1617,16 +1620,33 @@ class TestCore < TestInteractive
tmux.send_keys :BSpace
tmux.until do |lines|
assert_equal 271, lines.match_count
assert_includes lines, 'x 52'
assert_includes lines, '> 5'
end
tmux.send_keys :t
tmux.until do |lines|
assert_includes lines[-2], '+t'
end
# Automatically disabled when the focus has moved
tmux.send_keys :Up
tmux.until do |lines|
assert_includes lines, 'x 53'
refute_includes lines[-2], '+t'
end
# Should work even when combined with a focus moving actions
tmux.send_keys 'T'
tmux.until do |lines|
assert_includes lines, 'x 54'
assert_includes lines[-2], '+t'
end
tmux.send_keys 'T'
tmux.until do |lines|
assert_includes lines, 'x 55'
assert_includes lines[-2], '+t'
end
end
def test_one_and_zero