Git Product home page Git Product logo

gocui's Introduction

GOCUI - Go Console User Interface

github actions Go Report Card GoDoc GitHub tag (latest SemVer)

Minimalist Go package aimed at creating Console User Interfaces. A community fork based on the amazing work of jroimartin For v0 to v1 mirgration help read: migrate-to-v1.md

Features

  • Minimalist API.
  • Views (the "windows" in the GUI) implement the interface io.ReadWriter.
  • Support for overlapping views.
  • The GUI can be modified at runtime (concurrent-safe).
  • Global and view-level keybindings.
  • Mouse support.
  • Colored text.
  • Customizable editing mode.
  • Easy to build reusable widgets, complex layouts...

About fork

This fork has many improvements over the original work from jroimartin.

  • Written ontop of TCell
  • Better wide character support
  • Support for 1 Line height views
  • Support for running in docker container
  • Better cursor handling
  • Customize frame colors
  • Improved code comments and quality
  • Many small improvements
  • Change Visibility of views
  • Requires Go 1.13 or newer

For information about this org see: awesome-gocui/about.

Installation

Execute:

$ go get github.com/awesome-gocui/gocui

Documentation

Execute:

$ go doc github.com/awesome-gocui/gocui

Or visit godoc.org to read it online.

Example

See the _example folder for more examples

package main

import (
	"fmt"
	"log"

	"github.com/awesome-gocui/gocui"
)

func main() {
	g, err := gocui.NewGui(gocui.OutputNormal, true)
	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 && !errors.Is(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, 0); err != nil {
		if !errors.Is(err, gocui.ErrUnknownView) {
			return err
		}

		if _, err := g.SetCurrentView("hello"); err != nil {
			return err
		}

		fmt.Fprintln(v, "Hello world!")
	}

	return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
	return gocui.ErrQuit
}

Testing example

You can write simple tests for gocui which let you simulate keyboard and then validate the output drawn to the screen.

  1. Create an instance of gui with OutputSimulator set as the mode g, err := NewGui(OutputSimulator, true)
  2. Call GetTestingScreen to get a testingScreen instance.
  3. On this you can use SendKey to simulate input and GetViewContent to evaluate what is drawn.

Warning: Timing plays a part here, key bindings don't fire synchronously and drawing isn't instant. Here we used time.After to pause, gomega's asynchronous assertions are likely a better alternative for more complex tests.

Here is a simple example showing how this can be used to validate what a view shows and that a key binding is handled correctly:

func TestTestingScreenReturnsCorrectContent(t *testing.T) {
	// Track what happened in the view, we'll assert on these
	didCallCTRLC := false
	expectedViewContent := "Hello world!"
	viewName := "testView1"

	// Create a view specifying the "OutputSimulator" mode
	g, err := NewGui(OutputSimulator, true)
	if err != nil {
		log.Panicln(err)
	}
	g.SetManagerFunc(func(g *Gui) error {
		maxX, maxY := g.Size()
		if v, err := g.SetView(viewName, maxX/2-7, maxY/2, maxX/2+7, maxY/2+2, 0); err != nil {
			if !errors.Is(err, ErrUnknownView) {
				return err
			}

			if _, err := g.SetCurrentView(viewName); err != nil {
				return err
			}

			// Have the view draw "Hello world!"
			fmt.Fprintln(v, expectedViewContent)
		}

		return nil
	})

	// Create a key binding which sets "didCallCTRLC" when triggered
	exampleBindingToTest := func(g *Gui, v *View) error {
		didCallCTRLC = true
		return nil
	}
	if err := g.SetKeybinding("", KeyCtrlC, ModNone, exampleBindingToTest); err != nil {
		log.Panicln(err)
	}

	// Create a test screen and start gocui
	testingScreen := g.GetTestingScreen()
	cleanup := testingScreen.StartGui()
	defer cleanup()

	// Send a key to gocui
	testingScreen.SendKey(KeyCtrlC)

	// Wait for key to be processed
	<-time.After(time.Millisecond * 50)

	// Test that the keybinding fired and set "didCallCTRLC" to true
	if !didCallCTRLC {
		t.Error("Expect the simulator to invoke the key handler for CTRLC")
	}

	// Get the content from the testing screen
	actualContent, err := testingScreen.GetViewContent(viewName)
	if err != nil {
		t.Error(err)
	}

	// Test that it contains the "Hello World!" we thought the view should draw
	if strings.TrimSpace(actualContent) != expectedViewContent {
		t.Error(fmt.Printf("Expected view content to be: %q got: %q", expectedViewContent, actualContent))
	}
}

Note: Under the covers this is using the tcell SimulationScreen.

Screenshots

