brettbeatty

brettbeatty

Getting IO server to cooperate with raw TTY

I’m playing with building a TUI entirely in Elixir (no curses or anything). I use stty to put the TTY in raw mode, and that works fine when I read user input from STDIN, but I’m trying to change it to read user input explicitly from /dev/tty so content can be piped in. But I’m running into issues where the server wrapping the file doesn’t seem to work with TTY raw mode.

When I open /dev/tty with the :raw option, it doesn’t spin up an IO server, and I have to use :file.read/2 to read from it. This gets characters right as they’re typed, but it seems to grab bytes instead of unicode codepoints.

But if I don’t pass the :raw option and try to use IO.read/2 it doesn’t actually get characters until there’s an EOF on a new line, and I end up needing the icanon and icrnl flags to even do that. But IO.read/2 seems to actually return codepoints (I would prefer graphemes, but I don’t see a way to do that).

Are y’all aware of a way to get IO.read/2 on a file to work with a raw TTY mode?

#!/usr/bin/env sh
save_state=$(stty -g)
stty -f /dev/tty raw

# reads immediately after keypress
# elixir --erl '-noshell' -e '1 |> IO.read |> IO.inspect(label: "read")'

# reads immediately after keypress but bytes, not codepoints
# elixir --erl '-noshell' -e '"/dev/tty" |> File.open!([:read, :utf8, :raw]) |> :file.read(1) |> IO.inspect(label: "read")'

# reads after enter + eof (ctrl+d)
# stty -f /dev/tty icanon icrnl
# elixir --erl '-noshell' -e '"/dev/tty" |> File.open!([:read, :utf8]) |> :io.get_chars([], 1) |> IO.inspect(label: "read")'

# reads after enter + eof (ctrl+d)
stty -f /dev/tty icanon icrnl
elixir --erl '-noshell' -e '"/dev/tty" |> File.open!([:read, :utf8]) |> IO.read(1) |> IO.inspect(label: "read")'

stty -f /dev/tty "$save_state"
#io

Where Next?

Popular in Questions Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New

We're in Beta

About us Mission Statement