mirror of
https://github.com/octoleo/restic.git
synced 2024-11-27 07:16:40 +00:00
Merge pull request #4849 from fthoma/table-tcwidth
Use character display width for table padding
This commit is contained in:
commit
78485160fc
@ -8,6 +8,8 @@ import (
|
|||||||
"math/bits"
|
"math/bits"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/text/width"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FormatBytes(c uint64) string {
|
func FormatBytes(c uint64) string {
|
||||||
@ -105,3 +107,24 @@ func ToJSONString(status interface{}) string {
|
|||||||
}
|
}
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TerminalDisplayWidth returns the number of terminal cells needed to display s
|
||||||
|
func TerminalDisplayWidth(s string) int {
|
||||||
|
width := 0
|
||||||
|
for _, r := range s {
|
||||||
|
width += terminalDisplayRuneWidth(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
return width
|
||||||
|
}
|
||||||
|
|
||||||
|
func terminalDisplayRuneWidth(r rune) int {
|
||||||
|
switch width.LookupRune(r).Kind() {
|
||||||
|
case width.EastAsianWide, width.EastAsianFullwidth:
|
||||||
|
return 2
|
||||||
|
case width.EastAsianNarrow, width.EastAsianHalfwidth, width.EastAsianAmbiguous, width.Neutral:
|
||||||
|
return 1
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -84,3 +84,21 @@ func TestParseBytesInvalid(t *testing.T) {
|
|||||||
test.Equals(t, int64(0), v)
|
test.Equals(t, int64(0), v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTerminalDisplayWidth(t *testing.T) {
|
||||||
|
for _, c := range []struct {
|
||||||
|
input string
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
{"foo", 3},
|
||||||
|
{"aéb", 3},
|
||||||
|
{"ab", 3},
|
||||||
|
{"a’b", 3},
|
||||||
|
{"aあb", 4},
|
||||||
|
} {
|
||||||
|
if got := TerminalDisplayWidth(c.input); got != c.want {
|
||||||
|
t.Errorf("wrong display width for '%s', want %d, got %d", c.input, c.want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/restic/restic/internal/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Table contains data for a table to be printed.
|
// Table contains data for a table to be printed.
|
||||||
@ -89,7 +91,7 @@ func printLine(w io.Writer, print func(io.Writer, string) error, sep string, dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply padding
|
// apply padding
|
||||||
pad := widths[fieldNum] - len(v)
|
pad := widths[fieldNum] - ui.TerminalDisplayWidth(v)
|
||||||
if pad > 0 {
|
if pad > 0 {
|
||||||
v += strings.Repeat(" ", pad)
|
v += strings.Repeat(" ", pad)
|
||||||
}
|
}
|
||||||
@ -139,16 +141,18 @@ func (t *Table) Write(w io.Writer) error {
|
|||||||
columnWidths := make([]int, columns)
|
columnWidths := make([]int, columns)
|
||||||
for i, desc := range t.columns {
|
for i, desc := range t.columns {
|
||||||
for _, line := range strings.Split(desc, "\n") {
|
for _, line := range strings.Split(desc, "\n") {
|
||||||
if columnWidths[i] < len(line) {
|
width := ui.TerminalDisplayWidth(line)
|
||||||
columnWidths[i] = len(desc)
|
if columnWidths[i] < width {
|
||||||
|
columnWidths[i] = width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
for i, content := range line {
|
for i, content := range line {
|
||||||
for _, l := range strings.Split(content, "\n") {
|
for _, l := range strings.Split(content, "\n") {
|
||||||
if columnWidths[i] < len(l) {
|
width := ui.TerminalDisplayWidth(l)
|
||||||
columnWidths[i] = len(l)
|
if columnWidths[i] < width {
|
||||||
|
columnWidths[i] = width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,7 +163,7 @@ func (t *Table) Write(w io.Writer) error {
|
|||||||
for _, width := range columnWidths {
|
for _, width := range columnWidths {
|
||||||
totalWidth += width
|
totalWidth += width
|
||||||
}
|
}
|
||||||
totalWidth += (columns - 1) * len(t.CellSeparator)
|
totalWidth += (columns - 1) * ui.TerminalDisplayWidth(t.CellSeparator)
|
||||||
|
|
||||||
// write header
|
// write header
|
||||||
if len(t.columns) > 0 {
|
if len(t.columns) > 0 {
|
||||||
|
@ -29,6 +29,21 @@ first column
|
|||||||
----------------------
|
----------------------
|
||||||
data: first data field
|
data: first data field
|
||||||
----------------------
|
----------------------
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
func(t testing.TB) *Table {
|
||||||
|
table := New()
|
||||||
|
table.AddColumn("first\ncolumn", "{{.First}}")
|
||||||
|
table.AddRow(struct{ First string }{"data"})
|
||||||
|
return table
|
||||||
|
},
|
||||||
|
`
|
||||||
|
first
|
||||||
|
column
|
||||||
|
------
|
||||||
|
data
|
||||||
|
------
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -126,7 +141,7 @@ foo 2018-08-19 22:22:22 xxx other /home/user/other
|
|||||||
Time string
|
Time string
|
||||||
Tags, Dirs []string
|
Tags, Dirs []string
|
||||||
}
|
}
|
||||||
table.AddRow(data{"foo", "2018-08-19 22:22:22", []string{"work", "go"}, []string{"/home/user/work", "/home/user/go"}})
|
table.AddRow(data{"foo", "2018-08-19 22:22:22", []string{"work", "go’s"}, []string{"/home/user/work", "/home/user/go"}})
|
||||||
table.AddRow(data{"foo", "2018-08-19 22:22:22", []string{"other"}, []string{"/home/user/other"}})
|
table.AddRow(data{"foo", "2018-08-19 22:22:22", []string{"other"}, []string{"/home/user/other"}})
|
||||||
table.AddRow(data{"foo", "2018-08-19 22:22:22", []string{"other", "bar"}, []string{"/home/user/other"}})
|
table.AddRow(data{"foo", "2018-08-19 22:22:22", []string{"other", "bar"}, []string{"/home/user/other"}})
|
||||||
return table
|
return table
|
||||||
@ -135,7 +150,7 @@ foo 2018-08-19 22:22:22 xxx other /home/user/other
|
|||||||
host name time zz tags dirs
|
host name time zz tags dirs
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
foo 2018-08-19 22:22:22 xxx work /home/user/work
|
foo 2018-08-19 22:22:22 xxx work /home/user/work
|
||||||
go /home/user/go
|
go’s /home/user/go
|
||||||
foo 2018-08-19 22:22:22 xxx other /home/user/other
|
foo 2018-08-19 22:22:22 xxx other /home/user/other
|
||||||
foo 2018-08-19 22:22:22 xxx other /home/user/other
|
foo 2018-08-19 22:22:22 xxx other /home/user/other
|
||||||
bar
|
bar
|
||||||
|
Loading…
Reference in New Issue
Block a user