Skip to content

Commit 248ef0a

Browse files
committed
Merge branch 'frazze/stdlib/shell_extra_new_line_prompt' into maint
* frazze/stdlib/shell_extra_new_line_prompt: kernel: fix automatic newline in shell OTP-19847
2 parents a63e319 + 2e55a2b commit 248ef0a

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

lib/kernel/src/prim_tty.erl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,8 @@ handle_request(State = #state{ unicode = U }, {putc, Binary}) ->
831831
end,
832832
Moves = move_cursor(State, State#state.cols, ToCol)
833833
end,
834-
Binary1 = if PutcBufferState#state.putc_buffer =:= <<>> ->
834+
BinaryNoAnsi = remove_ansi_sequences(PutcBufferState#state.putc_buffer),
835+
Binary1 = if BinaryNoAnsi =:= <<>> ->
835836
%% Binary has a real new line at the end
836837
Binary;
837838
true ->
@@ -1014,6 +1015,19 @@ handle_request(State, Req) ->
10141015
erlang:display({unhandled_request, Req}),
10151016
{"", State}.
10161017

1018+
remove_ansi_sequences(<<27,Bin/binary>>) ->
1019+
Bins = binary:split(Bin, <<27>>, [global]),
1020+
remove_ansi_sequences1([<<27,B/binary>> || B <- Bins],[]);
1021+
remove_ansi_sequences(Bin) ->
1022+
[Acc|Bins] = binary:split(Bin, <<27>>, [global]),
1023+
remove_ansi_sequences1([<<27,B/binary>> || B <- Bins],[Acc]).
1024+
remove_ansi_sequences1([Bin|Bins], Acc) ->
1025+
{match, [{0, N}]} = re:run(Bin, ansi_regexp()),
1026+
<<_:N/binary, AnsiRest/binary>> = Bin,
1027+
remove_ansi_sequences1(Bins, [AnsiRest|Acc]);
1028+
remove_ansi_sequences1([], Acc) ->
1029+
list_to_binary(lists:reverse(Acc)).
1030+
10171031
last_or_empty([]) -> [];
10181032
last_or_empty([H]) -> H;
10191033
last_or_empty(L) -> [H|_] = lists:reverse(L), H.

lib/kernel/test/interactive_shell_SUITE.erl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@
7272
remsh_expand_compatibility_25/1, remsh_expand_compatibility_later_version/1,
7373
external_editor/1, external_editor_visual/1,
7474
external_editor_unicode/1, shell_ignore_pager_commands/1,
75-
shell_escape_sequence_end_of_prompt_followed_by_unicode/1]).
75+
shell_escape_sequence_end_of_prompt_followed_by_unicode/1,
76+
shell_output_automatic_newline_ansi_escape_sequence/1]).
7677

7778
-export([get_until/2]).
7879

@@ -159,6 +160,7 @@ groups() ->
159160
[{group,tty_tests},
160161
shell_invalid_unicode,
161162
shell_escape_sequence_end_of_prompt_followed_by_unicode,
163+
shell_output_automatic_newline_ansi_escape_sequence,
162164
external_editor_unicode
163165
%% unicode wrapping does not work right yet
164166
%% shell_unicode_wrap,
@@ -1418,7 +1420,17 @@ shell_escape_sequence_end_of_prompt_followed_by_unicode(Config) ->
14181420
shell_test_lib:stop_tty(Term),
14191421
ok
14201422
end.
1423+
shell_output_automatic_newline_ansi_escape_sequence(Config) ->
1424+
Term = start_tty(Config),
14211425

1426+
try
1427+
shell_test_lib:send_tty(Term,"spawn(fun() -> receive after 1000 -> ok end, io:put_chars([\"omg\\n\", <<27,91,48,109>>]) end).\n"),
1428+
shell_test_lib:check_content(Term, "omg\n\\("),
1429+
ok
1430+
after
1431+
shell_test_lib:stop_tty(Term),
1432+
ok
1433+
end.
14221434
%% Test the we can handle invalid ansi escape chars.
14231435
%% tmux cannot handle this... so we test this using to_erl
14241436
shell_invalid_ansi(_Config) ->

0 commit comments

Comments
 (0)