Code to move cursor right
This commit is contained in:
parent
57310a772a
commit
5e5cae8391
@ -120,3 +120,43 @@ func (self *Readline) move_cursor_left(amt uint, traverse_line_breaks bool) uint
|
|||||||
}
|
}
|
||||||
return amt_moved
|
return amt_moved
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Readline) move_cursor_right(amt uint, traverse_line_breaks bool) uint {
|
||||||
|
var amt_moved uint
|
||||||
|
for ; amt > 0; amt -= 1 {
|
||||||
|
line := self.lines[self.cursor_line]
|
||||||
|
if self.cursor_pos_in_line >= len(line) {
|
||||||
|
if !traverse_line_breaks || self.cursor_line == len(self.lines)-1 {
|
||||||
|
return amt_moved
|
||||||
|
}
|
||||||
|
self.cursor_line += 1
|
||||||
|
self.cursor_pos_in_line = 0
|
||||||
|
amt_moved += 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// This is an extremely inefficient algorithm but it does not matter since
|
||||||
|
// lines are not large.
|
||||||
|
before_runes := []rune(line[:self.cursor_pos_in_line])
|
||||||
|
after_runes := []rune(line[self.cursor_pos_in_line:])
|
||||||
|
orig_width := wcswidth.Stringwidth(line[:self.cursor_pos_in_line])
|
||||||
|
current_width := orig_width
|
||||||
|
for current_width == orig_width && len(after_runes) > 0 {
|
||||||
|
before_runes = append(before_runes, after_runes[0])
|
||||||
|
current_width = wcswidth.Stringwidth(string(before_runes))
|
||||||
|
after_runes = after_runes[1:]
|
||||||
|
}
|
||||||
|
// soak up any more runes that dont affect width
|
||||||
|
for len(after_runes) > 0 {
|
||||||
|
q := append(before_runes, after_runes[0])
|
||||||
|
w := wcswidth.Stringwidth(string(q))
|
||||||
|
if w != current_width {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
after_runes = after_runes[1:]
|
||||||
|
before_runes = q
|
||||||
|
}
|
||||||
|
self.cursor_pos_in_line = len(string(before_runes))
|
||||||
|
amt_moved += 1
|
||||||
|
}
|
||||||
|
return amt_moved
|
||||||
|
}
|
||||||
|
|||||||
@ -83,7 +83,31 @@ func TestCursorMovement(t *testing.T) {
|
|||||||
dt("one😀", func(rl *Readline) {
|
dt("one😀", func(rl *Readline) {
|
||||||
left(rl, 1, 1, false)
|
left(rl, 1, 1, false)
|
||||||
}, "one", "😀")
|
}, "one", "😀")
|
||||||
dt("oneä", func(rl *Readline) {
|
dt("oneà", func(rl *Readline) {
|
||||||
left(rl, 1, 1, false)
|
left(rl, 1, 1, false)
|
||||||
}, "one", "ä")
|
}, "one", "à")
|
||||||
|
|
||||||
|
right := func(rl *Readline, amt uint, moved_amt uint, traverse_line_breaks bool) {
|
||||||
|
rl.cursor_line = 0
|
||||||
|
rl.cursor_pos_in_line = 0
|
||||||
|
actual := rl.move_cursor_right(amt, traverse_line_breaks)
|
||||||
|
if actual != moved_amt {
|
||||||
|
t.Fatalf("Failed to move cursor by %#v\nactual != expected: %#v != %#v", amt, actual, moved_amt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dt("one\ntwo", func(rl *Readline) {
|
||||||
|
right(rl, 2, 2, false)
|
||||||
|
}, "on", "e\ntwo")
|
||||||
|
dt("one\ntwo", func(rl *Readline) {
|
||||||
|
right(rl, 4, 3, false)
|
||||||
|
}, "one", "\ntwo")
|
||||||
|
dt("one\ntwo", func(rl *Readline) {
|
||||||
|
right(rl, 4, 4, true)
|
||||||
|
}, "one\n", "two")
|
||||||
|
dt("😀one", func(rl *Readline) {
|
||||||
|
right(rl, 1, 1, false)
|
||||||
|
}, "😀", "one")
|
||||||
|
dt("àb", func(rl *Readline) {
|
||||||
|
right(rl, 1, 1, false)
|
||||||
|
}, "à", "b")
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user