mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 22:28:24 +02:00
Code to move cursor left
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/wcswidth"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
@@ -90,3 +91,32 @@ func (self *Readline) add_text(text string) {
|
||||
}
|
||||
self.lines = new_lines
|
||||
}
|
||||
|
||||
func (self *Readline) move_cursor_left(amt uint, traverse_line_breaks bool) uint {
|
||||
var amt_moved uint
|
||||
for ; amt > 0; amt -= 1 {
|
||||
if self.cursor_pos_in_line == 0 {
|
||||
if !traverse_line_breaks || self.cursor_line == 0 {
|
||||
return amt_moved
|
||||
}
|
||||
self.cursor_line -= 1
|
||||
self.cursor_pos_in_line = len(self.lines[self.cursor_pos_in_line])
|
||||
amt_moved += 1
|
||||
continue
|
||||
}
|
||||
// This is an extremely inefficient algorithm but it does not matter since
|
||||
// lines are not large.
|
||||
line := self.lines[self.cursor_line]
|
||||
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(runes) > 0 {
|
||||
runes = runes[:len(runes)-1]
|
||||
s := string(runes)
|
||||
current_width = wcswidth.Stringwidth(s)
|
||||
}
|
||||
self.cursor_pos_in_line = len(string(runes))
|
||||
amt_moved += 1
|
||||
}
|
||||
return amt_moved
|
||||
}
|
||||
|
||||
@@ -10,10 +10,9 @@ import (
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
func TestAddText(t *testing.T) {
|
||||
lp, _ := loop.New()
|
||||
|
||||
dt := func(initial string, prepare func(rl *Readline), expected ...string) {
|
||||
func test_func(t *testing.T) func(string, func(*Readline), ...string) *Readline {
|
||||
return func(initial string, prepare func(rl *Readline), expected ...string) *Readline {
|
||||
lp, _ := loop.New()
|
||||
rl := New(lp, RlInit{})
|
||||
rl.add_text(initial)
|
||||
if prepare != nil {
|
||||
@@ -34,8 +33,13 @@ func TestAddText(t *testing.T) {
|
||||
t.Fatalf("Text not as expected for: %#v\n%#v != %#v", initial, expected[2], rl.all_text())
|
||||
}
|
||||
}
|
||||
return rl
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestAddText(t *testing.T) {
|
||||
dt := test_func(t)
|
||||
dt("test", nil, "test", "", "test")
|
||||
dt("1234\n", nil, "1234\n", "", "1234\n")
|
||||
dt("abcd", func(rl *Readline) {
|
||||
@@ -50,5 +54,36 @@ func TestAddText(t *testing.T) {
|
||||
rl.cursor_pos_in_line = 2
|
||||
rl.add_text("12\n34")
|
||||
}, "abcd\nxy12\n34", "z", "abcd\nxy12\n34z")
|
||||
|
||||
}
|
||||
|
||||
func TestCursorMovement(t *testing.T) {
|
||||
dt := test_func(t)
|
||||
|
||||
left := func(rl *Readline, amt uint, moved_amt uint, traverse_line_breaks bool) {
|
||||
actual := rl.move_cursor_left(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) {
|
||||
left(rl, 2, 2, false)
|
||||
}, "one\nt", "wo")
|
||||
dt("one\ntwo", func(rl *Readline) {
|
||||
left(rl, 4, 3, false)
|
||||
}, "one\n", "two")
|
||||
dt("one\ntwo", func(rl *Readline) {
|
||||
left(rl, 4, 4, true)
|
||||
}, "one", "\ntwo")
|
||||
dt("one\ntwo", func(rl *Readline) {
|
||||
left(rl, 7, 7, true)
|
||||
}, "", "one\ntwo")
|
||||
dt("one\ntwo", func(rl *Readline) {
|
||||
left(rl, 10, 7, true)
|
||||
}, "", "one\ntwo")
|
||||
dt("one😀", func(rl *Readline) {
|
||||
left(rl, 1, 1, false)
|
||||
}, "one", "😀")
|
||||
dt("oneä", func(rl *Readline) {
|
||||
left(rl, 1, 1, false)
|
||||
}, "one", "ä")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user