• Robert Griesemer's avatar
    go/printer, gofmt: tuned table alignment for better results · 542ea5ad
    Robert Griesemer authored
    The go/printer (and thus gofmt) uses a heuristic to determine
    whether to break alignment between elements of an expression
    list which is spread across multiple lines. The heuristic only
    kicked in if the entry sizes (character length) was above a
    certain threshold (20) and the ratio between the previous and
    current entry size was above a certain value (4).
    
    This heuristic worked reasonably most of the time, but also
    led to unfortunate breaks in many cases where a single entry
    was suddenly much smaller (or larger) then the previous one.
    
    The behavior of gofmt was sufficiently mysterious in some of
    these situations that many issues were filed against it.
    
    The simplest solution to address this problem is to remove
    the heuristic altogether and have a programmer introduce
    empty lines to force different alignments if it improves
    readability. The problem with that approach is that the
    places where it really matters, very long tables with many
    (hundreds, or more) entries, may be machine-generated and
    not "post-processed" by a human (e.g., unicode/utf8/tables.go).
    
    If a single one of those entries is overlong, the result
    would be that the alignment would force all comments or
    values in key:value pairs to be adjusted to that overlong
    value, making the table hard to read (e.g., that entry may
    not even be visible on screen and all other entries seem
    spaced out too wide).
    
    Instead, we opted for a slightly improved heuristic that
    behaves much better for "normal", human-written code.
    
    1) The threshold is increased from 20 to 40. This disables
    the heuristic for many common cases yet even if the alignment
    is not "ideal", 40 is not that many characters per line with
    todays screens, making it very likely that the entire line
    remains "visible" in an editor.
    
    2) Changed the heuristic to not simply look at the size ratio
    between current and previous line, but instead considering the
    geometric mean of the sizes of the previous (aligned) lines.
    This emphasizes the "overall picture" of the previous lines,
    rather than a single one (which might be an outlier).
    
    3) Changed the ratio from 4 to 2.5. Now that we ignore sizes
    below 40, a ratio of 4 would mean that a new entry would have
    to be 4 times bigger (160) or smaller (10) before alignment
    would be broken. A ratio of 2.5 seems more sensible.
    
    Applied updated gofmt to all of src and misc. Also tested
    against several former issues that complained about this
    and verified that the output for the given examples is
    satisfactory (added respective test cases).
    
    Some of the files changed because they were not gofmt-ed
    in the first place.
    
    For #644.
    For #7335.
    For #10392.
    (and probably more related issues)
    
    Fixes #22852.
    
    Change-Id: I5e48b3d3b157a5cf2d649833b7297b33f43a6f6e
    542ea5ad
Name
Last commit
Last update
..
all Loading commit data...
internal Loading commit data...
testdata Loading commit data...
README Loading commit data...
asmdecl.go Loading commit data...
assign.go Loading commit data...
atomic.go Loading commit data...
bool.go Loading commit data...
buildtag.go Loading commit data...
cgo.go Loading commit data...
composite.go Loading commit data...
copylock.go Loading commit data...
dead.go Loading commit data...
deadcode.go Loading commit data...
doc.go Loading commit data...
httpresponse.go Loading commit data...
lostcancel.go Loading commit data...
main.go Loading commit data...
method.go Loading commit data...
nilfunc.go Loading commit data...
print.go Loading commit data...
rangeloop.go Loading commit data...
shadow.go Loading commit data...
shift.go Loading commit data...
structtag.go Loading commit data...
tests.go Loading commit data...
types.go Loading commit data...
unsafeptr.go Loading commit data...
unused.go Loading commit data...
vet_test.go Loading commit data...