From d6d0b260414ca251ba83a4084a053e1dde30244b Mon Sep 17 00:00:00 2001 From: Dmytro Maluka Date: Thu, 12 Sep 2024 20:39:14 +0200 Subject: [PATCH] Fix non-working raw escape bindings after restarting the screen (#3468) When we temporarily disable the screen (e.g. during RunInteractiveShell) and then enable it again, we reinitialize tcell.Screen from scratch, so we need to register all previously registered raw escape sequences once again. Otherwise raw escape bindings stop working, since the list of raw escape sequences of this newly create tcell.Screen is empty. Fixes #3392 --- internal/action/bindings.go | 4 ++-- internal/screen/screen.go | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/internal/action/bindings.go b/internal/action/bindings.go index 01ea7845..2462d730 100644 --- a/internal/action/bindings.go +++ b/internal/action/bindings.go @@ -89,7 +89,7 @@ func BindKey(k, v string, bind func(e Event, a string)) { } if strings.HasPrefix(k, "\x1b") { - screen.Screen.RegisterRawSeq(k) + screen.RegisterRawSeq(k) } bind(event, v) @@ -342,7 +342,7 @@ func UnbindKey(k string) error { } if strings.HasPrefix(k, "\x1b") { - screen.Screen.UnregisterRawSeq(k) + screen.UnregisterRawSeq(k) } defaults := DefaultBindings("buffer") diff --git a/internal/screen/screen.go b/internal/screen/screen.go index 16c011e6..c739f32b 100644 --- a/internal/screen/screen.go +++ b/internal/screen/screen.go @@ -33,6 +33,12 @@ var lock sync.Mutex // written to even if no event user event has occurred var drawChan chan bool +// rawSeq is the list of raw escape sequences that are bound to some actions +// via keybindings and thus should be parsed by tcell. We need to register +// them in tcell every time we reinitialize the screen, so we need to remember +// them in a list +var rawSeq = make([]string, 0) + // Lock locks the screen lock func Lock() { lock.Lock() @@ -121,6 +127,34 @@ func SetContent(x, y int, mainc rune, combc []rune, style tcell.Style) { } } +// RegisterRawSeq registers a raw escape sequence that should be parsed by tcell +func RegisterRawSeq(r string) { + for _, seq := range rawSeq { + if seq == r { + return + } + } + rawSeq = append(rawSeq, r) + + if Screen != nil { + Screen.RegisterRawSeq(r) + } +} + +// UnregisterRawSeq unregisters a raw escape sequence that should be parsed by tcell +func UnregisterRawSeq(r string) { + for i, seq := range rawSeq { + if seq == r { + rawSeq[i] = rawSeq[len(rawSeq)-1] + rawSeq = rawSeq[:len(rawSeq)-1] + } + } + + if Screen != nil { + Screen.UnregisterRawSeq(r) + } +} + // TempFini shuts the screen down temporarily func TempFini() bool { screenWasNil := Screen == nil @@ -195,6 +229,10 @@ func Init() error { Screen.EnableMouse() } + for _, r := range rawSeq { + Screen.RegisterRawSeq(r) + } + return nil }