diff options
| -rw-r--r-- | go.mod | 1 | ||||
| -rw-r--r-- | go.sum | 3 | ||||
| -rw-r--r-- | internal/colour/colour.go | 15 | ||||
| -rw-r--r-- | internal/entry/entry.go | 2 | ||||
| -rw-r--r-- | internal/platforms/linkedin/linkedin.go | 2 | ||||
| -rw-r--r-- | internal/prompt/file.go | 12 | ||||
| -rw-r--r-- | internal/prompt/prompt.go | 12 | ||||
| -rw-r--r-- | internal/schedule/stats.go | 2 | ||||
| -rw-r--r-- | internal/table/render.go | 21 | ||||
| -rw-r--r-- | internal/table/table.go | 100 |
10 files changed, 116 insertions, 54 deletions
@@ -11,6 +11,7 @@ require ( require ( cloud.google.com/go/compute/metadata v0.6.0 // indirect + github.com/buger/goterm v1.0.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -1,5 +1,7 @@ cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= +github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY= +github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= @@ -35,6 +37,7 @@ golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= diff --git a/internal/colour/colour.go b/internal/colour/colour.go index 030a6ef..3bdfffe 100644 --- a/internal/colour/colour.go +++ b/internal/colour/colour.go @@ -13,15 +13,9 @@ var ( } Infoln = func(args ...any) { fmt.Println(args...) } - Info2Col = color.New(color.FgHiYellow, color.BgBlue) - Info2fln = func(format string, args ...any) { - Info2Col.Printf(format, args...) - fmt.Print("\n") - } - SInfo2f = Info2Col.SprintfFunc() - - warnCol = color.New(color.FgHiWhite, color.BgRed) - Warnln = warnCol.PrintlnFunc() + AttentionCol = color.New(color.FgHiYellow, color.BgBlue) + warnCol = color.New(color.FgHiWhite, color.BgRed) + Warnln = warnCol.PrintlnFunc() successCol = color.New(color.FgWhite, color.BgGreen) Successfln = func(format string, args ...any) { @@ -30,5 +24,6 @@ var ( } - Ackf = color.New(color.FgBlack, color.BgHiYellow, color.Bold).PrintfFunc() + AckCol = color.New(color.FgBlack, color.BgHiYellow, color.Bold) + Ackf = AckCol.PrintfFunc() ) diff --git a/internal/entry/entry.go b/internal/entry/entry.go index 509ddfe..4454b01 100644 --- a/internal/entry/entry.go +++ b/internal/entry/entry.go @@ -131,7 +131,7 @@ func (en Entry) ContentWithLimit(sizeLimit int) (string, []string, error) { return "", urls, err } if len(content) > sizeLimit { - err := fmt.Errorf("%w (%d > %d): %v", ErrSizeLimitExceeded, len(content), sizeLimit, en) + err := fmt.Errorf("%w (%d > %d)", ErrSizeLimitExceeded, len(content), sizeLimit) if err2 := prompt.Acknowledge("You need to shorten the content as "+err.Error(), content); err2 != nil { return "", urls, errors.Join(err, err2) } diff --git a/internal/platforms/linkedin/linkedin.go b/internal/platforms/linkedin/linkedin.go index ebbf5dd..9c6f7b9 100644 --- a/internal/platforms/linkedin/linkedin.go +++ b/internal/platforms/linkedin/linkedin.go @@ -61,7 +61,7 @@ func post(ctx context.Context, args config.Args, sizeLimit int, en entry.Entry) return err } - question := fmt.Sprintf("Do you want to post this message to Linkedin (%v)?", prev) + question := "Do you want to post this message to Linkedin?" if content, err = prompt.FileAction(question, content, en.Path, prompt.RandomOption); err != nil { return err } diff --git a/internal/prompt/file.go b/internal/prompt/file.go index 11e32a2..f692b77 100644 --- a/internal/prompt/file.go +++ b/internal/prompt/file.go @@ -10,6 +10,7 @@ import ( "codeberg.org/snonux/gos/internal/colour" "codeberg.org/snonux/gos/internal/oi" + "codeberg.org/snonux/gos/internal/table" ) var ( @@ -20,8 +21,12 @@ var ( ) func FileAction(question, content, filePath string, includeRandomOption ...bool) (string, error) { - colour.Info2fln("%s:", filePath) - colour.Info2fln("%s", content) + table.New(). + WithBaseColor(colour.AttentionCol). + WithHeaderColor(colour.AckCol). + Header(question). + TextBox(content). + MustRender() reader := bufio.NewReader(os.Stdin) includeRandom := len(includeRandomOption) > 0 && includeRandomOption[0] == RandomOption @@ -31,7 +36,8 @@ func FileAction(question, content, filePath string, includeRandomOption ...bool) } for { - colour.Ackf("%s (y=yes/n=no/e=edit/d=delete%s):", question, randomOption) + fmt.Print(" ") + colour.Ackf("(y=yes/n=no/e=edit/d=delete%s):", randomOption) input, err := reader.ReadString('\n') if err != nil { return "", fmt.Errorf("error reading input: %w", err) diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index 646888f..8dfc437 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -6,16 +6,22 @@ import ( "os" "codeberg.org/snonux/gos/internal/colour" + "codeberg.org/snonux/gos/internal/table" ) func Acknowledge(messages ...string) error { if len(messages) > 1 { for _, content := range messages[1:] { - colour.Info2fln("%s", content) - fmt.Print("\n") + table.New(). + WithBaseColor(colour.AttentionCol). + WithHeaderColor(colour.AckCol). + Header(messages[0]). + TextBox(content). + MustRender() } } - colour.Ackf(messages[0] + " (press enter to acknowlege)") + fmt.Printf(" ") + colour.Ackf("(press enter to acknowlege)") reader := bufio.NewReader(os.Stdin) if _, err := reader.ReadString('\n'); err != nil { return err diff --git a/internal/schedule/stats.go b/internal/schedule/stats.go index eaddd7d..c1b32f3 100644 --- a/internal/schedule/stats.go +++ b/internal/schedule/stats.go @@ -149,7 +149,7 @@ func (s *stats) gatherQueuedStats(dir string) error { func (s stats) RenderTable(platform platforms.Platform) { table.New(). - WithColor(colour.Info2Col). + WithColor(colour.AttentionCol). Header(platform.String(), "value", "Lifetime stats", "value"). Row("Since (days)", s.sinceDays, "Total since (days)", s.totalSinceDays). Row("#Posted entries", s.posted, "#Total posted entries", s.totalPosted). diff --git a/internal/table/render.go b/internal/table/render.go index c7ed46c..55cddff 100644 --- a/internal/table/render.go +++ b/internal/table/render.go @@ -1,7 +1,6 @@ package table import ( - "fmt" "strings" ) @@ -33,26 +32,32 @@ func (r render) String() string { var sb strings.Builder sb.WriteString(r.separator) - sb.WriteString(r.rowString(r.tab.headers)) + sb.WriteString(r.rowString(r.tab.headers, r.tab.sheaderf)) sb.WriteString(r.separator) for _, row := range r.tab.rows { - sb.WriteString(r.rowString(row)) + sb.WriteString(r.rowString(row, r.tab.sprintf)) } sb.WriteString(r.separator) return sb.String() } -func (r render) rowString(row []string) string { - var sb strings.Builder +func (r render) rowString(row []string, stextf formatFunc) string { + var ( + sb strings.Builder + sbasef = r.tab.sprintf + ) for i, col := range row { - sb.WriteString(fmt.Sprintf("| %s ", col)) + sb.WriteString(sbasef("| ")) + sb.WriteString(stextf("%s", col)) + sb.WriteString(sbasef(" ")) for j := len(col); j < r.tab.lengths[i]; j++ { - sb.WriteString(" ") + sb.WriteString(sbasef(" ")) } } + sb.WriteString(sbasef("|")) - return r.tab.sprintf("%s|", sb.String()) + "\n" + return sb.String() + "\n" } diff --git a/internal/table/table.go b/internal/table/table.go index 5147b9c..48e1a00 100644 --- a/internal/table/table.go +++ b/internal/table/table.go @@ -3,25 +3,42 @@ package table import ( "fmt" "strconv" + "strings" + "github.com/buger/goterm" "github.com/fatih/color" ) type row []string +type formatFunc func(format string, args ...any) string + type Table struct { - headers []string - rows []row - lengths []int // Max length of each col - sprintf func(format string, args ...any) string // For colored output - err error + headers []string + rows []row + lengths []int // Max length of each col + sheaderf formatFunc // For colored output + sprintf formatFunc // For colored output + err error } func New() *Table { - return &Table{sprintf: fmt.Sprintf} + return &Table{ + sprintf: fmt.Sprintf, + sheaderf: fmt.Sprintf, + } } func (t *Table) WithColor(col *color.Color) *Table { + return t.WithHeaderColor(col).WithBaseColor(col) +} + +func (t *Table) WithHeaderColor(col *color.Color) *Table { + t.sheaderf = col.Sprintf + return t +} + +func (t *Table) WithBaseColor(col *color.Color) *Table { t.sprintf = col.Sprintf return t } @@ -40,24 +57,56 @@ func (t *Table) Header(args ...any) *Table { } func (t *Table) Row(args ...any) *Table { - if len(args) != len(t.headers) { - t.err = fmt.Errorf("Table row (%v) not same length as table headers (%v)", args, t.headers) + t.addRow(vals(args...)...) + return t +} + +func (t *Table) TextBox(text string) *Table { + maxLen := goterm.Width() - 4 + words := strings.Split(text, "\n") + var result []string + + for _, line := range words { + var currentLine string + for _, word := range strings.Fields(line) { + if len(currentLine)+len(word)+1 <= maxLen { + if len(currentLine) > 0 { + currentLine += " " + } + currentLine += word + } else { + if len(currentLine) > 0 { + result = append(result, currentLine) + } + currentLine = word + } + } + if len(currentLine) > 0 { + result = append(result, currentLine) + } + } + + for _, line := range result { + t.addRow(line) + } + + return t +} + +func (t *Table) addRow(row ...string) { + if len(row) != len(t.headers) { + t.err = fmt.Errorf("Table row (%v) not same length as table headers (%v)", row, t.headers) } if t.err != nil { - return t + return } - row := make(row, 0, len(args)) - for i, arg := range args { - strVal := val(arg) - row = append(row, strVal) - if t.lengths[i] < len(row[i]) { - t.lengths[i] = len(row[i]) + for i, strVal := range row { + if t.lengths[i] < len(strVal) { + t.lengths[i] = len(strVal) } } t.rows = append(t.rows, row) - - return t } func (t *Table) MustRender() { @@ -93,13 +142,10 @@ func val(val any) string { } } -// func dataRow(sb *strings.Builder, descr1 string, val1 any, descr2 string, val2 any) { -// const format = "| %-21s | %-11s | %-21s | %-11s |" -// sb.WriteString(colour.SInfo2f(format, descr1, val(val1), descr2, val(val2))) -// sb.WriteString("\n") -// } - -// func (t *Table) separator() { -// t.sb.WriteString(t.sep) -// t.sb.WriteString("\n") -// } +func vals(vals ...any) []string { + strVals := make([]string, 0, len(vals)) + for _, v := range vals { + strVals = append(strVals, val(v)) + } + return strVals +} |
