Skip to content

Commit dd2031a

Browse files
authored
Merge pull request #12 from nineinchnick/auto-expand
Auto expand if width is greater than screen
2 parents a766a57 + 184dbaa commit dd2031a

File tree

6 files changed

+133
-30
lines changed

6 files changed

+133
-30
lines changed

encode.go

Lines changed: 73 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ type TableEncoder struct {
4646
// summary is the summary map.
4747
summary map[int]func(io.Writer, int) (int, error)
4848

49+
// isCustomSummary when summary has been set via options
50+
isCustomSummary bool
51+
4952
// title is the title value.
5053
title *Value
5154

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

71+
// maxWidth of whole table, before switching to the ExpandedEncoder,
72+
// zero disables switching
73+
maxWidth int
74+
6875
// scanCount is the number of scanned results in the result set.
6976
scanCount int
7077

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

171178
enc.calcWidth(vals)
172179

180+
if enc.maxWidth != 0 && enc.tableWidth() > enc.maxWidth {
181+
t := *enc
182+
t.formatter = NewEscapeFormatter()
183+
exp := ExpandedEncoder{
184+
TableEncoder: t,
185+
}
186+
exp.offsets = make([]int, 2)
187+
exp.maxWidths = make([]int, 2)
188+
exp.calcWidth(vals)
189+
190+
if err := exp.encodeVals(vals); err != nil {
191+
return nil
192+
}
193+
continue
194+
}
195+
173196
// print header if not already done
174197
if !wroteHeader {
175198
wroteHeader = true
176-
177199
enc.header()
178200
}
179201

180-
rs := enc.rowStyle(enc.lineStyle.Row)
181-
// print buffered vals
182-
for i := 0; i < len(vals); i++ {
183-
enc.row(vals[i], rs)
184-
if i+1%1000 == 0 {
185-
// check error every 1k rows
186-
if err := enc.w.Flush(); err != nil {
187-
return err
188-
}
189-
}
202+
if err := enc.encodeVals(vals); err != nil {
203+
return err
190204
}
191-
}
192205

193-
// draw end border
194-
if enc.border >= 2 {
195-
enc.divider(enc.rowStyle(enc.lineStyle.End))
206+
// draw end border
207+
if enc.border >= 2 {
208+
enc.divider(enc.rowStyle(enc.lineStyle.End))
209+
}
196210
}
197211

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

219+
func (enc *TableEncoder) encodeVals(vals [][]*Value) error {
220+
rs := enc.rowStyle(enc.lineStyle.Row)
221+
// print buffered vals
222+
for i := 0; i < len(vals); i++ {
223+
enc.row(vals[i], rs)
224+
if i+1%1000 == 0 {
225+
// check error every 1k rows
226+
if err := enc.w.Flush(); err != nil {
227+
return err
228+
}
229+
}
230+
}
231+
232+
return nil
233+
}
234+
205235
// EncodeAll encodes all result sets to the writer using the encoder settings.
206236
func (enc *TableEncoder) EncodeAll(w io.Writer) error {
207237
var err error
@@ -518,6 +548,9 @@ func (enc *TableEncoder) writeAligned(b, filler []byte, a Align, width, max int)
518548
// summarize writes the table scan count summary.
519549
func (enc *TableEncoder) summarize(w io.Writer) {
520550
// do summary
551+
if enc.summary == nil {
552+
return
553+
}
521554
var f func(io.Writer, int) (int, error)
522555
if z, ok := enc.summary[-1]; ok {
523556
f = z
@@ -544,6 +577,9 @@ func NewExpandedEncoder(resultSet ResultSet, opts ...Option) (Encoder, error) {
544577
}
545578
t := tableEnc.(*TableEncoder)
546579
t.formatter = NewEscapeFormatter()
580+
if !t.isCustomSummary {
581+
t.summary = nil
582+
}
547583

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

602638
enc.calcWidth(vals)
603639

604-
rs := enc.rowStyle(enc.lineStyle.Row)
605-
606640
// print title if not already done
607641
if !wroteTitle && enc.title != nil {
608642
wroteTitle = true
@@ -611,14 +645,27 @@ func (enc *ExpandedEncoder) Encode(w io.Writer) error {
611645
enc.w.Write(enc.newline)
612646
}
613647

614-
// print buffered vals
615-
for i := 0; i < len(vals); i++ {
616-
enc.record(i, vals[i], rs)
617-
if i+1%1000 == 0 {
618-
// check error every 1k rows
619-
if err := enc.w.Flush(); err != nil {
620-
return err
621-
}
648+
if err := enc.encodeVals(vals); err != nil {
649+
return err
650+
}
651+
}
652+
653+
// add summary
654+
enc.summarize(w)
655+
656+
// flush will return the error code
657+
return enc.w.Flush()
658+
}
659+
660+
func (enc *ExpandedEncoder) encodeVals(vals [][]*Value) error {
661+
rs := enc.rowStyle(enc.lineStyle.Row)
662+
// print buffered vals
663+
for i := 0; i < len(vals); i++ {
664+
enc.record(i, vals[i], rs)
665+
if i+1%1000 == 0 {
666+
// check error every 1k rows
667+
if err := enc.w.Flush(); err != nil {
668+
return err
622669
}
623670
}
624671
}
@@ -627,9 +674,7 @@ func (enc *ExpandedEncoder) Encode(w io.Writer) error {
627674
if enc.border >= 2 && enc.scanCount != 0 {
628675
enc.divider(enc.rowStyle(enc.lineStyle.End))
629676
}
630-
631-
// flush will return the error code
632-
return enc.w.Flush()
677+
return nil
633678
}
634679

635680
// EncodeAll encodes all result sets to the writer using the encoder settings.

go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
module github.com/xo/tblfmt
22

3-
require github.com/mattn/go-runewidth v0.0.9
3+
require (
4+
github.com/mattn/go-runewidth v0.0.9
5+
github.com/nathan-fiscaletti/consolesize-go v0.0.0-20210105204122-a87d9f614b9d
6+
)
47

58
go 1.13

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
22
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
3+
github.com/nathan-fiscaletti/consolesize-go v0.0.0-20210105204122-a87d9f614b9d h1:PQW4Aqovdqc9efHl9EVA+bhKmuZ4ME1HvSYYDvaDiK0=
4+
github.com/nathan-fiscaletti/consolesize-go v0.0.0-20210105204122-a87d9f614b9d/go.mod h1:cxIIfNMTwff8f/ZvRouvWYF6wOoO7nj99neWSx2q/Es=

opts.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"io"
55
"strconv"
66
"unicode/utf8"
7+
8+
"github.com/nathan-fiscaletti/consolesize-go"
79
)
810

911
// Builder is the shared builder interface.
@@ -69,7 +71,8 @@ func FromMap(opts map[string]string) (Builder, []Option) {
6971
if e, ok := opts["expanded"]; ok {
7072
switch e {
7173
case "auto":
72-
fallthrough
74+
cols, _ := consolesize.GetConsoleSize()
75+
tableOpts = append(tableOpts, WithMaxWidth(cols))
7376
case "on":
7477
builder = NewExpandedEncoder
7578
}
@@ -126,6 +129,7 @@ func WithSummary(summary map[int]func(io.Writer, int) (int, error)) Option {
126129
switch enc := v.(type) {
127130
case *TableEncoder:
128131
enc.summary = summary
132+
enc.isCustomSummary = true
129133
}
130134
return nil
131135
}
@@ -195,6 +199,19 @@ func WithWidths(widths []int) Option {
195199
}
196200
}
197201

202+
// WithMaxWidth is a encoder option to set maximum width before switching to expanded format.
203+
func WithMaxWidth(w int) Option {
204+
return func(v interface{}) error {
205+
switch enc := v.(type) {
206+
case *TableEncoder:
207+
enc.maxWidth = w
208+
case *ExpandedEncoder:
209+
enc.maxWidth = w
210+
}
211+
return nil
212+
}
213+
}
214+
198215
// WithNewline is a encoder option to set the newline.
199216
func WithNewline(newline string) Option {
200217
return func(v interface{}) error {

tblfmt_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,20 @@ func TestTinyAligned(t *testing.T) {
235235
}
236236
}
237237

238+
func TestWideExpanded(t *testing.T) {
239+
resultSet := rswide()
240+
buf := new(bytes.Buffer)
241+
params := map[string]string{
242+
"format": "aligned",
243+
"expanded": "auto",
244+
"border": "2",
245+
}
246+
if err := EncodeAll(buf, resultSet, params); err != nil {
247+
t.Fatalf("expected no error when encoding, got: %v", err)
248+
}
249+
t.Log("\n", newlineRE.ReplaceAllString(buf.String(), "\t"))
250+
}
251+
238252
func TestBigAligned(t *testing.T) {
239253
resultSet := rsbig()
240254

util_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,28 @@ func rstiny() *rset {
150150
}
151151
}
152152

153+
func rswide() *rset {
154+
return &rset{
155+
cols: []string{
156+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
157+
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
158+
"cccccccccccccccccccccccccccccc",
159+
"dddddddddddddddddddddddddddddd",
160+
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
161+
"ffffffffffffffffffffffffffffff",
162+
"gggggggggggggggggggggggggggggg",
163+
"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",
164+
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
165+
"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjj",
166+
},
167+
vals: [][][]interface{}{
168+
{
169+
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"},
170+
},
171+
},
172+
}
173+
}
174+
153175
// rsset returns a predefined set of records for rs.
154176
func rsset(i int) [][]interface{} {
155177
return [][]interface{}{

0 commit comments

Comments
 (0)