Skip to content

Commit f9e68a0

Browse files
committed
Properly align comments in unicode lines
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
1 parent 12564f1 commit f9e68a0

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)