diff --git a/tools/tui/readline/actions.go b/tools/tui/readline/actions.go index 3f9ad8d84..555b348fd 100644 --- a/tools/tui/readline/actions.go +++ b/tools/tui/readline/actions.go @@ -42,7 +42,9 @@ func (self *Readline) text_after_cursor_pos() string { } } ans := buf.String() - ans = ans[:len(ans)-1] + if ans != "" { + ans = ans[:len(ans)-1] + } return ans } @@ -465,6 +467,9 @@ func (self *Readline) yank(repeat_count uint, pop bool) bool { func (self *Readline) apply_history_text(text string) { self.lines = utils.Splitlines(text) + if len(self.lines) == 0 { + self.lines = []string{""} + } } func (self *Readline) history_first() bool { diff --git a/tools/tui/readline/actions_test.go b/tools/tui/readline/actions_test.go index 4cd8f85b4..71936f6a8 100644 --- a/tools/tui/readline/actions_test.go +++ b/tools/tui/readline/actions_test.go @@ -373,3 +373,51 @@ func TestEraseChars(t *testing.T) { rl.erase_between(Position{X: 1}, Position{X: 2, Y: 2}) }, "", "oree") } + +func TestHistory(t *testing.T) { + lp, _ := loop.New() + rl := New(lp, RlInit{Prompt: "$$ "}) + + add_item := func(x string) { + rl.history.AddItem(x, 0) + } + add_item("a one") + add_item("a two") + add_item("b three") + add_item("b four") + + test := func(ac Action, before_cursor, after_cursor string) { + rl.perform_action(ac, 1) + if diff := cmp.Diff(before_cursor, rl.text_upto_cursor_pos()); diff != "" { + t.Fatalf("The text before the cursor was not as expected for action: %#v\n%s", ac, diff) + } + if diff := cmp.Diff(after_cursor, rl.text_after_cursor_pos()); diff != "" { + t.Fatalf("The text after the cursor was not as expected for action: %#v\n%s", ac, diff) + } + } + + test(ActionHistoryPrevious, "", "b four") + test(ActionHistoryPrevious, "", "b three") + test(ActionHistoryPrevious, "", "a two") + test(ActionHistoryPrevious, "", "a one") + test(ActionHistoryPrevious, "", "a one") + test(ActionHistoryNext, "", "a two") + test(ActionHistoryNext, "", "b three") + test(ActionHistoryNext, "", "b four") + test(ActionHistoryNext, "", "") + test(ActionHistoryNext, "", "") + + test(ActionHistoryPrevious, "", "b four") + test(ActionHistoryPrevious, "", "b three") + test(ActionHistoryNext, "", "b four") + + rl.ResetText() + rl.add_text("a") + test(ActionHistoryPrevious, "a", " two") + test(ActionHistoryPrevious, "a", " one") + test(ActionHistoryPrevious, "a", " one") + test(ActionHistoryNext, "a", " two") + test(ActionHistoryNext, "a", "") + test(ActionHistoryNext, "a", "") + +} diff --git a/tools/tui/readline/history.go b/tools/tui/readline/history.go index f7a1db2a1..c182c11ae 100644 --- a/tools/tui/readline/history.go +++ b/tools/tui/readline/history.go @@ -159,6 +159,7 @@ func NewHistory(path string, max_items int) *History { func (self *History) FindPrefixMatches(prefix, current_command string) *HistoryMatches { ans := HistoryMatches{items: make([]HistoryItem, 0, len(self.items)+1), prefix: prefix} if prefix == "" { + ans.items = ans.items[:len(self.items)] copy(ans.items, self.items) } else { for _, x := range self.items {