Giter VIP home page Giter VIP logo

gocui's People

Contributors

alitari avatar cswank avatar djcas9 avatar dtylman avatar gbitten avatar govlas avatar gulyasm avatar heppu avatar jameskmonger avatar jroimartin avatar julienbreux avatar kayoticsully avatar miguelmota avatar mkchoi212 avatar nwidger avatar rlisagor avatar telecoda 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  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

gocui's Issues

Add a View method that returns the actual contents of the view

Currently, if a view is wrapped, there seems to be no way to actually return the new view content, including the extra newlines. Buffer returns the content before the newlines have been calculated. This makes implementing scrolling with boundaries impossible.

View Title Alignment

Hi,
Using the gocui for creating a Terminal application. We have a main view more like a dialog which we would like to set the title. Right now the title comes to the left end of the layout. Any way to add the alignment for the title, so that it aligns to the middle?

view.Line(n) contains "\x00" at end

I need to get the text a line n but len(line) is off because of "\x00" at end of line.

Example:
line := v.Line(n)
if len(line) > 10 {
// Do something
}

The above doesn't work as expected because len is off by 1. Would be nice if Line func would do the following before it returns value:

strings.Replace(lineValue, "\x00", "", -1)

SetKeyBinding fails when called via a helper function

When defining my keybindings, I use this helper function:

    func setkey(g *gocui.Gui, key gocui.Key, fn gocui.KeybindingHandler) {
        if err := g.SetKeybinding("", key, gocui.ModNone, fn); err != nil {
            log.Panicln(err)
        }
    }

An example invocation that works is:

    setKey(g, gocui.KeyCtrlC, quit)

...but the following fails:

    setKey(g, 'q', quit)

...while the following correctly binds the q key:

        if err := g.SetKeybinding("", 'q', gocui.ModNone, quit); err != nil {
            log.Panicln(err)
        }

I'm pretty sure I'm missing something obvious here.

Support \r when printing

When printing to view
fmt.Fprint(v, "\r test")

casts:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x80 pc=0x4e1e95]

goroutine 1 [running]:
panic(0x7ca780, 0xc82000e1a0)
/usr/local/go/src/runtime/panic.go:481 +0x3e6
github.com/jroimartin/gocui.(*View).Write(0x0, 0xc820263c40, 0x6, 0x8, 0x720000, 0x0, 0x0)
/home/janbo/src/github.com/jroimartin/gocui/view.go:197 +0x45
fmt.Fprint(0x7f5a542ad1c8, 0x0, 0xc82004ba50, 0x1, 0x1, 0x0, 0x0, 0x0)
/usr/local/go/src/fmt/print.go:223 +0xa5

Cursor Not Displaying

Hi jroimartin,
Thanks for answering my earlier question. I am asking this question as a new thread, thinking that others who want to use this fantastic library may find these Q&A helpful.

The issue/question I am having is, I have to draw a UI and ask for the user input. I would like to show the cursor in the screen (may be blinking as well) so user knows where the cursor is. I created a sample using gocui https://github.com/shibukraj/synapseconsole/blob/master/console-dev.go

While running I am not able to draw the cursor at all. Can you guide me please.

Thanks again

Feature projects built with gocui

I think it would be cool to have a section on the readme highlighting projects built using your awesome package. I have been working on an IRC client using it https://github.com/mephux/komanda-cli and I'm sure there are hundreds of others.

Anyway, thought it would be a good idea to highlight how easy this package makes it building pretty complex terminal UI's outside of the examples in the package itself.

View.Line() does not return entered line of text

Greetings,

I may have stumbled across a bug, otherwise requesting clarification :-)

Here goes:

I need to implement a simple text entry, this is done inside a View. Just 1 line of text entry is desired - think a password / IP address / hostname etc., something short.

I implemented this using the View.Editable = true functionality so that a user can comfortably enter text. Wrote a handler for the Enter key in order to handle OK / submit.

Try running it, enter some text, press Enter.

In the handler, tried to get the entered text using view.Line(0), but ... the resulting string is empty.

But, when I enter some text, then press left arrow key a few times = move cursor into middle of entered text, then press the Enter key, then view.Line(0) returns everything right of the cursor.

From the documentation and the name of the function (Line) I would expect to receive the whole line of text, not just what is right of the cursor.

Is this a bug or am I understanding the use of this function wrong?

