From 79a70c316ebb7091cfbeb13cd56f6084602276d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B8=D1=80=D0=B8=D0=BB=D0=BB=20=D0=A1=D1=8B=D1=81?= =?UTF-8?q?=D0=BE=D0=B5=D0=B2?= Date: Sat, 21 Oct 2023 21:35:06 +0800 Subject: [PATCH] Improve stability for inserting symbols --- pkg/cli/content.go | 60 ++++++++++++++++++++++++----------------- pkg/cli/content_test.go | 27 +++++++++++-------- 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/pkg/cli/content.go b/pkg/cli/content.go index 71011be..1cf6aa8 100644 --- a/pkg/cli/content.go +++ b/pkg/cli/content.go @@ -72,7 +72,8 @@ func (c *Content) Clear() string { return "" } - output := LineClear + "\r" + output := c.MoveToEnd() + output += LineClear + "\r" for i := 0; i < len(c.text); i++ { if c.text[i] == '\n' { @@ -127,42 +128,51 @@ func (c *Content) RemoveSymbol() string { } func (c *Content) InsertSymbol(symbol rune) string { + if c.pos < 0 || c.pos > len(c.text) { + return "" + } + + if c.pos == len(c.text) { + c.text = append(c.text, symbol) + c.pos++ + + return string(symbol) + } + buffer := make([]rune, c.pos, len(c.text)+1) copy(buffer, c.text[:c.pos]) buffer = append(buffer, symbol) - output := "" - - if symbol == '\n' && c.pos < len(c.text) { - endOfLine := lastIndexOf(c.text, c.pos, '\n') - if endOfLine == -1 { - endOfLine = len(c.text) - } + buffer = append(buffer, c.text[c.pos:]...) + c.pos++ + c.text = buffer - for i := c.pos; i <= endOfLine; i++ { - output += string(' ') - } + if symbol != '\n' && c.text[c.pos] == '\n' { + return string(symbol) } - output += string(symbol) + startCurrentLine, lines := c.GetLinesAfterPosition(c.pos - 1) + + if symbol != '\n' { + // here probably i have a room for optimization + endCurrentLine := startCurrentLine + len(lines[0]) + return LineClear + "\r" + string(c.text[startCurrentLine:endCurrentLine]) + "\r" + string(c.text[startCurrentLine:c.pos]) + } - if c.pos < len(c.text) { - buffer = append(buffer, c.text[c.pos:]...) - moveCursor := "" + output := "" - for i := c.pos; i < len(c.text); i++ { - if c.text[i] != '\n' { - output += string(c.text[i]) - moveCursor += "\b" - } else { - break - } + for i := 0; i < len(lines); i++ { + output += LineClear + "\r" + lines[i] + if i < len(lines)-1 { + output += "\n" } + } - output += moveCursor + // Move cursor back to position + for i := 2; i < len(lines); i++ { + output += LineUp } - c.text = buffer - c.pos++ + output += "\r" return output } diff --git a/pkg/cli/content_test.go b/pkg/cli/content_test.go index 64d2240..037249d 100644 --- a/pkg/cli/content_test.go +++ b/pkg/cli/content_test.go @@ -350,6 +350,7 @@ func TestContent_InsertSymbol(t *testing.T) { contentAfter string symbol rune pos int + posAfter int }{ { name: "insert at the end", @@ -358,36 +359,34 @@ func TestContent_InsertSymbol(t *testing.T) { pos: 11, output: "!", contentAfter: "hello world!", + posAfter: 12, }, { - // This test is not really correct, but it is how it works now - // TODO: fix this test name: "insert at the beginning", input: "hello world", symbol: '>', pos: 0, - output: ">hello world\b\b\b\b\b\b\b\b\b\b\b", + output: "\x1b[2K\r>hello world\r>", contentAfter: ">hello world", + posAfter: 1, }, { - // This test is not really correct, but it is how it works now - // TODO: fix this test name: "insert in the middle", input: "hello world", symbol: ',', pos: 5, - output: ", world\b\b\b\b\b\b", + output: "\x1b[2K\rhello, world\rhello,", contentAfter: "hello, world", + posAfter: 6, }, { - // This test is not really correct, but it is how it works now - // TODO: fix this test name: "insert newline in the middle", input: "hello\nworld", symbol: '\n', pos: 4, - output: " \no\b", + output: "\x1b[2K\rhell\n\x1b[2K\ro\n\x1b[2K\rworld\x1b[1A\r", contentAfter: "hell\no\nworld", + posAfter: 5, }, { name: "insert newline at the end", @@ -396,6 +395,7 @@ func TestContent_InsertSymbol(t *testing.T) { pos: 11, output: "\n", contentAfter: "hello world\n", + posAfter: 12, }, { // This test is not really correct, but it is how it works now @@ -404,8 +404,9 @@ func TestContent_InsertSymbol(t *testing.T) { input: "hello\nworld", symbol: '\n', pos: 0, - output: " \nhello\b\b\b\b\b", + output: "\x1b[2K\r\n\x1b[2K\rhello\n\x1b[2K\rworld\x1b[1A\r", contentAfter: "\nhello\nworld", + posAfter: 1, }, } @@ -427,7 +428,11 @@ func TestContent_InsertSymbol(t *testing.T) { } if string(content.text) != tt.contentAfter { - t.Errorf("expected text to be '%s', but got '%s'", tt.contentAfter, string(content.text)) + t.Errorf("expected text to be '%q', but got '%q'", tt.contentAfter, string(content.text)) + } + + if content.pos != tt.posAfter { + t.Errorf("expected position to be '%d', but got '%d'", tt.posAfter, content.pos) } }) }