refactor(ansi): count text correctly

This commit is contained in:
Jan De Dobbeleer 2023-01-05 11:46:02 +01:00 committed by Jan De Dobbeleer
parent f1b1a72868
commit 0ebd59297b
3 changed files with 52 additions and 1 deletions

View file

@ -305,7 +305,6 @@ func (w *Writer) Write(background, foreground, text string) {
s := w.runes[i]
// ignore everything which isn't overriding
if s != '<' {
w.length += runewidth.RuneWidth(s)
w.write(i, s)
continue
}

View file

@ -6,11 +6,13 @@ import (
"github.com/jandedobbeleer/oh-my-posh/regex"
"github.com/jandedobbeleer/oh-my-posh/shell"
"github.com/mattn/go-runewidth"
)
func (w *Writer) write(i int, s rune) {
// ignore the logic when there is no hyperlink
if !w.hasHyperlink {
w.length += runewidth.RuneWidth(s)
w.builder.WriteRune(s)
return
}
@ -22,6 +24,7 @@ func (w *Writer) write(i int, s rune) {
}
if w.state == OTHER {
w.length += runewidth.RuneWidth(s)
w.builder.WriteRune(s)
return
}
@ -62,6 +65,9 @@ func (w *Writer) replaceHyperlink(text string) string {
return text
}
// we only care about the length of the text part
w.length += runewidth.StringWidth(results["TEXT"])
if w.Plain {
return results["TEXT"]
}

View file

@ -204,3 +204,49 @@ func TestWriteANSIColors(t *testing.T) {
assert.Equal(t, tc.Expected, got, tc.Case)
}
}
func TestWriteLength(t *testing.T) {
cases := []struct {
Case string
Expected int
Input string
Colors *cachedColor
}{
{
Case: "Bold",
Input: "<b>test</b>",
Expected: 4,
Colors: &cachedColor{Foreground: "black", Background: ParentBackground},
},
{
Case: "Bold with color override",
Input: "<b><#ffffff>test</></b>",
Expected: 4,
Colors: &cachedColor{Foreground: "black", Background: ParentBackground},
},
{
Case: "Bold with color override and link",
Input: "<b><#ffffff>test</></b> [url](https://example.com)",
Expected: 8,
Colors: &cachedColor{Foreground: "black", Background: ParentBackground},
},
{
Case: "Bold with color override and link and leading/trailing spaces",
Input: " <b><#ffffff>test</></b> [url](https://example.com) ",
Expected: 10,
Colors: &cachedColor{Foreground: "black", Background: ParentBackground},
},
}
for _, tc := range cases {
renderer := &Writer{
ParentColors: []*cachedColor{},
Colors: tc.Colors,
AnsiColors: &DefaultColors{},
}
renderer.Init(shell.GENERIC)
renderer.Write(tc.Colors.Background, tc.Colors.Foreground, tc.Input)
_, got := renderer.String()
assert.Equal(t, tc.Expected, got, tc.Case)
}
}