tview package now supports bracketed paste.

This commit is contained in:
Marcel Schramm 2020-11-18 23:14:03 +01:00
parent cf17e677f3
commit f6eca3f302
No known key found for this signature in database
GPG Key ID: 05971054C70EEDC7
3 changed files with 56 additions and 0 deletions

View File

@ -66,6 +66,9 @@ type Application struct {
// (screen.Init() and draw() will be called implicitly). A value of nil will
// stop the application.
screenReplacement chan tcell.Screen
// Defines whether a bracketed paste is currently ongoing.
pasteActive bool
}
// NewApplication creates and returns a new application.
@ -116,6 +119,7 @@ func (a *Application) SetScreen(screen tcell.Screen) *Application {
if a.MouseEnabled {
a.screen.EnableMouse()
}
screen.EnablePaste()
a.Unlock()
return a
}
@ -149,6 +153,7 @@ func (a *Application) Run() error {
if a.MouseEnabled {
a.screen.EnableMouse()
}
a.screen.EnablePaste()
}
// We catch panics to clean up because they mess up the terminal.
@ -215,6 +220,7 @@ func (a *Application) Run() error {
// Start event loop.
var keyEventHandleHierarchy []Primitive
var pastedRunes []rune
EventLoop:
for {
//resize slice to zero without having to allocate a new array.
@ -232,6 +238,14 @@ EventLoop:
a.RLock()
p := a.focus
inputCapture := a.inputCapture
if a.pasteActive {
if event.Rune() != 0 {
pastedRunes = append(pastedRunes, event.Rune())
a.RUnlock()
continue
}
}
a.RUnlock()
// Intercept keys.
@ -277,6 +291,25 @@ EventLoop:
}
screen.Clear()
a.draw()
case *tcell.EventPaste:
a.RLock()
p := a.focus
if event.Start() {
a.pasteActive = true
a.RUnlock()
} else if event.End() {
a.pasteActive = false
a.RUnlock()
if p != nil {
p.OnPaste(pastedRunes)
a.draw()
pastedRunes = pastedRunes[0:0]
}
} else {
a.RUnlock()
}
case *tcell.EventMouse:
if event.Buttons() == tcell.ButtonNone {
continue
@ -367,6 +400,11 @@ func getSelfIfCoordinatesMatch(primitive Primitive, x, y int) *Primitive {
return nil
}
// IsPasting indicates whether a bracketed paste is ongoing.
func (a *Application) IsPasting() bool {
return a.pasteActive
}
// Stop stops the application, causing Run() to return.
func (a *Application) Stop() {
a.Lock()
@ -411,6 +449,7 @@ func (a *Application) Suspend(f func()) bool {
if a.MouseEnabled {
screen.EnableMouse()
}
screen.EnablePaste()
a.screenReplacement <- screen
// One key event will get lost, see https://github.com/gdamore/tcell/issues/194

View File

@ -84,6 +84,8 @@ type Box struct {
nextFocusableComponents map[FocusDirection][]Primitive
parent Primitive
onPaste func([]rune)
}
// NewBox returns a Box without a border.
@ -609,3 +611,15 @@ func (b *Box) drawOverflow(screen tcell.Screen, showTop, showBottom bool) {
}
}
}
// SetOnPaste defines the function that's called in OnPaste.
func (b *Box) SetOnPaste(onPaste func([]rune)) {
b.onPaste = onPaste
}
// OnPaste is called when a bracketed paste is finished.
func (b *Box) OnPaste(runes []rune) {
if b.onPaste != nil {
b.onPaste(runes)
}
}

View File

@ -44,6 +44,9 @@ type Primitive interface {
// Box.WrapInputHandler() so you inherit that functionality.
InputHandler() InputHandlerFunc
// OnPaste is called when a bracketed paste is finished.
OnPaste([]rune)
// Focus is called by the application when the primitive receives focus.
// Implementers may call delegate() to pass the focus on to another primitive.
Focus(delegate func(p Primitive))