diff options
author | José Valim <jose.valim@dashbit.co> | 2021-12-03 18:56:24 +0100 |
---|---|---|
committer | José Valim <jose.valim@dashbit.co> | 2021-12-03 18:56:32 +0100 |
commit | abc23d00c4a9bbafcf08237ed64f93e175196bfa (patch) | |
tree | 5cb263ac838e31aa26508ed63e1f36a62bc00a46 | |
parent | 0db4f426c7deca2cf5db8206dfc80b472e90e465 (diff) | |
download | elixir-abc23d00c4a9bbafcf08237ed64f93e175196bfa.tar.gz |
Decouple parser state from buffer in IEx
-rw-r--r-- | lib/iex/lib/iex/evaluator.ex | 16 | ||||
-rw-r--r-- | lib/iex/lib/iex/server.ex | 18 | ||||
-rw-r--r-- | lib/iex/test/iex/autocomplete_test.exs | 2 |
3 files changed, 18 insertions, 18 deletions
diff --git a/lib/iex/lib/iex/evaluator.ex b/lib/iex/lib/iex/evaluator.ex index ed03059a8..9c8d36ae8 100644 --- a/lib/iex/lib/iex/evaluator.ex +++ b/lib/iex/lib/iex/evaluator.ex @@ -166,8 +166,8 @@ defmodule IEx.Evaluator do defp loop(%{server: server, ref: ref} = state) do receive do {:eval, ^server, code, iex_state} -> - {result, state} = eval(code, iex_state, state) - send(server, {:evaled, self(), result}) + {result, status, state} = eval(code, iex_state, state) + send(server, {:evaled, self(), status, result}) loop(state) {:fields_from_env, ^server, ref, receiver, fields} -> @@ -270,27 +270,27 @@ defmodule IEx.Evaluator do defp eval(code, iex_state, state) do try do {parser_module, parser_fun, args} = IEx.Config.parser() - args = [code, [line: iex_state.counter, file: "iex"], iex_state.buffer | args] + args = [code, [line: iex_state.counter, file: "iex"], iex_state.parser_state | args] do_eval(apply(parser_module, parser_fun, args), iex_state, state) catch kind, error -> print_error(kind, error, __STACKTRACE__) - {%{iex_state | buffer: ""}, state} + {%{iex_state | parser_state: ""}, :ok, state} end end - defp do_eval({:ok, forms, buffer}, iex_state, state) do + defp do_eval({:ok, forms, parser_state}, iex_state, state) do put_history(state) put_whereami(state) state = handle_eval(forms, iex_state.counter, state) - {%{iex_state | buffer: buffer, counter: iex_state.counter + 1}, state} + {%{iex_state | parser_state: parser_state, counter: iex_state.counter + 1}, :ok, state} after Process.delete(:iex_history) Process.delete(:iex_whereami) end - defp do_eval({:incomplete, buffer}, iex_state, state) do - {%{iex_state | buffer: buffer}, state} + defp do_eval({:incomplete, parser_state}, iex_state, state) do + {%{iex_state | parser_state: parser_state}, :incomplete, state} end defp put_history(%{history: history}) do diff --git a/lib/iex/lib/iex/server.ex b/lib/iex/lib/iex/server.ex index bd465b626..5e4fe2c1a 100644 --- a/lib/iex/lib/iex/server.ex +++ b/lib/iex/lib/iex/server.ex @@ -2,7 +2,7 @@ defmodule IEx.State do @moduledoc false # This state is exchanged between IEx.Server and # IEx.Evaluator which is why it is a struct. - defstruct buffer: "", + defstruct parser_state: "", counter: 1, prefix: "iex", on_eof: :stop_evaluator, @@ -89,7 +89,7 @@ defmodule IEx.Server do ) evaluator = start_evaluator(opts) - loop(iex_state(opts), evaluator, Process.monitor(evaluator)) + loop(iex_state(opts), :ok, evaluator, Process.monitor(evaluator)) end # Starts an evaluator using the provided options. @@ -121,12 +121,12 @@ defmodule IEx.Server do run_without_registration(opts) end - defp loop(state, evaluator, evaluator_ref) do + defp loop(state, prompt, evaluator, evaluator_ref) do self_pid = self() counter = state.counter {prompt_type, prefix} = - if state.buffer != "" do + if prompt == :incomplete do {:continuation_prompt, "..."} else {:prompt, state.prefix} @@ -151,7 +151,7 @@ defmodule IEx.Server do # Triggered by pressing "i" as the job control switch {:input, ^input, {:error, :interrupted}} -> io_error("** (EXIT) interrupted") - loop(%{state | buffer: ""}, evaluator, evaluator_ref) + loop(%{state | parser_state: ""}, :new, evaluator, evaluator_ref) # Triggered when IO dies while waiting for input {:input, ^input, {:error, :terminated}} -> @@ -166,8 +166,8 @@ defmodule IEx.Server do defp wait_eval(state, evaluator, evaluator_ref) do receive do - {:evaled, ^evaluator, new_state} -> - loop(new_state, evaluator, evaluator_ref) + {:evaled, ^evaluator, status, new_state} -> + loop(new_state, status, evaluator, evaluator_ref) msg -> handle_take_over(msg, state, evaluator, evaluator_ref, nil, fn state -> @@ -204,7 +204,7 @@ defmodule IEx.Server do if take_over?(take_pid, take_ref, true) do kill_input(input) take_opts = Keyword.put(take_opts, :previous_state, state) - loop(iex_state(take_opts), evaluator, evaluator_ref) + loop(iex_state(take_opts), :ok, evaluator, evaluator_ref) else callback.(state) end @@ -233,7 +233,7 @@ defmodule IEx.Server do Process.exit(evaluator, :kill) Process.demonitor(evaluator_ref, [:flush]) evaluator = start_evaluator(state.evaluator_options) - loop(%{state | buffer: ""}, evaluator, Process.monitor(evaluator)) + loop(%{state | parser_state: ""}, :ok, evaluator, Process.monitor(evaluator)) end defp handle_take_over( diff --git a/lib/iex/test/iex/autocomplete_test.exs b/lib/iex/test/iex/autocomplete_test.exs index e35ea0b52..876ba2ce5 100644 --- a/lib/iex/test/iex/autocomplete_test.exs +++ b/lib/iex/test/iex/autocomplete_test.exs @@ -14,7 +14,7 @@ defmodule IEx.AutocompleteTest do evaluator = Process.get(:evaluator) Process.group_leader(evaluator, Process.group_leader()) send(evaluator, {:eval, self(), line <> "\n", %IEx.State{}}) - assert_receive {:evaled, _, _} + assert_receive {:evaled, _, _, _} end) end |