Sure, using view.Buffer() returns everything and this is a possible workaround in this case - but then how does one get a specific line if there are multiple lines? That use case will show up soon. I would expect view.Line(i) to cover that functionality. As in give me the view's i-th line in the internal buffer.

Example code for cut and paste:

package main

import (
    "fmt"
    "log"
    "strings"

    "github.com/jroimartin/gocui"
)

func main() {
    g := gocui.NewGui()
    if err := g.Init(); err != nil {
        log.Panicln(err)
    }
    defer g.Close()

    g.SetLayout(layout)
    if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
        log.Panicln(err)
    }
    if err := g.SetKeybinding("token", gocui.KeyEnter, gocui.ModNone, readToken); err != nil {
        log.Panicln(err)
    }

    if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
        log.Panicln(err)
    }
}

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

func readToken(g *gocui.Gui, v *gocui.View) error {
    //FIXME issue is here
    token := strings.TrimSpace(v.Line(0))
    //token := strings.TrimSpace(v.Buffer())
    g.Close()
    fmt.Println("user has entered", token)
    return nil
}

func layout(g *gocui.Gui) error {
    maxX, maxY := g.Size()

    // Overlap (front)
    passLen := 25
    // calculate position for centering
    //TODO is this possible more easily to center a view of given size?
    x0 := (maxX - passLen - 2) / 2
    y0 := (maxY - 3) / 2
    if v, err := g.SetView("token", x0, y0, x0+passLen+2, y0+2); err != nil {
        if err != gocui.ErrUnknownView {
            return err
        }
        v.Title = "Enter security token"
        v.Editable = true
        v.Wrap = false
        if err := g.SetCurrentView("token"); err != nil {
            return err
        }
    }

    return nil
}

Should KeybindingHandler accept the pressed key/modifier?

Then you could transform this code:

if err := g.SetKeybinding("main", '0', 0, key0); err != nil {
    return err
}
if err := g.SetKeybinding("main", '1', 0, key1); err != nil {
    return err
}
// 0..9
if err := g.SetKeybinding("main", '9', 0, key9); err != nil {
    return err
}
...
func key0(g *gocui.Gui, v *gocui.View) error {
}
func key1(g *gocui.Gui, v *gocui.View) error {
}
// 0..9
func key9(g *gocui.Gui, v *gocui.View) error {
}

Into something like this:

if err := g.SetKeybinding("main", '0', 0, keyPressed); err != nil {
    return err
}
if err := g.SetKeybinding("main", '1', 0, keyPressed); err != nil {
    return err
}
// 0..9
if err := g.SetKeybinding("main", '9', 0, keyPressed); err != nil {
    return err
}
...
func keyPressed(g *gocui.Gui, v *gocui.View, key interface{}, mod Modifier) error {
}

The reason is because I want to accumulate the keys, like VI 'gg', so the keyPressed will only accumulate the keys until the execution.

Editor

Do you have any examples that shows the right usage of editor struct?

Getting text from internal buffer

This might be a really stupid question, but what is the easiest way to get all text from a particular view's internal buffer?

e.g. Say we Fprint a couple of things to a view

// v being our view

fmt.Fprint(v, "My Text")
fmt.Fprint(v, "My other Text")

How can I then easily get all the text from that view, preiferbabrly as a string?
Sorry if it's a dumb question I'm still really new to Go and I've had a look around the code here but I couldn't figure it out.

Colored text

Add support for colored text. E.g.: fmt.Println(v, "Regular text and [yb:Yellow bold text]")

Update README.md

Include the following information in README.md:

  • Description
  • Concepts and conventions
  • Small example
  • Installation instructions (go get ...)

Handling the ESCape key

At first I was confused why your demos all exit on CTRL-C instead of ESC. Then I noticed that any handler I install for KeyEsc will be ignored. I eventually traced this back to gocui hardcoding the termbox.InputAlt input mode in the MainLoop method in gui.go. If I hack the code to set termbox.InputEsc instead, I get the behavior I want. My first instinct is that this should be the application's choice, not gocui's. However, I may be missing something about what gocui needs in order to work. Any hints?

Semantic Versioning

Thanks for putting together such a helpful project!
There are a lot of api breaking changes between the 0.3.0 tag and the tip of master, is there any chance the next version could bump the major version to 1?

can't read from stdin

