Skip to content

Commit f23a41a

Browse files
authored
Properly align comments in unicode lines (#4171)
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 #4151
2 parents 479128b + f9e68a0 commit f23a41a

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

rustfmt-core/rustfmt-lib/src/lists.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::cmp;
44
use std::iter::Peekable;
55

66
use rustc_span::BytePos;
7+
use unicode_segmentation::UnicodeSegmentation;
78

89
use crate::comment::{find_comment_end, rewrite_comment, FindUncommented};
910
use crate::config::lists::*;
@@ -464,8 +465,10 @@ where
464465

465466
if !starts_with_newline(comment) {
466467
if formatting.align_comments {
467-
let mut comment_alignment =
468-
post_comment_alignment(item_max_width, inner_item.len());
468+
let mut comment_alignment = post_comment_alignment(
469+
item_max_width,
470+
UnicodeSegmentation::graphemes(inner_item.as_str(), true).count(),
471+
);
469472
if first_line_width(&formatted_comment)
470473
+ last_line_width(&result)
471474
+ comment_alignment
@@ -474,8 +477,10 @@ where
474477
{
475478
item_max_width = None;
476479
formatted_comment = rewrite_post_comment(&mut item_max_width)?;
477-
comment_alignment =
478-
post_comment_alignment(item_max_width, inner_item.len());
480+
comment_alignment = post_comment_alignment(
481+
item_max_width,
482+
UnicodeSegmentation::graphemes(inner_item.as_str(), true).count(),
483+
);
479484
}
480485
for _ in 0..=comment_alignment {
481486
result.push(' ');
@@ -533,7 +538,7 @@ where
533538
let mut first = true;
534539
for item in items.clone().into_iter().skip(i) {
535540
let item = item.as_ref();
536-
let inner_item_width = item.inner_as_ref().len();
541+
let inner_item_width = UnicodeSegmentation::graphemes(item.inner_as_ref(), true).count();
537542
if !first
538543
&& (item.is_different_group()
539544
|| item.post_comment.is_none()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
let mappings = [
3+
("gamma", 'ɡ'), // comment 1
4+
("sqrt", '√'), // comment 2
5+
("a", 'a'), // comment 3
6+
("eye", 'ಠ'), // comment 4
7+
];
8+
}

0 commit comments

Comments
 (0)