Movatterモバイル変換


[0]ホーム

URL:


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

Commitac31f8a

Browse files
committed
Fix display of annotation for double width characters
1 parenta0e10a8 commitac31f8a

File tree

2 files changed

+85
-21
lines changed

2 files changed

+85
-21
lines changed

‎src/display_list/from_snippet.rs‎

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,23 @@ fn format_body(
293293
letmut body =vec![];
294294
letmut current_line = slice.line_start;
295295
letmut current_index =0;
296-
letmut line_index_ranges =vec![];
296+
letmut line_info =vec![];
297+
298+
structLineInfo{
299+
line_start_index:usize,
300+
line_end_index:usize,
301+
// How many spaces each character in the line take up when displayed
302+
char_widths:Vec<usize>,
303+
}
297304

298305
for(line, end_line)inCursorLines::new(slice.source){
299306
let line_length = line.chars().count();
300307
let line_range =(current_index, current_index + line_length);
308+
let char_widths = line
309+
.chars()
310+
.map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0))
311+
.chain(std::iter::once(1))// treat the end of line as signle-width
312+
.collect::<Vec<_>>();
301313
body.push(DisplayLine::Source{
302314
lineno:Some(current_line),
303315
inline_marks:vec![],
@@ -306,16 +318,28 @@ fn format_body(
306318
range: line_range,
307319
},
308320
});
309-
line_index_ranges.push(line_range);
321+
line_info.push(LineInfo{
322+
line_start_index: line_range.0,
323+
line_end_index: line_range.1,
324+
char_widths,
325+
});
310326
current_line +=1;
311327
current_index += line_length + end_lineasusize;
312328
}
313329

314330
letmut annotation_line_count =0;
315331
letmut annotations = slice.annotations;
316-
for(idx,(line_start, line_end))in line_index_ranges.into_iter().enumerate(){
332+
for(
333+
idx,
334+
LineInfo{
335+
line_start_index,
336+
line_end_index,
337+
char_widths,
338+
},
339+
)in line_info.into_iter().enumerate()
340+
{
317341
let margin_left = margin
318-
.map(|m| m.left(line_end -line_start))
342+
.map(|m| m.left(line_end_index -line_start_index))
319343
.unwrap_or_default();
320344
// It would be nice to use filter_drain here once it's stable.
321345
annotations = annotations
@@ -328,15 +352,22 @@ fn format_body(
328352
_ =>DisplayAnnotationType::from(annotation.annotation_type),
329353
};
330354
match annotation.range{
331-
(start, _)if start >line_end =>true,
355+
(start, _)if start >line_end_index =>true,
332356
(start, end)
333-
if start >=line_start && end <=line_end
334-
|| start ==line_end && end - start <=1 =>
357+
if start >=line_start_index && end <=line_end_index
358+
|| start ==line_end_index && end - start <=1 =>
335359
{
336-
let range =(
337-
(start - line_start) - margin_left,
338-
(end - line_start) - margin_left,
339-
);
360+
let annotation_start_col = char_widths
361+
.iter()
362+
.take(start - line_start_index)
363+
.sum::<usize>()
364+
- margin_left;
365+
let annotation_end_col = char_widths
366+
.iter()
367+
.take(end - line_start_index)
368+
.sum::<usize>()
369+
- margin_left;
370+
let range =(annotation_start_col, annotation_end_col);
340371
body.insert(
341372
body_idx +1,
342373
DisplayLine::Source{
@@ -359,8 +390,12 @@ fn format_body(
359390
annotation_line_count +=1;
360391
false
361392
}
362-
(start, end)if start >= line_start && start <= line_end && end > line_end =>{
363-
if start - line_start ==0{
393+
(start, end)
394+
if start >= line_start_index
395+
&& start <= line_end_index
396+
&& end > line_end_index =>
397+
{
398+
if start - line_start_index ==0{
364399
ifletDisplayLine::Source{
365400
refmut inline_marks,
366401
..
@@ -374,7 +409,7 @@ fn format_body(
374409
});
375410
}
376411
}else{
377-
let range =(start -line_start, start -line_start +1);
412+
let range =(start -line_start_index, start -line_start_index +1);
378413
body.insert(
379414
body_idx +1,
380415
DisplayLine::Source{
@@ -398,7 +433,7 @@ fn format_body(
398433
}
399434
true
400435
}
401-
(start, end)if start <line_start && end >line_end =>{
436+
(start, end)if start <line_start_index && end >line_end_index =>{
402437
ifletDisplayLine::Source{
403438
refmut inline_marks,
404439
..
@@ -413,7 +448,11 @@ fn format_body(
413448
}
414449
true
415450
}
416-
(start, end)if start < line_start && end >= line_start && end <= line_end =>{
451+
(start, end)
452+
if start < line_start_index
453+
&& end >= line_start_index
454+
&& end <= line_end_index =>
455+
{
417456
ifletDisplayLine::Source{
418457
refmut inline_marks,
419458
..
@@ -427,11 +466,8 @@ fn format_body(
427466
});
428467
}
429468

430-
let end_mark =(end - line_start).saturating_sub(1);
431-
let range =(
432-
end_mark - margin_left,
433-
(end_mark +1) - margin_left,
434-
);
469+
let end_mark =(end - line_start_index).saturating_sub(1);
470+
let range =(end_mark - margin_left,(end_mark +1) - margin_left);
435471
body.insert(
436472
body_idx +1,
437473
DisplayLine::Source{

‎tests/formatter.rs‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,31 @@ fn test_i_29() {
550550

551551
assert_eq!(DisplayList::from(snippets).to_string(), expected);
552552
}
553+
554+
#[test]
555+
fntest_point_to_double_width_characters(){
556+
let snippets =Snippet{
557+
slices:vec![snippet::Slice{
558+
source:"こんにちは、世界",
559+
line_start:1,
560+
origin:Some("<current file>"),
561+
annotations: vec![snippet::SourceAnnotation{
562+
range:(6,8),
563+
label:"world",
564+
annotation_type: snippet::AnnotationType::Error,
565+
}],
566+
fold:false,
567+
}],
568+
title:None,
569+
footer:vec![],
570+
opt:Default::default(),
571+
};
572+
573+
let expected =r#" --> <current file>:1:7
574+
|
575+
1 | こんにちは、世界
576+
| ^^^^ world
577+
|"#;
578+
579+
assert_eq!(DisplayList::from(snippets).to_string(), expected);
580+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp