Allow customization of the continuation prompt on IEx (#9620)
It allows users to further customize IEx.
For example, it could be useful to include additional
information in the prompt:
Erlang/OTP X [erts-x.x] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Interactive Elixir (1.x.x) - press Ctrl+C to exit (type h() ENTER for help)
production - read-only session - i-abc435123asd12323 - eu-west-1
iex(1)> if true do
...(1)> :ok
...(1)> end
:ok
production - read-only session - i-abc435123asd12323 - eu-west-1
iex(2)>
This commit is contained in:
+10
-1
@@ -338,7 +338,9 @@ defmodule IEx do
|
||||
* `:width`
|
||||
* `:history_size`
|
||||
* `:default_prompt`
|
||||
* `:continuation_prompt`
|
||||
* `:alive_prompt`
|
||||
* `:alive_continuation_prompt`
|
||||
|
||||
They are discussed individually in the sections below.
|
||||
|
||||
@@ -420,7 +422,14 @@ defmodule IEx do
|
||||
The value is a keyword list with two possible keys representing prompt types:
|
||||
|
||||
* `:default_prompt` - used when `Node.alive?/0` returns `false`
|
||||
* `:alive_prompt` - used when `Node.alive?/0` returns `true`
|
||||
|
||||
* `:continuation_prompt` - used when `Node.alive?/0` returns `false`
|
||||
and more input is expected
|
||||
|
||||
* `:alive_prompt` - used when `Node.alive?/0` returns `true`
|
||||
|
||||
* `:alive_continuation_prompt` - used when `Node.alive?/0` returns
|
||||
`true` and more input is expected
|
||||
|
||||
The following values in the prompt string will be replaced appropriately:
|
||||
|
||||
|
||||
@@ -4,7 +4,16 @@ defmodule IEx.Config do
|
||||
|
||||
@table __MODULE__
|
||||
@agent __MODULE__
|
||||
@keys [:colors, :inspect, :history_size, :default_prompt, :alive_prompt, :width]
|
||||
@keys [
|
||||
:colors,
|
||||
:inspect,
|
||||
:history_size,
|
||||
:default_prompt,
|
||||
:continuation_prompt,
|
||||
:alive_prompt,
|
||||
:alive_continuation_prompt,
|
||||
:width
|
||||
]
|
||||
|
||||
# Read API
|
||||
|
||||
@@ -37,10 +46,18 @@ defmodule IEx.Config do
|
||||
Application.fetch_env!(:iex, :default_prompt)
|
||||
end
|
||||
|
||||
def continuation_prompt() do
|
||||
Application.get_env(:iex, :continuation_prompt, default_prompt())
|
||||
end
|
||||
|
||||
def alive_prompt() do
|
||||
Application.fetch_env!(:iex, :alive_prompt)
|
||||
end
|
||||
|
||||
def alive_continuation_prompt() do
|
||||
Application.get_env(:iex, :alive_continuation_prompt, alive_prompt())
|
||||
end
|
||||
|
||||
def color(color) do
|
||||
color(color, Application.get_env(:iex, :colors, []))
|
||||
end
|
||||
@@ -176,7 +193,9 @@ defmodule IEx.Config do
|
||||
defp merge_option(:inspect, old, new) when is_list(new), do: Keyword.merge(old, new)
|
||||
defp merge_option(:history_size, _old, new) when is_integer(new), do: new
|
||||
defp merge_option(:default_prompt, _old, new) when is_binary(new), do: new
|
||||
defp merge_option(:continuation_prompt, _old, new) when is_binary(new), do: new
|
||||
defp merge_option(:alive_prompt, _old, new) when is_binary(new), do: new
|
||||
defp merge_option(:alive_continuation_prompt, _old, new) when is_binary(new), do: new
|
||||
defp merge_option(:width, _old, new) when is_integer(new), do: new
|
||||
|
||||
defp merge_option(key, _old, new) do
|
||||
|
||||
@@ -117,9 +117,15 @@ defmodule IEx.Server do
|
||||
defp loop(state, evaluator, evaluator_ref) do
|
||||
self_pid = self()
|
||||
counter = state.counter
|
||||
prefix = if state.cache != [], do: "...", else: state.prefix
|
||||
|
||||
input = spawn(fn -> io_get(self_pid, prefix, counter) end)
|
||||
{prompt_type, prefix} =
|
||||
if state.cache != [] do
|
||||
{:continuation_prompt, "..."}
|
||||
else
|
||||
{:prompt, state.prefix}
|
||||
end
|
||||
|
||||
input = spawn(fn -> io_get(self_pid, prompt_type, prefix, counter) end)
|
||||
wait_input(state, evaluator, evaluator_ref, input)
|
||||
end
|
||||
|
||||
@@ -316,17 +322,17 @@ defmodule IEx.Server do
|
||||
|
||||
## IO
|
||||
|
||||
defp io_get(pid, prefix, counter) do
|
||||
prompt = prompt(prefix, counter)
|
||||
defp io_get(pid, prompt_type, prefix, counter) do
|
||||
prompt = prompt(prompt_type, prefix, counter)
|
||||
send(pid, {:input, self(), IO.gets(:stdio, prompt)})
|
||||
end
|
||||
|
||||
defp prompt(prefix, counter) do
|
||||
defp prompt(prompt_type, prefix, counter) do
|
||||
{mode, prefix} =
|
||||
if Node.alive?() do
|
||||
{:alive_prompt, prefix || remote_prefix()}
|
||||
{prompt_mode(prompt_type, :alive), prefix || remote_prefix()}
|
||||
else
|
||||
{:default_prompt, prefix || "iex"}
|
||||
{prompt_mode(prompt_type, :default), prefix || "iex"}
|
||||
end
|
||||
|
||||
prompt =
|
||||
@@ -338,6 +344,11 @@ defmodule IEx.Server do
|
||||
prompt <> " "
|
||||
end
|
||||
|
||||
defp prompt_mode(:prompt, :default), do: :default_prompt
|
||||
defp prompt_mode(:prompt, :alive), do: :alive_prompt
|
||||
defp prompt_mode(:continuation_prompt, :default), do: :continuation_prompt
|
||||
defp prompt_mode(:continuation_prompt, :alive), do: :alive_continuation_prompt
|
||||
|
||||
defp io_error(result) do
|
||||
IO.puts(:stdio, IEx.color(:eval_error, result))
|
||||
end
|
||||
|
||||
@@ -83,6 +83,11 @@ defmodule IEx.InteractionTest do
|
||||
assert capture_iex("1\n", opts, [], true) == "prompt(1)> 1\nprompt(2)>"
|
||||
end
|
||||
|
||||
test "continuation prompt" do
|
||||
opts = [default_prompt: "%prefix(%counter)>", continuation_prompt: "%prefix(%counter)>>>"]
|
||||
assert capture_iex("[\n1\n]\n", opts, [], true) == "iex(1)> ...(1)>>> ...(1)>>> [1]\niex(2)>"
|
||||
end
|
||||
|
||||
if IO.ANSI.enabled?() do
|
||||
test "color" do
|
||||
opts = [colors: [enabled: true, eval_result: [:red]]]
|
||||
|
||||
Reference in New Issue
Block a user