- Summary
- Installation and Usage Instructions
- Description
- Interactive Shell Types
- Smart: :user_drv
- Dumb: :user
- Interactive Shell Types
- Caveats
- License
I love Elixir. Period. But, the lack of a q/0
helper in IEx
has driven
me nuts since (my) day 1.
This is a proof-of-concept that a safe q/0
helper may be possible.
And, yes, it even works after switching nodes via the JCL.
For the impatient, I'll put this right up top. I highly recommend you read the remainder of this document, though. In particular the Caveats may be useful to know.
Append the contents of iex.exs
to your ~/.iex.exs
file.
Note that the script automagically aliases IExExs.Helpers
to H
for you.
Within IEx
, use H.q/0
to quit:
iex> H.q
You may also wish to try the H.jobs/0
helper:
iex> H.jobs
If you would like to just use jobs/0
and/or q/0
, then:
iex> import IExExs.Helpers
iex> jobs
iex> q
Some time ago, I created a naïve
pull request for a q/0
function in IEx.Helpers
. Anyway, it basically called :erlang.halt/0
.
@josevalim was kind enough to explain the rejection, rather than flat out
reject it:
Unfortunately this is hurtful when running on a remote shell because it turns off the remote node as well. For this reason we haven't added any sort of quit function so far. We'd gladly accept one if it means only turning off the current node.
This says to me that there is a safe way to turn off the IEx
node.
Exploring both the Elixir and Erlang/OTP source showed two basic shell types: dumb and smart. Each of these has its own issues that are worth discussing.
Smart terminals use :user_drv for user interaction. This allows the user to
type Ctrl-G
and interact with the Job Control Language (JCL). This allows
the user to quit gracefully with the q
command.
Unfortunately, there is no way to directly interact with the JCL via programming. I'm not sure why this design decision was made, but I find it a bit frustrating.
It is possible, however, to perform I/O with the :user_drv process on behalf of the user. This is a bit tricky, mostly due to timing reasons. I'll go into the details in Caveats, below.
The important message here: It is possible, though tricky, to interact with the JCL on behalf of the user.
First, let me say that the only way I've found to start a dumb terminal is by
using iex.bat
on Windows without the --werl
flag. My experiments with it
have shown the following:
- Dumb terminals cannot use the JCL
- Dumb terminals cannot be named via
--name
or--sname
- Dumb terminals cannot
- connect to a remote node
- be connected to by a remote node
Because of this, ending a session with :erlang.halt/0
should be safe.
Regardless, I've left it commented out in the iex.exs
file (line 83).
Uncomment the line if you wish to try it out.
The dumb terminal caveats are simply that lack of certainty in safety. If it
is safe to use :erlang.halt/0
, then this is the easy one.
The smart terminal, on the other hand, is a bit tricky.
First, this implementation is highly dependent on the internals of
user_drv.erl
. If I had my druthers, I would rewrite it and make the JCL
more directly programmable. However, this is a proof of concept, and that
seems to be going a bit far (though, I'm still thinking of trying it).
Second, I/O timing can be tricky. Sometimes a pause is needed for :user_drv
to process the Ctrl-G
. I did find source in the Erlang/OTP test suite that
showed a way to calibrate the pause, but it is not implemented here.
The short of it is, if q
or j
comes too quickly after Ctrl-G
,
:user_drv
will not observe the input, and the user is left hanging at a JCL
prompt.
Copyright 2015 Brett DiFrischia
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
I updated the
iex.exs
filename toIEx.exs
so the name of the gist would be more appropriate.