Module: Unmagic::Browser::Console::Prompt

Defined in:
lib/unmagic/browser/console/prompt.rb

Overview

An opt-in prompt that says what's open.

browser> until there's a page, and then the same green dot and title the renderer already shows for a session:

● Sign in · jobs.town> click "Email"

Off by default — the console prompts with a plain browser> . Ask for it with Unmagic::Browser::Console.start(prompt: :page).

IRB asks its context for the prompt every time it redraws the line — once per keystroke, not once per statement — so nothing here may talk to the browser. The page is read once after each statement instead, and what it said is held until the next one.

Constant Summary collapse

IDLE =

What to say when nothing's open.

"browser"
MAX_LABEL =

Long enough to tell two pages apart, short enough to leave room to type. Titles run long — "Sign in · jobs.town" is a short one.

32
SHARE =

How much of a narrow terminal the label may take before that limit comes down to meet it.

3
MIN_LABEL =

Below this there's no room for a title worth reading anyway.

12
CONTROL =

Control characters would tear the line apart — a title with a newline in it is rare, but it only has to happen once.

"\x00-\x1F"

Class Method Summary collapse

Class Method Details

.continuation(mark) ⇒ String

Lined up under render, so a multi-line statement reads as one block however long the title is.

Parameters:

  • mark (String)

    one visible character — IRB's %l, or a *

Returns:

  • (String)


89
90
91
# File 'lib/unmagic/browser/console/prompt.rb', line 89

def continuation(mark)
  "#{" " * (@width - 2)}#{mark} "
end

.install(context) ⇒ void

This method returns an undefined value.

Give a context a prompt that follows the browser around.

IRB reads prompt_i and friends off its context every time it draws, so overriding them there is all it takes; the formats in IRB.conf stay as they are for anyone who switches prompt modes.

Parameters:

  • context (IRB::Context)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/unmagic/browser/console/prompt.rb', line 52

def install(context)
  context.define_singleton_method(:prompt_i) { Prompt.render }
  context.define_singleton_method(:prompt_s) { Prompt.continuation("%l") }
  context.define_singleton_method(:prompt_c) { Prompt.continuation("*") }

  # Any statement can have moved the page — a click that follows a
  # link says nothing about it, and neither does `js "location = ..."`
  # — so the page gets asked after every one of them rather than after
  # the verbs we could think of.
  context.define_singleton_method(:evaluate) do |*args, **options, &block|
    super(*args, **options, &block)
  ensure
    Prompt.refresh
  end

  refresh
end

.refreshvoid

This method returns an undefined value.

Ask the page where it is. Everything that could raise or block happens here, so that drawing the prompt is only string work.



74
75
76
77
# File 'lib/unmagic/browser/console/prompt.rb', line 74

def refresh
  @live, @label = read
  @width = (@live ? 2 : 0) + columns_of(@label) + 2
end

.renderString

Returns the prompt.

Returns:

  • (String)

    the prompt



80
81
82
# File 'lib/unmagic/browser/console/prompt.rb', line 80

def render
  "#{marker}#{escape(@label)}> "
end