Skip to content

Commit

Permalink
Merge pull request #65 from tty2/feature/trim-prefix
Browse files Browse the repository at this point in the history
trim prefix
  • Loading branch information
mattn committed Sep 20, 2022
2 parents f9d5553 + 10a3ce9 commit 2c6a438
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
42 changes: 42 additions & 0 deletions runewidth.go
Expand Up @@ -2,6 +2,7 @@ package runewidth

import (
"os"
"strings"

"github.com/rivo/uniseg"
)
Expand Down Expand Up @@ -214,6 +215,42 @@ func (c *Condition) Truncate(s string, w int, tail string) string {
return s[:pos] + tail
}

// TruncateLeft cuts w cells from the beginning of the `s`.
func (c *Condition) TruncateLeft(s string, w int, prefix string) string {
if c.StringWidth(s) <= w {
return prefix
}

var width int
pos := len(s)

g := uniseg.NewGraphemes(s)
for g.Next() {
var chWidth int
for _, r := range g.Runes() {
chWidth = c.RuneWidth(r)
if chWidth > 0 {
break // See StringWidth() for details.
}
}

if width+chWidth > w {
if width < w {
_, pos = g.Positions()
prefix += strings.Repeat(" ", width+chWidth-w)
} else {
pos, _ = g.Positions()
}

break
}

width += chWidth
}

return prefix + s[pos:]
}

// Wrap return string wrapped with w cells
func (c *Condition) Wrap(s string, w int) string {
width := 0
Expand Down Expand Up @@ -291,6 +328,11 @@ func Truncate(s string, w int, tail string) string {
return DefaultCondition.Truncate(s, w, tail)
}

// TruncateLeft cuts w cells from the beginning of the `s`.
func TruncateLeft(s string, w int, prefix string) string {
return DefaultCondition.TruncateLeft(s, w, prefix)
}

// Wrap return string wrapped with w cells
func Wrap(s string, w int) string {
return DefaultCondition.Wrap(s, w)
Expand Down
26 changes: 26 additions & 0 deletions runewidth_test.go
Expand Up @@ -380,6 +380,32 @@ func TestTruncateNoNeeded(t *testing.T) {
}
}

var truncatelefttests = []struct {
s string
w int
prefix string
out string
}{
{"source", 4, "", "ce"},
{"source", 4, "...", "...ce"},
{"あいうえお", 6, "", "えお"},
{"あいうえお", 6, "...", "...えお"},
{"あいうえお", 10, "", ""},
{"あいうえお", 10, "...", "..."},
{"あいうえお", 5, "", " えお"},
{"Aあいうえお", 5, "", "うえお"},
}

func TestTruncateLeft(t *testing.T) {
t.Parallel()

for _, tt := range truncatelefttests {
if out := TruncateLeft(tt.s, tt.w, tt.prefix); out != tt.out {
t.Errorf("TruncateLeft(%q) = %q, want %q", tt.s, out, tt.out)
}
}
}

var isneutralwidthtests = []struct {
in rune
out bool
Expand Down

0 comments on commit 2c6a438

Please sign in to comment.