func tagNamesForFile(store *storage.Storage, tx *storage.Tx, fileId entities.FileId, explicitOnly, colour bool) ([]string, error) { fileTags, err := store.FileTagsByFileId(tx, fileId, explicitOnly) if err != nil { return nil, fmt.Errorf("could not retrieve file-tags for file '%v': %v", fileId, err) } taggings := make([]string, len(fileTags)) for index, fileTag := range fileTags { tag, err := store.Tag(tx, fileTag.TagId) if err != nil { return nil, fmt.Errorf("could not lookup tag: %v", err) } if tag == nil { return nil, fmt.Errorf("tag '%v' does not exist", fileTag.TagId) } var tagging string if fileTag.ValueId == 0 { tagging = formatTagValueName(tag.Name, "", colour, fileTag.Implicit, fileTag.Explicit) } else { value, err := store.Value(tx, fileTag.ValueId) if err != nil { return nil, fmt.Errorf("could not lookup value: %v", err) } if value == nil { return nil, fmt.Errorf("value '%v' does not exist", fileTag.ValueId) } tagging = formatTagValueName(tag.Name, value.Name, colour, fileTag.Implicit, fileTag.Explicit) } taggings[index] = tagging } ansi.Sort(taggings) return taggings, nil }
func PrintColumnsWidth(items []string, width int) { ansi.Sort(items) padding := 2 // minimum column padding var colWidths []int var calcWidth int cols := 0 rows := 1 // add a row until everything fits or we have every item on its own row for calcWidth = width + 1; calcWidth > width && rows <= len(items); rows++ { cols = 0 colWidths = make([]int, 0, width) calcWidth = -padding // last column has no padding // try to place items into columns for index, item := range items { col := index / rows if col >= len(colWidths) { // add column cols++ colWidths = append(colWidths, 0) calcWidth += padding } itemLength := len(ansi.Strip(item)) if itemLength > colWidths[col] { // widen column calcWidth += -colWidths[col] + itemLength colWidths[col] = itemLength } if calcWidth > width { // exceeded width break } } } rows-- // apportion any remaining space between the columns if cols > 2 && rows > 1 { padding = (width-calcWidth)/(cols-1) + 2 if padding < 2 { padding = 2 } } // render for rowIndex := 0; rowIndex < rows; rowIndex++ { for columnIndex := 0; columnIndex < cols; columnIndex++ { itemIndex := rows*columnIndex + rowIndex if itemIndex >= len(items) { break } item := items[itemIndex] fmt.Print(item) if columnIndex < cols-1 { itemLength := len(ansi.Strip(item)) padding := (colWidths[columnIndex] + padding) - itemLength fmt.Print(strings.Repeat(" ", padding)) } } fmt.Println() } }