func writeWrapped(s string, p string) { w := termsize.Columns() if w > maxLength { w = maxLength } else if w < minLength { w = minLength } debugPrefix := "" if debugEnabled { _, file, line, ok := runtime.Caller(2) if ok { ts := time.Now().Format("15:04:05.000") file = path.Base(file) debugPrefix = fmt.Sprintf("%s %s:%d ", ts, file, line) } } lines := strings.Split(strings.TrimSuffix(s, "\n"), "\n") for _, l := range lines { writeWrappedLine(debugPrefix+p+l, w) } }
// FmtFunc works as Fmt but calls the formatting function fn on each cell // before printing. func FmtFunc(fmt string, rows [][]string, fn Formatter) string { cols := len(rows[0]) width := make([]int, cols) for _, row := range rows { for i, cell := range row { if l := utf8.RuneCountInString(cell); l > width[i] { width[i] = l } } } termWidth := termsize.Columns() totWidth := func() (cw int) { for _, w := range width { cw += w } cw += intraColumnPadding * (len(width) - 1) return cw } for { tw := totWidth() if tw <= termWidth { break } // Make wider columns narrower first for i := range width { if width[i] >= tw/len(width) { width[i]-- } } } var buf bytes.Buffer for r, row := range rows { for c, cell := range row { if width[c] == 0 { continue } flags := 0 // UTF8 len l := utf8.RuneCountInString(cell) var pad string if l < width[c] { pad = strings.Repeat(" ", width[c]-l) flags |= Padded } else if l > width[c] { // BUG(jb): When there are multibyte UTF-8 characters we cut the string shorter than necessary. cell = cell[:width[c]] flags |= Truncated } if r == 0 || fmt[c] == 'l' { cell = cell + pad } else if fmt[c] == 'r' { cell = pad + cell } cell = fn(cell, r, c, flags) buf.WriteString(cell) if c < cols-1 { buf.WriteString(strings.Repeat(" ", intraColumnPadding)) } } buf.WriteString("\n") } return buf.String() }