Giter Club home page Giter Club logo

go-pretty's People

Contributors

dependabot[bot] avatar eclipseo avatar ferryvg avatar ilya-lesikov avatar iyear avatar jedib0t avatar mneira10 avatar nathanbaulch avatar rafiramadhana avatar sanyatuning avatar shreddedbacon avatar skeeve avatar titanous avatar virtuald avatar vsemichev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-pretty's Issues

AutoMerge doesn't appear to work with Append* commands

Describe the bug
When attempting to use the sample code here https://github.com/jedib0t/go-pretty/tree/main/table it doesn't seem to work with t.Append* commands.

To Reproduce

$ cat table.go
package main

import (
	"fmt"
	"os"

	"github.com/jedib0t/go-pretty/table"
	"github.com/jedib0t/go-pretty/text"
)

func main() {
	rowConfigAutoMerge := table.RowConfig{AutoMerge: true}

	t := table.NewWriter()
	t.AppendHeader(table.Row{"Node IP", "Pods", "Namespace", "Container", "RCE", "RCE"}, rowConfigAutoMerge)
	t.AppendHeader(table.Row{"", "", "", "", "EXE", "RUN"})
	t.AppendRow(table.Row{"1.1.1.1", "Pod 1A", "NS 1A", "C 1", "Y", "Y"}, rowConfigAutoMerge)
	t.AppendRow(table.Row{"1.1.1.1", "Pod 1A", "NS 1A", "C 2", "Y", "N"}, rowConfigAutoMerge)
	t.AppendRow(table.Row{"1.1.1.1", "Pod 1A", "NS 1B", "C 3", "N", "N"}, rowConfigAutoMerge)
	t.AppendRow(table.Row{"1.1.1.1", "Pod 1B", "NS 2", "C 4", "N", "N"}, rowConfigAutoMerge)
	t.AppendRow(table.Row{"1.1.1.1", "Pod 1B", "NS 2", "C 5", "Y", "N"}, rowConfigAutoMerge)
	t.AppendRow(table.Row{"2.2.2.2", "Pod 2", "NS 3", "C 6", "Y", "Y"}, rowConfigAutoMerge)
	t.AppendRow(table.Row{"2.2.2.2", "Pod 2", "NS 3", "C 7", "Y", "Y"}, rowConfigAutoMerge)
	t.AppendFooter(table.Row{"", "", "", 7, 5, 3})
	t.SetAutoIndex(true)
	t.SetColumnConfigs([]table.ColumnConfig{
		{Number: 1, AutoMerge: true},
		{Number: 2, AutoMerge: true},
		{Number: 3, AutoMerge: true},
		{Number: 4, AutoMerge: true},
		{Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
		{Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
	})
	t.SetOutputMirror(os.Stdout)
	t.SetStyle(table.StyleLight)
	t.Style().Options.SeparateRows = true
	fmt.Println(t.Render())

}
$  go run table.go
# command-line-arguments
./table.go:12:24: undefined: table.RowConfig
./table.go:15:16: too many arguments in call to t.AppendHeader
./table.go:17:13: too many arguments in call to t.AppendRow
./table.go:18:13: too many arguments in call to t.AppendRow
./table.go:19:13: too many arguments in call to t.AppendRow
./table.go:20:13: too many arguments in call to t.AppendRow
./table.go:21:13: too many arguments in call to t.AppendRow
./table.go:22:13: too many arguments in call to t.AppendRow
./table.go:23:13: too many arguments in call to t.AppendRow
./table.go:27:15: unknown field 'AutoMerge' in struct literal of type table.ColumnConfig
./table.go:27:15: too many errors

Expected behavior
Be able to reproduce the tables shown in the examples.

Software (please complete the following information):

  • OS: OSX
  • GoLang Version: go version go1.16.3 darwin/amd64

Multiple progress writers

Describe the bug

Unclear to me how to use multiple progress writers. Not sure if bug or usage on my end.

It seems that once the first writer is autostopped (as its attached trackers finished), the next writer won't be started/rendered, etc.. I have a few cases where I may need to create trackers, at the time of creating the first writer, it's unclear how many more trackers I need "later" in the process. So I opted for multiple writers, also to be able to customize them a bit to fit better into what they are tracking.

I am trying to figure out if it's due to being a pointer, and really I am referencing the same again, somehow go pw.Render() doesn't initialize it. But I haven't had much luck figuring out what it is exactly.

func CreateTracker(message string, length int64) *progress.Tracker {
	unit := &progress.UnitsDefault

	tracker := progress.Tracker{
		Message: message,
		Total:   length,
		Units:   *unit,
	}

	return &tracker
}

func CreateWriter(numberOfTrackers int) progress.Writer {
	pw := progress.NewWriter()
	pw.SetAutoStop(true)
	pw.SetTrackerLength(20)
	pw.ShowETA(false)
	pw.ShowOverallTracker(false)
	pw.ShowTime(true)
	pw.ShowTracker(true)
	pw.ShowValue(false)
	pw.SetMessageWidth(50)
	pw.SetNumTrackersExpected(numberOfTrackers)
	pw.SetSortBy(progress.SortByPercentDsc)
	pw.SetStyle(progress.StyleDefault)
	pw.SetTrackerPosition(progress.PositionRight)
	pw.Style().Colors = progress.StyleColorsExample
	pw.Style().Options.PercentFormat = "%4.1f%%"

	return pw
}

That's the code I use to bootstrap your's.

table: StyleLight is broken with SetAutoIndex(true)

Describe the bug
When SetAutoIndex(true) is called on a Table Writer, and the StyleLight is used, the index column rendering is broken.

Software (please complete the following information):

  • OS: OSX and Linux
  • GoLang Version: 1.10.2

Support cell merging on a per cell basis with something like HTML's "colspan"

Is your feature request related to a problem? Please describe.

I'd like to display tables with more control over the exact placement of separators than auto-merge allows. For example, something like this:

┌───────────────────────────────────────────────────────────────────────────────────────────────┐
│ Failed test: 1 == 0                                                                           │
├──────┬─────────────────┬────┬─────────────────┬───────────────────────────────────────────────┤
│      │      ACTUAL     │    │      EXPECT     │                                               │
│ PATH │ TYPE   │ VALUE  │ OP │ TYPE   │ VALUE  │ CALLER                                        │
├──────┼────────┴────────┴────┴────────┴────────┼───────────────────────────────────────────────┤
│ int  │                 │    │                 │ demo/demo_test.go@21 called detest.(*D).Equal │
│      │ int    │ 1      │ == │ int    │ 0      │                                               │
└──────┴────────┴────────┴────┴────────┴────────┴───────────────────────────────────────────────┘

Note the extra separators on the line starting with the caller "demo/demo_test.go ...".

AFAICT, there's no way to do this with auto-merge.

Describe the solution you'd like

I think the best way to do this would be to allow more explicit control over cell merging, with something like HTML's colspan. To do this in the current API I think you'd need to add something to the existing RowConfig{} struct. But a much nicer API would probably require creating some sort of Cell{} struct that could have a colspan (and it would also allow for much more granular control of horizontal alignment as a bonus).

Describe alternatives you've considered

I'm not sure there is any alternative to this, other than just accepting that I cannot do this. FWIW, I started off implementing my own table package which does do this, but it doesn't do cell wrapping, so I was looking at alternatives. If you're curious you can see my WIP at https://github.com/houseabsolute/detest/tree/master/internal/table

(As an aside, I'm now realizing that go-pretty doesn't do cell wrapping either, just truncation, so I'll probably keep working on my package, but I'd love to offload this work to something that other people are already using!)

Add arbitrary separators to tables

Is your feature request related to a problem? Please describe.
I would like to have the option to add a table row that is printed as a separator row. Like what happens with header and footer, but some way of programmatically add a new separator between any rows.

Describe the solution you'd like
Something like AddSeparator() to mark a line separator between rows.

Describe alternatives you've considered

Additional context
I'm trying to migrate my project hostctl to use go-pretty but this feature is needed to split content of each profile on the printed table.

Using merged columns and rows in a table

Hi,
first, you did an amazing work with this library, this is really great :).

I didn't find it in the examples, not sure if it possible but I wanted to check.
I want to create a table with merged columns and rows, like this one:
image

Is it possible?
In the header I am trying to create a column with merged column ("RCE") that is above two cells ("EXEC" and "RUN").

The second thing is to create separated lines from the "Container" column until the end because in each Pod I have number of containers and I want them to appear in separated rows.

This is how it looks when I tried to print it:

┌────────────────────────────────────────────────────────────┐
│                            Nodes                           │
├───┬─────────┬────────┬───────────┬────────────┬──────┬─────┤
│   │ NODE IP │ PODS   │ NAMESPACE │ CONTAINERS │ RCE  │ RCE │
├───┼─────────┼────────┼───────────┼────────────┼──────┼─────┤
│   │         │        │           │            │ EXEC │ RUN │
├───┼─────────┼────────┼───────────┼────────────┼──────┼─────┤
│ 1 │ 1.1.1.1 │ Pod1A  │ NS1       │ container1 │ Y    │ Y   │
├───┼─────────┼────────┼───────────┼────────────┼──────┼─────┤
│ 2 │         │        │           │ container2 │ N    │ N   │
├───┼─────────┼────────┼───────────┼────────────┼──────┼─────┤
│ 3 │         │        │           │ container3 │ Y    │ N   │
├───┼─────────┼────────┼───────────┼────────────┼──────┼─────┤
│ 4 │         │ Pod1_B │ NS3       │ container4 │ Y    │ Y   │
├───┼─────────┼────────┼───────────┼────────────┼──────┼─────┤
│ 5 │         │        │           │ container5 │ N    │ N   │
├───┼─────────┼────────┼───────────┼────────────┼──────┼─────┤
│ 6 │ 2.2.2.2 │ Pod2   │ NS2       │ container6 │ Y    │ Y   │
└───┴─────────┴────────┴───────────┴────────────┴──────┴─────┘

You can see the two issues I was talking about:
image

I wanted to merge all the one I marked.
Is it possible ?

This is the code for the printing I tried:

package main

import (
	"fmt"
	"github.com/jedib0t/go-pretty/table"
	"github.com/jedib0t/go-pretty/text"
)

type nodeInfo struct {
	nodeIP string
	pods	 []Pod
}

type Pod struct {
	Name string
	Namespace string
	Containers []Container
}
type Container struct {
	name string
	rceExec string
	rceRun string
}

func tableFoo(){

	nodes := []nodeInfo{
		{
			nodeIP: "1.1.1.1",
			pods:   []Pod{
				{
					Name: "Pod1A",
					Namespace:  "NS1",
					Containers: []Container{
						{name: "container1", rceExec: "Y", rceRun: "Y",},
						{name: "container2", rceExec: "N", rceRun: "N",},
						{name: "container3", rceExec: "Y", rceRun: "N",},
					},
				},	{
					Name: "Pod1_B",
					Namespace:  "NS3",
					Containers: []Container{
						{name: "container4", rceExec: "Y", rceRun: "Y",},
						{name: "container5", rceExec: "N", rceRun: "N",},
					},
				},
			},
		},		{
			nodeIP: "2.2.2.2",
			pods:   []Pod{
				{
					Name: "Pod2",
					Namespace:  "NS2",
					Containers: []Container{
						{name: "container6", rceExec: "Y", rceRun: "Y",},
					},
				},
			},
		},
	}
	tw := table.NewWriter()
	tw.AppendHeader(table.Row{"Node IP", "Pods", "Namespace", "Containers", "RCE", "RCE"})
	tw.AppendHeader(table.Row{"", "", "", "", "EXEC", "RUN"})

	//tw1 := table.NewWriter()
	for _, node := range nodes {
		printNodeOnce := true
		nodeIpTemp := ""
		if printNodeOnce {
			nodeIpTemp = node.nodeIP
			printNodeOnce = false
		}
		for _, pod := range node.pods {
			printOnce := true

			for _, container := range pod.Containers {
				podTemp := ""
				namespaceTemp := ""
				if printOnce{
					podTemp = pod.Name
					namespaceTemp = pod.Namespace
					printOnce = false
				}

				tw.AppendRow(table.Row{nodeIpTemp, podTemp, namespaceTemp, container.name, container.rceExec, container.rceRun})
				nodeIpTemp = ""
			}

		}
	}

	tw.SetTitle("Nodes")
	tw.SetStyle(table.StyleLight)
	tw.Style().Title.Align = text.AlignCenter
	tw.Style().Options.SeparateRows = true
	tw.SetAutoIndex(true)
	fmt.Println(tw.Render())
}

func main(){
	tableFoo()
}

/disc /enhancement

`WidthMaxEnforcer` with `text.Trim` doesn’t trim text

Describe the bug
Configuring a table column to a specified width, and setting the WidthMaxEnforcer field to text.Trim (from go-pretty/text) doesn’t actually trim the text. It instead pushes the next column by those remaining places.

To Reproduce

t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.AppendRows([]table.Row{
	{"U2", "Hey", "2021-04-19 13:37", "Yuh yuh yuh"},
	{"S12", "Uhhhh", "2021-04-19 13:37", "Some dummy data here"},
	{"R123", "Lobsters", "2021-04-19 13:37", "I like lobsters"},
	{"R123", "Some big name here and it's pretty big", "2021-04-19 13:37", "Abcdefghijklmnopqrstuvwxyz"},
	{"R123", "Small name", "2021-04-19 13:37", "Abcdefghijklmnopqrstuvwxyz"},
})

// 2nd column should get trimmed
t.SetColumnConfigs([]table.ColumnConfig{
	{Number: 2, WidthMax: 20, WidthMaxEnforcer: text.Trim},
})
t.Render()

This outputs:

+------+----------------------+------------------+----------------------------+
| U2   | Hey                  | 2021-04-19 13:37 | Yuh yuh yuh                |
| S12  | Uhhhh                | 2021-04-19 13:37 | Some dummy data here       |
| R123 | Lobsters             | 2021-04-19 13:37 | I like lobsters            |
| R123 | Some big name here and it's pretty big | 2021-04-19 13:37 | Abcdefghijklmnopqrstuvwxyz |
| R123 | Small name           | 2021-04-19 13:37 | Abcdefghijklmnopqrstuvwxyz |
+------+----------------------+------------------+----------------------------+

Expected behavior

+------+----------------------+------------------+----------------------------+
| U2   | Hey                  | 2021-04-19 13:37 | Yuh yuh yuh                |
| S12  | Uhhhh                | 2021-04-19 13:37 | Some dummy data here       |
| R123 | Lobsters             | 2021-04-19 13:37 | I like lobsters            |
| R123 | Some big name here a | 2021-04-19 13:37 | Abcdefghijklmnopqrstuvwxyz |
| R123 | Small name           | 2021-04-19 13:37 | Abcdefghijklmnopqrstuvwxyz |
+------+----------------------+------------------+----------------------------+

Software (please complete the following information):

  • OS: macOS Big Sur
  • Go version: 1.16.1 darwin/amd64

Hide columns I don't want to render

Hello! Thank you for this library

Describe the solution you'd like

I would like to hide columns from a pre-populated table when I render it.

Describe alternatives you've considered

I can restructure my code to dynamically return headers and data but it looks more complicated compared with hiding columns and render time. I am not really scared about the wasted memory consumed by hidden values at the moment.

Additional context

I am writing a CLI and in order to get consistency as part of the code itself, the Get command is only one for all the resources I support. it means that I accept from the outside a function that returns the data I want []interface{}, a list of headers []string and the function capable of converting a single row from the retrieve data into a table.Row.

I would like to add a feature to my Get command that only shows a sub of information.

Footer misalignment when any text.Color is used in the Transformer

Describe the bug
First of all, thank you so much for the amazing work @jedib0t 🏅

I appears that using any text.Color formatter in the footer transformer breaks the layout. To be clear, the snippet below is simplified. I don't only need to colorise the whole footer. It needs to be conditionally formatted and that's why I'm using Transformers.

To Reproduce

t := table.NewWriter()
t.SetStyle(table.StyleRounded)
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{"First Name", "Last Name", "Salary"})

