From bf7dd1c369957851012df7f454b43a1c356ca379 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 7 Oct 2022 13:23:35 +0530 Subject: [PATCH] Fix multiline prompts --- tools/cmd/at/shell.go | 3 ++- tools/tui/readline/api.go | 5 +++++ tools/tui/readline/draw.go | 14 +++++++------- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/tools/cmd/at/shell.go b/tools/cmd/at/shell.go index 183838d7a..4c997c9b7 100644 --- a/tools/cmd/at/shell.go +++ b/tools/cmd/at/shell.go @@ -56,8 +56,9 @@ func shell_loop(rl *readline.Readline, kill_if_signaled bool) (int, error) { return nil } if err == readline.ErrAcceptInput { - if strings.HasSuffix(rl.TextBeforeCursor(), "\\") && strings.HasPrefix(rl.TextAfterCursor(), "\n") { + if strings.HasSuffix(rl.TextBeforeCursor(), "\\") && rl.CursorAtEndOfLine() { rl.OnText("\n", false, false) + rl.Redraw() return nil } return ErrExec diff --git a/tools/tui/readline/api.go b/tools/tui/readline/api.go index 1da1a76d6..5a0d62630 100644 --- a/tools/tui/readline/api.go +++ b/tools/tui/readline/api.go @@ -73,6 +73,7 @@ func New(loop *loop.Loop, r RlInit) *Readline { ans.continuation_prompt = "> " } } + ans.continuation_prompt_len = wcswidth.Stringwidth(ans.continuation_prompt) if ans.mark_prompts { ans.prompt = PROMPT_MARK + "A" + ST + ans.prompt ans.continuation_prompt = PROMPT_MARK + "A;k=s" + ST + ans.continuation_prompt @@ -141,3 +142,7 @@ func (self *Readline) TextAfterCursor() string { func (self *Readline) AllText() string { return self.all_text() } + +func (self *Readline) CursorAtEndOfLine() bool { + return self.cursor.X >= len(self.lines[self.cursor.Y]) +} diff --git a/tools/tui/readline/draw.go b/tools/tui/readline/draw.go index 47629e6ad..2a24a4660 100644 --- a/tools/tui/readline/draw.go +++ b/tools/tui/readline/draw.go @@ -18,9 +18,7 @@ func (self *Readline) write_line_with_prompt(line, prompt string, screen_width i func (self *Readline) move_cursor_to_text_position(pos, screen_width int) int { num_of_lines := pos / screen_width - if num_of_lines > 0 { - self.loop.MoveCursorVertically(num_of_lines) - } + self.loop.MoveCursorVertically(num_of_lines) self.loop.QueueWriteString("\r") x := pos % screen_width self.loop.MoveCursorHorizontally(x) @@ -33,23 +31,25 @@ func (self *Readline) redraw() { } self.loop.QueueWriteString("\r") self.loop.ClearToEndOfScreen() - y := 0 line_with_cursor := 0 screen_size, err := self.loop.ScreenSize() if err != nil { screen_size.WidthCells = 80 screen_size.HeightCells = 24 } + screen_width := int(screen_size.WidthCells) + y := 0 for i, line := range self.lines { p := self.prompt if i > 0 { + y += 1 + self.loop.QueueWriteString("\r\n") p = self.continuation_prompt } - num_lines := self.write_line_with_prompt(line, p, int(screen_size.WidthCells)) if i == self.cursor.Y { line_with_cursor = y } - y += num_lines + y += self.write_line_with_prompt(line, p, screen_width) } self.loop.MoveCursorVertically(-y + line_with_cursor) line := self.lines[self.cursor.Y] @@ -57,6 +57,6 @@ func (self *Readline) redraw() { if self.cursor.Y > 0 { plen = self.continuation_prompt_len } - line_with_cursor += self.move_cursor_to_text_position(plen+wcswidth.Stringwidth(line[:self.cursor.X]), int(screen_size.WidthCells)) + line_with_cursor += self.move_cursor_to_text_position(plen+wcswidth.Stringwidth(line[:self.cursor.X]), screen_width) self.cursor_y = line_with_cursor }