github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+incompatible/util/ui/table.go (about)

     1  package ui
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/fatih/color"
     8  	"github.com/lunixbochs/vtclean"
     9  	runewidth "github.com/mattn/go-runewidth"
    10  )
    11  
    12  // DefaultTableSpacePadding is the default space padding in tables.
    13  const DefaultTableSpacePadding = 3
    14  
    15  // DisplayKeyValueTable outputs a matrix of strings as a table to UI.Out.
    16  // Prefix will be prepended to each row and padding adds the specified number
    17  // of spaces between columns. The final columns may wrap to multiple lines but
    18  // will still be confined to the last column. Wrapping will occur on word
    19  // boundaries.
    20  func (ui *UI) DisplayKeyValueTable(prefix string, table [][]string, padding int) {
    21  	rows := len(table)
    22  	if rows == 0 {
    23  		return
    24  	}
    25  
    26  	columns := len(table[0])
    27  
    28  	if columns < 2 || !ui.IsTTY {
    29  		ui.DisplayNonWrappingTable(prefix, table, padding)
    30  		return
    31  	}
    32  
    33  	ui.displayWrappingTableWithWidth(prefix, table, padding)
    34  }
    35  
    36  // DisplayNonWrappingTable outputs a matrix of strings as a table to UI.Out.
    37  // Prefix will be prepended to each row and padding adds the specified number
    38  // of spaces between columns.
    39  func (ui *UI) DisplayNonWrappingTable(prefix string, table [][]string, padding int) {
    40  	ui.terminalLock.Lock()
    41  	defer ui.terminalLock.Unlock()
    42  
    43  	if len(table) == 0 {
    44  		return
    45  	}
    46  
    47  	var columnPadding []int
    48  
    49  	rows := len(table)
    50  	columns := len(table[0])
    51  	for col := 0; col < columns; col++ {
    52  		var max int
    53  		for row := 0; row < rows; row++ {
    54  			if strLen := wordSize(table[row][col]); max < strLen {
    55  				max = strLen
    56  			}
    57  		}
    58  		columnPadding = append(columnPadding, max+padding)
    59  	}
    60  
    61  	for row := 0; row < rows; row++ {
    62  		fmt.Fprintf(ui.Out, prefix)
    63  		for col := 0; col < columns; col++ {
    64  			data := table[row][col]
    65  			var addedPadding int
    66  			if col+1 != columns {
    67  				addedPadding = columnPadding[col] - wordSize(data)
    68  			}
    69  			fmt.Fprintf(ui.Out, "%s%s", data, strings.Repeat(" ", addedPadding))
    70  		}
    71  		fmt.Fprintf(ui.Out, "\n")
    72  	}
    73  }
    74  
    75  // DisplayTableWithHeader outputs a simple non-wrapping table with bolded
    76  // headers.
    77  func (ui *UI) DisplayTableWithHeader(prefix string, table [][]string, padding int) {
    78  	if len(table) == 0 {
    79  		return
    80  	}
    81  	for i, str := range table[0] {
    82  		table[0][i] = ui.modifyColor(str, color.New(color.Bold))
    83  	}
    84  
    85  	ui.DisplayNonWrappingTable(prefix, table, padding)
    86  }
    87  
    88  func wordSize(str string) int {
    89  	cleanStr := vtclean.Clean(str, false)
    90  	return runewidth.StringWidth(cleanStr)
    91  }