Skip to content

Commit

Permalink
Merge pull request #12 from nineinchnick/auto-expand
Browse files Browse the repository at this point in the history
Auto expand if width is greater than screen
  • Loading branch information
nineinchnick authored Mar 14, 2021
2 parents a766a57 + 184dbaa commit dd2031a
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 30 deletions.
101 changes: 73 additions & 28 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ type TableEncoder struct {
// summary is the summary map.
summary map[int]func(io.Writer, int) (int, error)

// isCustomSummary when summary has been set via options
isCustomSummary bool

// title is the title value.
title *Value

Expand All @@ -65,6 +68,10 @@ type TableEncoder struct {
// They are at least as wide as user-supplied widths
maxWidths []int

// maxWidth of whole table, before switching to the ExpandedEncoder,
// zero disables switching
maxWidth int

// scanCount is the number of scanned results in the result set.
scanCount int

Expand Down Expand Up @@ -170,29 +177,36 @@ func (enc *TableEncoder) Encode(w io.Writer) error {

enc.calcWidth(vals)

if enc.maxWidth != 0 && enc.tableWidth() > enc.maxWidth {
t := *enc
t.formatter = NewEscapeFormatter()
exp := ExpandedEncoder{
TableEncoder: t,
}
exp.offsets = make([]int, 2)
exp.maxWidths = make([]int, 2)
exp.calcWidth(vals)

if err := exp.encodeVals(vals); err != nil {
return nil
}
continue
}

// print header if not already done
if !wroteHeader {
wroteHeader = true

enc.header()
}

rs := enc.rowStyle(enc.lineStyle.Row)
// print buffered vals
for i := 0; i < len(vals); i++ {
enc.row(vals[i], rs)
if i+1%1000 == 0 {
// check error every 1k rows
if err := enc.w.Flush(); err != nil {
return err
}
}
if err := enc.encodeVals(vals); err != nil {
return err
}
}

// draw end border
if enc.border >= 2 {
enc.divider(enc.rowStyle(enc.lineStyle.End))
// draw end border
if enc.border >= 2 {
enc.divider(enc.rowStyle(enc.lineStyle.End))
}
}

// add summary
Expand All @@ -202,6 +216,22 @@ func (enc *TableEncoder) Encode(w io.Writer) error {
return enc.w.Flush()
}

func (enc *TableEncoder) encodeVals(vals [][]*Value) error {
rs := enc.rowStyle(enc.lineStyle.Row)
// print buffered vals
for i := 0; i < len(vals); i++ {
enc.row(vals[i], rs)
if i+1%1000 == 0 {
// check error every 1k rows
if err := enc.w.Flush(); err != nil {
return err
}
}
}

return nil
}

// EncodeAll encodes all result sets to the writer using the encoder settings.
func (enc *TableEncoder) EncodeAll(w io.Writer) error {
var err error
Expand Down Expand Up @@ -518,6 +548,9 @@ func (enc *TableEncoder) writeAligned(b, filler []byte, a Align, width, max int)
// summarize writes the table scan count summary.
func (enc *TableEncoder) summarize(w io.Writer) {
// do summary
if enc.summary == nil {
return
}
var f func(io.Writer, int) (int, error)
if z, ok := enc.summary[-1]; ok {
f = z
Expand All @@ -544,6 +577,9 @@ func NewExpandedEncoder(resultSet ResultSet, opts ...Option) (Encoder, error) {
}
t := tableEnc.(*TableEncoder)
t.formatter = NewEscapeFormatter()
if !t.isCustomSummary {
t.summary = nil
}

enc := &ExpandedEncoder{
TableEncoder: *t,
Expand Down Expand Up @@ -601,8 +637,6 @@ func (enc *ExpandedEncoder) Encode(w io.Writer) error {

enc.calcWidth(vals)

rs := enc.rowStyle(enc.lineStyle.Row)

// print title if not already done
if !wroteTitle && enc.title != nil {
wroteTitle = true
Expand All @@ -611,14 +645,27 @@ func (enc *ExpandedEncoder) Encode(w io.Writer) error {
enc.w.Write(enc.newline)
}

// print buffered vals
for i := 0; i < len(vals); i++ {
enc.record(i, vals[i], rs)
if i+1%1000 == 0 {
// check error every 1k rows
if err := enc.w.Flush(); err != nil {
return err
}
if err := enc.encodeVals(vals); err != nil {
return err
}
}

// add summary
enc.summarize(w)

// flush will return the error code
return enc.w.Flush()
}

func (enc *ExpandedEncoder) encodeVals(vals [][]*Value) error {
rs := enc.rowStyle(enc.lineStyle.Row)
// print buffered vals
for i := 0; i < len(vals); i++ {
enc.record(i, vals[i], rs)
if i+1%1000 == 0 {
// check error every 1k rows
if err := enc.w.Flush(); err != nil {
return err
}
}
}
Expand All @@ -627,9 +674,7 @@ func (enc *ExpandedEncoder) Encode(w io.Writer) error {
if enc.border >= 2 && enc.scanCount != 0 {
enc.divider(enc.rowStyle(enc.lineStyle.End))
}

// flush will return the error code
return enc.w.Flush()
return nil
}

// EncodeAll encodes all result sets to the writer using the encoder settings.
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module github.com/xo/tblfmt

require github.com/mattn/go-runewidth v0.0.9
require (
github.com/mattn/go-runewidth v0.0.9
github.com/nathan-fiscaletti/consolesize-go v0.0.0-20210105204122-a87d9f614b9d
)

go 1.13
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/nathan-fiscaletti/consolesize-go v0.0.0-20210105204122-a87d9f614b9d h1:PQW4Aqovdqc9efHl9EVA+bhKmuZ4ME1HvSYYDvaDiK0=
github.com/nathan-fiscaletti/consolesize-go v0.0.0-20210105204122-a87d9f614b9d/go.mod h1:cxIIfNMTwff8f/ZvRouvWYF6wOoO7nj99neWSx2q/Es=
19 changes: 18 additions & 1 deletion opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"io"
"strconv"
"unicode/utf8"

"github.com/nathan-fiscaletti/consolesize-go"
)

// Builder is the shared builder interface.
Expand Down Expand Up @@ -69,7 +71,8 @@ func FromMap(opts map[string]string) (Builder, []Option) {
if e, ok := opts["expanded"]; ok {
switch e {
case "auto":
fallthrough
cols, _ := consolesize.GetConsoleSize()
tableOpts = append(tableOpts, WithMaxWidth(cols))
case "on":
builder = NewExpandedEncoder
}
Expand Down Expand Up @@ -126,6 +129,7 @@ func WithSummary(summary map[int]func(io.Writer, int) (int, error)) Option {
switch enc := v.(type) {
case *TableEncoder:
enc.summary = summary
enc.isCustomSummary = true
}
return nil
}
Expand Down Expand Up @@ -195,6 +199,19 @@ func WithWidths(widths []int) Option {
}
}

// WithMaxWidth is a encoder option to set maximum width before switching to expanded format.
func WithMaxWidth(w int) Option {
return func(v interface{}) error {
switch enc := v.(type) {
case *TableEncoder:
enc.maxWidth = w
case *ExpandedEncoder:
enc.maxWidth = w
}
return nil
}
}

// WithNewline is a encoder option to set the newline.
func WithNewline(newline string) Option {
return func(v interface{}) error {
Expand Down
14 changes: 14 additions & 0 deletions tblfmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,20 @@ func TestTinyAligned(t *testing.T) {
}
}

func TestWideExpanded(t *testing.T) {
resultSet := rswide()
buf := new(bytes.Buffer)
params := map[string]string{
"format": "aligned",
"expanded": "auto",
"border": "2",
}
if err := EncodeAll(buf, resultSet, params); err != nil {
t.Fatalf("expected no error when encoding, got: %v", err)
}
t.Log("\n", newlineRE.ReplaceAllString(buf.String(), "\t"))
}

func TestBigAligned(t *testing.T) {
resultSet := rsbig()

Expand Down
22 changes: 22 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,28 @@ func rstiny() *rset {
}
}

func rswide() *rset {
return &rset{
cols: []string{
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"cccccccccccccccccccccccccccccc",
"dddddddddddddddddddddddddddddd",
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"ffffffffffffffffffffffffffffff",
"gggggggggggggggggggggggggggggg",
"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjj",
},
vals: [][][]interface{}{
{
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"},
},
},
}
}

// rsset returns a predefined set of records for rs.
func rsset(i int) [][]interface{} {
return [][]interface{}{
Expand Down

0 comments on commit dd2031a

Please sign in to comment.