Skip to content

Commit

Permalink
Properly align comments in unicode lines
Browse files Browse the repository at this point in the history
For an end user, the number of characters in a string is most likely
interpreted as the number of [grapheme cluster](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)s in the string,
which may be different than either the number of unicode codepoints or
bytes. Use the number of graphemes to determine list comment alignment
rather than the byte length of the line.

Closes rust-lang#4151
  • Loading branch information
ayazhafiz authored and bradleypmartin committed May 25, 2020
1 parent e6d5aea commit a5232a2
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
15 changes: 10 additions & 5 deletions rustfmt-core/rustfmt-lib/src/lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::cmp;
use std::iter::Peekable;

use rustc_span::BytePos;
use unicode_segmentation::UnicodeSegmentation;

use crate::comment::{find_comment_end, rewrite_comment, FindUncommented};
use crate::config::lists::*;
Expand Down Expand Up @@ -464,8 +465,10 @@ where

if !starts_with_newline(comment) {
if formatting.align_comments {
let mut comment_alignment =
post_comment_alignment(item_max_width, inner_item.len());
let mut comment_alignment = post_comment_alignment(
item_max_width,
UnicodeSegmentation::graphemes(inner_item.as_str(), true).count(),
);
if first_line_width(&formatted_comment)
+ last_line_width(&result)
+ comment_alignment
Expand All @@ -474,8 +477,10 @@ where
{
item_max_width = None;
formatted_comment = rewrite_post_comment(&mut item_max_width)?;
comment_alignment =
post_comment_alignment(item_max_width, inner_item.len());
comment_alignment = post_comment_alignment(
item_max_width,
UnicodeSegmentation::graphemes(inner_item.as_str(), true).count(),
);
}
for _ in 0..=comment_alignment {
result.push(' ');
Expand Down Expand Up @@ -533,7 +538,7 @@ where
let mut first = true;
for item in items.clone().into_iter().skip(i) {
let item = item.as_ref();
let inner_item_width = item.inner_as_ref().len();
let inner_item_width = UnicodeSegmentation::graphemes(item.inner_as_ref(), true).count();
if !first
&& (item.is_different_group()
|| item.post_comment.is_none()
Expand Down
8 changes: 8 additions & 0 deletions rustfmt-core/rustfmt-lib/tests/target/issue-4151.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
let mappings = [
("gamma", 'ɡ'), // comment 1
("sqrt", '√'), // comment 2
("a", 'a'), // comment 3
("eye", 'ಠ'), // comment 4
];
}

0 comments on commit a5232a2

Please sign in to comment.