mirror of
https://github.com/junegunn/fzf.git
synced 2026-09-13 22:52:01 +08:00
Fix --gap-line cutting a grapheme cluster
RepeatToFill filled the remaining width rune by rune, so a cluster could be split at the right edge. Iterate grapheme clusters instead. Fix #4920
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
0.74.5
|
||||
------
|
||||
- Fixed `--gap-line` cutting a grapheme cluster when filling the last cells of the line (#4920)
|
||||
|
||||
0.74.4
|
||||
------
|
||||
- Fixed an escape sequence split across reads being parsed as a fragment, which leaked the rest into the query (#4899)
|
||||
|
||||
+9
-7
@@ -105,16 +105,18 @@ func RepeatToFill(str string, length int, limit int) string {
|
||||
rest := limit % length
|
||||
output := strings.Repeat(str, times)
|
||||
if rest > 0 {
|
||||
for _, r := range str {
|
||||
rest -= uniseg.StringWidth(string(r))
|
||||
if rest < 0 {
|
||||
break
|
||||
}
|
||||
output += string(r)
|
||||
if rest == 0 {
|
||||
// Iterate over grapheme clusters so that we don't cut a cluster in half
|
||||
end := 0
|
||||
graphemes := uniseg.NewGraphemes(str)
|
||||
for rest > 0 && graphemes.Next() {
|
||||
width := graphemes.Width()
|
||||
if width > rest {
|
||||
break
|
||||
}
|
||||
rest -= width
|
||||
_, end = graphemes.Positions()
|
||||
}
|
||||
output += str[:end]
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
@@ -109,6 +109,27 @@ func TestRepeatToFill(t *testing.T) {
|
||||
if RepeatToFill("abcde", 10, 42) != strings.Repeat("abcde", 4)+"abcde"[:2] {
|
||||
t.Error("Expected:", strings.Repeat("abcde", 4)+"abcde"[:2])
|
||||
}
|
||||
|
||||
// Should not cut a grapheme cluster in half
|
||||
for _, test := range []struct {
|
||||
str string
|
||||
limit int
|
||||
expected string
|
||||
}{
|
||||
{"a\u0301b", 1, "a\u0301"},
|
||||
{"a\u0301b", 3, "a\u0301ba\u0301"},
|
||||
{"a\u0301b", 4, "a\u0301ba\u0301b"},
|
||||
{"a\u4e00", 2, "a"},
|
||||
{"a\u4e00", 4, "a\u4e00a"},
|
||||
{"-\U0001f468\u200d\U0001f469\u200d\U0001f467", 1, "-"},
|
||||
{"-\U0001f468\u200d\U0001f469\u200d\U0001f467", 2, "-"},
|
||||
{"-\U0001f468\u200d\U0001f469\u200d\U0001f467", 4, "-\U0001f468\u200d\U0001f469\u200d\U0001f467-"},
|
||||
} {
|
||||
actual := RepeatToFill(test.str, StringWidth(test.str), test.limit)
|
||||
if actual != test.expected {
|
||||
t.Errorf("Expected: %q, actual: %q", test.expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringWidth(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user