jroimartin / gocui

Minimalist Go package aimed at creating Console User Interfaces.
BSD 3-Clause "New" or "Revised" License
9.92k stars 608 forks source link

view.Line() returns trailing \x00 byte #90

Closed ERnsTL closed 7 years ago

ERnsTL commented 7 years ago

Greetings,

In relation to issue #54, which is now fixed, there is an issue remaining: view.Line(0) returns the whole line and no second line exists in the Enter key handler, but there is a trailing \x00 = null byte returned by view.Line(0).

Test program for cut and paste; the issue shows up in function readToken:

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/jroimartin/gocui"
)

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

    g.SetManagerFunc(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, _ := v.Line(0)
    /*
    NOTE: second line does correctly not exist -> handlers are now correctly run before inserting newline automatically
    if line2, err := v.Line(1); err != nil {
      log.Fatalln("got expected error on access to non-existant line 2:", err)
    } else {
      fmt.Printf("received line 2! should not happen: >%s<, hex=%x, len=%d\n", line2, line2, len(line2))
    }
    */
    g.Close()
    // output shows \x00 byte at end
    fmt.Printf("user has entered: >%s<, hex=%x, len=%d\n", token, token, len(token))
    os.Exit(0)
    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 commented 7 years ago

Thanks for reporting the issue! Could it be the same issue as #69 ?

ERnsTL commented 7 years ago

With regards to how the issue manifests, yes, this seems to be the same issue, though above test program does not do any complex editing, just asks the user for a string and catches the Enter key.

ERnsTL commented 7 years ago

So the solution of this issue if I understand #69 correctly - depends on editing mode rewrite? Then it will be gone?

jroimartin commented 7 years ago

Exactly, the editing mode rewrite will fix these issues. BTW is it ok if I close this issue? We can continue the discussion in #69.

ERnsTL commented 7 years ago

Sure, I see this issue is also linked back, so closing is perfectly fine.