The _examples/stdin.go won't run for me on os/x in go 1.5 or 1.6. The program just hangs and when you kill it from another terminal it outputs this

2016/04/01 00:27:04 read /dev/stdin: input/output error

Could it be a problem with the way it's reading from stdin maybe interfering with the keybindings?

Keybinding on gocui.KeyEsc does not seem to work

Greetings, I just wanted to catch the Escape key via a key binding, but it did not work. I used other key bindings, so they generally seem to work. I tried in different terminal emulators, checked escape sequence options. System here: recent Ubuntu Linux.

Copy-paste test program:

package main

import (
    "fmt"
    "log"

    "github.com/jroimartin/gocui"
)

func main() {
    g := gocui.NewGui()
    if err := g.Init(); err != nil {
        log.Panicln(err)
    }
    defer g.Close()

    g.SetLayout(layout)
    if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
        log.Panicln(err)
    }
    if err := g.SetKeybinding("main", gocui.KeyEnter, gocui.ModNone, enterKey); err != nil {
        log.Panicln(err)
    }
    if err := g.SetKeybinding("main", gocui.KeyEsc, gocui.ModNone, escKey); err != nil {
        log.Panicln(err)
    }

    if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
        log.Panicln(err)
    }
}

func layout(g *gocui.Gui) error {
    if v, err := g.SetView("main", 0, 0, 50, 10); err != nil {
        if err != gocui.ErrUnknownView {
            return err
        }
        v.Frame = true
        v.Editable = true
        if err := g.SetCurrentView("main"); err != nil {
            return err
        }
    }
    return nil
}

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

func escKey(g *gocui.Gui, v *gocui.View) error {
    fmt.Fprint(v, "ESC KEY")
    return nil
}

func enterKey(g *gocui.Gui, v *gocui.View) error {
    fmt.Fprint(v, "ENTER KEY")
    return nil
}

Maybe this is just a wrong keycode taken over from termbox, I dont know.

Unable to get View after using SetLayout

In my layout function, I am creating the view messages_box using g.SetView("messages_box", 0, 0, maxX, maxY-5). After using g.SetLayout(layout), I try to call messageView, err := g.View("messages_box"), but I keep getting "unknown view."

SetKeyBinding for all unbound keys.

I want to create an autocomplete widget, so I want a callback any time the user types a letter. I obviously don't want to override CtrlC (globally bound), but everything else.

SetCurrentView

Hi Roi, i think this is an awesome tool. I have a question for you in demo2.go the layout function. When I take setCurrentView() (line 165) out of the if/else, the nextView no longer works.

nextView workds as :
if v, err := g.SetView("main", 30, -1, maxX, maxY); err != nil {
......
v.Editable = true
if err := g.SetCurrentView("main"); err != nil {
return err
}
}
return nil

nextView doesn't work when :
if v, err := g.SetView("main", 30, -1, maxX, maxY); err != nil {
......
v.Editable = true
}
if err := g.SetCurrentView("main"); err != nil {
return err
}
return nil

thanks

km

Should Gui.SetKeybinding accept a slice of viewnames?

Then you could transform this kind of code:

if err := g.SetKeybinding("side", gocui.KeyCtrlSpace, 0, nextView); err != nil {
    return err
}
if err := g.SetKeybinding("main", gocui.KeyCtrlSpace, 0, nextView); err != nil {
    return err
}

Into something like this:

if err := g.SetKeybinding([]string{"main","side"}, gocui.KeyCtrlSpace, 0, nextView); err != nil {
    return err
}

View with no frame -- consume zero character space

Need an option for a view to have no Frame.

When you do:
v.Frame = false
you still get a border, its just spaces instead of a visible line. I need a view option that consume no visual space for its border.

Optimize screen refresh

At this moment everything (view contets, frames, intersections) is re-drawed with every event. Only those views that have been modified should be refreshed, unless a resize event is detected.

unicode friendly

The border characters are not good for windows. You expect or are single width character. but it's ambiguous width characters in unicode. They are displayed as double width characters in east asia. http://www.unicode.org/reports/tr11/

And also, I'm looking _example/demo.go, it seems not support multi-byte characters. for example, when typing , it should move the cursor forwarding two cells.

Simplify demos

For example, demo2.go has been used for testing purposes and its source code is not clear enough.

Full edition mode

