(ctx context.Context, shellName string, columnNames []string, rows []table.Row)
| 580 | var bigQueryResults []table.Row |
| 581 | |
| 582 | func makeTableColumns(ctx context.Context, shellName string, columnNames []string, rows []table.Row) ([]table.Column, error) { |
| 583 | // Handle an initial query with no results |
| 584 | if len(rows) == 0 || len(rows[0]) == 0 { |
| 585 | allRows, _, err := getRows(ctx, columnNames, shellName, hctx.GetConf(ctx).DefaultFilter, "", 25) |
| 586 | if err != nil { |
| 587 | return nil, err |
| 588 | } |
| 589 | if len(allRows) == 0 || len(allRows[0]) == 0 { |
| 590 | // There are truly zero history entries. Let's still display a table in this case rather than erroring out. |
| 591 | allRows = make([]table.Row, 0) |
| 592 | row := make([]string, 0) |
| 593 | for range columnNames { |
| 594 | row = append(row, " ") |
| 595 | } |
| 596 | allRows = append(allRows, row) |
| 597 | } |
| 598 | return makeTableColumns(ctx, shellName, columnNames, allRows) |
| 599 | } |
| 600 | |
| 601 | // Calculate the minimum amount of space that we need for each column for the current actual search |
| 602 | columnWidths := calculateColumnWidths(rows, len(columnNames)) |
| 603 | totalWidth := (len(columnWidths) + 1) * 2 // The amount of space needed for the table padding |
| 604 | for i, name := range columnNames { |
| 605 | columnWidths[i] = max(columnWidths[i], len(name)) |
| 606 | totalWidth += columnWidths[i] |
| 607 | } |
| 608 | |
| 609 | // Calculate the maximum column width that is useful for each column if we search for the empty string |
| 610 | if bigQueryResults == nil { |
| 611 | bigRows, _, err := getRows(ctx, columnNames, shellName, "", "", 1000) |
| 612 | if err != nil { |
| 613 | return nil, err |
| 614 | } |
| 615 | bigQueryResults = bigRows |
| 616 | } |
| 617 | maximumColumnWidths := calculateColumnWidths(bigQueryResults, len(columnNames)) |
| 618 | |
| 619 | // Get the actual terminal width. If we're below this, opportunistically add some padding aiming for the maximum column widths |
| 620 | terminalWidth, _, err := getTerminalSize() |
| 621 | if err != nil { |
| 622 | return nil, fmt.Errorf("failed to get terminal size: %w", err) |
| 623 | } |
| 624 | for totalWidth < (terminalWidth - len(columnNames)) { |
| 625 | prevTotalWidth := totalWidth |
| 626 | for i := range columnNames { |
| 627 | if columnWidths[i] < maximumColumnWidths[i]+5 { |
| 628 | columnWidths[i] += 1 |
| 629 | totalWidth += 1 |
| 630 | } |
| 631 | } |
| 632 | if totalWidth == prevTotalWidth { |
| 633 | break |
| 634 | } |
| 635 | } |
| 636 | |
| 637 | // And if we are too large from the initial query, let's shrink things to make the table fit. We'll use the heuristic of always shrinking the widest column. |
| 638 | for totalWidth > terminalWidth { |
| 639 | largestColumnIdx := -1 |
no test coverage detected