Module: Interactive::Rewindable

Includes:
Interactive
Defined in:
lib/interact/rewindable.rb

Overview

Copyright © 2012 Alex Suraci

Defined Under Namespace

Classes: JumpToPrompt

Constant Summary collapse

HAS_CALLCC =

:nodoc:

true

Constants included from Interactive

ESCAPES, EVENTS

Instance Method Summary collapse

Methods included from Interactive

#read_char, #read_event, #read_line

Instance Method Details

#ask(question, options = {}) ⇒ Object

Ask a question and get an answer. Rewind-aware; call disable_rewind on your class to disable.

See Interact#ask for the other possible values in options.

question

The prompt, without “: ” at the end.

options

An optional hash containing the following options.

forget

Set to true to prevent rewinding from remembering the user’s answer.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/interact/rewindable.rb', line 39

def ask(question, options = {})
  rewind = HAS_CALLCC

  if rewind
    prompt, answer = callcc { |cc| [cc, nil] }
  else
    prompt, answer = nil, nil
  end

  if answer
    options[:default] = answer
  end

  prompts = (@__prompts ||= [])

  options[:prompts] = prompts

  ans = super

  if rewind
    prompts << [prompt, options[:forget] ? nil : ans]
  end

  ans
end

#finalizeObject

Clear prompts.

Questions asked after this are rewindable, but questions asked beforehand are no longer reachable.

Use this after you’ve performed some mutation based on the user’s input.



71
72
73
# File 'lib/interact/rewindable.rb', line 71

def finalize
  @__prompts = []
end

#handler(which, state) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/interact/rewindable.rb', line 75

def handler(which, state)
  prompts = state.options[:prompts] || []

  case which
  when :up, :shift_tab
    if back = prompts.pop
      raise JumpToPrompt, back
    end
  end

  super
end

#with_char_io(input) ⇒ Object



88
89
90
91
92
93
94
95
96
# File 'lib/interact/rewindable.rb', line 88

def with_char_io(input)
  before = set_input_state(input)
  yield
rescue JumpToPrompt => e
  restore_input_state(input, before)
  e.jump
ensure
  restore_input_state(input, before)
end