Portable Getch for Elixir?

I’ve had difficulty to find a simple & portable getch implementation for Elixir. The use case is for CLI scripts, where the user is prompted for a single-character keypress, without needing the return key.

I’ve looked at ex_ncurses, rustler, System.cmd, Ports, etc. This is the best I’ve come up with so far:

#!/usr/bin/env elixir

ruby_cmd = ~S"""
  ruby -e '
    require "io/console"
    @output = IO.new(4)
    @output.sync = true
    char = STDIN.getch
    @output.write(char)
  '
"""

IO.write("Press a key > ")
port = Port.open({:spawn, ruby_cmd}, [:binary, :nouse_stdio]) 
receive do
  {^port, {:data, result}} -> IO.puts("\nChar: #{result}")
end

This works on my Linux dev machine, but depends on Ruby. Does anyone know of a portable getch implementation? Maybe with Rustler and precompiled Rust binaries, or ???

3 Likes

I think thats not possible in Erlang.
I’d write the complete CLI in Python as it has very nice libraries to do that (or Ruby if you like that better).
Then hook it to a port.