defmodule Pi.Eval.Output do @moduledoc false alias Pi.Protocol.Tool.OutputPart alias Pi.Protocol.UI.Block alias Pi.Protocol.UI.Display @inspect_opts [charlists: :as_lists, limit: 50, pretty: true] @preview_inspect_opts [ charlists: :as_lists, limit: 20, pretty: false, printable_limit: 200, width: 1_000_000 ] def inspect_value(value), do: inspect(value, @inspect_opts) def preview(value), do: inspect(value, @preview_inspect_opts) def error_text(%{text: text}) when is_binary(text), do: text def error_text(text) when is_binary(text), do: text def error_exception(%{exception: exception}) when is_map(exception), do: exception def error_exception(_), do: nil def maybe_io_part(parts, ""), do: parts def maybe_io_part(parts, io), do: parts ++ [OutputPart.text(io)] def display(parts), do: %Display{blocks: Enum.map(parts, &part_block/1)} def capture_io(fun) do {:ok, pid} = StringIO.open("") original = Application.get_env(:elixir, :ansi_enabled) original_gl = Process.group_leader() Application.put_env(:elixir, :ansi_enabled, false) Process.group_leader(self(), pid) try do result = fun.() {_, content} = StringIO.contents(pid) {result, content} after Process.group_leader(self(), original_gl) StringIO.close(pid) Application.put_env(:elixir, :ansi_enabled, original) end end defp part_block(%OutputPart{} = part) do struct(Block, type: block_type(part.kind), text: part.body, language: part.language) end defp block_type(:code), do: :source defp block_type(kind), do: kind end