Current section
Files
Jump to
Current section
Files
lib/pane.ex
defmodule Pane do
@moduledoc """
Paginated data viewer for IEx. Useful for inspecting large collections and
deeply nested structs.
## Usage
```
iex> data = File.read!("mix.exs") # Or some other really long string
iex> Pane.console(data)
```
```
defmodule Pane.Mixfile do
use Mix.Project
@source_url "https://github.com/codedge-llc/pane"
@version "0.5.0"
def project do
[
app: :pane,
build_embedded: Mix.env() == :prod,
deps: deps(),
dialyzer: dialyzer(),
docs: docs(),
elixir: "~> 1.13",
name: "Pane",
[1 of 5] (j)next (k)prev (f)first (l)last (q)quit
```
## Available Commands
* `j` - Next page
* `k` - Previous page
* `f` - First page
* `l` - Last page
* `q` - Quit
"""
@doc ~S"""
Paginates data and starts a pseudo-interactive console.
"""
@spec console(any) :: no_return
def console(data) when is_binary(data) do
if IO.ANSI.enabled?() do
start_and_recv(data)
else
prompt = "Pane requires ANSI escape codes to work. Enable? (Yn) "
case IO.gets(prompt) do
"Y" <> _rest -> enable_ansi_and_start(data)
"y" <> _rest -> enable_ansi_and_start(data)
_ -> :ok
end
end
end
def console(data), do: data |> inspect(pretty: true) |> console()
defp enable_ansi_and_start(data) do
Application.put_env(:elixir, :ansi_enabled, true)
start_and_recv(data)
end
defp start_and_recv(data) do
Pane.Viewer.start_link(data: data)
recv_input()
end
defp recv_input do
IEx.Helpers.clear()
IO.puts(Pane.Viewer.current_page().data)
input = <<"\n", Pane.Viewer.prompt()::binary>> |> IO.gets()
process(input)
end
defp process("f\n") do
Pane.Viewer.first_page()
recv_input()
end
defp process("l\n") do
Pane.Viewer.last_page()
recv_input()
end
defp process("j\n") do
Pane.Viewer.next_page()
recv_input()
end
defp process("k\n") do
Pane.Viewer.prev_page()
recv_input()
end
defp process("q\n") do
Pane.Viewer.stop()
IEx.Helpers.clear()
:ok
end
defp process(_else) do
Pane.Viewer.current_page()
recv_input()
end
end