nameTransformer := text.Transformer(func(val interface{}) string {
   // Replacing this with fmt.Sprint(val) will solve the problem
   // But no formatting obviously!    
   return text.Bold.Sprint(val)
})

t.SetColumnConfigs([]table.ColumnConfig{
 {
	Name:              "Salary",
	Transformer:       nameTransformer,
	TransformerFooter: nameTransformer,
   },
})
t.AppendRows([]table.Row{
	{"Arya", "Stark", 3000},
	{"Jon", "Snow", 2000},
})
t.AppendSeparator()
t.AppendFooter(table.Row{"", "Total", 10000})
t.Render()

Expected behavior
The table should be properly aligned but this is what I see:

Screenshots
image

Software (please complete the following information):

  • OS: MacOS Catalina 10.15.4
  • GoLang Version: go1.14.2 darwin/amd64

Panic: integer divide by zero when setting a style

panic: runtime error: integer divide by zero

goroutine 1 [running]:
github.com/jedib0t/go-pretty/v6/text.RepeatAndTrim(0x0, 0x0, 0x5, 0x0, 0x0)
	/home/user/go/pkg/mod/github.com/jedib0t/go-pretty/[email protected]/text/string.go:110 +0x12d
github.com/jedib0t/go-pretty/v6/table.(*Table).initForRenderRowSeparator(0xc00018f5b0)
	/home/user/go/pkg/mod/github.com/jedib0t/go-pretty/[email protected]/table/table.go:746 +0x1a5
