Install GOCUI
masterTo add GOCUI to your Go project, use the following command:
go get github.com/jroimartin/gocuirepository·master·Indexed 27 days ago
https://github.com/jroimartin/gocuiA minimalist Go package for creating Console User Interfaces (CUIs). It provides a concurrent-safe way to manage overlapping views, keybindings, and mouse support in a terminal environment. Features include a flexible layout system via managers, an Editor interface for custom text input logic, and support for terminal attributes like colors and font styles.
To add GOCUI to your Go project, use the following command:
go get github.com/jroimartin/gocuiNewGui to create a new interface instance with a specific terminal output mode. To clean up resources and close the terminal, call Close(). The MainLoop() method starts the event loop and runs until an error is returned; a successful exit is indicated by ErrQuit.To build a basic console user interface, you need to:
gocui.NewGui(gocui.OutputNormal).g.SetManagerFunc(layout).g.SetKeybinding().g.MainLoop().Views in GOCUI implement the io.ReadWriter interface, allowing you to use standard functions like fmt.Fprintln to write text to them.
package main
import (
"fmt"
"log"
"github.com/jroimartin/gocui"
)
func main() {
g, err := gocui.NewGui(gocui.OutputNormal)
if err != nil {
log.Panicln(err)
}
defer g.Close()
g.SetManagerFunc(layout)
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
log.Panicln(err)
}
if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
log.Panicln(err)
}
}
func layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
if v, err := g.SetView("hello", maxX/2-7, maxY/2, maxX/2+7, maxY/2+2); err != nil {
if err != gocui.ErrUnknownView {
return err
}
fmt.Fprintln(v, "Hello world!")
}
return nil
}
func quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}Use these methods to extract text from the View's buffer:
Buffer() string: Returns the entire contents of the internal buffer as a single string.BufferLines() []string: Returns the lines in the internal buffer as a slice of strings.ViewBuffer() string: Returns the contents of the buffer as it is currently shown to the user (respecting scrolling/origin).ViewBufferLines() []string: Returns the lines currently visible to the user as a slice of strings.Line(y int) (string, error): Returns the string of the line at the specified buffer position y.Word(x, y int) (string, error): Returns the word at the specified buffer position (x, y).The Editor interface allows you to define custom text input and cursor movement logic for a View. To implement it, create a type that satisfies the Edit method signature:
type MyEditor struct{}
func (e *MyEditor) Edit(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) {
// Custom logic here
}You can also use the EditorFunc adapter to turn a regular function into an Editor object.
type Editor interface {
Edit(v *View, key Key, ch rune, mod Modifier)
}
type EditorFunc func(v *View, key Key, ch rune, mod Modifier)
func (f EditorFunc) Edit(v *View, key Key, ch rune, mod Modifier) {
f(v, key, ch, mod)
}Use these methods to control where the cursor is located and where the buffer starts rendering:
SetCursor(x, y int) error: Sets the cursor position relative to the view. Returns an error if the point is invalid.Cursor() (x, y int): Returns the current cursor position.SetOrigin(x, y int) error: Sets the origin position of the view's internal buffer. This is used to implement manual horizontal or vertical scrolling.Origin() (x, y int): Returns the current origin position.A Manager defines the layout of the GUI. You can set one or more managers using SetManager. The Layout method of the manager is called every time the GUI is redrawn.
To use a simple function as a manager, use SetManagerFunc.
Views are rectangular areas within the GUI. You can manage them using the following methods:
SetView(name string, x0, y0, x1, y1 int) (*View, error): Creates a new view or updates an existing one. If the view is new, it returns ErrUnknownView to signal initialization is needed.View(name string) (*View, error): Retrieves a view by name. Returns ErrUnknownView if not found.ViewByPosition(x, y int) (*View, error): Returns the view at the specified coordinates (checking top views first).SetCurrentView(name string) (*View, error): Gives focus to a specific view.DeleteView(name string) error: Removes a view by name.SetViewOnTop(name string) (*View, error): Moves a view to the top of the stack.SetViewOnBottom(name string) (*View, error): Moves a view to the bottom of the stack.Since View implements io.ReadWriter, you can interact with it using standard I/O patterns:
Write(p []byte) to append data to the buffer. You can also use fmt.Fprint(view, "text").Read(p []byte) to read data from the buffer. It returns io.EOF at the end of the buffer.Rewind() to reset the read offset to 0, refreshing the read cache with the current buffer contents.Clear() to empty the view's internal buffer.The Gui struct provides several fields to customize the interface behavior:
BgColor, FgColor: Background and foreground colors (type Attribute).SelBgColor, SelFgColor: Background and foreground colors for the frame of the current view.Highlight: If true, SelBgColor and SelFgColor are used to draw the frame of the current view.Cursor: If true, the terminal cursor is enabled.Mouse: If true, mouse events are enabled.InputEsc: If true, unmatched ESC sequences are treated as KeyEsc.ASCII: If true, uses ASCII characters instead of Unicode for drawing borders.Size() (x, y int): Returns the number of visible columns (x) and rows (y) in the view.Name() string: Returns the name of the view.Update method. This queues the function to be executed within the main event loop, ensuring thread safety.