r2cui

_examples/demo.go

_examples/dynamic.go

Projects using gocui

  • omnivore: Distributed SSH commands with output matching.
  • komanda-cli: IRC Client For Developers.
  • vuls: Agentless vulnerability scanner for Linux/FreeBSD.
  • wuzz: Interactive cli tool for HTTP inspection.
  • httplab: Interactive web server.
  • domainr: Tool that checks the availability of domains based on keywords.
  • gotime: Time tracker for projects and tasks.
  • claws: Interactive command line client for testing websockets.
  • terminews: Terminal based RSS reader.
  • diagram: Tool to convert ascii arts into hand drawn diagrams.
  • pody: CLI app to manage Pods in a Kubernetes cluster.
  • kubexp: Kubernetes client.
  • kcli: Tool for inspecting kafka topics/partitions/messages.
  • fac: git merge conflict resolver
  • jsonui: Interactive JSON explorer for your terminal.
  • cointop: Interactive terminal based UI application for tracking cryptocurrencies.
  • lazygit: simple terminal UI for git commands.
  • lazydocker: The lazier way to manage everything docker.

Note: if your project is not listed here, let us know! :)

gocui's People

Contributors

bbrodriges avatar bcl avatar coloursofnoise avatar cswank avatar dankox avatar djcas9 avatar ekkkkkknoes avatar glvr182 avatar govlas avatar gulyasm avatar ibnesayeed avatar jesseduffield avatar josharian avatar jroimartin avatar julienbreux avatar kavantix avatar kayoticsully avatar lawrencegripper avatar mattn avatar miguelmota avatar mjarkk avatar mkchoi212 avatar nwidger avatar remyabel2 avatar ripienaar avatar riscript avatar rlisagor avatar skanehira avatar telecoda avatar zchee 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

gocui's Issues

[BUG] [REGRESSION] First line not rendered on MinGW

Describe the bug
The first line of the UI is cut off, and an extra empty line is added to the end when running on MinGW.

