From f8ab6299860deb9971689cbdfc597b07515ec87b Mon Sep 17 00:00:00 2001 From: Henrixounez <30901439+Henrixounez@users.noreply.github.com> Date: Sun, 10 Nov 2019 17:33:21 +0100 Subject: [PATCH] readline: fix cursor position with prompt including ansi escape sequences --- vlib/readline/readline.v | 1 + vlib/readline/readline_linux.v | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/vlib/readline/readline.v b/vlib/readline/readline.v index b7f478e8ef..47a8912fce 100644 --- a/vlib/readline/readline.v +++ b/vlib/readline/readline.v @@ -36,6 +36,7 @@ mut: overwrite bool cursor_row_offset int prompt string + prompt_offset int previous_lines []ustring search_index int is_tty bool diff --git a/vlib/readline/readline_linux.v b/vlib/readline/readline_linux.v index 42b3541d29..759df0cf04 100644 --- a/vlib/readline/readline_linux.v +++ b/vlib/readline/readline_linux.v @@ -93,6 +93,7 @@ pub fn (r mut Readline) read_line_utf8(prompt string) ?ustring { r.cursor = 0 r.prompt = prompt r.search_index = 0 + r.prompt_offset = get_prompt_offset(prompt) if r.previous_lines.len <= 1 { r.previous_lines << ''.ustring() r.previous_lines << ''.ustring() @@ -150,6 +151,19 @@ pub fn read_line(prompt string) ?string { return s } +fn get_prompt_offset(prompt string) int { + mut len := 0 + + for i := 0; i < prompt.len; i++ { + if prompt[i] == `\e` { + for ;i < prompt.len && prompt[i] != `m`; i++ {} + } else { + len = len + 1 + } + } + return prompt.len - len +} + fn (r Readline) analyse(c int) Action { match c { `\0` { return .eof } @@ -291,7 +305,7 @@ fn (r mut Readline) refresh_line() { if end_of_input[0] == 0 && end_of_input[1] > 0 { print('\n') } - shift_cursor(cursor_pos[0], - (end_of_input[1] - cursor_pos[1])) + shift_cursor(cursor_pos[0] - r.prompt_offset, - (end_of_input[1] - cursor_pos[1])) r.cursor_row_offset = cursor_pos[1] }