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(n) contains "\x00" at end #69

Closed kkellner closed 7 years ago

kkellner commented 8 years ago

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)

jroimartin commented 8 years ago

Can you confirm if it only happens with lines that have been manually written in editable Views?

If so, it's closely related to #60 and should be fixed once that issue is closed. On the other hand, rewriting the edition mode is in progress and (hopefully) will be merged soon.

kkellner commented 8 years ago

Confirmed -- this is only happening with view's that have editors attached.

FYI, my use case is creating a "field widget" to enter 1 line of short text, like a input field on a web page. It will have a label, a fieldName and a maxLength. This will create two views, 1 that will contain the field label and another 1 row view that will be used for the field entry text.

I wrappered the exiting editor to handle the complex part of editing, but my wrapper simple ignores up/down arrows and prevents text beyond maxLength for the field. This is also why the other enhancement request to allow a zero frame view. Let me know if I'm making this too complex and if there is a better way to do this.

jroimartin commented 8 years ago

What about doing it this way?

https://gist.github.com/jroimartin/3b2e943a3811d795e0718b4a95b89bec

jroimartin commented 8 years ago

Please, take into account that I did several simplifications, but should be enough to get an idea :)

kkellner commented 8 years ago

Your example is pretty close, however it doesn't allow for arrow keys for editing text already typed into the field. My version used a wrapper around the DefaultEditor to do any special processing on keystrocks, then pass them onto the DefaultEditor as I didn't want to deal with the complexity of processing the arrow keys, insert, etc. Below was my func... a bit ugly with debug code in. Your solution was cleaner -- if it could handle the full editing of the field.

func (w MyEditor) Edit(v gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) { lineValue, _ := v.Line(0) lineValue = strings.Replace(lineValue, "\x00", "", -1) currentSize := len(lineValue) atMax := false if currentSize >= w.MaxFieldSize { atMax = true } fmt.Printf("\n[%v], currentSize:%v atMax:%v ", lineValue, currentSize, atMax)

switch { case key == gocui.KeyArrowRight: x, _ := v.Cursor() fmt.Printf("\nx:%v", x) if x < currentSize { w.baseEditor.Edit(v, key, ch, mod) } case key == gocui.KeyArrowLeft: fallthrough case key == gocui.KeyBackspace || key == gocui.KeyBackspace2: fallthrough case key == gocui.KeyDelete: fallthrough case key == gocui.KeyInsert: w.baseEditor.Edit(v, key, ch, mod) case key == gocui.KeyEnter: // v.EditNewLine() case key == gocui.KeyArrowDown: // v.MoveCursor(0, 1, false) case key == gocui.KeyArrowUp: // v.MoveCursor(0, -1, false) default: if !atMax { //fmt.Printf("key:[%v] ch:[%v]", key, ch ) w.baseEditor.Edit(v, key, ch, mod) } }

}

jroimartin commented 8 years ago

Yes, I tried to keep the snippet as simple as possible and focus on how to create widgets and so on. Definitely, the new edition mode should make easier to customize this kind of things.

jroimartin commented 7 years ago

Fixed via 2677ad04454bb2a43069dda0675b602b0ec2c14c. Can you check? :)