I’d like to launch an editor (like
emacs) from my command-line script.
In Ruby I’d use
In Elixir, when I try
System.cmd "vim",  with various options, I run into terminal I/O issues.
Can anyone recommend best practice to launch
emacs from Elixir?
I don’t run a common terminal(sakura) so this may look odd
Thanks for that tip - clever! I got it to work using
System.cmd("terminator", ["-x", "vim", "/path/to/file"]) But this approach doesn’t work over ssh, and requires the script to know what terminal program is installed.
Still looking for an
exec solution that launches the editor in the console. This is simple in
ruby - can it be done in elixir/erlang?
I spent a while playing with this and couldn’t find a way to make it work - I can really understand the need for this so it’s sad it doesn’t seem possible. I deleted my previous post as it turned out to be unhelpful
Maybe someone more experienced with elixir internals will come and offer you a holy grail .
Can you be a bit more specific about your “terminal issues”? I would just do a System.cmd.
To test for yourself: fire up
iex and type
System.cmd "vim", 
I see these errors:
Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal
You can try
System.cmd("vim", , into: IO.stream(:stdio, :line)) That writes the
vim startup page to the terminal, but no keyboard input.
I’ve also tried:
System.cmd("bash", ["-c", "vim"]),
System.cmd("exec", ["-c", "vim"]) and a bunch of other variations.
I think launching an editor requires
unix fork/exec from erlang/elixir, but I couldn’t find any reference showing how to do this.
I’m using Ubuntu 16.04, bash 4.3, terminator 0.98, erlang 19, elixir 1.3.4.
If you have any ideas/suggestions I’m all ears!!
You can do something else if you really want. You can run the vim in tmux in background detached mode, and then attach it into different console/ssh conection like:
$ tmux new -d -s foo vim # convert this to System.cmd from elixir
$ tmux attach -t foo # execute this from different console as the same user
System.cmd "tmux" ["split-window"] works. Given that, we have many
tmux scripting options - nice idea!!
You can detect that you are running under a
tmux session using
System.get_env("TMUX"). So if running under
tmux, launch the editor, otherwise show an error message. That will work.
Still - it would be nicer to drop the
tmux dependency and just
exec vim like you can do in Bash or Ruby. Can anyone confirm if this is possible in Elixir? Or if not possible, explain why?
@hubertlepicki thank you for the
Ok–see “output is not to a terminal”, “input is not from a
terminal”–that’s the more specific I was thinking of. I don’t have an
ubuntu image handy to test this but I did just try this with emacs on
Windows and it works just fine.
System.cmd “/usr/bin/emacs/bin/runemacs”, 
Yes I know I’m discussing Windows vs Ubuntu and vim vs. emacs- but since
you seemed to be asking how to open the editor in general this does seem an
appropriate test. If on the other hand you’re asking for more than simply
opening up the editor then again please add more detail to your question.
My point is that I don’t think the problem is System.cmd; System.cmd works
just fine. I think the issue is that you’re trying to do more than just
fire up vim and that’s fine but that seems to be an issue with Vim–not
Elixir. Check this link
for that “Output is not to a terminal” message. And here
for more on “Input is not from a terminal”.
Basically it looks as if you’re trying to do more than simply start Vim
(perhaps unintentionally) and if that’s the case then you need to spell out
what it is that you’re trying to do. At any rate I don’t think this is an
You’re showing your windows bias. There is actually a real problem here; processes run by System.cmd on unix based systems don’t have a tty attached to stdin/stdout. You can’t run anything that needs “editor like” access to the tty.( at least with the default settings).
There are a bunch of ways to get around this ( xterm -c , tmux, etc… ), but System.cmd has some real limitations on unix compared to languages like Ruby. You can easily open an editor in a windowing environment (tmux is ascii windows more or less ), but in the classic glass tty mode, you can’t.
To be honest, wanting to do this kind of seems like a screwhammer approach, but regardless there isn’t a straightforward way to open a tty based editor on unix on the BEAM. We aren’t doing any favors to anybody in pretending that the problem doesn’t exist.
No - just trying to start vim on ubuntu using
System.cmd "vim", .
Interesting to hear that it worked on windows!! I would like an approach that works for all platforms and editors.
FYI on Ubuntu I also failed to launch
nano - seems that this is more than a vim-specific issue.
Thanks for posting the links.
Even if the tty was accessible
System.cmd doesn’t have the correct semantics to work with an editor. It doesn’t work with ed for example, because System.cmd is meant to run a command and capture stdout. It swallows all stdout until the process exits.
The other issue I can think off the top of my head is that by default I/O is line based from STDIN. (i.e. the stdin I/O handler does not send input to a process until \n is entered). There are ways to enable char based input to do curses like apps. (Does anyone out there remember line-mode telnet?)
There is no direct interface to fork/exec available on the BEAM. Ports come close, but they use stdin/out of the sub-process to communicate. I’m not sure there’s any way access the tty of the controlling BEAM process.
If you REALLY need to use an editor, I’d suggest running the escript as a subprocess of another scripting language and capture the output of the escript using various expect style libraries.
Have the escript output “edit filename”, and the wrapper script edit the file. The escript should wait for input like “edit filename done” and the wrapper will need to send that when finished.
Does all that feel like pounding screws with a hammer? 'Cause as much as I really like using Elixir for cli type stuff, there are some problems that it just doesn’t match up well with.
Thanks for your feedback. Seems like launching an editor or any type of curses interface isn’t going to happen direct from Escript.
Besides this I/O issue, I find Elixir to be very nice for building CLI. My Escripts tend to have a very thin ‘CLI’ layer, very decoupled from the app. It would be simple to write a CLI layer in another language, at the cost of extra complexity in distribution & installation.
Another idea: I found a couple of NIF based packages to integrate Erlang & Ncurses. See https://github.com/sofuture/encurses and https://github.com/mazenharake/cecho . Perhaps it would be possible to use NIF to create a ‘Launch an Editor’ package(?)
For now, I’ll use the tmux workaround.
James Smith (not sure if he’s on the forum) gave a talk at the first ElixirConf in which he drove a rogue-like game via Elixir. I think it was with ports. That might give you some more ideas to try.
Not really my windows bias Booker–my ignorance of behavior on *nix. I
just assumed that if Windows was capable of handling this then surely *nix
would be. My bad for making an assumption.
As ex_top demonstrates, https://github.com/utkarshkukreti/ex_top, you can certainly use curses from within Elixir. So I guess you could port a minimal editor environment to Elixir.
I’m not sure NIFS would help all that much. You need to dup stdin/out or somehow grab access to the process groups ttys.
For future reference …
Here’s a function to detect the presence of TMUX:
defp using_tmux?(), do: System.get_env("TMUX") != nil
Here’s a function to launch vim in a TMUX split-window:
defp launch_vim_for(file_path) do
System.cmd "tmux", ["split-window", "vim", file_path]
This thread seems rather old… however I am looking to do the same thing. Did anyone ever figure this out?
The question of it becomes “how do you launch an editor when you don’t have stdin/stdout?” in essence.
Being that, do you prefer a GUI editor, or a terminal editor? And if a terminal editor do you want a new tab? Or if a console editor would another tmux session be fine?
A terminal editor is fine. My issue is that this tool that I am making will be available and used by all the devs in my organization. I can’t be sure that everyone has and is running a tmux session.