Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
ERnsTL opened this issue Aug 15, 2016 · 5 comments
Closed

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

ERnsTL opened this issue Aug 15, 2016 · 5 comments
Assignees
Labels
Milestone

Comments

@ERnsTL
Copy link

ERnsTL commented Aug 15, 2016

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
}
@jroimartin
Copy link
Owner

You are right, looks like a bug. I'll try to fix it as soon as possible.

On the other hand, I want to rewrite the edition mode from scratch and this bug is quite related, so it should be addressed as soon as the new edition mode is in place.

Thanks for reporting it!

@jroimartin jroimartin added this to the gocui v0.3 milestone Aug 30, 2016
@jroimartin jroimartin added the bug label Aug 30, 2016
@jroimartin jroimartin self-assigned this Aug 30, 2016
@tkausl
Copy link

tkausl commented Oct 6, 2016

I came across the same problem today, the problem seems to be that the handlers are executed after the key was already put in to the field, hence it reads the last (now empty) line. It would be great if handlers were called before any other action happens and - even better - if they could prevent further actions (as in not putting them in the edit-field).

jroimartin added a commit that referenced this issue Oct 11, 2016
@jroimartin
Copy link
Owner

jroimartin commented Oct 11, 2016

@tkausl is right. v.Line return the line in the position y (relative to the view's origin). Initially v.Line(0) points to the internal line 0 because the origin is (0, 0); but, once you press enter, a new line is inserter and the origin is moved to (0, 1) so v.Line(0) points to internal line 1 when the keybinding handler is executed.

After 76554e4 handlers are executed before edition (for key events) and after mouse actions. However I'm not sure about preventing further actions... In that case, it would be better to use a non-editing keybinding or setting v.Edition = false temporarily.

What do you think?

@jroimartin
Copy link
Owner

jroimartin commented Oct 26, 2016

@tkausl can you check PR #66? :)

@tkausl
Copy link

tkausl commented Oct 26, 2016

Looks good for a start

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants