From dd23533ce98a2beee58fb6daad6e3e8fa555ca93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szikszai=20Guszt=C3=A1v?= Date: Thu, 28 Nov 2024 05:48:03 +0100 Subject: [PATCH] Highlight single character errors. (#721) --- spec/errors/access_expected_field_2 | 14 ++++++++++++ src/errorable.cr | 5 ++++- src/parsers/connect_variable.cr | 34 ++++++++++++++++------------- src/utils/terminal_snippet.cr | 6 ++--- 4 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 spec/errors/access_expected_field_2 diff --git a/spec/errors/access_expected_field_2 b/spec/errors/access_expected_field_2 new file mode 100644 index 000000000..804f744f9 --- /dev/null +++ b/spec/errors/access_expected_field_2 @@ -0,0 +1,14 @@ +component Main { + fun render : String { + "". word +-------------------------------------------------------------------------------- +░ ERROR (ACCESS_EXPECTED_FIELD) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ + +I was expecting the name of the accessed entity but I found "a space" instead: + + ┌ errors/access_expected_field_2:3:8 + ├─────────────────────────────────── + 1│ component Main { + 2│ fun render : String { + 3│ "". word + │ ⌃ diff --git a/src/errorable.cr b/src/errorable.cr index d136caa64..4bdc755dd 100644 --- a/src/errorable.cr +++ b/src/errorable.cr @@ -81,8 +81,11 @@ module Mint target = case value in Parser + min = + value.char == '\0' ? 0 : 1 + SnippetData.new( - to: value.position.offset + value.word.to_s.size, + to: value.position.offset + [min, value.word.to_s.size].max, filename: value.file.relative_path, from: value.position.offset, input: value.file.contents) diff --git a/src/parsers/connect_variable.cr b/src/parsers/connect_variable.cr index 68da2432a..46e6a113b 100644 --- a/src/parsers/connect_variable.cr +++ b/src/parsers/connect_variable.cr @@ -5,23 +5,27 @@ module Mint next unless name = variable_constant(track: false) || variable(track: false) - whitespace - if keyword! "as" - whitespace + target = + parse do + whitespace + next unless keyword! "as" + whitespace - next error :connect_variable_expected_as do - block do - text "The" - bold "exposed name" - text "of a connection" - bold "must be specified, here is an example:" - end + next error :connect_variable_expected_as do + block do + text "The" + bold "exposed name" + text "of a connection" + bold "must be specified, here is an example:" + end - snippet "connect Store exposing { item as name }" - expected "the exposed name", word - snippet self - end unless target = variable - end + snippet "connect Store exposing { item as name }" + expected "the exposed name", word + snippet self + end unless variable = self.variable + + variable + end Ast::ConnectVariable.new( from: start_position, diff --git a/src/utils/terminal_snippet.cr b/src/utils/terminal_snippet.cr index d90abedf6..499c2973e 100644 --- a/src/utils/terminal_snippet.cr +++ b/src/utils/terminal_snippet.cr @@ -34,16 +34,16 @@ module Mint self[0, diff_from] center = - self[diff_from, diff_to].colorize.on(:white).fore(:red).to_s + self[diff_from, diff_to] right = self[diff_to, contents.size] highlighted = - left + center + right + left + center.colorize.on(:white).fore(:red).to_s + right arrows = - (" " * left.size) + ("⌃" * center.uncolorize.size) + (" " * left.size) + ("⌃" * center.size) {highlighted, arrows} end