From 7c79850d02e535a9136ccc4cf5abea4ab4030c92 Mon Sep 17 00:00:00 2001 From: Richard Carlsson Date: Thu, 4 Feb 2021 18:15:36 +0100 Subject: [PATCH] Ensure underlining indents by code points, not bytes --- lib/compiler/src/sys_messages.erl | 34 +++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/lib/compiler/src/sys_messages.erl b/lib/compiler/src/sys_messages.erl index 0b46075f81b8..e5065c8279d3 100644 --- a/lib/compiler/src/sys_messages.erl +++ b/lib/compiler/src/sys_messages.erl @@ -95,6 +95,10 @@ quote_source_1(File, Loc1, Line) when is_integer(Line) -> quote_source_1(File, {StartLine, StartCol}, {EndLine, EndCol}) -> case file:read_file(File) of {ok, Bin} -> + Enc = case epp:read_encoding_from_binary(Bin) of + none -> epp:default_encoding(); + Enc0 -> Enc0 + end, Ctx = if StartLine =:= EndLine -> 0; @@ -102,7 +106,7 @@ quote_source_1(File, {StartLine, StartCol}, {EndLine, EndCol}) -> end, case seek_line(Bin, 1, StartLine - Ctx) of {ok, Bin1} -> - quote_source_2(Bin1, StartLine, StartCol, EndLine, EndCol, Ctx); + quote_source_2(Bin1, Enc, StartLine, StartCol, EndLine, EndCol, Ctx); error -> "" end; @@ -110,8 +114,8 @@ quote_source_1(File, {StartLine, StartCol}, {EndLine, EndCol}) -> "" end. -quote_source_2(Bin, StartLine, StartCol, EndLine, EndCol, Ctx) -> - case take_lines(Bin, StartLine - Ctx, EndLine + Ctx) of +quote_source_2(Bin, Enc, StartLine, StartCol, EndLine, EndCol, Ctx) -> + case take_lines(Bin, Enc, StartLine - Ctx, EndLine + Ctx) of [] -> ""; Lines -> @@ -137,7 +141,7 @@ line_prefix() -> "% ". fmt_line(L, Text) -> - io_lib:format("~ts~4.ts| ~ts\n", [line_prefix(), line_to_txt(L), Text]). + [line_prefix(), io_lib:format("~4.ts| ", [line_to_txt(L)]), Text, "\n"]. line_to_txt(0) -> ""; line_to_txt(L) -> integer_to_list(L). @@ -173,9 +177,9 @@ underline(Text, Start, Start) -> underline(Text, Start, End) -> underline(Text, Start, End, 1). -underline(<<$\t, Text/binary>>, Start, End, N) when N < Start -> +underline([$\t | Text], Start, End, N) when N < Start -> [$\t | underline(Text, Start, End, N + 1)]; -underline(<<_, Text/binary>>, Start, End, N) when N < Start -> +underline([_ | Text], Start, End, N) when N < Start -> [$\s | underline(Text, Start, End, N + 1)]; underline(_Text, _Start, End, N) -> underline_1(N, End). @@ -191,14 +195,22 @@ seek_line(<<$\r, $\n, Rest/binary>>, N, L) -> seek_line(Rest, N + 1, L); seek_line(<<_, Rest/binary>>, N, L) -> seek_line(Rest, N, L); seek_line(<<>>, _, _) -> error. -take_lines(<<>>, _Here, _To) -> +take_lines(<<>>, _Enc, _Here, _To) -> []; -take_lines(Bin, Here, To) when Here =< To -> - {Line, Rest} = take_line(Bin, <<>>), - [{Here, Line} | take_lines(Rest, Here + 1, To)]; -take_lines(_Bin, _Here, _To) -> +take_lines(Bin, Enc, Here, To) when Here =< To -> + {Text, Rest} = take_line(Bin, <<>>), + [{Here, text_to_string(Text, Enc)} + | take_lines(Rest, Enc, Here + 1, To)]; +take_lines(_Bin, _Enc, _Here, _To) -> []. +text_to_string(Text, Enc) -> + case unicode:characters_to_list(Text, Enc) of + String when is_list(String) -> String; + {error, String, _Rest} -> String; + {incomplete, String, _Rest} -> String + end. + take_line(<<$\n, Rest/binary>>, Ack) -> {Ack, Rest}; take_line(<<$\r, $\n, Rest/binary>>, Ack) ->