Fix race condition where preview window is not properly cleared

This commit is contained in:
Junegunn Choi 2016-06-15 13:03:42 +09:00
parent 8a90f26c8a
commit e455836cc9
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
2 changed files with 28 additions and 17 deletions

View File

@ -82,6 +82,11 @@ type selectedItem struct {
type byTimeOrder []selectedItem type byTimeOrder []selectedItem
type previewRequest struct {
ok bool
str string
}
func (a byTimeOrder) Len() int { func (a byTimeOrder) Len() int {
return len(a) return len(a)
} }
@ -908,21 +913,23 @@ func (t *Terminal) Loop() {
if t.hasPreviewWindow() { if t.hasPreviewWindow() {
go func() { go func() {
for { for {
focused := "" request := previewRequest{false, ""}
t.previewBox.Wait(func(events *util.Events) { t.previewBox.Wait(func(events *util.Events) {
for req, value := range *events { for req, value := range *events {
switch req { switch req {
case reqPreviewEnqueue: case reqPreviewEnqueue:
focused = value.(string) request = value.(previewRequest)
} }
} }
events.Clear() events.Clear()
}) })
if len(focused) > 0 { if request.ok {
command := strings.Replace(t.preview.command, "{}", quoteEntry(focused), -1) command := strings.Replace(t.preview.command, "{}", quoteEntry(request.str), -1)
cmd := util.ExecCommand(command) cmd := util.ExecCommand(command)
out, _ := cmd.CombinedOutput() out, _ := cmd.CombinedOutput()
t.reqBox.Set(reqPreviewDisplay, string(out)) t.reqBox.Set(reqPreviewDisplay, string(out))
} else {
t.reqBox.Set(reqPreviewDisplay, "")
} }
} }
}() }()
@ -936,7 +943,7 @@ func (t *Terminal) Loop() {
} }
go func() { go func() {
focused := "" focused := previewRequest{false, ""}
for { for {
t.reqBox.Wait(func(events *util.Events) { t.reqBox.Wait(func(events *util.Events) {
defer events.Clear() defer events.Clear()
@ -953,20 +960,18 @@ func (t *Terminal) Loop() {
case reqList: case reqList:
t.printList() t.printList()
cnt := t.merger.Length() cnt := t.merger.Length()
var currentFocus previewRequest
if cnt > 0 && cnt > t.cy { if cnt > 0 && cnt > t.cy {
currentFocus := t.current() currentFocus = previewRequest{true, t.current()}
} else {
currentFocus = previewRequest{false, ""}
}
if currentFocus != focused { if currentFocus != focused {
focused = currentFocus focused = currentFocus
if t.isPreviewEnabled() { if t.isPreviewEnabled() {
t.previewBox.Set(reqPreviewEnqueue, focused) t.previewBox.Set(reqPreviewEnqueue, focused)
} }
} }
} else {
if focused != "" && t.isPreviewEnabled() {
t.pwindow.Erase()
}
focused = ""
}
case reqJump: case reqJump:
if t.merger.Length() == 0 { if t.merger.Length() == 0 {
t.jumping = jumpDisabled t.jumping = jumpDisabled
@ -1076,7 +1081,7 @@ func (t *Terminal) Loop() {
t.resizeWindows() t.resizeWindows()
cnt := t.merger.Length() cnt := t.merger.Length()
if t.previewing && cnt > 0 && cnt > t.cy { if t.previewing && cnt > 0 && cnt > t.cy {
t.previewBox.Set(reqPreviewEnqueue, t.current()) t.previewBox.Set(reqPreviewEnqueue, previewRequest{true, t.current()})
} }
req(reqList, reqInfo) req(reqList, reqInfo)
} }

View File

@ -1229,14 +1229,20 @@ class TestGoFZF < TestBase
end end
def test_preview def test_preview
tmux.send_keys %[seq 1000 | #{FZF} --preview 'echo {{}-{}}' --bind ?:toggle-preview], :Enter tmux.send_keys %[seq 1000 | sed s/^2$// | #{FZF} --preview 'sleep 0.2; echo {{}-{}}' --bind ?:toggle-preview], :Enter
tmux.until { |lines| lines[1].include?(' {1-1}') } tmux.until { |lines| lines[1].include?(' {1-1}') }
tmux.send_keys :Up
tmux.until { |lines| lines[1].include?(' {-}') }
tmux.send_keys '555' tmux.send_keys '555'
tmux.until { |lines| lines[1].include?(' {555-555}') } tmux.until { |lines| lines[1].include?(' {555-555}') }
tmux.send_keys '?' tmux.send_keys '?'
tmux.until { |lines| !lines[1].include?(' {555-555}') } tmux.until { |lines| !lines[1].include?(' {555-555}') }
tmux.send_keys '?' tmux.send_keys '?'
tmux.until { |lines| lines[1].include?(' {555-555}') } tmux.until { |lines| lines[1].include?(' {555-555}') }
tmux.send_keys :BSpace
tmux.until { |lines| lines[-2].start_with? ' 28/1000' }
tmux.send_keys 'foobar'
tmux.until { |lines| !lines[1].include?('{') }
end end
def test_preview_hidden def test_preview_hidden