From 08141133f0d84f81525f2b596ed89f23d8592a8e Mon Sep 17 00:00:00 2001
From: Inky-developer <developerinky@gmail.com>
Date: Mon, 3 Jan 2022 20:42:12 +0100
Subject: [PATCH] Fix #52 This fixes wrong line numbers shown when the `fold`
 is set to `true`

---
 src/display_list/from_snippet.rs      | 12 ++++++------
 tests/fixtures/no-color/issue_52.toml | 16 ++++++++++++++++
 tests/fixtures/no-color/issue_52.txt  |  7 +++++++
 3 files changed, 29 insertions(+), 6 deletions(-)
 create mode 100644 tests/fixtures/no-color/issue_52.toml
 create mode 100644 tests/fixtures/no-color/issue_52.txt

diff --git a/src/display_list/from_snippet.rs b/src/display_list/from_snippet.rs
index faf48f2..83e51f5 100644
--- a/src/display_list/from_snippet.rs
+++ b/src/display_list/from_snippet.rs
@@ -111,10 +111,9 @@ fn format_slice(
 ) -> Vec<DisplayLine<'_>> {
     let main_range = slice.annotations.get(0).map(|x| x.range.0);
     let origin = slice.origin;
-    let line_start = slice.line_start;
     let need_empty_header = origin.is_some() || is_first;
     let mut body = format_body(slice, need_empty_header, has_footer, margin);
-    let header = format_header(origin, main_range, line_start, &body, is_first);
+    let header = format_header(origin, main_range, &body, is_first);
     let mut result = vec![];
 
     if let Some(header) = header {
@@ -133,7 +132,6 @@ fn zip_opt<A, B>(a: Option<A>, b: Option<B>) -> Option<(A, B)> {
 fn format_header<'a>(
     origin: Option<&'a str>,
     main_range: Option<usize>,
-    mut row: usize,
     body: &[DisplayLine<'_>],
     is_first: bool,
 ) -> Option<DisplayLine<'a>> {
@@ -145,24 +143,26 @@ fn format_header<'a>(
 
     if let Some((main_range, path)) = zip_opt(main_range, origin) {
         let mut col = 1;
+        let mut line_offset = 1;
 
         for item in body {
             if let DisplayLine::Source {
                 line: DisplaySourceLine::Content { range, .. },
+                lineno,
                 ..
             } = item
             {
                 if main_range >= range.0 && main_range <= range.1 {
                     col = main_range - range.0 + 1;
+                    line_offset = lineno.unwrap_or(1);
                     break;
                 }
-                row += 1;
             }
         }
 
         return Some(DisplayLine::Raw(DisplayRawLine::Origin {
             path,
-            pos: Some((row, col)),
+            pos: Some((line_offset, col)),
             header_type: display_header,
         }));
     }
@@ -307,7 +307,7 @@ fn format_body(
         let char_widths = line
             .chars()
             .map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0))
-            .chain(std::iter::once(1)) // treat the end of line as signle-width
+            .chain(std::iter::once(1)) // treat the end of line as single-width
             .collect::<Vec<_>>();
         body.push(DisplayLine::Source {
             lineno: Some(current_line),
diff --git a/tests/fixtures/no-color/issue_52.toml b/tests/fixtures/no-color/issue_52.toml
new file mode 100644
index 0000000..8d54613
--- /dev/null
+++ b/tests/fixtures/no-color/issue_52.toml
@@ -0,0 +1,16 @@
+[title]
+annotation_type = "Error"
+
+[[slices]]
+source = """
+
+
+invalid syntax
+"""
+line_start = 1
+origin = "path/to/error.rs"
+fold = true
+[[slices.annotations]]
+label = "error here"
+annotation_type = "Warning"
+range = [2,16]
diff --git a/tests/fixtures/no-color/issue_52.txt b/tests/fixtures/no-color/issue_52.txt
new file mode 100644
index 0000000..b1c6bf2
--- /dev/null
+++ b/tests/fixtures/no-color/issue_52.txt
@@ -0,0 +1,7 @@
+error
+ --> path/to/error.rs:3:1
+  |
+...
+3 | invalid syntax
+  | -------------- error here
+  |
\ No newline at end of file