mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-01 20:52:06 -07:00
Fix panic caused by incorrect update ordering
Fix #4442 Make sure to prepare windows before rendering elements. Thanks to @nugged for the report.
This commit is contained in:
@@ -450,31 +450,35 @@ func (a byTimeOrder) Less(i, j int) bool {
|
|||||||
return a[i].at.Before(a[j].at)
|
return a[i].at.Before(a[j].at)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EventTypes are listed in the order of their priority.
|
||||||
const (
|
const (
|
||||||
reqPrompt util.EventType = iota
|
reqResize util.EventType = iota
|
||||||
|
reqReinit
|
||||||
|
reqFullRedraw
|
||||||
|
reqRedraw
|
||||||
|
|
||||||
|
reqJump
|
||||||
|
reqPrompt
|
||||||
reqInfo
|
reqInfo
|
||||||
reqHeader
|
reqHeader
|
||||||
reqFooter
|
reqFooter
|
||||||
reqList
|
reqList
|
||||||
reqJump
|
|
||||||
reqActivate
|
|
||||||
reqReinit
|
|
||||||
reqFullRedraw
|
|
||||||
reqResize
|
|
||||||
reqRedraw
|
|
||||||
reqRedrawInputLabel
|
reqRedrawInputLabel
|
||||||
reqRedrawHeaderLabel
|
reqRedrawHeaderLabel
|
||||||
reqRedrawFooterLabel
|
reqRedrawFooterLabel
|
||||||
reqRedrawListLabel
|
reqRedrawListLabel
|
||||||
reqRedrawBorderLabel
|
reqRedrawBorderLabel
|
||||||
reqRedrawPreviewLabel
|
reqRedrawPreviewLabel
|
||||||
reqClose
|
|
||||||
reqPrintQuery
|
|
||||||
reqPreviewReady
|
reqPreviewReady
|
||||||
reqPreviewEnqueue
|
reqPreviewEnqueue
|
||||||
reqPreviewDisplay
|
reqPreviewDisplay
|
||||||
reqPreviewRefresh
|
reqPreviewRefresh
|
||||||
reqPreviewDelayed
|
reqPreviewDelayed
|
||||||
|
|
||||||
|
reqActivate
|
||||||
|
reqClose
|
||||||
|
reqPrintQuery
|
||||||
reqBecome
|
reqBecome
|
||||||
reqQuit
|
reqQuit
|
||||||
reqFatal
|
reqFatal
|
||||||
@@ -1624,14 +1628,12 @@ func (t *Terminal) changeHeader(header string) bool {
|
|||||||
return needFullRedraw
|
return needFullRedraw
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) changeFooter(footer string) bool {
|
func (t *Terminal) changeFooter(footer string) {
|
||||||
var lines []string
|
var lines []string
|
||||||
if len(footer) > 0 {
|
if len(footer) > 0 {
|
||||||
lines = strings.Split(strings.TrimSuffix(footer, "\n"), "\n")
|
lines = strings.Split(strings.TrimSuffix(footer, "\n"), "\n")
|
||||||
}
|
}
|
||||||
needFullRedraw := len(t.footer) != len(lines)
|
|
||||||
t.footer = lines
|
t.footer = lines
|
||||||
return needFullRedraw
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateHeader updates the header
|
// UpdateHeader updates the header
|
||||||
@@ -2889,6 +2891,13 @@ func (t *Terminal) resizeIfNeeded() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check footer window
|
||||||
|
if len(t.footer) > 0 && (t.footerWindow == nil || t.footerWindow.Height() != len(t.footer)) ||
|
||||||
|
len(t.footer) == 0 && t.footerWindow != nil {
|
||||||
|
t.printAll()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the header borders are used and header has changed
|
// Check if the header borders are used and header has changed
|
||||||
allHeaderLines := t.visibleHeaderLines()
|
allHeaderLines := t.visibleHeaderLines()
|
||||||
primaryHeaderLines := allHeaderLines
|
primaryHeaderLines := allHeaderLines
|
||||||
@@ -5116,6 +5125,8 @@ func (t *Terminal) Loop() error {
|
|||||||
t.uiMutex.Lock()
|
t.uiMutex.Lock()
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
info := false
|
info := false
|
||||||
|
header := false
|
||||||
|
footer := false
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
req := util.EventType(key)
|
req := util.EventType(key)
|
||||||
value := (*events)[req]
|
value := (*events)[req]
|
||||||
@@ -5153,13 +5164,9 @@ func (t *Terminal) Loop() error {
|
|||||||
}
|
}
|
||||||
t.printList()
|
t.printList()
|
||||||
case reqHeader:
|
case reqHeader:
|
||||||
if !t.resizeIfNeeded() {
|
header = true
|
||||||
t.printHeader()
|
|
||||||
}
|
|
||||||
case reqFooter:
|
case reqFooter:
|
||||||
if !t.resizeIfNeeded() {
|
footer = true
|
||||||
t.printFooter()
|
|
||||||
}
|
|
||||||
case reqActivate:
|
case reqActivate:
|
||||||
t.suppress = false
|
t.suppress = false
|
||||||
if t.hasPreviewer() {
|
if t.hasPreviewer() {
|
||||||
@@ -5243,8 +5250,16 @@ func (t *Terminal) Loop() error {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if info && !t.resizeIfNeeded() {
|
if (info || header || footer) && !t.resizeIfNeeded() {
|
||||||
t.printInfo()
|
if info {
|
||||||
|
t.printInfo()
|
||||||
|
}
|
||||||
|
if header {
|
||||||
|
t.printHeader()
|
||||||
|
}
|
||||||
|
if footer {
|
||||||
|
t.printFooter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
t.flush()
|
t.flush()
|
||||||
t.mutex.Unlock()
|
t.mutex.Unlock()
|
||||||
@@ -5670,24 +5685,17 @@ func (t *Terminal) Loop() error {
|
|||||||
t.cx = len(t.input)
|
t.cx = len(t.input)
|
||||||
case actChangeHeader, actTransformHeader, actBgTransformHeader:
|
case actChangeHeader, actTransformHeader, actBgTransformHeader:
|
||||||
capture(false, func(header string) {
|
capture(false, func(header string) {
|
||||||
|
// When a dedicated header window is not used, we may need to
|
||||||
|
// update other elements as well.
|
||||||
if t.changeHeader(header) {
|
if t.changeHeader(header) {
|
||||||
if t.headerWindow != nil {
|
req(reqList, reqPrompt, reqInfo)
|
||||||
// Need to resize header window
|
|
||||||
req(reqRedraw)
|
|
||||||
} else {
|
|
||||||
req(reqHeader, reqList, reqPrompt, reqInfo)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
req(reqHeader)
|
|
||||||
}
|
}
|
||||||
|
req(reqHeader)
|
||||||
})
|
})
|
||||||
case actChangeFooter, actTransformFooter, actBgTransformFooter:
|
case actChangeFooter, actTransformFooter, actBgTransformFooter:
|
||||||
capture(false, func(footer string) {
|
capture(false, func(footer string) {
|
||||||
if t.changeFooter(footer) {
|
t.changeFooter(footer)
|
||||||
req(reqRedraw)
|
req(reqFooter)
|
||||||
} else {
|
|
||||||
req(reqFooter)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
case actChangeHeaderLabel, actTransformHeaderLabel, actBgTransformHeaderLabel:
|
case actChangeHeaderLabel, actTransformHeaderLabel, actBgTransformHeaderLabel:
|
||||||
capture(true, func(label string) {
|
capture(true, func(label string) {
|
||||||
|
@@ -1981,4 +1981,11 @@ class TestCore < TestInteractive
|
|||||||
refute lines.any_include?('[1]')
|
refute lines.any_include?('[1]')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_render_order
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --bind='focus:preview(echo boom)+change-footer(bam)'), :Enter
|
||||||
|
tmux.until { assert_equal 100, it.match_count }
|
||||||
|
tmux.until { assert it.any_include?('boom') }
|
||||||
|
tmux.until { assert it.any_include?('bam') }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user