The Erlang Shell

What century was that again? :grin:

Filthy rodent verminā€¦ :face_with_peeking_eye:

For that use case (which probably is rare), there could be an Erlang-as-you-know-it key binding which you can install and use on all environments you are using :woman_shrugging:

3 Likes

ā€œAt the Time When Things Were Otherwise and the Moon was Differentā€ :stuck_out_tongue_closed_eyes:

5 Likes

:thinking: ā€¦ Pratchett?

2 Likes

Correct :wink: ā€œNationā€, unless I am mistaken.

4 Likes

For me a good history management would allow people to store history in separated files. This would avoid sharing history across multiple projects.

erl -kernel_shell_history enabled -kernel_shell_history_dir ./shell_history

Plus the capability to have multiple history for one node. For instance when you have a server that expose an ssh connection, the shell history is the node shell history. Which is not that great for multi users node or clusters.

2 Likes

The capability to capture control sequence in the IO protocol is key. This is missing when wanting to implement your own control sequence. And in the ssh module it makes it impossible to make the connection quit on Control-D as nothing can be captured.

2 Likes

Do you mean what -kernel shell_history_path Dir does? Or is something missing with that implementation?

Since Erlang has no concept of multiple users it is not obvious (at least to me) how to select which history it should use. For ssh it could be possible to do better, but for -remsh Iā€™m unsure what to do.

Being able to configure all sorts of key binding and what is captured is one of the things on our list of things to do. So this should be possible to achieve when we are done.

2 Likes

One thing I used a lot when working with F# in the past is editing code in my editor then sending an expression or function to a running F# shell for evaluation and testing. Perhaps this is already possible right now?

I havenā€™t read every comment above so apologies if this has already been mentioned.

2 Likes

I think that would be something for ErlangLS or your favourite code editor to do. Not sure the shell can help out all that much there except being better at parsing all valid Erlang code (macros, attributes, functions etc).

3 Likes

Apologies if this has already been covered, but Iā€™d like to be able to paste code from a .erl file into a vanilla shell and have it just work such as:

1> -type foo() :: 1..20.
2> -record('Things', {
2>       'One' :: foo(),
2>       'Two' :: foo(),
3>       'Tri' :: string()
3> }).
4> record_info(fields, 'Things').

In the above contrived example, neither -type nor record_info currently work in the shell.

4 Likes

Indeed, Karlā€™s favourite editor can do that. :wink: Iā€™ve recorded a quick demo. Iā€™m using GitHub - akinsho/toggleterm.nvim: A neovim lua plugin to help easily manage multiple terminal windows (another popular plugin is GitHub - numToStr/FTerm.nvim: No-nonsense floating terminal plugin for neovim):

https://asciinema.org/a/496194

In real life, the commands would be mapped to some keys of course, but Iā€™m showing full commands to make it clear what is going on.

UPDATE: I just noticed that some colors were lost when recording using https://asciinema.org so some UI elements look strange but whatever - you get the idea and asciinema is still awesome.

3 Likes

I wish Vim mode was possible in iex and erl. I use it all the time in zsh.

2 Likes

One thing that just came to my mind: A nicer message handling would be great. It could be just simple things, like an indication of the queue size on the prompt or (and this is what Iā€™d like the most) timestamps on flush(). :slight_smile:

2 Likes

a record prompt like:

1>rd(record, {a, b, c}).
2># recor\tab
2>#record
2>#record.\tab
a    b    c

I have try it with my web shell, itā€™s nice to use :smile:

2 Likes

Option to remember variable bindingsā€¦seeā€¦

This is something I wrote for Elixir as my first project. Basically a more advanced history: GitHub - nhpip/history: An improved history for the Elixir IEx shell

Highlights:

  1. History saved between shell sessions
  2. Remembers variable bindings between shell sessions
  3. Nicer presented history
  4. Execute and/or copy commands previously issued
  5. Scroll up/down history but pasting of a large term or code will be thought of a single line instead of many
  6. History/bindings are remembered per node name or globally
3 Likes

Another feature request is the ability to start the shell at any moment in the code. There is no official API to do so and Rebar hacks it in order to get rebar3 shell to work: rebar3/rebar_prv_shell.erl at fc52e08b400e4e1cae980368577ed69c2bfd0653 Ā· erlang/rebar3 Ā· GitHub :slight_smile:

8 Likes

On documentation helpers:
I could use a version of h() which allows the ā€œregularā€ form of a function with the module:function form:
e.g. h(erlang:system_time).

This would allow me to copypaste directly to h().
Now I have to copy the module:function and replace the colon with a comma.

3 Likes

At the moment, anything typed in the Erlang shell has to be valid erlang syntax, which h(erlang:system_time) is not. I too would have liked it to be possible to type what you propose, but it is not trivial to get working.

1 Like

Would fun erlang:system_time/_ be an option?

1 Like

It needs to be an executable expression, so fun erlang:system_time/1 would work, but Iā€™m not sure how much easier that is to write?

1 Like