fit task table in term
This commit is contained in:
parent
a21867690b
commit
e49c3b8bdc
|
@ -30,48 +30,6 @@ func FormatError(err error) string {
|
||||||
return fmt.Sprintf("could not perform command.\n\nerror: %s\n", err.Error())
|
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 {
|
func FormatTask(t *task.LocalTask) string {
|
||||||
output := fmt.Sprintf(`folder: %s
|
output := fmt.Sprintf(`folder: %s
|
||||||
action: %s
|
action: %s
|
||||||
|
@ -122,40 +80,3 @@ func ParseTaskFieldArgs(args []string) (*task.LocalUpdate, error) {
|
||||||
|
|
||||||
return lu, nil
|
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue