Skip to content

Instantly share code, notes, and snippets.

@zachallaun
Created November 14, 2024 17:14
Show Gist options
  • Save zachallaun/2c0f0e848e5cec0962ff90fc89e29f49 to your computer and use it in GitHub Desktop.
Save zachallaun/2c0f0e848e5cec0962ff90fc89e29f49 to your computer and use it in GitHub Desktop.
`getn` implemented using raw mode in OTP 28
defmodule Getn do
def getn(prompt, count \\ 1) do
if System.otp_release() >= "28" do
case :shell.start_interactive({:noshell, :raw}) do
:ok -> getn_raw(prompt, count)
_error -> gets_cooked(prompt)
end
else
gets_cooked(prompt)
end
end
defp getn_raw(prompt, count) do
IO.write(prompt)
resp = get_chars(count)
IO.write("\r\n")
:shell.start_interactive({:noshell, :cooked})
resp
end
defp get_chars(count) do
if count <= 0 do
""
else
resp = IO.getn("", count)
IO.write(resp)
resp <> get_chars(count - String.length(resp))
end
end
defp gets_cooked(prompt) do
prompt
|> IO.gets()
|> String.trim_trailing("\n")
end
end
resp = Getn.getn("1 char: ", 1)
IO.puts("got: #{inspect(resp)}")
resp = Getn.getn("2 chars: ", 2)
IO.puts("got: #{inspect(resp)}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment