Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 083dedb

Browse files
committed
fix!: Take in byte spans
BREAKING CHANGE: This switches from char spans to byte spans
1 parent 027c95b commit 083dedb

File tree

4 files changed

+44
-38
lines changed

4 files changed

+44
-38
lines changed

‎Cargo.lock‎

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ maintenance = { status = "actively-developed" }
2525

2626
[dependencies]
2727
anstyle = "1.0.4"
28+
itertools = "0.12.1"
2829
unicode-width = "0.1.11"
2930

3031
[dev-dependencies]

‎src/renderer/display_list.rs‎

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
//!
3333
//! The above snippet has been built out of the following structure:
3434
use crate::snippet;
35+
use itertools::FoldWhile::{Continue, Done};
36+
use itertools::Itertools;
3537
use std::fmt::{Display, Write};
3638
use std::{cmp, fmt};
3739

@@ -804,13 +806,27 @@ fn format_header<'a>(
804806

805807
for item in body {
806808
if let DisplayLine::Source {
807-
line: DisplaySourceLine::Content { range, .. },
809+
line: DisplaySourceLine::Content { text, range },
808810
lineno,
809811
..
810812
} = item
811813
{
812814
if main_range >= range.0 && main_range <= range.1 {
813-
col = main_range - range.0 + 1;
815+
let char_column = text
816+
.chars()
817+
.map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0))
818+
.chain(std::iter::once(1)) // treat the end of line as single-width
819+
.enumerate()
820+
.fold_while((0, 0), |(count, acc), (i, width)| {
821+
if acc <= main_range - range.0 {
822+
Continue((i, acc + width))
823+
} else {
824+
Done((count, acc))
825+
}
826+
})
827+
.into_inner()
828+
.0;
829+
col = char_column + 1;
814830
line_offset = lineno.unwrap_or(1);
815831
break;
816832
}
@@ -932,7 +948,7 @@ fn format_body(
932948
has_footer: bool,
933949
margin: Option<Margin>,
934950
) -> Vec<DisplayLine<'_>> {
935-
let source_len = slice.source.chars().count();
951+
let source_len = slice.source.len();
936952
if let Some(bigger) = slice.annotations.iter().find_map(|x| {
937953
// Allow highlighting one past the last character in the source.
938954
if source_len + 1 < x.range.1 {
@@ -955,18 +971,14 @@ fn format_body(
955971
struct LineInfo {
956972
line_start_index: usize,
957973
line_end_index: usize,
958-
// How many spaces each character in the line take up when displayed
959-
char_widths: Vec<usize>,
960974
}
961975

962976
for (line, end_line) in CursorLines::new(slice.source) {
963-
let line_length = line.chars().count();
964-
let line_range = (current_index, current_index + line_length);
965-
let char_widths = line
977+
let line_length: usize = line
966978
.chars()
967979
.map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0))
968-
.chain(std::iter::once(1))// treat the end of line as single-width
969-
.collect::<Vec<_>>();
980+
.sum();
981+
let line_range = (current_index, current_index + line_length);
970982
body.push(DisplayLine::Source {
971983
lineno: Some(current_line),
972984
inline_marks: vec![],
@@ -978,7 +990,6 @@ fn format_body(
978990
line_info.push(LineInfo {
979991
line_start_index: line_range.0,
980992
line_end_index: line_range.1,
981-
char_widths,
982993
});
983994
current_line += 1;
984995
current_index += line_length + end_line as usize;
@@ -991,7 +1002,6 @@ fn format_body(
9911002
LineInfo {
9921003
line_start_index,
9931004
line_end_index,
994-
char_widths,
9951005
},
9961006
) in line_info.into_iter().enumerate()
9971007
{
@@ -1012,16 +1022,8 @@ fn format_body(
10121022
if start >= line_start_index && end <= line_end_index
10131023
|| start == line_end_index && end - start <= 1 =>
10141024
{
1015-
let annotation_start_col = char_widths
1016-
.iter()
1017-
.take(start - line_start_index)
1018-
.sum::<usize>()
1019-
- margin_left;
1020-
let annotation_end_col = char_widths
1021-
.iter()
1022-
.take(end - line_start_index)
1023-
.sum::<usize>()
1024-
- margin_left;
1025+
let annotation_start_col = start - line_start_index - margin_left;
1026+
let annotation_end_col = end - line_start_index - margin_left;
10251027
let range = (annotation_start_col, annotation_end_col);
10261028
body.insert(
10271029
body_idx + 1,
@@ -1064,10 +1066,7 @@ fn format_body(
10641066
});
10651067
}
10661068
} else {
1067-
let annotation_start_col = char_widths
1068-
.iter()
1069-
.take(start - line_start_index)
1070-
.sum::<usize>();
1069+
let annotation_start_col = start - line_start_index;
10711070
let range = (annotation_start_col, annotation_start_col + 1);
10721071
body.insert(
10731072
body_idx + 1,
@@ -1125,11 +1124,7 @@ fn format_body(
11251124
});
11261125
}
11271126

1128-
let end_mark = char_widths
1129-
.iter()
1130-
.take(end - line_start_index)
1131-
.sum::<usize>()
1132-
.saturating_sub(1);
1127+
let end_mark = (end - line_start_index).saturating_sub(1);
11331128
let range = (end_mark - margin_left, (end_mark + 1) - margin_left);
11341129
body.insert(
11351130
body_idx + 1,

‎tests/formatter.rs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fn test_point_to_double_width_characters() {
4141
line_start: 1,
4242
origin: Some("<current file>"),
4343
annotations: vec![SourceAnnotation {
44-
range: (6,8),
44+
range: (12,16),
4545
label: "world",
4646
annotation_type: AnnotationType::Error,
4747
}],
@@ -69,7 +69,7 @@ fn test_point_to_double_width_characters_across_lines() {
6969
line_start: 1,
7070
origin: Some("<current file>"),
7171
annotations: vec![SourceAnnotation {
72-
range: (2,8),
72+
range: (4,15),
7373
label: "Good morning",
7474
annotation_type: AnnotationType::Error,
7575
}],
@@ -100,12 +100,12 @@ fn test_point_to_double_width_characters_multiple() {
100100
origin: Some("<current file>"),
101101
annotations: vec![
102102
SourceAnnotation {
103-
range: (0, 3),
103+
range: (0, 6),
104104
label: "Sushi1",
105105
annotation_type: AnnotationType::Error,
106106
},
107107
SourceAnnotation {
108-
range: (6,8),
108+
range: (11,15),
109109
label: "Sushi2",
110110
annotation_type: AnnotationType::Note,
111111
},
@@ -136,7 +136,7 @@ fn test_point_to_double_width_characters_mixed() {
136136
line_start: 1,
137137
origin: Some("<current file>"),
138138
annotations: vec![SourceAnnotation {
139-
range: (6,14),
139+
range: (12,23),
140140
label: "New world",
141141
annotation_type: AnnotationType::Error,
142142
}],

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /