cocoa-xu / ExPTY

Fork pseudoterminals in Elixir
Apache License 2.0
18 stars 0 forks source link
elixir pseudoterminal tty

(Warning: this project is still WIP, there are a lot of things (like proper cleanups) not done yet, and right now it shows a minimal working product (without proper cleanups yet!) with Kino. Use at your own risk.

Any help/PR is welcome!

ExPTY

ExPTY fills the gap where executables spawned by Port do not have a tty available to them.

Module Example
ExPTY ```elixir iex> pty = ExPTY.spawn("tty", [], on_data: fn _, _, data -> IO.write(data) end) #PID<0.229.0> /dev/ttys001 ```
Port ```elixir iex> Port.open({:spawn, "tty"}, [:binary]) #Port<0.5> iex> flush() {#Port<0.5>, {:data, "not a tty\n"}} :ok ```

Most importantly, and as a consequence of the point above, we can now forward all data to somewhere else (e.g., via WebSocket to LiveBook) have a full terminal experience.

Example

defmodule Example do  
  def run do
    {:ok, pty} =
      ExPTY.spawn("tty", [],
        name: "xterm-color",
        cols: 80,
        rows: 24,
        on_data: __MODULE__,
        on_exit: __MODULE__
      )

    pty
  end

  def on_data(ExPTY, _erl_pid, data) do
    IO.write(data)
  end

  def on_exit(ExPTY, _erl_pid, exit_code, signal_code) do
    IO.puts("exit_code=#{exit_code}, signal_code=#{signal_code}")
  end
end

Installation

Unix

For Unix systems it's pretty much what you would expect, a working C/C++ toolchain, CMake, Make.

Windows

For Windows users, if you're not using Livebook, it's also the same as installing any other NIF libraries.

However, if you're trying to install it on a Livebook, you need to set up some environment variables.

Normally, these environment variables would be set by vcvarsall.bat in your cmd (or powershell, or any other shell), but here we have to do it manually:

Enum.each(String.split(env, "\n"), fn env_var ->
  case String.split(env_var, "=", parts: 2) do
    [name, value] ->
      System.put_env(name, value)
    _ -> :ok
  end
end)

If available in Hex, the package can be installed by adding ExPTY to your list of dependencies in mix.exs:

def deps do
  [
    {:expty, "~> 0.1.0"}
  ]
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/expty.

Acknowledgements

This project is largely based on microsoft/node-pty. Many thanks to all developers and maintainers, without them this wouldn't be possible.