Skip to content

Commit 5bec091

Browse files
committed
Add indentation to string to quoted
1 parent 93a4a0f commit 5bec091

File tree

5 files changed

+73
-7
lines changed

5 files changed

+73
-7
lines changed

lib/eex/lib/eex/compiler.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ defmodule EEx.Compiler do
304304
source: source,
305305
line: line,
306306
quoted: [],
307-
parser_options: parser_options,
307+
parser_options: [indentation: indentation] ++ parser_options,
308308
indentation: indentation
309309
}
310310

lib/eex/test/eex_test.exs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,59 @@ defmodule EExTest do
502502
end
503503
end
504504

505+
test "from Elixir parser" do
506+
line = __ENV__.line + 6
507+
508+
message =
509+
assert_raise TokenMissingError, fn ->
510+
EEx.compile_string(
511+
"""
512+
<li>
513+
<strong>Some:</strong>
514+
<%= true && @some[ %>
515+
</li>
516+
""",
517+
file: __ENV__.file,
518+
line: line,
519+
indentation: 12
520+
)
521+
end
522+
523+
assert message |> Exception.message() |> strip_ansi() =~ """
524+
525+
514 │ true && @some[\s
526+
│ │ └ missing closing delimiter (expected "]")
527+
│ └ unclosed delimiter
528+
"""
529+
end
530+
531+
test "from Elixir parser with line breaks" do
532+
line = __ENV__.line + 6
533+
534+
message =
535+
assert_raise TokenMissingError, fn ->
536+
EEx.compile_string(
537+
"""
538+
<li>
539+
<strong>Some:</strong>
540+
<%= true &&
541+
@some[ %>
542+
</li>
543+
""",
544+
file: __ENV__.file,
545+
line: line,
546+
indentation: 12
547+
)
548+
end
549+
550+
assert message |> Exception.message() |> strip_ansi() =~ """
551+
552+
#{line + 3} │ @some[\s
553+
│ │ └ missing closing delimiter (expected "]")
554+
│ └ unclosed delimiter
555+
"""
556+
end
557+
505558
test "honor line numbers" do
506559
assert_raise EEx.SyntaxError,
507560
"nofile:100:6: expected closing '%>' for EEx expression",
@@ -948,6 +1001,12 @@ defmodule EExTest do
9481001
end
9491002
end
9501003

1004+
@strip_ansi [IO.ANSI.green(), IO.ANSI.red(), IO.ANSI.reset()]
1005+
1006+
defp strip_ansi(doc) do
1007+
String.replace(doc, @strip_ansi, "")
1008+
end
1009+
9511010
defp assert_eval(expected, actual, binding \\ [], opts \\ []) do
9521011
opts = Keyword.merge([file: __ENV__.file, engine: opts[:engine] || EEx.Engine], opts)
9531012
result = EEx.eval_string(actual, binding, opts)

lib/elixir/src/elixir.erl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,10 +490,14 @@ parser_location(Meta) ->
490490
{ok, Forms} ->
491491
Forms;
492492
{error, {Meta, Error, Token}} ->
493-
elixir_errors:parse_error(Meta, File, Error, Token, {String, StartLine, StartColumn})
493+
Indentation = proplists:get_value(indentation, Opts, 0),
494+
Input = {String, StartLine, StartColumn, Indentation},
495+
elixir_errors:parse_error(Meta, File, Error, Token, Input)
494496
end;
495497
{error, {Meta, Error, Token}} ->
496-
elixir_errors:parse_error(Meta, File, Error, Token, {String, StartLine, StartColumn})
498+
Indentation = proplists:get_value(indentation, Opts, 0),
499+
Input = {String, StartLine, StartColumn, Indentation},
500+
elixir_errors:parse_error(Meta, File, Error, Token, Input)
497501
end.
498502

499503
to_binary(List) when is_list(List) -> elixir_utils:characters_to_binary(List);

lib/elixir/src/elixir_errors.erl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,11 +446,12 @@ cut_snippet(Location, Input) ->
446446
nil
447447
end.
448448

449-
cut_snippet({InputString, StartLine, StartColumn}, Line, Span) ->
449+
cut_snippet({InputString, StartLine, StartColumn, Indentation}, Line, Span) ->
450450
%% In case the code is indented, we need to add the indentation back
451451
%% for the snippets to match the reported columns.
452-
Indent = binary:copy(<<" ">>, StartColumn - 1),
453-
Lines = string:split(InputString, "\n", all),
452+
Prelude = lists:duplicate(max(StartColumn - Indentation - 1, 0), " "),
453+
Lines = string:split(Prelude ++ InputString, "\n", all),
454+
Indent = binary:copy(<<" ">>, Indentation),
454455
[Head | Tail] = lists:nthtail(Line - StartLine, Lines),
455456
IndentedTail = indent_n(Tail, Span - 1, <<"\n", Indent/binary>>),
456457
elixir_utils:characters_to_binary([Indent, Head, IndentedTail]).

lib/elixir/src/elixir_tokenizer.erl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,11 @@ tokenize(String, Line, Column, Opts) ->
130130
Acc#elixir_tokenizer{preserve_comments=PreserveComments};
131131
({unescape, Unescape}, Acc) when is_boolean(Unescape) ->
132132
Acc#elixir_tokenizer{unescape=Unescape};
133+
({indentation, Indentation}, Acc) when Indentation >= 0 ->
134+
Acc#elixir_tokenizer{column=Indentation+1};
133135
(_, Acc) ->
134136
Acc
135-
end, #elixir_tokenizer{identifier_tokenizer=IdentifierTokenizer, column=Column}, Opts),
137+
end, #elixir_tokenizer{identifier_tokenizer=IdentifierTokenizer}, Opts),
136138

137139
tokenize(String, Line, Column, Scope, []).
138140

0 commit comments

Comments
 (0)