Skip to content

Commit

Permalink
Improve stability for inserting symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
ksysoev committed Oct 21, 2023
1 parent 715faf9 commit 79a70c3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 36 deletions.
60 changes: 35 additions & 25 deletions pkg/cli/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -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' {
Expand Down Expand Up @@ -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
}
Expand Down
27 changes: 16 additions & 11 deletions pkg/cli/content_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ func TestContent_InsertSymbol(t *testing.T) {
contentAfter string
symbol rune
pos int
posAfter int
}{
{
name: "insert at the end",
Expand All @@ -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",
Expand All @@ -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
Expand All @@ -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,
},
}

Expand All @@ -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)
}
})
}
Expand Down

0 comments on commit 79a70c3

Please sign in to comment.