diff --git a/pkg/utils/formatting.go b/pkg/utils/formatting.go index 241d69732..47e17b612 100644 --- a/pkg/utils/formatting.go +++ b/pkg/utils/formatting.go @@ -40,7 +40,7 @@ func WithPadding(str string, padding int, alignment Alignment) string { // returns a list of strings that should be joined with "\n", and an array of // the column positions func RenderDisplayStrings(displayStringsArr [][]string, columnAlignments []Alignment) ([]string, []int) { - displayStringsArr, columnAlignments = excludeBlankColumns(displayStringsArr, columnAlignments) + displayStringsArr, columnAlignments, removedColumns := excludeBlankColumns(displayStringsArr, columnAlignments) padWidths := getPadWidths(displayStringsArr) columnConfigs := make([]ColumnConfig, len(padWidths)) columnPositions := make([]int, len(padWidths)+1) @@ -58,13 +58,21 @@ func RenderDisplayStrings(displayStringsArr [][]string, columnAlignments []Align } columnPositions[i+1] = columnPositions[i] + padWidth + 1 } + // Add the removed columns back into columnPositions (a removed column gets + // the same position as the following column); clients should be able to rely + // on them all to be there + for _, removedColumn := range removedColumns { + if removedColumn < len(columnPositions) { + columnPositions = slices.Insert(columnPositions, removedColumn, columnPositions[removedColumn]) + } + } return getPaddedDisplayStrings(displayStringsArr, columnConfigs), columnPositions } // NOTE: this mutates the input slice for the sake of performance -func excludeBlankColumns(displayStringsArr [][]string, columnAlignments []Alignment) ([][]string, []Alignment) { +func excludeBlankColumns(displayStringsArr [][]string, columnAlignments []Alignment) ([][]string, []Alignment, []int) { if len(displayStringsArr) == 0 { - return displayStringsArr, columnAlignments + return displayStringsArr, columnAlignments, []int{} } // if all rows share a blank column, we want to remove that column @@ -80,7 +88,7 @@ outer: } if len(toRemove) == 0 { - return displayStringsArr, columnAlignments + return displayStringsArr, columnAlignments, []int{} } // remove the columns @@ -97,7 +105,7 @@ outer: } } - return displayStringsArr, columnAlignments + return displayStringsArr, columnAlignments, toRemove } func getPaddedDisplayStrings(stringArrays [][]string, columnConfigs []ColumnConfig) []string { diff --git a/pkg/utils/formatting_test.go b/pkg/utils/formatting_test.go index a91a96ea1..3858fd2ec 100644 --- a/pkg/utils/formatting_test.go +++ b/pkg/utils/formatting_test.go @@ -169,7 +169,7 @@ func TestRenderDisplayStrings(t *testing.T) { input: [][]string{{""}, {""}}, columnAlignments: nil, expectedOutput: "", - expectedColumnPositions: []int{0}, + expectedColumnPositions: []int{0, 0}, }, { input: [][]string{{"a"}, {""}}, @@ -193,43 +193,49 @@ func TestRenderDisplayStrings(t *testing.T) { input: [][]string{{"a", "", "c"}, {"d", "", "f"}}, columnAlignments: nil, expectedOutput: "a c\nd f", - expectedColumnPositions: []int{0, 2}, + expectedColumnPositions: []int{0, 2, 2}, }, { input: [][]string{{"a", "", "c", ""}, {"d", "", "f", ""}}, columnAlignments: nil, expectedOutput: "a c\nd f", - expectedColumnPositions: []int{0, 2}, + expectedColumnPositions: []int{0, 2, 2}, }, { input: [][]string{{"abc", "", "d", ""}, {"e", "", "f", ""}}, columnAlignments: nil, expectedOutput: "abc d\ne f", - expectedColumnPositions: []int{0, 4}, + expectedColumnPositions: []int{0, 4, 4}, + }, + { + input: [][]string{{"", "abc", "", "", "d", "e"}, {"", "f", "", "", "g", "h"}}, + columnAlignments: nil, + expectedOutput: "abc d e\nf g h", + expectedColumnPositions: []int{0, 0, 4, 4, 4, 6}, }, { input: [][]string{{"abc", "", "d", ""}, {"e", "", "f", ""}}, columnAlignments: []Alignment{AlignLeft, AlignLeft}, // same as nil (default) expectedOutput: "abc d\ne f", - expectedColumnPositions: []int{0, 4}, + expectedColumnPositions: []int{0, 4, 4}, }, { input: [][]string{{"abc", "", "d", ""}, {"e", "", "f", ""}}, columnAlignments: []Alignment{AlignRight, AlignLeft}, expectedOutput: "abc d\n e f", - expectedColumnPositions: []int{0, 4}, + expectedColumnPositions: []int{0, 4, 4}, }, { input: [][]string{{"a", "", "bcd", "efg", "h"}, {"i", "", "j", "k", "l"}}, columnAlignments: []Alignment{AlignLeft, AlignLeft, AlignRight, AlignLeft}, expectedOutput: "a bcd efg h\ni j k l", - expectedColumnPositions: []int{0, 2, 6, 10}, + expectedColumnPositions: []int{0, 2, 2, 6, 10}, }, { input: [][]string{{"abc", "", "d", ""}, {"e", "", "f", ""}}, columnAlignments: []Alignment{AlignRight}, // gracefully defaults unspecified columns to left-align expectedOutput: "abc d\n e f", - expectedColumnPositions: []int{0, 4}, + expectedColumnPositions: []int{0, 4, 4}, }, }