From ed4799cc0a3ce9e567c0b012b98a4960e43656ac Mon Sep 17 00:00:00 2001 From: favonia Date: Sun, 27 Oct 2024 23:47:20 -0500 Subject: [PATCH] feat(SourceMarker): display EOL and EOF points as "EOL" and "EOF" (#171) --- src/MarkedSource.ml | 9 ++++++++- src/MarkedSourceData.ml | 7 ++++++- src/SourceMarker.ml | 13 +++++++++++-- src/tty/Tty.ml | 10 +++++++--- test/TestSourceMarker.ml | 32 ++++++++++++++++---------------- test/TestTty.expected | 12 ++++++------ 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/MarkedSource.ml b/src/MarkedSource.ml index d52d4fa..044e5f4 100644 --- a/src/MarkedSource.ml +++ b/src/MarkedSource.ml @@ -6,10 +6,17 @@ let dump_marker dump_tag fmt = | RangeEnd tag -> Format.fprintf fmt {|@[<2>RangeEnd@ @[%a@]@]|} dump_tag tag | Point tag -> Format.fprintf fmt {|@[<2>Point@ @[%a@]@]|} dump_tag tag +let dump_special_position fmt = + function + | End_of_line -> Format.fprintf fmt {|End_of_line|} + | End_of_file -> Format.fprintf fmt {|End_of_file|} + let dump_token dump_tag fmt = function | String str -> Format.fprintf fmt {|@[<2>String@ "%s"@]|} (String.escaped str) - | Marker m -> Format.fprintf fmt {|@[<2>Marker@ @[<1>(%a)@]@]|} (dump_marker dump_tag) m + | Marker (p, m) -> + Format.fprintf fmt {|@[<2>Marker@ @[<1>(@[%a@],@ @[%a@])@]@]|} + (Utils.dump_option dump_special_position) p (dump_marker dump_tag) m let dump_line dump_tag fmt {markers; tokens} = Format.fprintf fmt {|@[<1>{@[<2>markers=@,@[%a@]@];@ @[<2>tokens=@ @[%a@]@]}@]|} diff --git a/src/MarkedSourceData.ml b/src/MarkedSourceData.ml index 98f47e6..a807f66 100644 --- a/src/MarkedSourceData.ml +++ b/src/MarkedSourceData.ml @@ -1,3 +1,8 @@ +(** Special positions. *) +type special_position = + | End_of_line + | End_of_file + (** A marker is a delimiter of a range or a specific point. *) type 'tag marker = | RangeBegin of 'tag @@ -7,7 +12,7 @@ type 'tag marker = (** A token is either a string or a marker. *) type 'tag token = | String of string - | Marker of 'tag marker + | Marker of special_position option * 'tag marker (** A line is a list of {!type:segment}s along with tags. *) type 'tag line = diff --git a/src/SourceMarker.ml b/src/SourceMarker.ml index 2c779fc..beaf4a5 100644 --- a/src/SourceMarker.ml +++ b/src/SourceMarker.ml @@ -83,11 +83,20 @@ module Make (Tag : Tag) = struct | (loc, marker) :: markers when state.cursor.line_num = loc.line_num (* on the same line *) -> if loc.offset > eof then invalid_arg "Asai.SourceMarker.mark: position beyond EOF; use the debug mode"; if loc.offset > state.eol then invalid_arg "Asai.SourceMarker.mark: unexpected newline; use the debug mode"; + let special_position = + if loc.offset = state.eol then + if loc.offset = eof then + Some End_of_file + else + Some End_of_line + else + None + in let tokens = if loc.offset = state.cursor.offset then - state.tokens <: Marker marker + state.tokens <: Marker (special_position, marker) else - state.tokens <: String (read_between ~source state.cursor.offset loc.offset) <: Marker marker + state.tokens <: String (read_between ~source state.cursor.offset loc.offset) <: Marker (special_position, marker) in go { state with tokens; cursor = loc } markers | markers -> diff --git a/src/tty/Tty.ml b/src/tty/Tty.ml index 5ce939d..e02f576 100644 --- a/src/tty/Tty.ml +++ b/src/tty/Tty.ml @@ -111,11 +111,15 @@ struct function | MarkedSource.String s -> render_styled_segment ~param fmt (TtyTagSet.prioritized set) s; set - | MarkedSource.Marker RangeEnd t -> + | MarkedSource.Marker (_, RangeEnd t) -> TtyTagSet.remove t set - | MarkedSource.Marker Point t -> + | MarkedSource.Marker (Some End_of_file, Point t) -> + render_styled_segment ~param fmt (Some t) "‹EOF›"; set + | MarkedSource.Marker (Some End_of_line, Point t) -> + render_styled_segment ~param fmt (Some t) "‹EOL›"; set + | MarkedSource.Marker (None, Point t) -> render_styled_segment ~param fmt (Some t) "‹POS›"; set - | MarkedSource.Marker RangeBegin t -> + | MarkedSource.Marker (_, RangeBegin t) -> TtyTagSet.add t set in Format.fprintf fmt (" " ^^ highlight "%*d |" ^^ " ") diff --git a/test/TestSourceMarker.ml b/test/TestSourceMarker.ml index f1c6836..056b772 100644 --- a/test/TestSourceMarker.ml +++ b/test/TestSourceMarker.ml @@ -18,13 +18,13 @@ let single_line mode eol () = [{markers = [(1, "1"); (2, "2")]; tokens = [String "aaa"; - Marker (RangeBegin (1, "1")); + Marker (None, RangeBegin (1, "1")); String "bbb"; - Marker (RangeBegin (2, "2")); + Marker (None, RangeBegin (2, "2")); String "ccc"; - Marker (RangeEnd (1, "1")); + Marker (None, RangeEnd (1, "1")); String "ddd"; - Marker (RangeEnd (2, "2")); + Marker (None, RangeEnd (2, "2")); String "eee"; ]}]} ]} @@ -46,13 +46,13 @@ let multi_lines_with_ls () = [{markers=[]; tokens= [String "aa"; - Marker (RangeBegin (1, "1")); + Marker (None, RangeBegin (1, "1")); String "bbbbb"; ]}; {markers=[(1, "1")]; tokens= [String "bbbb"; - Marker (RangeEnd (1, "1")); + Marker (None, RangeEnd (1, "1")); String "ccc"; ]}]} ]} @@ -105,7 +105,7 @@ ggggghh [{markers=[]; tokens= [String "aa"; - Marker (RangeBegin (1, "2")); + Marker (None, RangeBegin (1, "2")); String "bbbbb"]}; {markers=[]; tokens= @@ -113,10 +113,10 @@ ggggghh {markers=[(2, "1"); (1, "2")]; tokens= [String "b"; - Marker (RangeBegin (2, "1")); + Marker (None, RangeBegin (2, "1")); String "*cc"; - Marker (RangeEnd (2, "1")); - Marker (RangeEnd (1, "2")); + Marker (None, RangeEnd (2, "1")); + Marker (None, RangeEnd (1, "2")); String "ddd"]}; {markers=[]; tokens= @@ -133,20 +133,20 @@ ggggghh {markers=[(8, "4"); (4, "3")]; tokens= [String "ee"; - Marker (RangeBegin (4, "3")); + Marker (None, RangeBegin (4, "3")); String "++"; - Marker (RangeBegin (8, "4")); + Marker (None, RangeBegin (8, "4")); String "fff"; - Marker (RangeEnd (8, "4")); - Marker (RangeEnd (4, "3"))]}]}; + Marker (Some End_of_line, RangeEnd (8, "4")); + Marker (Some End_of_line, RangeEnd (4, "3"))]}]}; {begin_line_num=15; end_line_num=15; lines= [{markers=[(16, "5")]; tokens= - [Marker (RangeBegin (16, "5")); + [Marker (None, RangeBegin (16, "5")); String "ggggg"; - Marker (RangeEnd (16, "5")); + Marker (None, RangeEnd (16, "5")); String "hh"]}]}]}] in let actual = SM.mark ~line_breaks:`Traditional ~block_splitting_threshold:5 ranges in diff --git a/test/TestTty.expected b/test/TestTty.expected index 9091b4b..61719a1 100644 --- a/test/TestTty.expected +++ b/test/TestTty.expected @@ -107,10 +107,10 @@ ○ message 3 → warning[hello] - 23 | wwwwwwwwww‹POS› + 23 | wwwwwwwwww‹EOF› ^ this is the main message ■ /path/to/file.cool - 23 | wwwwwwwwww‹POS› + 23 | wwwwwwwwww‹EOF› ^ ending of another file → warning[hello] @@ -222,10 +222,10 @@ ○ message 3 → warning[hello] - 23 | wwwwwwwwww‹POS› + 23 | wwwwwwwwww‹EOF› ^ this is the main message ■ /path/to/file.cool - 23 | wwwwwwwwww‹POS› + 23 | wwwwwwwwww‹EOF› ^ ending of another file → warning[hello] @@ -337,9 +337,9 @@ ○ message 3 → warning[hello] - 23 | wwwwwwwwww‹POS› + 23 | wwwwwwwwww‹EOF› ^ this is the main message ■ /path/to/file.cool - 23 | wwwwwwwwww‹POS› + 23 | wwwwwwwwww‹EOF› ^ ending of another file