Skip to content

Commit

Permalink
Merge branch 'readline_keys'
Browse files Browse the repository at this point in the history
  • Loading branch information
akavel committed Dec 4, 2018
2 parents 63f291e + 8127fd5 commit 85e85fd
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 12 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Please keep the contents of this file sorted alphabetically.

Calum MacRae <[email protected]>
Mateusz Czapliński <[email protected]>
Rohan Verma <[email protected]>
48 changes: 36 additions & 12 deletions up.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import (
"github.com/spf13/pflag"
)

const version = "0.3.1 (2018-10-31)"
const version = "0.3.2 (2018-12-04)"

// TODO: in case of error, show it in red (bg?), then below show again initial normal output (see also #4)
// TODO: F1 should display help, and it should be multi-line, and scrolling licensing credits
Expand Down Expand Up @@ -283,9 +283,10 @@ func NewEditor(prompt string) *Editor {

type Editor struct {
// TODO: make editor multiline. Reuse gocui or something for this?
prompt []rune
value []rune
cursor int
prompt []rune
value []rune
killspace []rune
cursor int
// lastw is length of value on last Draw; we need it to know how much to erase after backspace
lastw int
}
Expand Down Expand Up @@ -326,27 +327,43 @@ func (e *Editor) HandleKey(ev *tcell.EventKey) bool {
e.delete(-1)
case key(tcell.KeyDelete):
e.delete(0)
case key(tcell.KeyLeft):
case key(tcell.KeyLeft),
key(tcell.KeyCtrlB),
ctrlKey(tcell.KeyCtrlB):
if e.cursor > 0 {
e.cursor--
}
case key(tcell.KeyRight):
case key(tcell.KeyRight),
key(tcell.KeyCtrlF),
ctrlKey(tcell.KeyCtrlF):
if e.cursor < len(e.value) {
e.cursor++
}
case key(tcell.KeyCtrlA),
ctrlKey(tcell.KeyCtrlA):
e.cursor = 0
case key(tcell.KeyCtrlE),
ctrlKey(tcell.KeyCtrlE):
e.cursor = len(e.value)
case key(tcell.KeyCtrlK),
ctrlKey(tcell.KeyCtrlK):
e.kill()
case key(tcell.KeyCtrlY),
ctrlKey(tcell.KeyCtrlY):
e.insert(e.killspace...)
default:
// Unknown key/combination, not handled
return false
}
return true
}

func (e *Editor) insert(ch rune) {
// Insert character into value (https://github.com/golang/go/wiki/SliceTricks#insert)
e.value = append(e.value, 0)
copy(e.value[e.cursor+1:], e.value[e.cursor:])
e.value[e.cursor] = ch
e.cursor++
func (e *Editor) insert(ch ...rune) {
// Based on https://github.com/golang/go/wiki/SliceTricks#insert
e.value = append(e.value, ch...) // = PREFIX + SUFFIX + (filler)
copy(e.value[e.cursor+len(ch):], e.value[e.cursor:]) // = PREFIX + (filler) + SUFFIX
copy(e.value[e.cursor:], ch) // = PREFIX + ch + SUFFIX
e.cursor += len(ch)
}

func (e *Editor) delete(dx int) {
Expand All @@ -358,6 +375,13 @@ func (e *Editor) delete(dx int) {
e.cursor = pos
}

func (e *Editor) kill() {
if e.cursor != len(e.value) {
e.killspace = append(e.killspace[:0], e.value[e.cursor:]...)
}
e.value = e.value[:e.cursor]
}

type BufView struct {
// TODO: Wrap bool
Y int // Y of the view in the Buf, for down/up scrolling
Expand Down
83 changes: 83 additions & 0 deletions up_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package main

import "testing"

func Test_Editor_insert(test *testing.T) {
cases := []struct {
comment string
e Editor
insert []rune
wantValue []rune
}{
{
comment: "prepend ASCII char",
e: Editor{
value: []rune(`abc`),
cursor: 0,
},
insert: []rune{'X'},
wantValue: []rune(`Xabc`),
},
{
comment: "prepend UTF char",
e: Editor{
value: []rune(`abc`),
cursor: 0,
},
insert: []rune{'☃'},
wantValue: []rune(`☃abc`),
},
{
comment: "insert ASCII char",
e: Editor{
value: []rune(`abc`),
cursor: 1,
},
insert: []rune{'X'},
wantValue: []rune(`aXbc`),
},
{
comment: "insert UTF char",
e: Editor{
value: []rune(`abc`),
cursor: 1,
},
insert: []rune{'☃'},
wantValue: []rune(`a☃bc`),
},
{
comment: "append ASCII char",
e: Editor{
value: []rune(`abc`),
cursor: 3,
},
insert: []rune{'X'},
wantValue: []rune(`abcX`),
},
{
comment: "append UTF char",
e: Editor{
value: []rune(`abc`),
cursor: 3,
},
insert: []rune{'☃'},
wantValue: []rune(`abc☃`),
},
{
comment: "insert 2 ASCII chars",
e: Editor{
value: []rune(`abc`),
cursor: 1,
},
insert: []rune{'X', 'Y'},
wantValue: []rune(`aXYbc`),
},
}

for _, c := range cases {
c.e.insert(c.insert...)
if string(c.e.value) != string(c.wantValue) {
test.Errorf("%q: bad value\nwant: %q\nhave: %q", c.comment, c.wantValue, c.e.value)
}
}
}

0 comments on commit 85e85fd

Please sign in to comment.