Ascii.Pieces.Terminal (Ascii v0.3.0)

Copy Markdown View Source

A shell session: typed commands, output, scrolling, clear.

A shell session in a rounded frame. Each command is typed a key at a time, its output prints line by line and scrolls, and a clear starts over. As upstream draws it, it plays a session of its own; give it a history and it shows yours: commands and their output, or a log's tail.

Options

Give them to Ascii.new/2 as options:, and new ones while it plays with Ascii.put_options/2 (or a Phoenix player's options). New history carries on from what is on screen: with typing, what has been typed stays, new entries are typed from then on, and new lines of output under the last command print; without, the history is shown as it stands.

  • history - what the terminal shows instead of upstream's session: a list of %{command: "...", output: ["...", ...]}, each command after the prompt with the lines it printed under it. An entry without a command is output alone, so a log's tail is history: [%{output: lines}]. The newest lines are at the bottom, older ones scrolled away, and lines too long for the width are cut. After a command the prompt comes back, the cursor blinking after it; after output alone the cursor waits at the start of the next line, as it does while a command runs. Default []: upstream's session.
  • typing - with history, play it out: each command typed a key at a time and its output printed a line at a time, once through, and then hold. Default false: the history shown at once.
  • prompt - before each command; a space follows it. Default "~/notes $".
  • title - in the top of the frame; "" for none. Default "~/notes".
  • cols, rows - the frame's size, the border included, 12 to 200 by 3 to 60; upstream's 62 by 18 by default.

Colours

In one ink, or a gradient, with :ink and :gradient (see Ascii.Ink); part by part with :parts (see Ascii.Parts), parts: true taking the colours suggested here:

  • frame - the window's border, grey; title, its title.
  • prompt - the prompt, blue.
  • command - what is typed after it.
  • output - what the commands print; a todo list's items marked checked ([x]), green, or unchecked ([ ]), grey.
  • cursor - the cursor, yellow.

A line that reads as both a command and output (a prompt made to look like output) is in no part.

Keys and clicks

It takes none: it shows a session, and Ascii.handle_event/2 ignores every event. To make it a shell of your own, take the keys in your app and give it the new history. A Phoenix player given interactive and notify still tells your LiveView where it was clicked, and on which part (Ascii.part_at/4), a command or a line of output, say.

Screen readers

Ascii.describe/1 tells the history: "terminal my_app: 1 command, the last mix test", or for output alone "terminal ~/notes: 2 lines of output, the last: two". Playing upstream's session, it gives the piece's name and note.

Example

history = [%{command: "mix test", output: ["...........", "11 tests, 0 failures"]}]
options = %{title: "my_app", prompt: "$", history: history, cols: 40, rows: 8}
term = Ascii.new!("terminal", options: options, parts: true)
{frame, _term} = Ascii.frame(term, 0.0)
Enum.at(frame.lines, 3)
#=> "│ 11 tests, 0 failures                 │"

Ascii.describe(term)
#=> "terminal my_app: 1 command, the last mix test"
<Ascii.Phoenix.live_player id="log" piece="terminal" options={%{title: "deploy", history: [%{output: @log}]}} parts />

Ported from src/pieces/terminal.ts in bas3line/ascii (MIT).