@@ -1590,7 +1590,6 @@ proc reportModules {search_queries header hsgrkey hstyle show_mtime show_idx\
15901590 }
15911591
15921592 set len_list {}
1593- set max_len 0
15941593 # dictionary-sort results unless if output order is specified
15951594 if {![ llength $mod_list_order ] } {
15961595 set clean_list [ lsort -dictionary $clean_list ]
@@ -1607,9 +1606,6 @@ proc reportModules {search_queries header hsgrkey hstyle show_mtime show_idx\
16071606 # compute display element length list on sorted result
16081607 lappend display_list $sgrmap($disp)
16091608 lappend len_list $lenmap($disp)
1610- if {$lenmap($disp) > $max_len } {
1611- set max_len $lenmap($disp)
1612- }
16131609 }
16141610 }
16151611
@@ -1622,7 +1618,7 @@ proc reportModules {search_queries header hsgrkey hstyle show_mtime show_idx\
16221618
16231619 # output formatted elements
16241620 displayElementList $header $hsgrkey $hstyle $one_per_line $show_idx 1\
1625- $display_list $len_list $max_len $ via
1621+ $display_list $len_list $via
16261622}
16271623
16281624proc showModulePath {} {
@@ -1667,10 +1663,10 @@ proc displaySeparatorLine {{title {}} {sgrkey {}} {extra {}}} {
16671663# get a list of elements and print them in a column or in a
16681664# one-per-line fashion
16691665proc displayElementList {header sgrkey hstyle one_per_line display_idx\
1670- start_idx display_list {len_list {}} {max_len 0} { via {}}} {
1666+ start_idx display_list {len_list {}} {via {}}} {
16711667 set elt_cnt [ llength $display_list ]
16721668 reportDebug " header=$header , sgrkey=$sgrkey , hstyle=$hstyle ,\
1673- elt_cnt=$elt_cnt , max_len= $max_len , one_per_line=$one_per_line ,\
1669+ elt_cnt=$elt_cnt , one_per_line=$one_per_line ,\
16741670 display_idx=$display_idx , start_idx=$start_idx , via=$via "
16751671
16761672 # end proc if no element are to print
@@ -1716,97 +1712,10 @@ proc displayElementList {header sgrkey hstyle one_per_line display_idx\
17161712 # save room for numbers and spacing: 2 or 3 digits + ) + space
17171713 set elt_prefix_len [ expr {$display_idx ? $idx_len + 2 : {0}}]
17181714 # save room for two spaces after element
1719- set elt_suffix_len 2
1720-
1721- # compute rows*cols grid size with optimized column number
1722- # the size of each column is computed to display as much column
1723- # as possible on each line
1724- incr max_len $elt_suffix_len
1725- foreach len $len_list {
1726- lappend elt_len [ incr len $elt_suffix_len ]
1727- }
1728-
17291715 set tty_cols [ getState term_columns]
1730- # find valid grid by starting with non-optimized solution where each
1731- # column length is equal to the length of the biggest element to display
1732- set cur_cols [ tcl::mathfunc::max [expr {int(($tty_cols - \
1733- $elt_prefix_len ) / $max_len )}] 0]
1734- # when display is found too short to display even one column
1735- if {$cur_cols == 0} {
1736- set cols 1
1737- set rows $elt_cnt
1738- array set col_width [ list 0 $max_len ]
1739- } else {
1740- set cols 0
1741- set rows 0
1742- }
1743- set last_round 0
1744- set restart_loop 0
1745- while {$cur_cols > $cols } {
1746- if {!$restart_loop } {
1747- if {$last_round } {
1748- incr cur_rows
1749- } else {
1750- set cur_rows [ expr {int(ceil(double($elt_cnt ) / $cur_cols ))}]
1751- }
1752- for {set i 0} {$i < $cur_cols } {incr i} {
1753- set cur_col_width($i ) 0
1754- }
1755- for {set i 0} {$i < $cur_rows } {incr i} {
1756- set row_width($i ) 0
1757- }
1758- set istart 0
1759- } else {
1760- ##nagelfar ignore Unknown variable
1761- set istart [ expr {$col * $cur_rows }]
1762- # only remove width of elements from current col
1763- for {set row 0} {$row < ($i % $cur_rows )} {incr row} {
1764- ##nagelfar ignore Unknown variable
1765- incr row_width($row ) -[ expr {$pre_col_width + $elt_prefix_len }]
1766- }
1767- }
1768- set restart_loop 0
1769- for {set i $istart } {$i < $elt_cnt } {incr i} {
1770- set col [ expr {int($i / $cur_rows )}]
1771- set row [ expr {$i % $cur_rows }]
1772- # restart loop if a column width change
1773- if {[ lindex $elt_len $i ] > $cur_col_width($col) } {
1774- set pre_col_width $cur_col_width($col)
1775- set cur_col_width($col ) [ lindex $elt_len $i ]
1776- set restart_loop 1
1777- break
1778- }
1779- # end search of maximum number of columns if computed row width
1780- # is larger than terminal width
1781- if {[ incr row_width($row ) +[expr {$cur_col_width($col) \
1782- + $elt_prefix_len }] ] > $tty_cols } {
1783- # start last optimization pass by increasing row number until
1784- # reaching number used for previous column number, by doing so
1785- # this number of column may pass in terminal width, if not
1786- # fallback to previous number of column
1787- if {$last_round && $cur_rows == $rows } {
1788- incr cur_cols -1
1789- } else {
1790- set last_round 1
1791- }
1792- break
1793- }
1794- }
1795- # went through all elements without reaching terminal width limit so
1796- # this number of column solution is valid, try next with a greater
1797- # column number
1798- if {$i == $elt_cnt } {
1799- set cols $cur_cols
1800- set rows $cur_rows
1801- array set col_width [ array get cur_col_width]
1802- # number of column is fixed if last optimization round has started
1803- # reach end also if there is only one row of results
1804- if {!$last_round && $rows > 1} {
1805- incr cur_cols
1806- }
1807- }
18081716
1809- }
1717+ lassign [ compute_output_grid $tty_cols $len_list $elt_prefix_len ] rows\
1718+ cols cols_width
18101719 reportDebug list=$display_list
18111720 reportDebug " rows/cols=$rows /$cols ,\
18121721 lastcol_item_cnt=[expr {int($elt_cnt % $rows )}]"
@@ -1821,7 +1730,8 @@ proc displayElementList {header sgrkey hstyle one_per_line display_idx\
18211730 }
18221731 # cannot use 'format' as strings may contain SGR codes
18231732 append displist [ lindex $display_list $index ] [ string repeat\
1824- { } [expr {$col_width($col) - [lindex $len_list $index ] }]]
1733+ { } [expr {[lindex $cols_width $col ] - [ lindex $len_list \
1734+ $index ] - $elt_prefix_len }]]
18251735 }
18261736 }
18271737 append displist \n
@@ -1834,6 +1744,58 @@ proc displayElementList {header sgrkey hstyle one_per_line display_idx\
18341744 reportSeparateNextContent
18351745}
18361746
1747+ # returns rows, cols and each col width of the output grid with most cols
1748+ proc compute_output_grid {out_width len_list prefix_len} {
1749+ set col_sepa_len 2
1750+ set elt_count [ llength $len_list ]
1751+ if {!$elt_count } {
1752+ return {0 0 {0}}
1753+ }
1754+
1755+ # start with max possible columns guessed from shortest element in list
1756+ set min_len [ tcl::mathfunc::min {*}$len_list ]
1757+ set col_min [ expr {$prefix_len + $min_len + $col_sepa_len }]
1758+ # exact same output with 1 elt to print whether width is tiny or large
1759+ set max_cols [ tcl::mathfunc::min $elt_count \
1760+ [expr {int(floor(double($out_width ) / $col_min ))}] ]
1761+
1762+ for {set cols $max_cols } {$cols > 1} {incr cols -1} {
1763+ set rows [ expr {int(ceil(double($elt_count ) / $cols ))}]
1764+ set cols_width {}
1765+
1766+ # compute width of each column (max length among elements in that col)
1767+ for {set c 0} {$c < $cols } {incr c} {
1768+ set idx_first [ expr {$c * $rows }]
1769+ set idx_last [ expr {$idx_first + $rows - 1}]
1770+ # stop when no more element for available columns
1771+ if {$idx_first >= $elt_count } {
1772+ break
1773+ }
1774+ set col_max [ tcl::mathfunc::max {*}[lrange $len_list $idx_first \
1775+ $idx_last ] ]
1776+ set col_width [ expr {$prefix_len + $col_max }]
1777+ # column separator suffix is not added on last column
1778+ if {($c + 1) < $cols && ($idx_last + 1) < $elt_count } {
1779+ incr col_width $col_sepa_len
1780+ }
1781+ lappend cols_width $col_width
1782+
1783+ # immediately try fewer columns if we already exceed output grid
1784+ if {[ tcl::mathop::+ {*}$cols_width ] > $out_width } {
1785+ break
1786+ }
1787+ }
1788+
1789+ # ff it fits, this is the maximum cols possible
1790+ if {[ tcl::mathop::+ {*}$cols_width ] <= $out_width } {
1791+ return [ list $rows $cols $cols_width ]
1792+ }
1793+ }
1794+
1795+ # fits in 1 column
1796+ return [ list $elt_count 1 {0}]
1797+ }
1798+
18371799# Report an output key to help understand what the SGR used on this output
18381800# correspond to
18391801proc displayKey {} {
@@ -1936,19 +1898,11 @@ proc displayKey {} {
19361898 }
19371899 }
19381900
1939- # find largest element
1940- set max_len 0
1941- foreach len $len_list {
1942- if {$len > $max_len } {
1943- set max_len $len
1944- }
1945- }
1946-
19471901 if {[ llength $display_list ] } {
19481902 # display header
19491903 report Key:
19501904 # display key content
1951- displayElementList noheader {} {} 0 0 0 $display_list $len_list $max_len
1905+ displayElementList noheader {} {} 0 0 0 $display_list $len_list
19521906 }
19531907}
19541908
0 commit comments