github.com/jedib0t/go-pretty/v6/table.(*Table).initForRender(0xc00018f5b0)
	/home/user/go/pkg/mod/github.com/jedib0t/go-pretty/[email protected]/table/table.go:569 +0x65
github.com/jedib0t/go-pretty/v6/table.(*Table).Render(0xc00018f5b0, 0xc000128640, 0x4)
	/home/user/go/pkg/mod/github.com/jedib0t/go-pretty/[email protected]/table/render.go:22 +0x45
main.main.func2(0xc000039140, 0x0, 0x0)

My code:

t := table.NewWriter()
style := table.Style{
	Name:    "my-style",
}
t.SetStyle(style)
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{"#", "Name", "Address", "Phone", "Birthday"})

for i, info := range data.Items {
	t.AppendRows([]table.Row{{i, info.Name, info.Address, info.Phone, info.Birthday}})
}
t.AppendSeparator()
t.AppendFooter(table.Row{"Total", len(data.Items), "", ""})
t.Render()

If the title is longer than column 1 + 2, title wraps abnormally

If the title is longer than column 1 + 2, the length of the title is the total length of the column, like this:

+---------+
| FixedBy |
| tesCach |
| ePrintS |
| tats    |
+-----+---+
| GET | 1 |
| NEW | 1 |
| REC | 1 |
+-----+---+

such title are not easy to read, we think the table should expand and not wrap title:

+--------------------------+
| FixedBytesCachePrintStats|
+----------------------+---+
|         GET          | 1 |
|         NEW          | 1 |
|         REC          | 1 |
+----------------------+---+

code used to generate the table:

t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.SetTitle("FixedBytesCachePrintStats")
t.AppendRows([]table.Row{{"GET", 1},
	{"NEW", 1},
	{"REC", 1}})
t.Render()

Set background/foreground colors by row

Hi,

Really nice package, easy to use and direct csv/html outputs are great.

I would like to change color row, didn't see anything related. My purpose is to set a background in red if a specific = X, green if Y, etc.

Same idea with html export, It could specify class for rows.

Regards,

Indeterminate Progress bar

Is your feature request related to a problem? Please describe.

I have a tool which performs several operations where the total is unknown. I still use a progress bar to indicate that something is happening, but it would be nice to have a mode where the progressbar indicate that its length is unknown.

Describe the solution you'd like

Similar to how pv works with a unknown length, it will just show the speed and have a little widget flying back'n'forth in the progress area

 [....<=>............] [34 in 3.504094s] ... Fetching ...

Describe alternatives you've considered
The current progressbar works, but it gives the user a sense that no progress is happening since it will always show 0%

Additional context
For reference, my needs come from having 10 parallel workers that each work on the same list of input. I have a master tracker for the total number of completed work, but I also have one for each worker - this way I can have a progressbar with a message for each piece of work currently being worked on:

99.71% [#################.] [680 in 3.50413s] ... Total
 0.00% [..................] [34 in 3.504094s] ... Fetching aaa
 0.00% [..................] [34 in 3.504095s] ... Fetching bbb
 0.00% [..................] [34 in 3.504068s] ... Fetching ccc
 0.00% [..................] [34 in 3.50407s] ... Fetching ddd

Since all workers share the same pool of work, they can't know how many they will work on in total

Potential unicode issue with tables/padding

Describe the bug
The table formatting and padding worked brilliantly, until unicode characters were added to the mix, which seems to have broken the padding.

To Reproduce
See screenshot.

Expected behavior
I was half expecting this to be handled automagically, and while I'm not even sure if it's doable within the context of this library, I'd very much prefer to see it work.

Screenshots
Imgur

Software (please complete the following information):

  • OS: macOS Mojave
  • GoLang Version 1.12

AppendSeparator | Method not available

Describe the bug
package table not allowing use of AppendSeparator()
t.AppendSeparator undefined (type table.Writer has no field or method AppendSeparator)

I can see the method is still in the source, however.

To Reproduce
Use most recent branch of go-pretty

import () {
	"github.com/jedib0t/go-pretty/table"
}

func main() {
    ...
    t := table.NewWriter()
    (header and first row)
    t.AppendSeparator
    (row ...n)
    t.Render()
    ...
}

Expected behavior
Row separator to be printed.

Screenshots
n/a - unable to compile

Software (please complete the following information):

  • OS: Archlinux 5.6.13-arch1-1
  • GoLang Version: go version go1.14.3 linux/amd64

Additional context
Everything else from table appears to be functioning correctly.

Option to suppress empty columns

Is your feature request related to a problem? Please describe.
It'd be great if there was a way to suppress columns that only have empty cells. I'm calling AppendRow from a loop and one of the columns is only populated in some cases and it'd be great if the whole column could be suppressed if none of the rows have any value for it.

Describe the solution you'd like
There are probably a lot of ways to address this, for example by marking a column as optional, or by being able to remove a column right before rendering.

Describe alternatives you've considered
I could make a two pass loop, first to determine if the column will have any values and then again to actually populate it, or probably some other workarounds, but it'd be more convenient if there was some built in way.

set witdth of Cols based on col number

Is your feature request related to a problem? Please describe.
While printing table without row headers, it seems it is not possible to set the col width.

Describe the solution you'd like
Can we not use the column number and set the width?

Describe alternatives you've considered
I have had to set row headers, just to set the width

Print rows one by one and incrementally

I'm writing a CLI application that subscribes on a channel (let's say a nats subject) and I want to print the received message in a table. But I don't know how to print just a new row and not the whole table. My problem is every time I call the Render method of a table, it prints all of the rows of the table and if I don't call it, nothing is shown.

tables: Prevent wrapping on non-wrappable character

Is your feature request related to a problem? Please describe.

I use go-pretty for tables that describe ddev projects. For example:

$ ddev list
detected terminal width=76 usableWidth=61 statusWidth=7 nameWidth=10 typeWIdth=7 locationWidth=20 urlWidth=20 totUsedWidth=64
┌────────┬─────────┬──────────────────────┬──────────────────────┬─────────┐
│ NAME   │ TYPE    │ LOCATION             │ URL                  │ STATUS  │
├────────┼─────────┼──────────────────────┼──────────────────────┼─────────┤
│ d9     │ drupal9 │ ~/workspace/d9       │                      │ stopped │
├────────┼─────────┼──────────────────────┼──────────────────────┼─────────┤
│ junk   │ php     │ ~/work/ddev/ddev/jun │ http://junk.ddev.sit │ running │
│        │         │ k                    │ e                    │  (ok)   │
├────────┼─────────┼──────────────────────┼──────────────────────┼─────────┤
│ Router │         │ healthy              │                      │         │
└────────┴─────────┴──────────────────────┴──────────────────────┴─────────┘

The feature request would be to have a way to prevent wrapping of things that make a mess when they wrap. The example would be the "location" and URL cells on the "junk" project here. I often need to copy/paste those, and the wrap just makes that impossible

Describe the solution you'd like

Have an option to prevent wrapping on non-space/tab/whatever characters

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Unclear how to use SortBy

Describe the bug
I could not find documentation on t.SortBy

To Reproduce
The following

t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{"first", "second"})
t.SortBy("first")
...

generates cannot use "first" (type string) as type []table.SortBy in argument to t.SortBy (or anything else that is being passed, for that matter).

Expected behavior
I would like to be referred to documentation usage of the method SortBy. As per here I expect t.SortBy("column name") to work, but apparently this is not the right grammar.

How is SortBy supposed to be called?

Sort by time.Date

Firstly, thank you for this thoughtfully implemented project! The documentation (via comments and code) are very well done and the use of library is very intuitive!

Is your feature request related to a problem? Please describe.
As the title hints, sorting by the builtin time.Time struct would be a logical additional feature to this project. I have a personal project used to translate and reconcile a my bank account against my budget app (don't ask me why they don't already). So naturally, I want the table to be printed chronologically.

My current solution is to print an additional column for the unix (int) representation of the time and sort the table by that column. This works fine but for a table hundreds or thousands of rows long, it's a pretty ugly output. I'm functionally printing 2 time.Time columns, in different formats.

Describe the solution you'd like
An option to sort tables by time.Time values.

Describe alternatives you've considered
Defining an additional column to list unix time, then sorting that by integer values. It's ugly and requires extra, likely duplicated code. Pretty much anyone who wants to sort by date will need two columns - one for human readable time, and one for sortable time.

Additional context
Add any other context or screenshots about the feature request here.

My project is still incomplete, but if you're interested to see how i'm consuming this project: https://github.com/copejon/reconcilitator

Excuse the multitude of readme typos. Written late at night and not as fun to fix as coding.

Respect separators with auto-merge

I am trying to build a table which shows who you are playing and also prints the board. The best I have been able to achive is the following:

┏━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃   ┃ MY TURN ┃ OPPONENT     ┃ LAST MOVE ┃ BOARD           ┃
┣━━━╋━━━━━━━━━╋━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━┫
┃ 0 ┃ true    ┃ A.I. level 1 ┃ c2c3      ┃ ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖ ┃
┃   ┃         ┃              ┃           ┃ ♙ ♙ ♙ - ♙ ♙ ♙ ♙ ┃
┃   ┃         ┃              ┃           ┃ - - - - - - - - ┃
┃   ┃         ┃              ┃           ┃ - - - ♙ - - - - ┃
┃   ┃         ┃              ┃           ┃ - - - - - - - - ┃
┃   ┃         ┃              ┃           ┃ - - ♟ ♟ - - - - ┃
┃   ┃         ┃              ┃           ┃ ♟ ♟ - - ♟ ♟ ♟ ♟ ┃
┃   ┃         ┃              ┃           ┃ ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜ ┃
┣━━━╋         ┃              ┣━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━┫
┃ 1 ┃         ┃              ┃ g8f6      ┃ ♜ ♞ ♝ ♚ ♛ ♝ - ♜ ┃
┃   ┃         ┃              ┃           ┃ ♟ ♟ ♟ ♟ - ♟ ♟ ♟ ┃
┃   ┃         ┃              ┃           ┃ - - - - - ♞ - - ┃
┃   ┃         ┃              ┃           ┃ - - - - ♟ - - - ┃
┃   ┃         ┃              ┃           ┃ - - - - ♙ - - - ┃
┃   ┃         ┃              ┃           ┃ - - ♘ - - - - - ┃
┃   ┃         ┃              ┃           ┃ ♙ ♙ ♙ ♙ - ♙ ♙ ♙ ┃
┃   ┃         ┃              ┃           ┃ ♖ - ♗ ♔ ♕ ♗ ♘ ♖ ┃
┗━━━┻━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━┛

However I think it would look neater with each row. Especially with more games.

┏━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃   ┃ MY TURN ┃ OPPONENT     ┃ LAST MOVE ┃ BOARD           ┃
┣━━━╋━━━━━━━━━╋━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━┫
┃ 0 ┃ true    ┃ A.I. level 1 ┃ c2c3      ┃ ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖ ┃
┃   ┃         ┃              ┃           ┃ ♙ ♙ ♙ - ♙ ♙ ♙ ♙ ┃
┃   ┃         ┃              ┃           ┃ - - - - - - - - ┃
┃   ┃         ┃              ┃           ┃ - - - ♙ - - - - ┃
┃   ┃         ┃              ┃           ┃ - - - - - - - - ┃
┃   ┃         ┃              ┃           ┃ - - ♟ ♟ - - - - ┃
┃   ┃         ┃              ┃           ┃ ♟ ♟ - - ♟ ♟ ♟ ♟ ┃
┃   ┃         ┃              ┃           ┃ ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜ ┃
┣━━━╋━━━━━━━━━╋━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━┫
┃ 1 ┃ true    ┃ A.I. level 1 ┃ g8f6      ┃ ♜ ♞ ♝ ♚ ♛ ♝ - ♜ ┃
┃   ┃         ┃              ┃           ┃ ♟ ♟ ♟ ♟ - ♟ ♟ ♟ ┃
┃   ┃         ┃              ┃           ┃ - - - - - ♞ - - ┃
┃   ┃         ┃              ┃           ┃ - - - - ♟ - - - ┃
┃   ┃         ┃              ┃           ┃ - - - - ♙ - - - ┃
┃   ┃         ┃              ┃           ┃ - - ♘ - - - - - ┃
┃   ┃         ┃              ┃           ┃ ♙ ♙ ♙ ♙ - ♙ ♙ ♙ ┃
┃   ┃         ┃              ┃           ┃ ♖ - ♗ ♔ ♕ ♗ ♘ ♖ ┃
┗━━━┻━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━┛

For now I will stick with where it is at the moment, but I think it will start to look untidy if it's constantly flipping between merged and unmerged.

Seems to me like t.AppendSeparator should break the merge, or at least this should be an option.

Thanks

Transformer affects sorting

Describe the bug
I expected SortBy to operate on the raw table data. However as soon as I set a transformer on the column I sort by, the sorting breaks.

Software (please complete the following information):

  • OS: Linux
  • GoLang Version 1.15.2

Table Title

Hi,

Is there a way to write a title like this and all table be aligned?

+Title-+-----+--------+-----------+------+-----------------------------+
|      |  A  |    B   |     C     |   D  |              E              |
+------+-----+--------+-----------+------+-----------------------------+
| 1   |   1 | Arya   | Stark     | 3000 |                             |
| 2   |  20 | Jon    | Snow      | 2000 | You know nothing, Jon Snow! |
| 3   | 300 | Tyrion | Lannister | 5000 |                             |
+------+-----+--------+-----------+------+-----------------------------+

I have tried creating a new BoxStyle changing TopLeft but the first line gets bigger and the others not.

increase row distance (padding)

Describe the bug

Apologies if this is documented and I could not find it: I would like to increase distance between consecutive rows, namely allow for bigger padding between one row and the other.

To Reproduce

Looking at these properties it seems only allowedRowLength is defined, likewise I could not find an equivalent of t.SetColumnConfig for rows. Moreover box styles only allow for PaddingLeft/Right and I could not find a similar entry for "row up/down".

Expected behavior

Does such option exist at all and what would you recommend in alternative?

Is it possible to use two headers with different colors ?

I have the following code:

package main
import(
	"github.com/jedib0t/go-pretty/table"
	"os"
)


func main (){
	t := table.NewWriter()
	t.SetOutputMirror(os.Stdout)
	t.AppendHeader(table.Row{"A", "B", "C"})
	t.AppendRow([]interface{}{"Arya          a", "Stark       a", "You know    a"})
	t.SetStyle(table.StyleColoredBright)
	t.Render()
}

It prints the following table:
image

I wanted to add another header on the above table but with different color, that it will appear like that:
image

This is what I tried to do:

package main
import(
	"fmt"
	"github.com/jedib0t/go-pretty/table"
	"github.com/jedib0t/go-pretty/text"
	"os"
	"strings"
)
func main (){
	t := table.NewWriter()
	t.SetOutputMirror(os.Stdout)
	t.AppendHeader(table.Row{"A", "B", "C"})
	t.AppendRow([]interface{}{"Arya          a", "Stark       a", "You know    a"})
	t.SetStyle(table.StyleColoredBright)

	result := t.Render()
	tableStrLines := strings.Split(result, "\n")
	titleLine := []rune(tableStrLines[0])

	fmt.Printf("%s%s" , text.BgMagenta.EscapeSeq(), text.FgBlack.EscapeSeq())
	header1 := fmt.Sprintf("Game of Thrones: %s", "hola")
	for len(header1) < len(titleLine) {
		header1 += " "
	}
	fmt.Println(header1 + "\n") 
	fmt.Printf("%s%s" , text.BgBlack.EscapeSeq(), text.FgWhite.EscapeSeq())
}

But the problem is that it prints me the line below because I ran the Render() before I calculate the header length. Also it prints it with larger length although I calculate exactly how much it needs to be:
image

Is there other way to do it ?

table: Text coloring is broken when Column length is restricted

Describe the bug
When a column's length is restricted using SetAllowedColumnLengths(...), cells in that column with color coding show the right color only on the first line. All lines other than the first get rendered in the default color.

Software (please complete the following information):

  • OS: OSX and Linux
  • GoLang Version: 1.10.2

Centering the Title

Describe the bug
Thanks for the great library!

The color table [1] implies that the title string can be centered.

I found the SetTitle function, which takes a format string as its first argument, so if I know the terminal width, I could presumably use sprintf-style formatting... but is that a property I can grab?

Or is there an easier way of centering the title string?

Thanks again for the great library!

[1] https://github.com/jedib0t/go-pretty/blob/master/cmd/demo-table/demo-colors.png

Setting the MessageWidth to 40 caused incorrect progress output

Describe the bug
I modified cmd/demo-progress/demo.go to use SetMessageWidth(40) and the progress stop to work properly (display keep scrolling down)

To Reproduce
See above

Expected behavior
Expect same behavior as with < 40 MessageWidth.

Screenshots
image

Software (please complete the following information):
CentOS 7 Linux

Additional context

Need more than done/fail, add custom ones.

The MarkAsDone/MarkAsErrored are nice, but we need custom ones, such as "canceled", "aborted" "skipped" or "interrupted", etc.

Maybe a MarkAsErrored(string) would be useful.

Allow column to bleed to the right into empty columns to the right (spreadsheet-style)

Describe the bug

I don't know that this is a bug or a support request or a feature request, but I'd like to be able to have the content of a cell fill the rest of the row to the right if the columns to the right are empty, as spreadsheets have always done by default.

Like spreadsheet cell B3 does here:

Untitled_spreadsheet_-_Google_Sheets

Is there a way to do that?

What I'm working on is so simple that I'm happy to change the number of columns on the fly as well, but haven't been able to figure out how to do that without breaking things, but that would work fine as well, if I could just change from 4 cols to 2, for example, and have the second column fill the space that columns 2-3-4 had.

Thanks for your help!

Option to invert rows and columns

Is it possible to add a feature to flip a table, such that the rows and columns are interchanged?
For example, table

-----------------------
| Header 1 | Header 2 |
-----------------------
| Data 1   | Data 2   |
-----------------------
| Data 3   | Data 4   |
-----------------------

should be flipped to

------------------------------
| Header 1 | Data 1 | Data 3 |
------------------------------
| Header 2 | Data 2 | Data 4 |
------------------------------

Shorten time output value in progress bar

Hi,

The progress bar allows to display the elapsed time for a tracker. However, the time is currently displayed with lots of digits after the decimal point:

19.9% [####...................] [254 in 52.349705s; ~ETA: 3m43s]
58.4% [#############..........] [751 in 4m25.041613s; ~ETA: 3m12s]

It would be great if one could specify how many digits after the decimal point should be displayed, perhaps with a default of something between 0 and 2. After all, most times this should be totally sufficient.

Thanks & keep up the great work!

progress: would like to indicate error before completion

Is your feature request related to a problem? Please describe.

Let's say I have 100 pieces of a task, each piece takes 10 seconds to accomplish, and I can do them concurrently. If one of them fails, I'd like to tell the user that one of them has failed, but the others are still making progress.

Describe the solution you'd like

It would probably be best to let the tracker continue, and update the tracker message to indicate that an error occurred. Currently Tracker.Message is public, but (even though not documented as such) probably shouldn't be written after a tracker is started because string assignment isn't guaranteed to be atomic (https://groups.google.com/g/golang-nuts/c/UWJlS8mPTlM).

Adding a mechanism to update the tracker message (and/or color) would work nicely. The user would still need to finalize the tracker via MarkAsErrored. What do you think?

... yes, I know I added MarkAsErrored, but clearly I didn't actually think through what I really wanted before doing that. :)

Progressbar ETA when ShowOverallTracker(false)

Is your feature request related to a problem? Please describe.

ETA is not displayed when using pw.ShowOverallTracker(false)

Describe the solution you'd like

Add a ShowETA function to display the ETA when not using OverallTracker

Thanks!

Nicolas.

Strange padding issue when rendering `%` in a column

Describe the bug
Hello, I'm working on a PR in another project which is using this library: rocketmiles/aws-cct#9

I'm attempting to add a column which is a percent value, so I'm also adding % as part of the fmt.Sprintf call: https://github.com/rocketmiles/aws-cct/pull/9/files#diff-2873f79a86c0d8b3335cd7731b0ecf7dd4301eb19a82ef7a1cba7589b5252261R175

The first issue I came across is that I seemed to need to "double escape" the percentage sign (%%%% instead of %% as I expected based on Go docs). The second is that the padding on the column seems to think that there are 2 characters added instead of one (note the border is collapsed by 1 char):

+-------------------------------------------------+-------------+-------------+------------+---------------+
| SERVICE                                         | 2020-09-01  | 2020-10-01  | DELTA      | DELTA PERCENT |
+-------------------------------------------------+-------------+-------------+------------+---------------+
| Amazon Macie                                    |       $0.00 |      $56.40 |     $56.40 |       +Inf%  |
| Amazon Comprehend                               |       $0.00 |       $0.02 |      $0.02 |       +Inf%  |
| Amazon EC2 Container Service                    |      $64.22 |     $151.43 |     $87.21 |      135.8%  |

To Reproduce

If there's nothing immediately obvious about this bug report or if you think it might be some other part of my system I can try to make a more specific reproduction.

Expected behavior

  • Escape % normally: %% instead of %%%%
  • Table padding is calculated correctly

Screenshots

Software (please complete the following information):

  • OS: MacOS 10.15.7
  • go1.15.3 darwin/amd64

Additional context
None

progress: Support for an Overall Progress tracker

Is your feature request related to a problem? Please describe.
A separate (mostly) non-user managed overall progress tracker would be awesome to keep track of the overall progress in a long running process with an approximate ETA based on the number of trackers done until now.

Provide mechanism to express an error for progress

Is your feature request related to a problem? Please describe.

If I'm tracking the progress of an operation that failed, I'd like the final state of the progress bar to show that it failed instead of showing "done!". It seems that you can just change tracker.Message, but I don't think go guarantees that you can concurrently change that without using sync? ​

Describe the solution you'd like

It would be nice if there was a MarkAsDoneError() function for the tracker that marked it as done, changed the text to red, and set the message to "error" or something like that.

It seems likely that the user would want to print the actual error messages after the progress bar has finished rendering, so providing a custom error message doesn't seem useful.

Line outputted in between, breaks the display. Ideally default StdOut should be changed.

Is your feature request related to a problem? Please describe.
In my code, if an error occurs, there may be some output on the stdout. Using go-pretty, what happens is that on the next render, we go up and re-write that line and it hides it.

What would be perfect, would be for go-pretty to change the default stdout when rendering is initially started, then render its graph and either allow for the original stdout to out in a file or to be emitted after the rendering (or before).

So that for example if a task emits a line such as "Error occured" the display looks like:

Error occurred
tracker
tracker

or

tracker
tracker
Error occurred

Right now the string is totally overwritten and it then makes it hard to understand what really happened. Like if I didn't want my program to emit on Stdout, but there is some case left, finding them would be easier this way.

Add option to not escape HTML for table

I'd like to render HTML tables with links. However it seems the HTML is escaped, so this:

t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{"Item", "Link"})
t.AppendRow(table.Row{"Foo", `<a href="http://example.com">Go to item</a>`})
t.RenderHTML()

Results in this:

<table class="go-pretty-table">
  <thead>
  <tr>
    <th>Item</th>
    <th>Link</th>
  </tr>
  </thead>
  <tbody>
  <tr>
    <td>Foo</td>
    <td>&lt;a href=&#34;http://example.com&#34;&gt;Go to item&lt;/a&gt;</td>
  </tr>
  </tbody>
</table>

Is there a way to disable the HTML escaping?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.