Skip to content

Fix wrong indenting with hard tabs in binop pairs#6883

Open
matthewhughes934 wants to merge 3 commits into
rust-lang:mainfrom
matthewhughes934:hard-tabs-issue-6859
Open

Fix wrong indenting with hard tabs in binop pairs#6883
matthewhughes934 wants to merge 3 commits into
rust-lang:mainfrom
matthewhughes934:hard-tabs-issue-6859

Conversation

@matthewhughes934
Copy link
Copy Markdown
Contributor

@matthewhughes934 matthewhughes934 commented May 5, 2026

This changeset is split up into 3 patches. The first two are some small
changes (in src/utils.rs) to help make the third commit, the bulk of
this changeset, a bit simpler. The third commit introduces an additional
argument to a util function, and so requires updating all its callsites.

All changes outside of src/utils.rs should just be updating these
callsites (with the exception of an added test). The commits:

  • Avoid passing entire config to get_prefix_space_width

    And pass only the required attribute, similarly to wrap_str

  • Rewrite get_prefix_space_width to also give the prefix end

    This is required so that last_line_width knows the width of the prefix
    and where the rest of the string starts.

    Rename the function appropriately and replace a call to str::chars
    with str::char_indices to make it more explicit we want an index here
    (though the two are equivalent in this case, since we only loop over
    single byte characters)

  • Teach last_line_width about config.tab_spaces

    So that the line width is calculated as the rendered width of any
    trailing space plus the unicode width of the rest of the string.
    That is, for example, so that the line:

      \s\s\s\ssome_func();
    

    Would have the same length as

      \tsome_func();
    

    Assuming tab_spaces=4.

    This fixes a issue where the formatting a collection of binary
    operations would depend on whether hard of soft tabs were used.
    Specifically in the change to the call of last_line_width at line 135
    of src/pairs.rs: the inconsistency above meant under some conditions
    when using hard tabs we could satisfy the condition on that line and
    drop into the block to snuggle the lines together, where with soft tabs
    a different width would be computed and we'd avoid snuggling them. A
    test has been added covering this case.

@rustbot rustbot added the S-waiting-on-author Status: awaiting some action (such as code changes or more information) from the author. label May 5, 2026
And pass only the required attribute, similarly to `wrap_str`
This is required so that `last_line_width` knows the width of the prefix
and where the rest of the string starts.

Rename the function appropriately and replace a call to `str::chars`
with `str::char_indices` to make it more explicit we want an index here
(though the two are equivalent in this case, since we only loop over
single byte characters)
So that the line width is calculated as the rendered width of any
trailing space plus the unicode width of the rest of the string.
That is, for example, so that the line:

    \s\s\s\ssome_func();

Would have the same length as

    \tsome_func();

Assuming `tab_spaces=4`.

This fixes a issue where the formatting a collection of binary
operations would depend on whether hard of soft tabs were used.
Specifically in the change to the call of `last_line_width` at line 135
of `src/pairs.rs`: the inconsistency above meant under some conditions
when using hard tabs we could satisfy the condition on that line and
drop into the block to snuggle the lines together, where with soft tabs
a different width would be computed and we'd avoid snuggling them. A
test has been added covering this case.
@matthewhughes934 matthewhughes934 marked this pull request as ready for review May 26, 2026 19:14
@rustbot rustbot added S-waiting-on-review Status: awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: awaiting some action (such as code changes or more information) from the author. labels May 26, 2026
@matthewhughes934
Copy link
Copy Markdown
Contributor Author

two notes/questions:

  1. Is last_line_width still an appropriate name? Is it well understood (in the context of this repo) that a line's "width" includes the configured expansion of tabs to the appropriate number of spaces (or would other devs expect e.g. just the unicode width)?
  2. There is also first_line_width that still does the same computation as last_line_width used to do, so I expect that there might be some bugs related to that too (but haven't looked). If this change is accepted I think that function should be updated to (as a separate change)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants