mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
90 lines
1.6 KiB
Go
90 lines
1.6 KiB
Go
package ui
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"io"
|
||
|
|
"regexp"
|
||
|
|
"strings"
|
||
|
|
"unicode/utf8"
|
||
|
|
)
|
||
|
|
|
||
|
|
var ansiEscapeRe = regexp.MustCompile(`\x1b\[[0-9;]*[A-Za-z]`)
|
||
|
|
|
||
|
|
func VisibleWidth(s string) int {
|
||
|
|
return utf8.RuneCountInString(ansiEscapeRe.ReplaceAllString(s, ""))
|
||
|
|
}
|
||
|
|
|
||
|
|
func RenderTable(out io.Writer, rows [][]string, after func(rowIdx int) error) error {
|
||
|
|
if len(rows) == 0 {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
cols := len(rows[0])
|
||
|
|
widths := make([]int, cols)
|
||
|
|
for _, row := range rows {
|
||
|
|
for i, cell := range row {
|
||
|
|
if w := VisibleWidth(cell); w > widths[i] {
|
||
|
|
widths[i] = w
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for rIdx, row := range rows {
|
||
|
|
for i, cell := range row {
|
||
|
|
if i == cols-1 {
|
||
|
|
if _, err := fmt.Fprint(out, cell); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
pad := widths[i] - VisibleWidth(cell)
|
||
|
|
if _, err := fmt.Fprint(out, cell, strings.Repeat(" ", pad+2)); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if _, err := fmt.Fprintln(out); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
if after != nil {
|
||
|
|
dataIdx := rIdx - 1
|
||
|
|
if err := after(dataIdx); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func FirstColumnIndent(rows [][]string) string {
|
||
|
|
if len(rows) == 0 {
|
||
|
|
return ""
|
||
|
|
}
|
||
|
|
w := 0
|
||
|
|
for _, row := range rows {
|
||
|
|
if v := VisibleWidth(row[0]); v > w {
|
||
|
|
w = v
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return strings.Repeat(" ", w+2)
|
||
|
|
}
|
||
|
|
|
||
|
|
func Truncate(s string, n int) string {
|
||
|
|
runes := []rune(s)
|
||
|
|
if len(runes) <= n {
|
||
|
|
return s
|
||
|
|
}
|
||
|
|
if n <= 3 {
|
||
|
|
return string(runes[:n])
|
||
|
|
}
|
||
|
|
return string(runes[:n-3]) + "..."
|
||
|
|
}
|
||
|
|
|
||
|
|
func TruncateLeft(s string, n int) string {
|
||
|
|
runes := []rune(s)
|
||
|
|
if len(runes) <= n {
|
||
|
|
return s
|
||
|
|
}
|
||
|
|
if n <= 3 {
|
||
|
|
return string(runes[len(runes)-n:])
|
||
|
|
}
|
||
|
|
return "..." + string(runes[len(runes)-(n-3):])
|
||
|
|
}
|