The Erlang Shell


When working with Erlang, the shell is central to a lot of the work that we do. It is where most of us started out when learning Erlang and it is where we have spent countless hours trying to debug issues in production.

For Erlang/OTP 26, we are going to take a close look at the shell and see what we can improve in there. There are already a lot of issues[1] at the Erlang/OTP github tracker related to problems with the shell and we intend to address as many of those as we can. However, we do not only want to look at fixing current bugs, but also expand what the shell does today.

Some of the ideas that we have right now are:

  • Introduce multiline editing (and multiline history)
  • Implement a new shell for Windows using Console Virtual Terminal Sequences, thus removing werl.
  • Allow user to interrupt/background hanging/long running jobs in the shell
  • Various improvements related to autocompletion

What would you like to see in the Erlang shell? Customizable key binding? More colors? Better APIs for creating project-specific shells?

Lukas and the Erlang/OTP team

[1]: All open shell related issues (that I have found)


Having support for the very common Control-L shortcut to clear the terminal while in the shell would be incredibly beneficial to clear the mess after several commands.


Excellent idea @galdor ! Exactly what I was thinking.

  • Introduce multiline editing (and multiline history)

A PERMANENT history even after restarting erl would be so great !



Some way to separate Erlang and Elixir history (and per-project, maybe?) in a useful way…


I would probably configure the default Erlang build to have history turned on by default, along with Unicode auto conversion in at first.

Multi line editing would be good for sure.

I would have liked it if the shell parsing structure was amenable to getting vi mode implementable but I don’t imagine this would be easy nor popular.

I’d like for remote shells to keep working

Syntax highlighting would be great, along with better autocomplete.


There’s iex doesn't reset terminal blocking flag when it exits · Issue #9805 · elixir-lang/elixir · GitHub, which turns out to be an Erlang bug, which leads to a whole chain of “duplicates”, culminating in ERL-282: escript fails when redirecting stdout to less and less terminates · Issue #3150 · erlang/otp · GitHub (mentioned), but I’m worried that there’s multiple issues being conflated in those bug reports.


Yes, agreed.

Do you have any example of what you mean by this? I’m a bit unclear what would be needed to make this work.

Syntax highlighting of what? expressions as you type them in the shell? or terms as they are returned?

Any ideas around what type of thing should be autocompleted?


Yes, I’m aware of those and also that there are multiple issues there that need fixing.


The kernel application allows configuration of a shell history. You can enable it using erl -kernel shell_history enabled, or setting ERL_FLAGS=-kernel shell_history enabled. Is this what you mean, or something different?


Ctrl+L today in the shell redraws the current line, which is a feature I find very handy when logger/dbg is printing things to stdout as I type. I would not like it if that feature went away.

Btw, Ctrl+L in my shell sets the cursor to be at the top left, while clear clears that history buffer as well. I assume you would like Ctrl+L to do the first option, but thought I would double-check to make sure.


It’s tricky, but essentially would require modal editing (hence why I don’t think it would be realistic to expect it).

So instead of pressing ctrl+a to go to the beginning of the line or ctrl+e to go to the end, I switch from insert mode to edit mode and press 0 or $.

Common commands in edit mode include things such as ct" which means "change the content from the current cursor until the next "" and switches back to insert mode.

I frankly have no idea how the same shell code can be made to switch from one to the other; I just know that I looked at how it was handled in the current one and it was very much impossible. I also know pretty much nobody uses that sort of shortcuts, so I wouldn’t be mad not to see it, that’s the usual.

Yeah, I think that the “as I type” mode is the most useful one, particularly around things like whether I’m still stuck in a string (or quoted atom), and in some cases matching on closing parens or brackets.

Suggestions for function arguments are probably the trickiest one, possibly based on type names if that is carried.


I imagine there could be configurable shortcuts.

And yes, Ctrl+L clears the terminal and insert a new prompt. This behaviour is incredibly common for all shells — system or language — I ever used. Some advanced shells such as zsh even keep what was currently typed in the current prompt line.

Not having it means the only way to clear the mess is to exit and re-start the Erlang shell. This is a constant annoyance.

Note that Ctrl-L does not erase history indeed.


psql has this feature:

\e or \edit [ filename ] [ line_number ]

If filename is specified, the file is edited; after the editor exits, the file’s content is copied into the current query buffer. If no filename is given, the current query buffer is copied to a temporary file which is then edited in the same fashion. Or, if the current query buffer is empty, the most recently executed query is copied to a temporary file and edited in the same fashion.

If we could implement this you could get something close, but since it would open up a new vi session you would not be able to view the current content of the terminal at the same time. Unless you set EDITOR=“xterm vi”… not sure how useful something like that would be.


One minor improvement: do not repeat the prompt when entering multiline input. So instead of this:

1> 1 +
1> 2.

Let’s have this, which is easier to copy-paste:

1> 1 +

One awesome but huge improvement: allow expanding/collapsing sub-terms with mouse clicks.


bash and zsh kind of does this, but only when you use arrow-up to get the history. i.e.

> a="a
> b
> c"
## Arrow-up
> a="a

I think I would prefer it to be the bash/zsh way, though I have no better reason than “that is what bash and zsh does”.

For anything returned to the shell through a command this might be possible, but for things that are printed by the application (i.e. logging, dbg, io:format etc) it would be very hard to do.

Would only having it from return values in the shell still be useful, or is it dbg/logger/io:format where the largest benefit would come?


wow… I was looking for this feature for years and gave up anywhen…
Thanks for the hint!
That is sometimes the problem with ERLANG:
many gems but hard, or should I say hardly, to find.

Best Regards


I tend to agree with @dszoboszlay, copy and paste is a great argument.

However, if we decided not to have any prompt

1> mod:fun(mod:fun2()
compared to
1> mod:fun(mod:fun2())

Its difficult to tell if the function is stuck/executing or if I forgot to complete the expression with ‘.’.
Some kind of indication is necessary (IMO) to help new adopters to make that distinction.
Can probably be solved by cleverly using colors.


What I’d like to see in the shell is that it would be possible to apply parse transforms to the typed commands. Maybe something similar to how records are handled, where you read records with rr() and the shell remembers the record definitions, in the same vein, you’d be able to specify which parse transforms you’d like the shell to invoke on the typed input. The later should be also configurable through given user_default or shell_default modules.


Interesting idea! I think that should be relatively easy to do actually… do you have an example of what you would do using this?