Implement full edition mode:

  • \n in between the lines.
  • Backspace or Delete deletes \n.
  • ^w, ^a, ^e...
  • Tabstop (fixed?)
  • Natural cursor movement in "wrap" mode.

Reading buffer without carriage returns inserted by Wrap = true

Hey! First of all, thank you so much for an awesome library! I have only been using it for a few days but I already have a version of my app working really well, thanks to how great your library is.

I am building a simple cui note taking app (https://github.com/jameycribbs/cribbnotes_cui). So far, I've been able to get pretty much everything working that I want, but I have run into an issue when saving a note to a json file. When I use the view.Buffer() method to grab the internal buffer, and I have view.Wrap=true, then the json file I save has all of the carriage returns that are getting inserted into the text because Wrap is set to true.

Is there any way to keep Wrap=true, but be able to grab the contents of the internal buffer without the carriage returns that are being inserted?

I took a look at the source code, but I didn't see a way to do this. I'm fairly new to Go, so I am probably missing something.

Thanks for any help you can give and thanks again for such a great library!

Jamey Cribbs

Keybinding prints key when switching to editable view.

I am trying to write some code that edits a view with vim like key-bindings. The problem I am running into is the key I press is also getting inserted. I have put together some test code to hopefully explain better.

package main

import (
    "log"
    "github.com/jroimartin/gocui"
)

func edit(g *gocui.Gui, v *gocui.View) error {
    v.Editable = true
    return nil
}

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

func keybindings(g *gocui.Gui) error {
    if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {return err}
    if err := g.SetKeybinding("main", 'i', gocui.ModNone, edit); err != nil {return err}

    return nil
}


func layout(g *gocui.Gui) error {
    maxX, maxY := g.Size()
    if v, err := g.SetView("main", 30, -1, maxX, maxY); err != nil {
        if err != gocui.ErrUnknownView {
            return err
        }

        v.Editable = false
        v.Wrap = true
        if _, err := g.SetCurrentView("main"); err != nil {return err}
    }
    return nil
}

func main() {
    g, _ := gocui.NewGui()
    defer g.Close()

    g.SetManagerFunc(layout)
    keybindings(g); 
    g.Cursor = true

    if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {log.Panicln(err)}
}

What happens is when I press the 'i' key to change the main view from not-Editable to Editable it also inserts an i character. Is there a way to prevent this?

Thank you for any help!

On OSX, ESC sequences corresponding to mouse events are not correctly parsed by termbox-go

This is not a bug in gocui. It should be fixed in OSX (making iTerm2/Terminal.app's xterm emulation to send ESC sequences atomically) or in termbox-go (supporting the way used by iTerm2/Terminal.app to report mouse events).

More information: nsf/termbox-go#120

On OSX, when Gui.Mouse is enabled and the focus is in an editable buffer, if the terminal receives mouse events, the event loop receives an EventKey for each byte of the ESC sequence that corresponds to the mouse event. Because it is an editable buffer, these sequences end up being written in the buffer, as can be seen in the following screenshot:

screenshot

This happens because iTerm2 or Terminal.app do not send the ESC sequence atomically.

question about windows level

Hello.

I made some roughing (but working well) code to close issue #3.

But with an independent View'ers redraw, I have a some troubles with the windows hierarchy.
If we create, for example, first window (at level "0") and second on top of previous (at level "1"), then inactive "top level" window may fall through under level "0" (in situation, when level "0" need redraw, and level "1" dosen' need, but we want level "1" on top).

I see several solutions to this situation:

  1. add "window level" politic (windows can have some "window level" option, and redrawn based on these rules);
  2. or add simple "always on top" rule;

I need a strong opinion of the author of the project :)

PS: sorry for my bad English

How do I update a view from another goroutine?

I have a top-like application that updates views vi coroutines. I am able to update the views fine but get panic (panic: bytes.Buffer: truncation out of range) when the terminal is reset. I notice that if I do not call flush from my update code the error does not occur, but the ui does not refresh until an event is processed. How do I correctly signal to gocui that a view has changed?

view titles

hi,

is there a way to add a title to the view?
If not, that'd be nice to have, it can be in the same level as the frame like https://github.com/gizak/termui does.

The syntax could be something like this:

if v, err := g.SetView(...); err != nil {
    v.Title = "Title"
    v.TitleAlign = "left|right|center"
}

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.