Browse Source

Add Application.HandlePanic

Resolves #74.
master
Trevor Slocum 2 months ago
parent
commit
492ab21896
  1. 1
      CHANGELOG
  2. 38
      application.go
  3. 1
      demos/box/main.go
  4. 2
      demos/button/main.go
  5. 2
      demos/checkbox/main.go
  6. 2
      demos/dropdown/main.go
  7. 2
      demos/flex/main.go
  8. 2
      demos/focusmanager/main.go
  9. 2
      demos/form/main.go
  10. 2
      demos/frame/main.go
  11. 2
      demos/grid/main.go
  12. 1
      demos/inputfield/autocomplete/main.go
  13. 2
      demos/inputfield/autocompleteasync/main.go
  14. 2
      demos/inputfield/simple/main.go
  15. 2
      demos/list/main.go
  16. 2
      demos/modal/main.go
  17. 2
      demos/panels/main.go
  18. 2
      demos/presentation/main.go
  19. 1
      demos/primitive/main.go
  20. 1
      demos/progressbar/main.go
  21. 2
      demos/tabbedpanels/main.go
  22. 2
      demos/table/main.go
  23. 2
      demos/textview/main.go
  24. 2
      demos/treeview/main.go
  25. 2
      demos/unicode/main.go
  26. 4
      doc_test.go

1
CHANGELOG

@ -1,4 +1,5 @@
v1.5.7 (WIP)
- Add Application.HandlePanic
- Add Modal.SetButtonsAlign and Modal.SetTextAlign
- Fix TextView.GetRegionText error when text contains color tags
- Fix TextView region tags when placed at the end of a line

38
application.go

@ -125,6 +125,23 @@ func NewApplication() *Application {
}
}
// HandlePanic (when deferred at the start of a goroutine) handles panics
// gracefully. The terminal is returned to its original state before the panic
// message is printed.
//
// Panics may only be handled by the panicking goroutine. Because of this,
// HandlePanic must be deferred at the start of each goroutine (including main).
func (a *Application) HandlePanic() {
p := recover()
if p == nil {
return
}
a.finalizeScreen()
panic(p)
}
// SetInputCapture sets a function which captures all key events before they are
// forwarded to the key event handler of the primitive which currently has
// focus. This function can then choose to forward that key event (or a
@ -290,15 +307,7 @@ func (a *Application) Run() error {
return err
}
// We catch panics to clean up because they mess up the terminal.
defer func() {
if p := recover(); p != nil {
if a.screen != nil {
a.screen.Fini()
}
panic(p)
}
}()
defer a.HandlePanic()
// Draw the screen for the first time.
a.Unlock()
@ -308,6 +317,8 @@ func (a *Application) Run() error {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer a.HandlePanic()
defer wg.Done()
for {
a.RLock()
@ -431,6 +442,8 @@ func (a *Application) Run() error {
semaphore := &sync.Mutex{}
go func() {
defer a.HandlePanic()
for update := range a.updates {
semaphore.Lock()
update()
@ -570,13 +583,18 @@ func (a *Application) Stop() {
a.Lock()
defer a.Unlock()
a.finalizeScreen()
a.screenReplacement <- nil
}
func (a *Application) finalizeScreen() {
screen := a.screen
if screen == nil {
return
}
a.screen = nil
screen.Fini()
a.screenReplacement <- nil
}
// Suspend temporarily suspends the application by exiting terminal UI mode and

1
demos/box/main.go

@ -8,6 +8,7 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
box := cview.NewBox()
box.SetBorder(true)

2
demos/button/main.go

@ -5,6 +5,8 @@ import "code.rocketnine.space/tslocum/cview"
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
button := cview.NewButton("Hit Enter to close")

2
demos/checkbox/main.go

@ -7,6 +7,8 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
checkbox := cview.NewCheckBox()

2
demos/dropdown/main.go

@ -5,6 +5,8 @@ import "code.rocketnine.space/tslocum/cview"
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
dropdown := cview.NewDropDown()

2
demos/flex/main.go

@ -14,6 +14,8 @@ func demoBox(title string) *cview.Box {
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
subFlex := cview.NewFlex()

2
demos/focusmanager/main.go

@ -18,6 +18,8 @@ func wrap(f func()) func(ev *tcell.EventKey) *tcell.EventKey {
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
input1 := cview.NewInputField()

2
demos/form/main.go

@ -7,6 +7,8 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
form := cview.NewForm()

2
demos/frame/main.go

@ -8,6 +8,8 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
box := cview.NewBox()

2
demos/grid/main.go

@ -7,6 +7,8 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
newPrimitive := func(text string) cview.Primitive {

1
demos/inputfield/autocomplete/main.go

@ -12,6 +12,7 @@ const wordList = "ability,able,about,above,accept,according,account,across,act,a
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
words := strings.Split(wordList, ",")

2
demos/inputfield/autocompleteasync/main.go

@ -17,6 +17,8 @@ type company struct {
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
inputField := cview.NewInputField()
inputField.SetLabel("Enter a company name: ")
inputField.SetFieldWidth(30)

2
demos/inputfield/simple/main.go

@ -8,6 +8,8 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
inputField := cview.NewInputField()

2
demos/list/main.go

@ -9,6 +9,8 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
list := cview.NewList()

2
demos/modal/main.go

@ -7,6 +7,8 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
modal := cview.NewModal()

2
demos/panels/main.go

@ -11,6 +11,8 @@ const panelCount = 5
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
panels := cview.NewPanels()

2
demos/presentation/main.go

@ -43,6 +43,8 @@ var app = cview.NewApplication()
// Starting point for the presentation.
func main() {
defer app.HandlePanic()
var debugPort int
flag.IntVar(&debugPort, "debug", 0, "port to serve debug info")
flag.Parse()

1
demos/primitive/main.go

@ -61,6 +61,7 @@ func (r *RadioButtons) InputHandler() func(event *tcell.EventKey, setFocus func(
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
radioButtons := NewRadioButtons([]string{"Lions", "Elephants", "Giraffes"})
radioButtons.SetBorder(true)

1
demos/progressbar/main.go

@ -9,6 +9,7 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
grid := cview.NewGrid()
grid.SetColumns(-1, 6, 4, 30, -1)

2
demos/tabbedpanels/main.go

@ -11,6 +11,8 @@ const panelCount = 5
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
panels := cview.NewTabbedPanels()

2
demos/table/main.go

@ -12,6 +12,8 @@ const loremIpsumText = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
table := cview.NewTable()

2
demos/textview/main.go

@ -21,6 +21,8 @@ Capitalize on low hanging fruit to identify a ballpark value added activity to b
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
textView := cview.NewTextView()

2
demos/treeview/main.go

@ -12,6 +12,8 @@ import (
// Show a navigable tree view of the current directory.
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
rootDir := "."

2
demos/unicode/main.go

@ -9,6 +9,8 @@ import (
func main() {
app := cview.NewApplication()
defer app.HandlePanic()
panels := cview.NewPanels()
form := cview.NewForm()

4
doc_test.go

@ -10,6 +10,8 @@ import (
func ExampleNewApplication() {
// Initialize application.
app := NewApplication()
// Handle panics gracefully.
defer app.HandlePanic()
// Create shared TextView.
sharedTextView := NewTextView()
@ -71,6 +73,8 @@ func ExampleNewApplication() {
func ExampleApplication_EnableMouse() {
// Initialize application.
app := NewApplication()
// Handle panics gracefully.
defer app.HandlePanic()
// Enable mouse support.
app.EnableMouse(true)

Loading…
Cancel
Save