fit task table in term

This commit is contained in:
Erik Winter 2022-06-20 16:03:56 +02:00 committed by Erik Winter
parent a21867690b
commit e49c3b8bdc
2 changed files with 141 additions and 79 deletions

View File

@ -30,48 +30,6 @@ func FormatError(err error) string {
return fmt.Sprintf("could not perform command.\n\nerror: %s\n", err.Error())
}
func FormatTaskTable(tasks []*task.LocalTask, cols []Column) string {
if len(tasks) == 0 {
return "no tasks to display\n"
}
var data [][]string
for _, t := range tasks {
var line []string
for _, col := range cols {
switch col {
case COL_ID:
line = append(line, fmt.Sprintf("%d", t.LocalId))
case COL_STATUS:
var updated []string
if t.IsRecurrer() {
updated = append(updated, "r")
}
if t.LocalStatus == task.STATUS_UPDATED {
updated = append(updated, "u")
}
if !t.Due.IsZero() && task.Today().After(t.Due) {
updated = append(updated, "o")
}
line = append(line, strings.Join(updated, " "))
case COL_DUE:
if t.Due.IsZero() {
line = append(line, "")
continue
}
line = append(line, t.Due.Human())
case COL_ACTION:
line = append(line, t.Action)
case COL_PROJECT:
line = append(line, t.Project)
}
}
data = append(data, line)
}
return fmt.Sprintf("\n%s\n", FormatTable(data))
}
func FormatTask(t *task.LocalTask) string {
output := fmt.Sprintf(`folder: %s
action: %s
@ -122,40 +80,3 @@ func ParseTaskFieldArgs(args []string) (*task.LocalUpdate, error) {
return lu, nil
}
func FormatTable(data [][]string) string {
if len(data) == 0 {
return ""
}
max := make([]int, len(data[0]))
for _, line := range data {
for i, col := range line {
if len(col) > max[i] {
max[i] = len(col)
}
}
}
var output string
for r, line := range data {
if r%3 == 0 {
output += fmt.Sprintf("%s", "\x1b[48;5;237m")
}
for c, col := range line {
output += col
for s := 0; s < max[c]-len(col); s++ {
output += " "
}
if c != len(line)-1 {
output += " "
}
}
if r%3 == 0 {
output += fmt.Sprintf("%s", "\x1b[49m")
}
output += "\n"
}
return output
}

141
cmd/cli/format/table.go Normal file
View File

@ -0,0 +1,141 @@
package format
import (
"fmt"
"os"
"os/exec"
"strconv"
"strings"
"ewintr.nl/gte/internal/task"
)
func FormatTaskTable(tasks []*task.LocalTask, cols []Column) string {
if len(tasks) == 0 {
return "no tasks to display\n"
}
var data [][]string
for _, t := range tasks {
var line []string
for _, col := range cols {
switch col {
case COL_ID:
line = append(line, fmt.Sprintf("%d", t.LocalId))
case COL_STATUS:
var updated []string
if t.IsRecurrer() {
updated = append(updated, "r")
}
if t.LocalStatus == task.STATUS_UPDATED {
updated = append(updated, "u")
}
if !t.Due.IsZero() && task.Today().After(t.Due) {
updated = append(updated, "o")
}
line = append(line, strings.Join(updated, " "))
case COL_DUE:
if t.Due.IsZero() {
line = append(line, "")
continue
}
line = append(line, t.Due.Human())
case COL_ACTION:
line = append(line, t.Action)
case COL_PROJECT:
line = append(line, t.Project)
}
}
data = append(data, line)
}
return fmt.Sprintf("\n%s\n", FormatTable(data))
}
func FormatTable(data [][]string) string {
if len(data) == 0 {
return ""
}
// make all cells in a column the same width
max := make([]int, len(data[0]))
for _, row := range data {
for c, cell := range row {
if len(cell) > max[c] {
max[c] = len(cell)
}
}
}
for r, row := range data {
for c, cell := range row {
for s := len(cell); s < max[c]; s++ {
data[r][c] += " "
}
}
}
// make it smaller if the result is too wide
// only by making the widest column smaller for now
maxWidth := findTermWidth()
if maxWidth != 0 {
width := len(max) - 1
for _, m := range max {
width += m
}
shortenWith := width - maxWidth
widestColNo, widestColLen := 0, 0
for i, m := range max {
if m > widestColLen {
widestColNo, widestColLen = i, m
}
}
newTaskColWidth := max[widestColNo] - shortenWith
if newTaskColWidth < 0 {
return "table is too wide to display\n"
}
if newTaskColWidth < max[widestColNo] {
for r, row := range data {
data[r][widestColNo] = row[widestColNo][:newTaskColWidth]
}
}
}
// print the rows
var output string
for r, row := range data {
if r%3 == 0 {
output += fmt.Sprintf("%s", "\x1b[48;5;237m")
}
for c, col := range row {
output += col
if c != len(row)-1 {
output += " "
}
}
if r%3 == 0 {
output += fmt.Sprintf("%s", "\x1b[49m")
}
output += "\n"
}
return output
}
func findTermWidth() int {
cmd := exec.Command("stty", "size")
cmd.Stdin = os.Stdin
out, err := cmd.Output()
if err != nil {
return 0
}
s := string(out)
s = strings.TrimSpace(s)
sArr := strings.Split(s, " ")
width, err := strconv.Atoi(sArr[1])
if err != nil {
return 0
}
return width
}