To Reproduce
Steps to reproduce the behavior:

  1. Use the latest version of awesome-gocui/gocui (v1.0.1)
  2. Use g.SetView("test", 0, 0, maxX-1, maxY-1, 0) to create a view that should surround the terminal
  3. Run the program (using winpty, see #43)

Expected behavior
A border lining the terminal

Screenshots
image
scrolling up shows that the first line is indeed cut off
image

Environment (please complete the following information):

  • OS: Windows
  • Version 7

Additional context
Could not reproduce issue on native linux
Issue is not present when version v0.6.1-0.20191115151952-a34ffb055986 is pinned (version used by git bug) (a34ffb0)

[BUG] Can not input multibyte properly

Describe the bug
Put the cursor on the alphabet and input multi-byte it's not inserted correctly.

To Reproduce
Steps to reproduce the behavior:

  1. run _example/demo.go
  2. input or paste multibyte like ใ‚ดใƒชใƒฉ

Expected behavior
Multi-byte can be inserted correctly.

Screenshots
bug-gocui

Environment (please complete the following information):

Additional context
If nothing there on cursor, it will be inserted correctly

[BUG]Err Fprintln

Describe the bug
when i run hello example somting wrong

To Reproduce
run hello example

Expected behavior
correct print

Screenshots
image

Environment (please complete the following information):
Linux version 5.10.7-3-MANJARO (builduser@LEGION) (gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35.1) #1 SMP PREEMPT Fri Jan 15 21:11:34 UTC 2021

[BUG] SelFgColor and SelBgColor are not used for Highlight anymore

Describe the bug
Apparently, SelFgColor and SelBgColor are not used anymore in highlighted frames. The original SetRune implementation checked the highlight state, and the current SetRune only bolds the fgColor, as seen in this commit d9a7952

To Reproduce

v.Highlight = true
v.SelFgColor = gocui.ColorYellow

Observe the highlighted color is only bolded.

Expected behavior
I expected to be able to use SelFgColor and SelBgColor to set the color. I'm under the impression that using SetHiglight and manually tracking the highlight state is what you expect users to do, then? Otherwise, I would like to bolden the text, but also check if the SelFgColor and SelBgColor are not ColorDefault, and if so, use them too.

What do you think?

Additionally, the documentation is then out of date. I understand this project was taken over to resurrect it (I switched today from jroimartin/gocui to this one) and I don't get why the documentation-- even on the main page lacking the overlap flag-- has not been updated.

Access other views from EditorFunc

I would like to know if it's possible to access another view from an EditorFunc. Basically, depending on what has been entered in the view with the editor, I would like to update a different view.

As a parameter to the EditorFunc, the Gui isn't passed to be able to get a reference to other views, and I can't see how to get it without keeping the Gui in a global.

I guess the other option is to create a Keybinding for all the keys and runes, and implement an editor like that?

Thanks

Adding Go module support

Describe the feature you'd like
For building the examples and for shipping, we should add the go mod files. (without vendor)

Describe alternatives you've considered
/
Additional context
After #8

[BUG] Overrides previous ANSI style

Describe the bug
So this is pretty simple to replicate and test, but \x1b[1m \x1b[31m test this string will not be bold, which it should, based on ANSI standards. the first ANSI styling is overwritten by the second, however i don't use any reset flag so it shouldn't.. the following two strings should be identical, but they are not: \x1b[1m\x1b[31m test and \x1b[1;31m test.

YOu can easily test the expected output by using echo -e "\x1b[1m \x1b[31m test" - it basically seems like gocui overwrites the current color scheme/settings at every call, which IMO is a bug. Not sure if it's a feature. hehe

Environment (please complete the following information):

  • OS: Linux

[BUG] MoveCursor moves beyond line end

Describe the bug
When the cursor is on the last character of a line, and v.MoveCursor(1,0,false) is executed, the cursor position (returned by v.Cursor) is equal to then len of the line, which is out of bound.
To Reproduce
See above

Expected behavior
When v.MoveCursor(1,0,false) is executed and the x is equal to the last index of the line, y should be increase, and x reset to 0. The happens correctly the next execution of v.MoveCursor(1,0,false).
Screenshots
NA
Environment (please complete the following information):
MacOS 10.14

Additional context
NA

version of go-runewidth

Just a FYI, you might want to update the go-runewidth version to the latest as it at least fix the width of a bunch a characters. Those bugs tends to be quite annoying to track down.

Adding tabs

Describe the feature you'd like
Sometime there is just not enough room in the terminal, or two views are
closely related. This calls for a new thing called a "tab". Just like with your browser, a tab holds different information but does not require you to start up a new window.

Describe alternatives you've considered
Manual tabbing, but it is a pain for the developer to create this each and every time.

Additional context
The title of the view would look like this: โ”€Tab one / Tab twoโ”€. and the current tab would be highlighted.

Icon

Describe the feature you'd like
To make Gocui a truly amazing project, we need an icon. If anyone knows a graphics designer who would do this for an opensource project (to have another piece of art added to their portfolio), please do let us know.

Describe alternatives you've considered
Making it myself but I am absolutely terrible with graphics.

Additional context
/

Status of `awesome-gocui/keybinding`?

I am trying to clean up some technical debt of my solid state drive, among which is the patch awesome-gocui/keybinding#3 that I've made to allow https://github.com/wagoodman/dive quit with a single key shortcut like q.

I am asking, because tests for its repo are failing awesome-gocui/keybinding#4

And in addition there is also https://github.com/awesome-gocui/gocui/blob/master/keybinding.go in this repo, also with Parse function.

Expected behavior

I would expect a syntax and example comparison between two libs, or if https://github.com/awesome-gocui/keybinding is already merged, to see a deprecation notice there.

Keybindings for Ctrl, Shift + Arrow keys, Backspace

Describe the feature you'd like
I would like to be able to bind functions to the following combinations:

  • Ctrl + Arrow key
  • Ctrl + Backspace
  • Shift + Arrow key
  • Shift + Backspace

Context
The Alt key seems to be the only available modifier (gocui.ModAlt) and some Ctrl key combinations are realized as special keys (gocui.KeyCtrlC). The Shift key combinations don't seem to be bindable at all.

Is there a reason why is there a different interface for different modifiers? Would it be possible to unify this? Is this connected to some underlying issue with termbox?

Thank you for your work

Release v1.0.0?

As it has now been 2 months since the creation of the v1.0.0 pre-release versions and there has only been 1 issue should we release v1.0.0?
@dankox What are your thoughts?

Text wrapping is adding new lines into the output

I have an editable field in my UI for users to enter a description for what they're doing, and text wrapping is turned on. When I retrieve and print the buffer as a string at the end, there's a new line where the text wrapped in the UI.

Here's my code for the view:

if v, err := g.SetView("Description", 0, titleHeight+1, twothrdwiDth-1, titleHeight+1+descHeight, 0); err != nil {
		v.Highlight = false
		v.Frame = true
		v.Title = " Description "
		v.SelBgColor = gocui.ColorRed
		v.SelFgColor = gocui.ColorBlack
		v.Editable = true		
                v.Wrap = true
	}

Screen Shot 2020-06-24 at 12 58 47 PM

Screen Shot 2020-06-24 at 12 59 28 PM

Easier UI

Describe the feature you'd like
A easier way to generate UI,
Currently everything needs to be set with fixed position but it's quite a bit of work to implement this in a new app when having a advanced UI.

I personally like the CSS grid layout for creating UIs and i think the underlying idea of grid layouts fits GoCui really well because the base concept is really easy and it's made for not nested widgets (Most ui managers have UI in UI in UI what is not used in gocui and in CSS grid).

Describe alternatives you've considered
/

Additional context
The origin repo also had in issue about this: jroimartin#183
Also as mentions in the original issue it might be a good idea to put this in a separate repo.

When #8 is merged i would like to work on this thought i want to hear first the thoughts of others.

Maxlines option on views

Describe the feature you'd like
The ability to clear out the internal buffers either up to the point that the data is being displayed again, or to some arbitrary point provided in the constructor.

There was an issue for something like this on the original repo: jroimartin#103 and an associated PR: jroimartin#104

Describe alternatives you've considered
Ive tried doing this myself with Clear() and an Fprintf:

		_, y := dataView.Size()
		if dataView.LinesHeight() > y*2 {
			lines := getLast(dataView.BufferLines(), y*1)
			dataView.Clear()
			dataView.Title = fmt.Sprintf("cleanup done at %s", time.Now())
			fmt.Fprint(dataView, strings.Join(lines, "\n"))
		}
// ----------------------
func getLast(ls []string, last int) []string {
	out := make([]string, 0, last)
	if len(ls) < last {
		// fast path, we're not trimming anything
		copy(out, ls)
		return out
	}
	// we need to chomp
	copy(out, ls[len(ls)-last:])
	return out
}

But Clear() seems far to slow to make this work seamlessly. Not to mention that this requires significant extra processing and memory usage to convert the lines out of their internal representation and back.

Reflection magic:

			dv := reflect.Indirect(reflect.ValueOf(dataView))

			buffer := dv.FieldByName("lines")
			buffer = reflect.NewAt(buffer.Type(), unsafe.Pointer(buffer.UnsafeAddr())).Elem()
			l := buffer.Len()
			buffer.Set(buffer.Slice(l-y, l))

			tainted := dv.FieldByName("tainted")
			tainted = reflect.NewAt(tainted.Type(), unsafe.Pointer(tainted.UnsafeAddr())).Elem()
			tainted.Set(reflect.ValueOf(true))

			dataView.Title = fmt.Sprintf("cleanup done at %s", time.Now())
		}
	}

I dont think I really need to point out the issues with this approach. It does work, but reflection to this degree is in general a dangerous idea, and is brittle at best.

Additional context
The use case here is a long running TUI that is constantly written to, for me specifically that is for my game management IRC bot's TUI. As that has near constant writes from game server logs.

Add community documents

  • Description
  • Readme
  • Code of conduct
  • Contributing guide
  • License
  • Issue templates
  • Pull request templates

[BUG] Unable to Fprintf to view

Describe the bug
When trying to use Fprintf() on a view using the following code, nothing appears. It seems as if the view is rendering outside of the actual frame?

func printToView(viewName string, message string) {
	g.Update(func(g *gocui.Gui) error {
		updatingView, err := g.View(viewName)
		if err != nil {
			return err
		}

		if config.Basics.UnicodeEmojis {
			message = emojiUnicodeConvert(message)
		}
		fmt.Fprintf(updatingView, "%s\n", message)
		return nil
	})
}

To Reproduce
Steps to reproduce the behavior:

  1. Run https://github.com/rudi9719/kbtui (which was recently updated to catch up to gocui)
  2. Trigger printToView() which calls fmt.Fprintf on a view
  3. Profit

Expected behavior
The printed string would appear inside of the view being updated

Environment (please complete the following information):

  • OS: Linux imogene 5.11.19-1-MANJARO #1 SMP PREEMPT Fri May 7 17:34:25 UTC 2021 x86_64 GNU/Linux
  • Version: go version go1.16.4 linux/amd64

Additional context
Not sure if this is due to recent changes or not; there were 3 code changes I had to make in order to get the code to build with the updated version of gocui. Seems like if I output enough to Fprintf() it'll EVENTUALLY show what I originally printed, but there's a hidden buffer of things I've printed waiting to actually render.

Improve get terminal window size in the docker container

Describe the feature you'd like
The current gocui dosn't work in the docker container's endpoint because the termbox cannot get terminal window size when run the container.

Describe alternatives you've considered
Improve get terminal window size like as follows.
When we use the container must to be wait SIGWINCH.

skanehira/docui@aa1739a

Additional context
We have to improve the termbox?
Or gocui?
I want to discussion.

[BUG] Parse() doesn't parse Alt, Shift modifiers and converts Ctrl to a key

Parse() fails process Alt+ and Shift+ combinations. See the code below.

package main

import (
	"github.com/awesome-gocui/gocui"
	"github.com/kr/pretty"
)

func main() {
	pretty.Println(gocui.Parse("q"))
	pretty.Println(gocui.Parse("ctrl+q"))
	pretty.Println(gocui.Parse("shift+q"))
	pretty.Println(gocui.Parse("alt+q"))
}

This outputs,

int32(113) gocui.Modifier(0) nil
gocui.Key(17) gocui.Modifier(0) nil
nil gocui.Modifier(0) &errors.errorString{s:"no such keybind"}
nil gocui.Modifier(0) &errors.errorString{s:"no such keybind"}

Another strange behavior is that https://pkg.go.dev/github.com/awesome-gocui/gocui#Parse should return modifier separately from Key, but it for Ctrl+ there is no Modifier and it is mixed into the key.

To Reproduce

https://play.golang.org/p/UPWMipkgA9U

Expected behavior

Key('q') Modifier() nil
Key('q') Modifier('ctrl') nil
Key('q') Modifier('shift') nil
Key('q') Modifier('alt') nil

[BUG] Mouse handling delayed in neovim terminal

Describe the bug
Mouse clicks inside neovim terminal are delayed until the next system event.
Mouse handling works fine with jroimartin/gocui

To Reproduce
Steps to reproduce the behavior:

  1. Open nvim
  2. Open the nvim terminal with :term
  3. Run a gocui project that uses the MouseLeft keybinding
  4. Notice that nothing happened
  5. Press a random key on the keyboard
  6. Notice that the mouse press is now detected

Expected behavior
The mouse click should be detected immediately

Environment (please complete the following information):

  • OS: macOS catalina
  • nvim 0.5

Context

  • Calling g.Update does not help
  • MouseRelease is trigged (although not on release)`

Can not run Example in Docker [BUG]

Describe the bug
When running the example in Docker it crashes with the error

fatal error: unexpected signal during runtime execution

To Reproduce
Steps to reproduce the behavior:

  1. Compile readme example in docker container
  2. Run docker-container

Expected behavior
Running example

Environment (please complete the following information):

  • OS: Linux, Pop!Os 19.04
  • Docker version 19.03.0

Additional context
File compiled with

CGO_ENABLED=0 GOOS=linux go build -a -installsuffix "static" -o main .

detect when idle

In the testing code, we include a sleep and hope all the gui events have been handled. It would make tests simpler (and more deterministic) if there was an API to call and return when all pending events have been handled.

Problem with SetCursor() used by mouse

Describe the bug
SetCursor() function working on top of the view buffer lines can cause panics when mouse control is turned on.

To Reproduce
Steps to reproduce the behavior:

  1. clone branch from PR #80
  2. run go run _examples/mouse.go
  3. move cursor in to the spot in view which doesn't have text (basically just moving it at the end of the highlighted line does the trick)

Expected behavior
It shouldn't panic.

Additional context
SetCursor function was used before from outside "world" point of view with just knowledge of the View dimension. This is easy to deal with as all terminals/consoles have specific dimension, Views are setup according to it, and application can points to it.
If it's used with the knowledge of the view buffer content, programs need to be updated to consider it and not point to the position which would be outside of this buffer.
Even in gocui mouse position is used relative to the terminal window and View and registering the location without any knowledge of the buffer content.

Proposed solution could be, that there will be another two functions SetCursorInBuffer, CursorInBuffer, which would act as the current SetCursor and Cursor and the original functions would be enhanced to translate the position from buffer position to "real" position on the screen.
This way SetCursor would use original View dimension to check for invalid point and the new functions could be used in edit.go to work with the buffer as it is right now.

FYI: gocui triggers a bug in Go 1.13 (pre-release)

This is a heads up that gocui appears to trigger a bug in Go 1.13 (at least rc1), so if folks come to this repo and complain about crashes, you'll know what's happening.

The issue is reported upstream at golang/go#33841.

Feel free to close this issue any time once you've seen it.

Migrating to a different underlying library

Just gonna throw it out here, Termbox-Go is no longer maintained by NSF as we probably all know.
This made me wonder if it might be time for us to switch to a different library.

For example TCell. In #41 we discussed briefly about the Shift-Enter problem and how we could fix this. This keybind would be possible with TCell.

Hope to get feedback on this thought

Frame color for Views

Hi,
I wanted to ask, if I could create a PR for adding frame color for seperate views. Basically it would add new color attribute to view for frame and title color.

I had created a fork with that change which I'm using in my project. But I was hoping something like that could be added to this repo too.

Here is my commit in the forked repo: dankox@a7e8d20

gocui.KeyCtrlTilde doesn't seem to be triggering

Anyone else had this issue? My keybinding for gocui.KeyCtrlTilde doesn't seem to be running

	if err := g.SetKeybinding("", gocui.KeyCtrlTilde, gocui.ModNone, ui.plan_move_week_quick_enter(rc, 1)); err != nil {
		return fmt.Errorf("Failed to set keybinding: %s", err)
	}
	if err := g.SetKeybinding("", gocui.KeyCtrl2, gocui.ModNone, ui.plan_move_week_quick_enter(rc, 2)); err != nil {
		return fmt.Errorf("Failed to set keybinding: %s", err)
	}


func (ui *PlanningUI) plan_move_week_quick_enter(rc *Radar, numForward int) func(g *gocui.Gui, v *gocui.View) error {
	return func(g *gocui.Gui, v *gocui.View) error {
		log.Debugf("Moving %d weeks forward",  numForward)
	}
}

When I hit ctrl+2, I get the log. when I hit ctrl+~, nothing happens.

[BUG] Exits on Open

Describe the bug
After converting from jroimartin/gocui to awesome-gocui (adding params to g.NewGui(), and g.SetView()) my projectnow exits cleanly upon opening rather than starting the main loop.

To Reproduce
Steps to reproduce the behavior:

  1. Compile project
  2. Start Project

Expected behavior
TUI with 4 views should appear, and populate with text as they did with jroimartin/gocui

Screenshots
N/A

Environment (please complete the following information):

  • OS: Ubuntu 19.04
  • Version go1.13.1 linux/amd64

Additional context
https://github.com/Rudi9719/kbtui/tree/awesome-gocui

I began migrating to this (maintained) fork of gocui to implement features that were missing from the original, however it looks like it just closes after gocui.NewGui() it doesn't return the normal tuple, and just exits.

Documentation update

Describe the feature you'd like
Some parts of the code are not yet codumentated. We should add documentation to everything.

Describe alternatives you've considered
/
Additional context
After #8

[BUG] Arrows not moving cursor properly

Describe the bug
Arrow keys aren't moving cursor properly in view?

To Reproduce
Steps to reproduce the behavior:
On a view with editable text in it

  1. view.SetCursor(0,0)
  2. view.SetOrigin(0,0)
  3. view.MoveCursor(x, y, true) <- x,y being end of text
  4. Move cursor using arrows
  5. Enter text

Expected behavior
Text should be entered under the cursor. It seems like the left and right arrows work properly, however up and down arrows move cursor either left or right by one char rather than up or down.

Screenshots
If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

  • OS: Ubuntu 19.04
  • Version go1.13.1

Additional context
Trying to pop up a view, clear it of any cruft, populate it with a string, and move the cursor to the end of the string. I tried making a func moveCursorToEnd() to try and move the cursor to the end of a view to get around this, however the func is also causing the same issue
https://github.com/Rudi9719/kbtui/tree/bugs/edit-cursor

[BUG] Italic and strikethrough doesn't seem to work

Describe the bug
So i've been trying to produce italic font for quite some time, and trying to debug why it wouldn't display on my gocui application, but it seems to be a general problem with gocui - and I realized that you don't use neither in your example - so I realized the problem might be on your end. But i cant fathom what can possibly be the cause of it.
To Reproduce

the following doesn't use strikethrough or italic on my end.

// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"log"

	"github.com/awesome-gocui/gocui"
)

func main() {
	g, err := gocui.NewGui(gocui.OutputNormal, true)
	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 && !gocui.IsQuit(err) {
		log.Panicln(err)
	}
}

func layout(g *gocui.Gui) error {
	maxX, maxY := g.Size()
	if v, err := g.SetView("colors", maxX/2-7, maxY/2-12, maxX/2+7, maxY/2+13, 0); err != nil {
		if !gocui.IsUnknownView(err) {
			return err
		}
		for i := 0; i <= 7; i++ {
			for _, j := range []int{1, 3, 4, 7, 9} {
				fmt.Fprintf(v, "Hello \033[3%d;%dmcolors!\033[0m\n", i, j)
			}
		}
		if _, err := g.SetCurrentView("colors"); err != nil {
			return err
		}
	}
	return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
	return gocui.ErrQuit
}

Expected behavior

ANSI italic and strikethrough works.

Screenshots
image <- this picture should italic and strikethrough, but only has underscore and reverse
Environment (please complete the following information):

  • OS: Archlinux, running in alacritty. has also been tested in termite. both have italic and strikethrough working - just not in gocui
  • Version (not sure how to find

[BUG] MinGW compatibility

Describe the bug
Unable to render UI when running in a MinGW environment

To Reproduce

  • git-bug
    git bug user create
    git bug termui
    image
    also see MichaelMure/git-bug#222

  • jsonui
    cat test.json | ./jsonui_windows_amd64.exe
    image

Expected behavior
Console UI is shown

Screenshots
Attached in reproduce

Environment (please complete the following information):

  • OS: Windows 10, 7 (64bit)
  • PortableGit 2.23.0

Additional context
NA

Build & Testing automation

Describe the feature you'd like
As with any project, testing gocui is important. We should set up tools like circle-ci and codecov to automaticly check some things.

Describe alternatives you've considered
Testing manually. This is too much work with too many points where it can go wrong.

Additional context
/

... overlapping ?

I'm migrating from the original gocui to this awesome community maintained version. In the process, I noticed new parameters for NewGui() and SetView(). Looking at the code, it's not super obvious what this overlapping is about and how it could/should be used.

Could you explain a little bit what it is about and maybe give a small example?

Thank you

Add ability to use tcell simulated screen for testing gocui

Describe the feature you'd like (Happy to PR this feature)
tcell supports a simulated screen, this allows you to write unit tests which provide input and then assert about the content drawn on the screen.

https://github.com/gdamore/tcell/blob/master/sim_test.go

Adding in this feature by either exposing the tcell simulated screen or a wrapper to abstract it but allow input of keys and validation of the resulting content drawn would help building testable UI apps.

Describe alternatives you've considered
Currently I do some horrible things in our CI pipeline to create a "real" screen on the CI box then spin up a xterm instance and pipe the results back.

Additional context
Here is an example of another tcell based project using the simulated screen to write some nice tests. https://github.com/zyedidia/micro/blob/c0907bb58e35ee05202a78226a2f53909af228ca/cmd/micro/micro_test.go#L183

Release v0.5.1

Thanks for the speedy review of #36 (for #33)! May I request that you add a new tag/released version so that folks like me using 1.13 can pick up the bug fix without a replace directive in our go.mod? Thanks!

[BUG] Rune-based keybindings do not work without a current view

Describe the bug
I have a Gui without a currentView and only with global keybindings. I ran into the problem that keybindings based on rune would not work for me while keybindings based on gocui.Key were still working. I traced the issue a bit and found that the reason seems to be that no current view is set. I describe this under "Additional Context" below. The minimum viable reproduction is based upon one of the files in _example/.

To Reproduce
Steps to reproduce the behavior:

  1. Edit _examples/table.go
  2. Add a second keybinding below the Ctrl-C like this:
if err := g.SetKeybinding("", 'q', gocui.ModNone, quit); err != nil {
    log.Panicln(err)
}
  1. Run with go run table.go
  2. Press the q key

Expected behavior
With q pressed, the application should quit.

Environment (please complete the following information):

  • OS: Tested on Linux, Windows 7, Windows 10
  • Version: gocui v0.6.0

Additional context
I chose table.go as it is the only example without a call to func (g *Gui) SetCurrentView(name string)```. If you amend the method func (t *Table) Layout(g *gocui.Gui) errorfunction intable.gowith a call toSetCurrentView` right before the return at the end like in the following code snippet, then the keypress will work.

g.SetCurrentView(t.name)

My layman's guess would be that the culprit is in https://github.com/awesome-gocui/gocui/blob/master/gui.go#L790:

  • v is nil in the call to execKeybindings, because g.currentView is nil in the call to onKey in https://github.com/awesome-gocui/gocui/blob/master/gui.go#L745
  • kb.ch is not 0, but is set to a rune.
  • Hence, the if-condition never resolves to true, globalKb is never assigned a non-nil value, and execKeybinding is never called for the global keybinding.

Allow removing view cursor to "un-highlight" all lines

Demonstrated using _examples/mouse.go

  • Current behaviour:
    gocui_mouse_bug
  • Desired behaviour:
    gocui_mouse_fixed

The fix displayed above was done by adding a View.RemoveCursor method to set the cursor position to (-1, -1), which was called during Gui.onKey on the last view selected by the mouse.
Patch File (as .txt due to GitHub restrictions)

This implementation is presumeably a bad idea due to setting the cursor position to an invalid point, so other ideas would be appreciated.

Allow access to tcell.Screen for redrawing/complex scenarios

Firstly, thanks for all the work on the fork it's awesome!

Describe the feature you'd like

I'd like to have methods which allow me to use the underlying screen.

I build out a terminal based browser for Azure Cloud which lets you browse to an item and then open your favourite editor to edit it (nano, vi) then once you save and close the editor the update is pushed and the gocui UI redrawn.

With the old gocui we had our own fork which exposed out Flush for us to do this, with the tcell based version I can do the same once I have access to the screen object from tcell_driver.go

Would you be open to a PR to allow get/set public funcs on the screen to enable this and other complex scenarios?

Describe alternatives you've considered

Alternative would be not to expose screen but allow public funcs for

func TcellInit() error {
	return tcellInit()
}

func TCellClose() {
	screen.Fini()
}

Additional context
Here is my PR and a gif showing the flow the change allows.

lawrencegripper/azbrowse#310 (comment)

editv3

[BUG] EditGoToEndOfLine and EditGoToStartOfLine do not account for origin

This is a great project and I am really glad you guys are still supporting it and adding some really useful features. I was fiddling about with my app the recently and I noticed that a couple of functions don't seem to be working properly. Sorry if I have misunderstood anything but I am still fairly new to golang

Both the following functions are part of the view class in edit.go:
EditGoToEndOfLine if already on the last line loops over MoveCursor until the cursor no longer changes. However, when it reaches the end of the view, it is the origin that changes not the cursor. Therefore, it does not actually go to the end of the line but the end of the view

EditGoToStartOfLine does much the same in that it sets cursor to zero but does nothing to the origin. This means that if origin is not zero, it will not go back to the start of the line

Steps to reproduce the behavior:

  1. Create a view without wrap enabled and fill it with data (only on single line) at least 10 or so characters longer than the view
  2. Move origin to about midway through line
  3. Bind EditGoToStartOfLine and EditGoToEndOfLine to keys
  4. Flick between "start" and "end" and notice it does not actually reach the end nor beginning

Origin should also be updated within these functions to go to the true start/end of line

  • OS: Linux
  • Version: Not sure how to find out but used go get about 4 months ago. The effected code still seems to be in master

I think simple solutions would be:

func (v *View) EditGotoToStartOfLine() {
   _, cursorY := v.Cursor()
   _, originY := v.Origin()
   v.SetCursor(0, cursorY)
   v.SetOrigin(0, originY)
}
func (v *View) EditGotoToEndOfLine() {
   _, cursorY := v.Cursor()
   _, originY := v.Origin()
   if line, err := v.Line(cursorY + originY); err == nil {
      width, _ := v.Size()
      if len(line) < width {
         v.SetCursor(width, cursorY)
      } else {
         v.SetCursor(width-1, cursorY)
         v.SetOrigin(len(line) - (width - 1), originY)
      }
   }
} 

Key binding doesn't seem to be working for runes

I was using jroimartin/gocui for a while and recently migrated to this fork.

When I type in one field of my gui, I intend to update another field according to what I wrote. I use a keybinding for this, effectively for each alphanumeric character I type.
for _, c := range "{};=<>()[]'\"/\\-+:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" { g.SetKeybinding("Title", c, gocui.ModNone, create_update_titleBuff(c)) }

create_update_titleBuff writes the appropriate characters to each field I'm looking to edit

This no longer seems to be working. There is no error when setting the keybinding, but the create_update_titleBuff() does not seem to actually be called -- the other functionality within that function isn't happening. Instead, it appears as if I'm just typing into the Title field.

New View.SetCursor() - problem/question

I found this problem when I was trying to update my application to use gocui version v1.0.0-beta-2.

I had there code like this (where v is referencing gocui.View):

v.Clear()
v.SetCursor(0, 0)

The View which is there, is 1 line in height. It's basically a command prompt and after hitting enter, the prompt will be cleared and cursor set to the beginning.

I know that I don't have error checks :) but the point is, that after the upgrade the function SetCursor was changed like this:

gocui/view.go

Line 239 in a0f5add

if x < 0 || y < 0 || y >= len(v.lines) || (len(v.lines[y]) >= x && x >= maxX) {

Now after View.Clear (which sets v.lines = nil) I can't really run View.SetCursors(0, 0). Easy fix for me in this situation is just to move SetCursor above Clear, but I'm just wondering if this shouldn't be fixed in gocui too.

@mjarkk I think you did these changes regarding the line buffer. So I would like to hear your opinion. Before the check was like this:

if x < 0 || x >= maxX || y < 0 || y >= maxY {

Which makes it work, because the maxY is 1 in my case. And it kinda makes sense, because you could point anywhere into the view this way.

So I'm curious about the reason to limit the SetCursor this way, as it appears that before it was possible to set it in the range of the View dimension while after the change the limitation is to the lines in the line buffer.

information about this fork

Describe the feature you'd like
In the readme or in docs add a section about this fork with information about why we forked it and a number of important changes this fork has compared to jromartin's

Describe alternatives you've considered
/

Additional context
In general it would be nice to have better documentation, related to (#12).

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.