Code Monkey home page Code Monkey logo

gowid's Introduction

Terminal User Interface Widgets in Go

Gowid provides widgets and a framework for making terminal user interfaces. It's written in Go and inspired by urwid.

Widgets out-of-the-box include:

  • input components like button, checkbox and an editable text field with support for passwords
  • layout components for arranging widgets in columns, rows and a grid
  • structured components - a tree, an infinite list and a table
  • pre-canned widgets - a progress bar, a modal dialog, a bar graph and a menu
  • a VT220-compatible terminal widget, heavily cribbed from urwid πŸ˜ƒ

All widgets support interaction with the mouse when the terminal allows.

Gowid is built on top of the fantastic tcell package.

There are many alternatives to gowid - see Similar Projects

The most developed gowid application is currently termshark, a terminal UI for tshark.

Installation

go get github.com/gcla/gowid/...

Examples

Make sure $GOPATH/bin is in your PATH (or ~/go/bin if GOPATH isn't set), then tab complete "gowid-" e.g.

gowid-fib

Here is a port of urwid's palette example:

Here is urwid's graph example:

And urwid's fibonacci example:

A demonstration of gowid's terminal widget, a port of urwid's terminal widget:

Finally, here is an animation of termshark in action:

Hello World

This example is an attempt to mimic urwid's "Hello World" example.

package main

import (
	"github.com/gcla/gowid"
	"github.com/gcla/gowid/widgets/divider"
	"github.com/gcla/gowid/widgets/pile"
	"github.com/gcla/gowid/widgets/styled"
	"github.com/gcla/gowid/widgets/text"
	"github.com/gcla/gowid/widgets/vpadding"
)

//======================================================================

func main() {

	palette := gowid.Palette{
		"banner":  gowid.MakePaletteEntry(gowid.ColorWhite, gowid.MakeRGBColor("#60d")),
		"streak":  gowid.MakePaletteEntry(gowid.ColorNone, gowid.MakeRGBColor("#60a")),
		"inside":  gowid.MakePaletteEntry(gowid.ColorNone, gowid.MakeRGBColor("#808")),
		"outside": gowid.MakePaletteEntry(gowid.ColorNone, gowid.MakeRGBColor("#a06")),
		"bg":      gowid.MakePaletteEntry(gowid.ColorNone, gowid.MakeRGBColor("#d06")),
	}

	div := divider.NewBlank()
	outside := styled.New(div, gowid.MakePaletteRef("outside"))
	inside := styled.New(div, gowid.MakePaletteRef("inside"))

	helloworld := styled.New(
		text.NewFromContentExt(
			text.NewContent([]text.ContentSegment{
				text.StyledContent("Hello World", gowid.MakePaletteRef("banner")),
			}),
			text.Options{
				Align: gowid.HAlignMiddle{},
			},
		),
		gowid.MakePaletteRef("streak"),
	)

	f := gowid.RenderFlow{}

	view := styled.New(
		vpadding.New(
			pile.New([]gowid.IContainerWidget{
				&gowid.ContainerWidget{IWidget: outside, D: f},
				&gowid.ContainerWidget{IWidget: inside, D: f},
				&gowid.ContainerWidget{IWidget: helloworld, D: f},
				&gowid.ContainerWidget{IWidget: inside, D: f},
				&gowid.ContainerWidget{IWidget: outside, D: f},
			}),
			gowid.VAlignMiddle{},
			f),
		gowid.MakePaletteRef("bg"),
	)

	app, _ := gowid.NewApp(gowid.AppArgs{
		View:    view,
		Palette: &palette,
	})
    
	app.SimpleMainLoop()
}

Running the example above displays this:

Documentation

Similar Projects

Gowid is late to the TUI party. There are many options from which to choose - please read https://appliedgo.net/tui/ for a nice summary for the Go language. Here is a selection:

  • urwid - one of the oldest, for those working in python
  • tview - active, polished, concise, lots of widgets, Go
  • termui - focus on graphing and dataviz, Go
  • gocui - focus on layout, good input options, mouse support, Go
  • clui - active, many widgets, mouse support, Go
  • tui-go - QT-inspired, experimental, nice examples, Go

Dependencies

Gowid depends on these great open-source packages:

  • urwid - not a Go-dependency, but the model for most of gowid's design
  • tcell - a cell based view for text terminals, like xterm, inspired by termbox
  • asciigraph - lightweight ASCII line-graphs for Go
  • logrus - structured pluggable logging for Go
  • testify - tools for testifying that your code will behave as you intend

Contact

License

License: MIT

gowid's People

Contributors

asv avatar danslimmon avatar gcla avatar hinshun avatar kardbord avatar nagesh-ibm-power avatar r-smith avatar robopuff avatar zacharyhamm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gowid's Issues

Mouse hover steals focus

I have a pretty simple layout with a few columns and piles - For whatever reason, if you hover the mouse over certain parts of the layout, it will steal the focus. I'm pasting in a simple example. Notice that hovering your mouse over the text on the right side, causes the button below it to suddenly get focus.

package main

import (
	"github.com/gcla/gowid"
	"github.com/gcla/gowid/widgets/button"
	"github.com/gcla/gowid/widgets/columns"
	"github.com/gcla/gowid/widgets/edit"
	"github.com/gcla/gowid/widgets/framed"
	"github.com/gcla/gowid/widgets/pile"
	"github.com/gcla/gowid/widgets/styled"
	"github.com/gcla/gowid/widgets/text"
)

func main() {
	palette := gowid.Palette{
		"frameActive":   gowid.MakePaletteEntry(gowid.ColorYellow, gowid.ColorBlack),
		"frameInactive": gowid.MakePaletteEntry(gowid.ColorDarkGray, gowid.ColorBlack),
		"editActive":    gowid.MakePaletteEntry(gowid.ColorWhite, gowid.ColorDarkBlue),
		"editInactive":  gowid.MakePaletteEntry(gowid.ColorDarkGray, gowid.ColorBlack),
		"btnActive":     gowid.MakePaletteEntry(gowid.ColorRed, gowid.ColorBlack),
		"btnInactive":   gowid.MakePaletteEntry(gowid.ColorDarkGray, gowid.ColorBlack),
	}
	// Left side: styled edit widget in a styled frame.
	leftEdit := styled.NewExt(
		edit.New(edit.Options{Text: "This is an edit widget"}),
		gowid.MakePaletteRef("editInactive"),
		gowid.MakePaletteRef("editActive"))
	leftFrame := styled.NewExt(
		framed.NewUnicode(leftEdit),
		gowid.MakePaletteRef("frameInactive"),
		gowid.MakePaletteRef("frameActive"))

	// Right side:
	// Text widgets in columns.
	rightCols := columns.New([]gowid.IContainerWidget{
		&gowid.ContainerWidget{IWidget: text.New("Text in column A"), D: gowid.RenderWithUnits{U: 20}},
		&gowid.ContainerWidget{IWidget: text.New("Text in column B"), D: gowid.RenderWithUnits{U: 20}},
	})

	// Styled button.
	rightBtn := styled.NewExt(
		button.New(text.New("  Button  ")),
		gowid.MakePaletteRef("btnInactive"),
		gowid.MakePaletteRef("btnActive"))

	rightRows := pile.New([]gowid.IContainerWidget{
		&gowid.ContainerWidget{IWidget: rightCols, D: gowid.RenderWithUnits{U: 2}},
		&gowid.ContainerWidget{IWidget: rightBtn, D: gowid.RenderFixed{}},
	})
	rightFrame := styled.NewExt(
		framed.NewUnicode(rightRows),
		gowid.MakePaletteRef("frameInactive"),
		gowid.MakePaletteRef("frameActive"))

	// Combine left and right frames.
	cols := columns.New([]gowid.IContainerWidget{
		&gowid.ContainerWidget{IWidget: leftFrame, D: gowid.RenderWithUnits{U: 30}},
		&gowid.ContainerWidget{IWidget: rightFrame, D: gowid.RenderWithWeight{W: 1}},
	})

	app, _ := gowid.NewApp(gowid.AppArgs{View: cols, Palette: palette})
	app.SimpleMainLoop()
}

Usage questions

  1. Is there any way to completely disable logging?

  2. On a list widget, is there a way to tell if there is more content above or below what is currently shown on the screen? I found the AtTop, AtBottom, and AtMiddle functions, but they don't seem to work like I'm thinking. I just wanted some way to indicate to the user that there are additional items to scroll through. I can't figure out exactly what the gowid-editor in the examples folder is doing with vscroll.

Debug info prints when resizing terminal window

While resizing a terminal window on Linux, debug info is printing on the bottom of the window. It seems like 75% of the time the debug info stays printed after the resize is done. This doesn't happen on Windows.

resize

apps run slowly on weak systems when there's lots of mouse movement

For more information, see termshark issue gcla/termshark#61

The reason for this is that mouse movement inside a gowid app generates a large number of tcell mouse events, and currently, gowid applications process them all, in sequence. On complicated widget hierarchies, this can cause a backlog because of the relatively expensive render of the widget hierarchy. The result is a laggy UI until the backlog is cleared.

Usage question - extra space between list items

I'm building a navigation menu using a list widget. I have an OnFocusChanged callback to change the display based on which menu item was selected. How would I go about adding an extra gap between some of the list items? (Such as: Item A, Item B, Item C, [SPACE], Item D, Item E). Right now I'm adding the gap to the list using the widget: disable.New(fill.NewEmpty()).

The method I came up with works fine when using the keyboard, but if you click in the gap area with your mouse, it seems to act as though the item AFTER the gap was selected, yet in the list it still shows your original item has the focus highlight. (Item A is selected with a styled highlight, click in the filler space and the routine for Item D gets called, yet the list still shows Item A as highlighted).

Here's a simple example:

package main

import (
	"fmt"

	"github.com/gcla/gowid"
	"github.com/gcla/gowid/widgets/columns"
	"github.com/gcla/gowid/widgets/disable"
	"github.com/gcla/gowid/widgets/fill"
	"github.com/gcla/gowid/widgets/framed"
	"github.com/gcla/gowid/widgets/list"
	"github.com/gcla/gowid/widgets/selectable"
	"github.com/gcla/gowid/widgets/styled"
	"github.com/gcla/gowid/widgets/text"
)

func main() {
	palette := gowid.Palette{
		"menuInactive": gowid.MakePaletteEntry(gowid.ColorLightGray, gowid.ColorBlack),
		"menuActive":   gowid.MakePaletteEntry(gowid.ColorBlack, gowid.ColorWhite),
	}

	debugText := text.New("Select a menu item")

	menuItems := []string{
		"Item A",
		"Item B",
		"Item C",
		"",
		"Item D",
		"Item E",
	}

	// Build the navigation menu.
	menuWidgets := make([]gowid.IWidget, 0, len(menuItems))
	for _, item := range menuItems {
		if len(item) == 0 {
			//menuWidgets = append(menuWidgets, null.New())
			menuWidgets = append(menuWidgets, disable.New(fill.NewEmpty()))
		} else {
			menuWidgets = append(menuWidgets,
				selectable.New(
					styled.NewExt(
						text.New(item),
						gowid.MakePaletteRef("menuInactive"),
						gowid.MakePaletteRef("menuActive"))))
		}
	}
	menuList := list.New(list.NewSimpleListWalker(menuWidgets))
	menuFramed := framed.NewUnicode(menuList)

	// My on OnFocus callback.  What's the best way to get which widget received focus?
	menuList.OnFocusChanged(gowid.WidgetCallback{Name: "cb", WidgetChangedFunction: func(app gowid.IApp, w gowid.IWidget) {
		position := menuList.Walker().Focus().(list.ListPos).ToInt()
		debugText.SetText(fmt.Sprintf("Changed to index: %v", position), app)
	}})

	// Put debug text and list into columns.
	cols := columns.New([]gowid.IContainerWidget{
		&gowid.ContainerWidget{IWidget: menuFramed, D: gowid.RenderWithUnits{U: 12}},
		&gowid.ContainerWidget{IWidget: debugText, D: gowid.RenderFixed{}},
	})

	app, _ := gowid.NewApp(gowid.AppArgs{View: cols, Palette: palette})
	app.SimpleMainLoop()
}

Application crashes - "integer divide by zero"

I built the following test app:

...
	line1 := make([]gowid.IWidget, 0)
	line2 := make([]gowid.IWidget, 0)
	line3 := make([]gowid.IWidget, 0)

	text1 := text.New("line1 item0")
	text1h := holder.New(text1)
	text1s := styled.NewWithRanges(text1h,
		[]styled.AttributeRange{styled.AttributeRange{0, -1, gowid.MakePaletteRef("test1notfocus")}}, []styled.AttributeRange{styled.AttributeRange{0, -1, gowid.MakePaletteRef("streak")}})
	btn1 := button.New(text1s)
	line1 = append(line1, btn1)

	for i := 1; i < 5; i++ {
		txt := text.New(fmt.Sprintf("line1 item%d", i))
		line1 = append(line1, txt)
	}

	text2 := text.New("line2 item0")
	text2h := holder.New(text2)
	text2s := styled.NewWithRanges(text2h,
		[]styled.AttributeRange{styled.AttributeRange{0, -1, gowid.MakePaletteRef("test1notfocus")}}, []styled.AttributeRange{styled.AttributeRange{0, -1, gowid.MakePaletteRef("streak")}})
	btn2 := button.New(text2s)
	line2 = append(line2, btn2)

	for i := 1; i < 5; i++ {
		txt := text.New(fmt.Sprintf("line2 item%d", i))
		line2 = append(line2, txt)
	}

	text3 := text.New("line3 item0")
	text3h := holder.New(text3)
	text3s := styled.NewWithRanges(text3h,
		[]styled.AttributeRange{styled.AttributeRange{0, -1, gowid.MakePaletteRef("test1notfocus")}}, []styled.AttributeRange{styled.AttributeRange{0, -1, gowid.MakePaletteRef("streak")}})
	btn3 := button.New(text3s)
	line3 = append(line3, btn3)

	for i := 1; i < 5; i++ {
		txt := text.New(fmt.Sprintf("line3 item%d", i))
		line3 = append(line3, txt)
	}

	gfwids1 := []gowid.IWidget{line1[0], line1[1], line1[2], line1[3], line1[4]}
	grid1 := grid.New(gfwids1, 15, 3, 1, gowid.HAlignMiddle{})

	gfwids2 := []gowid.IWidget{line2[0], line2[1], line2[2], line2[3], line2[4]}
	grid2 := grid.New(gfwids2, 15, 3, 1, gowid.HAlignMiddle{})

	gfwids3 := []gowid.IWidget{line3[0], line3[1], line3[2], line3[3], line3[4]}
	grid3 := grid.New(gfwids3, 15, 3, 1, gowid.HAlignMiddle{})

	grids := make([]gowid.IWidget, 0)
	grids = append(grids, grid1)
	grids = append(grids, grid2)
	grids = append(grids, grid3)

	walker := list.NewSimpleListWalker(grids)
	lb := list.New(walker)

	pw := vpadding.New(lb, gowid.VAlignTop{}, gowid.RenderFlow{})

	app, err = gowid.NewApp(gowid.AppArgs{
		View:    pw,
		Palette: &palette,
		Log:     log.StandardLogger(),
	})

	app.SimpleMainLoop()

If I start it and press "up" or "down" key - it crashes the following way:

panic: runtime error: integer divide by zero

goroutine 1 [running]:
github.com/gcla/gowid/widgets/grid.GenerateWidgets({0x5f7ce0, 0xc00021a000}, {0x5b06a0, 0x6c9460}, {0x5f5c58, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/grid/grid.go:408 +0x1098
github.com/gcla/gowid/widgets/grid.(*Widget).GenerateWidgets(0xc00021a000, {0x5b06a0, 0x6c9460}, {0x5f5c58, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/grid/grid.go:210 +0x65
github.com/gcla/gowid/widgets/grid.UserInput({0x5f7ce0, 0xc00021a000}, {0x5a9680, 0xc00029f4e0}, {0x5b06a0, 0x6c9460}, {0x1, 0x1}, {0x5f8108, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/grid/grid.go:326 +0x7ed
github.com/gcla/gowid/widgets/grid.(*Widget).UserInput(0xc00021a000, {0x5a9680, 0xc00029f4e0}, {0x5b06a0, 0x6c9460}, {0x1, 0x1}, {0x5f8108, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/grid/grid.go:206 +0x98
github.com/gcla/gowid.UserInputIfSelectable({0x5f61f8, 0xc00021a000}, {0x5a9680, 0xc00029f4e0}, {0x5b06a0, 0x6c9460}, {0x1, 0x1}, {0x5f8108, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/support.go:793 +0xb3
github.com/gcla/gowid/widgets/list.(*Widget).UserInput(0xc0001d7960, {0x5a9680, 0xc00029f4e0}, {0x5b06a0, 0x6c9790}, {0x1, 0x1}, {0x5f8108, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/list/list.go:717 +0x709
github.com/gcla/gowid.UserInputIfSelectable({0x5f62a0, 0xc0001d7960}, {0x5a9680, 0xc00029f4e0}, {0x5b06a0, 0x6c9790}, {0x1, 0x1}, {0x5f8108, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/support.go:793 +0xb3
github.com/gcla/gowid/widgets/vpadding.UserInput({0x5f74c0, 0xc000114410}, {0x5a9680, 0xc00029f4e0}, {0x5b4000, 0xc0002a9bd0}, {0x1, 0x1}, {0x5f8108, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/vpadding/vpadding.go:285 +0x45e
github.com/gcla/gowid/widgets/vpadding.(*Widget).UserInput(0xc000114410, {0x5a9680, 0xc00029f4e0}, {0x5b4000, 0xc0002a9bd0}, {0x1, 0x1}, {0x5f8108, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/vpadding/vpadding.go:124 +0x98
github.com/gcla/gowid.UserInputIfSelectable({0x5f6348, 0xc000114410}, {0x5a9680, 0xc00029f4e0}, {0x5b4000, 0xc0002a9bd0}, {0x1, 0x1}, {0x5f8108, 0xc00014a580})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/support.go:793 +0xb3
github.com/gcla/gowid.(*App).handleInputEvent(0xc00014a580, {0x5a9680, 0xc00029f4e0}, {0x5f4500, 0x708e90})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/app.go:665 +0x185
github.com/gcla/gowid.(*App).HandleTCellEvent(0xc00014a580, {0x5a9680, 0xc00029f4e0}, {0x5f4500, 0x708e90})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/app.go:469 +0x945
github.com/gcla/gowid.(*App).handleEvents(0xc00014a580, {0x5f4500, 0x708e90})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/app.go:648 +0x145
github.com/gcla/gowid.(*App).MainLoop(0xc00014a580, {0x5f4500, 0x708e90})
	/home/peter/go/pkg/mod/github.com/gcla/[email protected]/app.go:629 +0x12d
main.main()
	/usr/home/peter/Programming/golang/test1/test1.go:214 +0x2afb

End Process exit status 2

Hello World example panics on Windows

examples\gowid-helloworld\helloworld.go panics on Windows.

time="2019-05-18T22:32:47-07:00" level=info msg="Terminal was resized" event="&{{13776608566125785016 4994801 0x6d7f40} 148 60}"
panic: Color RGBColor(#a0,#00,#60) of type gowid.RGBColor not supported in mode 16 colors

Go 1.12. Windows 10.

Crash in RedrawTerminal: index out of range

I have a new type of crash after rebuilding of cbsd-tui:

Exception has occurred: panic
"runtime error: index out of range [70] with length 70"
Stack:
	 3  0x0000000000648ce5 in github.com/gcla/gowid/widgets/text.(*ContentToCellArray).ProcessCell
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/text/text.go:499
	 4  0x0000000000646d93 in github.com/gcla/gowid/widgets/text.Content.RangeOver
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/text/text.go:173
	 5  0x000000000064baf8 in github.com/gcla/gowid/widgets/text.(*Content).RangeOver
	     at <autogenerated>:1
	 6  0x00000000006499cb in github.com/gcla/gowid/widgets/text.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/text/text.go:575
	 7  0x000000000064b754 in github.com/gcla/gowid/widgets/text.(*WidgetWithCursor).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/text/text.go:822
	 8  0x0000000000670b36 in github.com/gcla/gowid/widgets/edit.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/edit/edit.go:316
	 9  0x0000000000670574 in github.com/gcla/gowid/widgets/edit.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/edit/edit.go:289
	10  0x000000000062ad53 in github.com/gcla/gowid.(*ContainerWidget).Render
	     at <autogenerated>:1
	11  0x0000000000642c14 in github.com/gcla/gowid/widgets/columns.RenderSubWidgets
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:677
	12  0x000000000063d939 in github.com/gcla/gowid/widgets/columns.(*Widget).RenderSubWidgets
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:214
	13  0x0000000000641f5a in github.com/gcla/gowid/widgets/columns.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:620
	14  0x000000000063d7f4 in github.com/gcla/gowid/widgets/columns.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:210
	15  0x00000000007324ec in main.(*EditWithScrollbar).Render
	     at /home/peter/Programming/golang/cbsd-tui/editwithscrollbar.go:104
	16  0x0000000000668be9 in github.com/gcla/gowid/widgets/styled.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/styled/styled.go:113
	17  0x0000000000631974 in github.com/gcla/gowid/widgets/boxadapter.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/boxadapter/boxadapter.go:105
	18  0x0000000000631094 in github.com/gcla/gowid/widgets/boxadapter.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/boxadapter/boxadapter.go:71
	19  0x000000000064fa9c in github.com/gcla/gowid/widgets/framed.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/framed/framed.go:232
	20  0x000000000064ed94 in github.com/gcla/gowid/widgets/framed.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/framed/framed.go:182
	21  0x000000000062ad53 in github.com/gcla/gowid.(*ContainerWidget).Render
	     at <autogenerated>:1
	22  0x000000000066269a in github.com/gcla/gowid/widgets/pile.RenderSubwidgets.func1
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:495
	23  0x0000000000662b43 in github.com/gcla/gowid/widgets/pile.BoxMakerFunc.MakeBox
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:516
	24  0x0000000000663a91 in github.com/gcla/gowid/widgets/pile.RenderBoxMaker
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:667
	25  0x000000000065f9be in github.com/gcla/gowid/widgets/pile.(*Widget).RenderBoxMaker
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:219
	26  0x000000000066284e in github.com/gcla/gowid/widgets/pile.RenderSubwidgets
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:498
	27  0x000000000065f7f9 in github.com/gcla/gowid/widgets/pile.(*Widget).RenderSubWidgets
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:211
	28  0x0000000000661ac4 in github.com/gcla/gowid/widgets/pile.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:444
	29  0x000000000065f3f4 in github.com/gcla/gowid/widgets/pile.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:198
	30  0x000000000064fa9c in github.com/gcla/gowid/widgets/framed.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/framed/framed.go:232
	31  0x000000000064ed94 in github.com/gcla/gowid/widgets/framed.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/framed/framed.go:182
	32  0x0000000000668be9 in github.com/gcla/gowid/widgets/styled.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/styled/styled.go:113
	33  0x00000000006370f0 in github.com/gcla/gowid/widgets/cellmod.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/cellmod/cellmod.go:107
	34  0x0000000000636e54 in github.com/gcla/gowid/widgets/cellmod.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/cellmod/cellmod.go:97
	35  0x000000000066e173 in github.com/gcla/gowid/widgets/dialog.(*Widget).Render
	     at <autogenerated>:1
	36  0x0000000000657430 in github.com/gcla/gowid/widgets/padding.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/padding/padding.go:201
	37  0x0000000000657134 in github.com/gcla/gowid/widgets/padding.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/padding/padding.go:169
	38  0x000000000065ca27 in github.com/gcla/gowid/widgets/overlay.Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/overlay/overlay.go:310
	39  0x000000000065ba94 in github.com/gcla/gowid/widgets/overlay.(*Widget).Render
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/widgets/overlay/overlay.go:226
	40  0x000000000067e653 in github.com/gcla/gowid/widgets/holder.(*Widget).Render
	     at <autogenerated>:1
	41  0x00000000006135bf in github.com/gcla/gowid.RenderRoot
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/support.go:835
	42  0x00000000006048da in github.com/gcla/gowid.(*App).RedrawTerminal
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/app.go:726
	43  0x0000000000604085 in github.com/gcla/gowid.(*App).RunThenRenderEvent
	     at /home/peter/go/pkg/mod/github.com/gcla/[email protected]/app.go:670
	44  0x000000000072998a in main.ExecShellCommand.func1
	     at /home/peter/Programming/golang/cbsd-tui/cbsd-tui.go:780

Tutorial 1 prints debug info on Windows

On Windows 10, the first application in the tutorial that is supposed to print 'hello world' on the screen is instead printing a line of debug info:

time="2019-0518T22:37:17-07:00" level=info msg="Terminal was resized" event="&{{13776608856134938696 7999262101 0x69dee0} 148 30}"

Go 1.12. Windows 10.

Install command fails on macOS

On macOS High Sierra 10.13.6 the install command fails:

$ env | grep GOPATH
GOPATH=/Users/hernan/go

$ go get github.com/gcla/gowid/...

Output:

go get github.com/gcla/gowid/examples/gowid-asciigraph: open /bin/gowid-asciigraph: permission denied
go get github.com/gcla/gowid/examples/gowid-fib: open /bin/gowid-fib: permission denied
go get github.com/gcla/gowid/examples/gowid-editor: open /bin/gowid-editor: permission denied
go get github.com/gcla/gowid/examples/gowid-dir: open /bin/gowid-dir: permission denied
go get github.com/gcla/gowid/examples/gowid-graph: open /bin/gowid-graph: permission denied
go get github.com/gcla/gowid/examples/gowid-helloworld: open /bin/gowid-helloworld: permission denied
go get github.com/gcla/gowid/examples/gowid-overlay1: open /bin/gowid-overlay1: permission denied
go get github.com/gcla/gowid/examples/gowid-menu: open /bin/gowid-menu: permission denied
go get github.com/gcla/gowid/examples/gowid-overlay3: open /bin/gowid-overlay3: permission denied
go get github.com/gcla/gowid/examples/gowid-overlay2: open /bin/gowid-overlay2: permission denied
go get github.com/gcla/gowid/examples/gowid-palette: open /bin/gowid-palette: permission denied
go get github.com/gcla/gowid/examples/gowid-tree: open /bin/gowid-tree: permission denied
go get github.com/gcla/gowid/examples/gowid-terminal: open /bin/gowid-terminal: permission denied
go get github.com/gcla/gowid/examples/gowid-tutorial1: open /bin/gowid-tutorial1: permission denied
go get github.com/gcla/gowid/examples/gowid-tutorial2: open /bin/gowid-tutorial2: permission denied
go get github.com/gcla/gowid/examples/gowid-tutorial3: open /bin/gowid-tutorial3: permission denied
go get github.com/gcla/gowid/examples/gowid-tutorial4: open /bin/gowid-tutorial4: permission denied
go get github.com/gcla/gowid/examples/gowid-table: open /bin/gowid-table: permission denied
go get github.com/gcla/gowid/examples/gowid-tutorial5: open /bin/gowid-tutorial5: permission denied
go get github.com/gcla/gowid/examples/gowid-widgets1: open /bin/gowid-widgets1: permission denied
go get github.com/gcla/gowid/examples/gowid-tutorial6: open /bin/gowid-tutorial6: permission denied
go get github.com/gcla/gowid/examples/gowid-widgets2: open /bin/gowid-widgets2: permission denied
go get github.com/gcla/gowid/examples/gowid-widgets3: open /bin/gowid-widgets3: permission denied
go get github.com/gcla/gowid/examples/gowid-widgets5: open /bin/gowid-widgets5: permission denied
go get github.com/gcla/gowid/examples/gowid-widgets4: open /bin/gowid-widgets4: permission denied
go get github.com/gcla/gowid/examples/gowid-widgets6: open /bin/gowid-widgets6: permission denied
go get github.com/gcla/gowid/examples/gowid-widgets7: open /bin/gowid-widgets7: permission denied
go get github.com/gcla/gowid/examples/gowid-widgets8: open /bin/gowid-widgets8: permission denied

Should I run the command as root?

[ QUESTION ] Update widget NOW

I use edit widget to show command's output. According to the gowid documentation, I use
app.Run(gowid.RunFunction(func(app gowid.IApp) { <some code> app.Redraw() } construction to update the content of the edit widget. It works correctly, but the updates received by the widget are not very frequent, really I get only one update at the end of my command, so I cannot see the progress of command execution. Is there any way to do more frequent updates? I tried to use app.RedrawTerminal() somehow, but the application crashes sometimes, probably due to race conditions.

Jumping cursor on Windows

When a text input box has focus with a blinking cursor, moving your mouse pointer across the console window causes the cursor to very rapidly jump back and forth between the top left corner and the cursor position in the text box. I can upload an animated gif if that helps explain it. I've only seen the issue on Windows, and only on edit-type widgets that have focus and a blinking cursor.

Create a new release

Previously on Debian packaging of termshark... πŸ˜†

We currently have 1.0.0 release of this library packaged in Debian. Could you create a new release, so we don't have to jump to different versioning (git)?

Return does not jump to the next line in the editor

Steps to reproduce:

  1. Clone the latest master of gowid
  2. Enter the gowid-editor example
  3. go build
  4. touch test.txt
  5. Resize the terminal window to be relatively narrow (ie. 60 characters wide)
  6. Run ./gowid-editor test.txt
  7. Press return and watch the cursor move 1 to the right.
  8. Press return again and watch the cursor jump 1 line down and then not at the beginning of the next line, but 1 position to the right.
  9. Press backspace and watch the cursor jump 1 line up.
  10. Press backspace and watch the cursor jump 1 position to the left.

I'm using konsole on Arch Linux.

How to implement this layout

We are working on a small project that will let us practice vim. Your terminal ui seems like the one closest to what we want but we are having a hard time figuring it out since we are new to golang. We are trying to adjust your terminal example and would like to end up with something like the following:

Screen Shot 2021-02-17 at 3 14 30 PM

We just arent sure how to organize the widgets correctly. Any tips would be appreciated. Thanks

Application crashes sometimes in RedrawTerminal

...with the following error in console:

panic: interface conversion: gowid.RenderFixed is not gowid.IRenderWithWeight: missing method Weight
goroutine 1 [running]:
github.com/gcla/gowid/widgets/columns.widgetWidthsExt({0x828115490, 0xc000177130}, {0xc0015141e0, 0xa, 0xa}, {0xc001514280, 0xa, 0xa}, {0x264e20, 0xc000a4a080}, ...)
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:550 +0xc98
github.com/gcla/gowid/widgets/columns.WidgetWidths({0x2ccda0, 0xc000177130}, {0x264e20, 0xc000a4a080}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:430 +0x19a
github.com/gcla/gowid/widgets/columns.(*Widget).WidgetWidths(0xc000177130, {0x264e20, 0xc000a4a080}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:225 +0x8e
github.com/gcla/gowid/widgets/columns.RenderSubWidgets({0x2d2488, 0xc000177130}, {0x264e20, 0xc000a4a080}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:665 +0x156
github.com/gcla/gowid/widgets/columns.(*Widget).RenderSubWidgets(0xc000177130, {0x264e20, 0xc000a4a080}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:214 +0x8e
github.com/gcla/gowid/widgets/columns.Render({0x2d2488, 0xc000177130}, {0x264e20, 0xc000a4a080}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:620 +0x13c
github.com/gcla/gowid/widgets/columns.(*Widget).Render(0xc000177130, {0x264e20, 0xc000a4a080}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/columns/columns.go:210 +0x78
github.com/gcla/gowid/widgets/pile.RenderSubwidgets.func1({0x2cdd98, 0xc0001c98e0}, {0x264e20, 0xc000a4a080}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:495 +0x72
github.com/gcla/gowid/widgets/pile.BoxMakerFunc.MakeBox(0x28cfa0, {0x2cdd98, 0xc0001c98e0}, {0x264e20, 0xc000a4a080}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:516 +0x84
github.com/gcla/gowid/widgets/pile.RenderBoxMaker({0x2d2550, 0xc0001d4280}, {0x264e20, 0xc000a4a050}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500}, {0x2ca6e0, ...})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:583 +0x710
github.com/gcla/gowid/widgets/pile.(*Widget).RenderBoxMaker(0xc0001d4280, {0x264e20, 0xc000a4a050}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500}, {0x2ca6e0, 0x28cfa0})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:219 +0xbf
github.com/gcla/gowid/widgets/pile.RenderSubwidgets({0x2d2550, 0xc0001d4280}, {0x264e20, 0xc000a4a050}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:498 +0xba
github.com/gcla/gowid/widgets/pile.(*Widget).RenderSubWidgets(0xc0001d4280, {0x264e20, 0xc000a4a050}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:211 +0x8e
github.com/gcla/gowid/widgets/pile.Render({0x2d2550, 0xc0001d4280}, {0x264e20, 0xc000a4a050}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:444 +0xc2
github.com/gcla/gowid/widgets/pile.(*Widget).Render(0xc0001d4280, {0x264e20, 0xc000a4a050}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:198 +0x78
github.com/gcla/gowid/widgets/pile.RenderSubwidgets.func1({0x2cdd98, 0xc0001c99a0}, {0x264e20, 0xc000a4a050}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:495 +0x72
github.com/gcla/gowid/widgets/pile.BoxMakerFunc.MakeBox(0x28cfa0, {0x2cdd98, 0xc0001c99a0}, {0x264e20, 0xc000a4a050}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:516 +0x84
github.com/gcla/gowid/widgets/pile.RenderBoxMaker({0x2d2550, 0xc0001d4300}, {0x264e20, 0xc000a4a000}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500}, {0x2ca6e0, ...})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:658 +0xba2
github.com/gcla/gowid/widgets/pile.(*Widget).RenderBoxMaker(0xc0001d4300, {0x264e20, 0xc000a4a000}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500}, {0x2ca6e0, 0x28cfa0})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:219 +0xbf
github.com/gcla/gowid/widgets/pile.RenderSubwidgets({0x2d2550, 0xc0001d4300}, {0x264e20, 0xc000a4a000}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:498 +0xba
github.com/gcla/gowid/widgets/pile.(*Widget).RenderSubWidgets(0xc0001d4300, {0x264e20, 0xc000a4a000}, {0x0, 0x0}, 0x0, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:211 +0x8e
github.com/gcla/gowid/widgets/pile.Render({0x2d2550, 0xc0001d4300}, {0x264e20, 0xc000a4a000}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:444 +0xc2
github.com/gcla/gowid/widgets/pile.(*Widget).Render(0xc0001d4300, {0x264e20, 0xc000a4a000}, {0x0, 0x0}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/pile/pile.go:198 +0x78
github.com/gcla/gowid/widgets/overlay.Render({0x2d0780, 0xc00155ed20}, {0x264e20, 0xc000a4a000}, {0x1, 0x1}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/overlay/overlay.go:304 +0xf9
github.com/gcla/gowid/widgets/overlay.(*Widget).Render(0xc00155ed20, {0x264e20, 0xc000a4a000}, {0x1, 0x1}, {0x2d2618, 0xc000194500})
        /root/go/pkg/mod/github.com/gcla/[email protected]/widgets/overlay/overlay.go:226 +0x78
github.com/gcla/gowid.RenderRoot({0x2ce000, 0xc0001c9a20}, 0xc000194500)
        /root/go/pkg/mod/github.com/gcla/[email protected]/support.go:835 +0xfa
github.com/gcla/gowid.(*App).RedrawTerminal(0xc000194500)
        /root/go/pkg/mod/github.com/gcla/[email protected]/app.go:719 +0x3d
github.com/gcla/gowid.(*App).HandleTCellEvent(0xc000194500, {0x255280, 0xc000933e40}, {0x2ca900, 0x869498})
        /root/go/pkg/mod/github.com/gcla/[email protected]/app.go:501 +0xadd
github.com/gcla/gowid.(*App).handleEvents(0xc000194500, {0x2ca900, 0x869498})
        /root/go/pkg/mod/github.com/gcla/[email protected]/app.go:675 +0x145
github.com/gcla/gowid.(*App).MainLoop(0xc000194500, {0x2ca900, 0x869498})
        /root/go/pkg/mod/github.com/gcla/[email protected]/app.go:656 +0x129
main.main()
        /root/cbsd-tui/cbsd-tui.go:1265 +0x32b2

cbsd-tui.go:1265 is just app.MainLoop(handler{})

The problem arrives when I update a dialog (with edit widget inside) in cycle showing the output of a command as it comes. The dialog is created as follows:

func CreateActionsLogDialog(editWidget *edit.Widget) *dialog.Widget {
	baheight := cbsdJailConsole.Height()
	ba := boxadapter.New(
		styled.New(
			NewEditWithScrollbar(editWidget),
			gowid.MakePaletteRef("white"),
		),
		baheight,
	)
	actionlogdialog := dialog.New(
		framed.NewUnicode(ba),
		dialog.Options{
			Buttons:         []dialog.Button{dialog.CloseD},
			Modal:           true,
			NoShadow:        true,
			TabToButtons:    true,
			BackgroundStyle: gowid.MakePaletteRef("bluebg"),
			BorderStyle:     gowid.MakePaletteRef("dialog"),
			ButtonStyle:     gowid.MakePaletteRef("white-focus"),
			FocusOnWidget:   true,
		},
	)
	return actionlogdialog
}

NewEditWithScrollbar is taken from editor example.

I suppose that there are some race conditions somewhere...

broken on go 1.15.2?

Could be me?

~ go get github.com/gcla/gowid/...                                             
# github.com/gcla/gowid
../../gcla/gowid/app.go:828:25: cannot convert defSt.OnOff (type tcell.AttrMask) to type tcell.Style
../../gcla/gowid/decoration.go:485:20: cannot convert st.OnOff (type tcell.AttrMask) to type tcell.Style
../../gcla/gowid/decoration.go:924:27: constant -2 overflows tcell.Color
../../gcla/gowid/decoration.go:931:7: constant -2 overflows tcell.Color
~ go version                                                                               
go version go1.15.2 darwin/amd64

Simple examples

Hey. As a new TUI user hopping from tview, the lack of simple examples disturb me. Take a look at this:

https://github.com/gcla/gowid/blob/master/examples/gowid-menu/menu.go

A new person wouldn't for the life of them comprehend this. Comparing this 171 LOC example with tview's example:

package main

import "github.com/rivo/tview"

func main() {
	app := tview.NewApplication()
	dropdown := tview.NewDropDown().
		SetLabel("Select an option (hit Enter): ").
		SetOptions([]string{"First", "Second", "Third", "Fourth", "Fifth"}, nil)
	if err := app.SetRoot(dropdown, true).SetFocus(dropdown).Run(); err != nil {
		panic(err)
	}
}

You could see the obvious differences.

My recommendation: move the current examples to advanced/ and make a bare minimum simple/ example folder like Gtk.

gowid-terminal example hangs on DEL (xterm/vt220 backspace)

Using xterm, running gowid-terminal, if I press backspace (^?, DEL), the terminal demo hangs on all input. Some bits from my .Xresources that might be helpful:

Xterm*metaSendsEscape:	 true
Xterm*backarrowKey:	 false
Xterm*decTerminalID: vt340
Xterm*numColorRegisters: 1024
Xterm*scrollBar: false
Xterm*allowWindowOps: true

Some other issues:

I am the author of Jexer, another TUI framework, and am testing gowid's terminal support for its features. If you run 'java -jar path/to/jexer.jar', you may also notice these two issues:

  • Privacy Message (ESC ^ {stuff} ESC \) is not being consumed/discarded. You will see "hideMousePointer" or "showMousePointer" in output when exiting the demo.
  • The DCS sequence for sixel output is not consumed/discarded. If you load an image (via the Tools / hamburger menu | "Open image..."), its sixel output will leave garbage all over the screen.

When I ran gowid-terminal inside Jexer's terminal widget, I also encountered a crash (panic out of range). Jexer runs its terminals inside either 'script -fqe /dev/null' or ptypipe. Under ptypipe, no problem, but under 'script', I'm sometimes seeing this crash:

gowid_terminal_1

The easiest way for me to see it was: 'java -Djexer.Swing=true path/to/jexer.jar', then press "Terminal" button, then inside that gowid-terminal and move the mouse over the terminal window.

gowid.UrwidColor is invalid

panic: Color UrwidColor(dark gray) of type *gowid.UrwidColor is invalid

goroutine 1 [running]:
github.com/gcla/gowid.(*UrwidColor).ToTCellColor(0xc0000aa880, 0x3, 0x639a40)
/data/code/go/pkg/mod/github.com/gcla/[email protected]/decoration.go:627 +0x4a6
github.com/gcla/gowid.IColorToTCell(0x6379e0, 0xc0000aa880, 0x1, 0x3, 0xc000018170)
/data/code/go/pkg/mod/github.com/gcla/[email protected]/decoration.go:1062 +0x3b

Terminal widget crashes: invalid memory address or nil pointer dereference

According to the document https://github.com/gcla/gowid/blob/master/docs/Widgets.md :
The terminal canvas implements io.Writer allowing a client to write ANSI codes using this standard Golang interface.

I'm trying to send something to a terminal widgets, adding the following code after

		_, err = t.Canvas().Write([]byte("ls -lisa \n"))
		if err != nil {
    		panic(err)
		}				

The application crashes as follows:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x88 pc=0x553546]

goroutine 1 [running]:
github.com/gcla/gowid/widgets/terminal.(*Canvas).ProcessByte(0x0, 0x6c)
	/home/peter/Programming/golang/gowid/widgets/terminal/term_canvas.go:1485 +0x26
github.com/gcla/gowid/widgets/terminal.(*Canvas).Write(0x0, {0xc0001d7b06, 0xa, 0xa})
	/home/peter/Programming/golang/gowid/widgets/terminal/term_canvas.go:427 +0x45
main.main()
	/home/peter/Programming/golang/gowid/examples/gowid-terminal/terminal.go:289 +0x1c98
exit status 2

Release new version

Hi! I am working on the Debian packaging for termshark and I see that it requires functionality that is not yet in a tagged version of gowid. If necessary I can just package it based on the appropriate git sha but would you be willing to cut a new tagged release of gowid? If so it would make things easier for me!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.