2018-10-27 17:04:13 -04:00
|
|
|
class Pry
|
2018-11-03 09:58:16 -04:00
|
|
|
# Prompt represents the Pry prompt, which can be used with Readline-like
|
|
|
|
# libraries. It defines a few default prompts (default prompt, simple prompt,
|
|
|
|
# etc) and also provides an API to add custom prompts.
|
2018-10-28 04:12:39 -04:00
|
|
|
#
|
2018-11-03 09:58:16 -04:00
|
|
|
# @example
|
|
|
|
# Pry::Prompt.add(
|
|
|
|
# :ipython,
|
|
|
|
# 'IPython-like prompt', [':', '...:']
|
|
|
|
# ) do |_context, _nesting, _pry_, sep|
|
|
|
|
# sep == ':' ? "In [#{_pry_.input_ring.count}]: " : ' ...: '
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # Produces:
|
|
|
|
# # In [3]: def foo
|
|
|
|
# # ...: puts 'foo'
|
|
|
|
# # ...: end
|
|
|
|
# # => :foo
|
|
|
|
# # In [4]:
|
2018-10-28 04:12:39 -04:00
|
|
|
# @since v0.11.0
|
2018-11-03 09:58:16 -04:00
|
|
|
# @api public
|
2018-10-28 04:12:39 -04:00
|
|
|
module Prompt
|
|
|
|
# @return [String]
|
2018-10-27 17:35:27 -04:00
|
|
|
DEFAULT_NAME = 'pry'.freeze
|
|
|
|
|
2018-10-28 04:12:39 -04:00
|
|
|
# @return [Array<Object>] the list of objects that are known to have a
|
|
|
|
# 1-line #inspect output suitable for prompt
|
2018-10-28 04:07:44 -04:00
|
|
|
SAFE_CONTEXTS = [String, Numeric, Symbol, nil, true, false].freeze
|
2018-10-27 17:35:27 -04:00
|
|
|
|
2018-11-03 12:57:02 -04:00
|
|
|
# @deprecated Use {Pry::Prompt.add} instead.
|
|
|
|
MAP = {}
|
|
|
|
deprecate_constant(:MAP) if respond_to?(:deprecate_constant)
|
|
|
|
|
2018-11-03 09:58:16 -04:00
|
|
|
# A Hash that holds all prompts. The keys of the Hash are prompt
|
|
|
|
# names, the values are Hash instances of the format {:description, :value}.
|
|
|
|
@prompts = {}
|
2018-10-28 04:12:39 -04:00
|
|
|
|
|
|
|
class << self
|
2018-11-03 09:58:16 -04:00
|
|
|
# Retrieves a prompt.
|
|
|
|
#
|
|
|
|
# @example
|
|
|
|
# Prompt[:my_prompt][:value]
|
|
|
|
#
|
|
|
|
# @param [Symbol] prompt_name The name of the prompt you want to access
|
|
|
|
# @return [Hash{Symbol=>Object}]
|
|
|
|
# @since v0.12.0
|
|
|
|
def [](prompt_name)
|
|
|
|
all[prompt_name.to_s]
|
2018-10-28 04:12:39 -04:00
|
|
|
end
|
|
|
|
|
2018-11-03 09:58:16 -04:00
|
|
|
# @return [Hash{Symbol=>Hash}] the duplicate of the internal prompts hash
|
|
|
|
# @note Use this for read-only operations
|
|
|
|
# @since v0.12.0
|
|
|
|
def all
|
|
|
|
@prompts.dup
|
2018-10-28 04:12:39 -04:00
|
|
|
end
|
|
|
|
|
2018-11-03 09:58:16 -04:00
|
|
|
# Adds a new prompt to the prompt hash.
|
|
|
|
#
|
|
|
|
# @param [Symbol] prompt_name
|
|
|
|
# @param [String] description
|
|
|
|
# @param [Array<String>] separators The separators to differentiate
|
|
|
|
# between prompt modes (default mode and class/method definition mode).
|
|
|
|
# The Array *must* have a size of 2.
|
|
|
|
# @yield [context, nesting, _pry_, sep]
|
|
|
|
# @yieldparam context [Object] the context where Pry is currently in
|
|
|
|
# @yieldparam nesting [Integer] whether the context is nested
|
|
|
|
# @yieldparam _pry_ [Pry] the Pry instance
|
|
|
|
# @yieldparam separator [String] separator string
|
|
|
|
# @return [nil]
|
|
|
|
# @raise [ArgumentError] if the size of `separators` is not 2
|
|
|
|
# @since v0.12.0
|
|
|
|
def add(prompt_name, description = '', separators = %w[> *])
|
|
|
|
unless separators.size == 2
|
|
|
|
raise ArgumentError, "separators size must be 2, given #{separators.size}"
|
2018-10-28 04:12:39 -04:00
|
|
|
end
|
2018-11-03 09:58:16 -04:00
|
|
|
|
|
|
|
@prompts[prompt_name.to_s] = {
|
|
|
|
description: description,
|
|
|
|
value: separators.map do |sep|
|
|
|
|
proc { |context, nesting, _pry_| yield(context, nesting, _pry_, sep) }
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
|
|
|
nil
|
2018-10-28 04:12:39 -04:00
|
|
|
end
|
2018-10-28 07:02:14 -04:00
|
|
|
|
2018-11-03 09:58:16 -04:00
|
|
|
private
|
|
|
|
|
2018-10-28 07:02:14 -04:00
|
|
|
def prompt_name(name)
|
|
|
|
return name unless name.is_a?(Pry::Config::Lazy)
|
|
|
|
|
|
|
|
name.call
|
|
|
|
end
|
2018-10-28 04:12:39 -04:00
|
|
|
end
|
|
|
|
|
2018-11-03 09:58:16 -04:00
|
|
|
add(:default, <<DESC) do |context, nesting, _pry_, sep|
|
|
|
|
The default Pry prompt. Includes information about the
|
|
|
|
current expression number, evaluation context, and nesting
|
|
|
|
level, plus a reminder that you're using Pry.
|
|
|
|
DESC
|
|
|
|
format(
|
|
|
|
"[%<in_count>s] %<name>s(%<context>s)%<nesting>s%<separator>s ",
|
|
|
|
in_count: _pry_.input_ring.count,
|
|
|
|
name: prompt_name(_pry_.config.prompt_name),
|
|
|
|
context: Pry.view_clip(context),
|
|
|
|
nesting: (nesting > 0 ? ":#{nesting}" : ''),
|
|
|
|
separator: sep
|
|
|
|
)
|
|
|
|
end
|
2018-10-27 17:35:27 -04:00
|
|
|
|
2018-11-03 09:58:16 -04:00
|
|
|
add(:simple, "A simple '>>'.", ['>> ', ' | ']) do |_, _, _, sep|
|
|
|
|
sep
|
|
|
|
end
|
2014-03-19 09:06:26 -04:00
|
|
|
|
2018-11-03 09:58:16 -04:00
|
|
|
add(:nav, <<DESC, %w[> *]) do |context, nesting, _pry_, sep|
|
|
|
|
A prompt that displays the binding stack as a path and
|
|
|
|
includes information about _in_ and _out_.
|
|
|
|
DESC
|
|
|
|
tree = _pry_.binding_stack.map { |b| Pry.view_clip(b.eval('self')) }
|
|
|
|
format(
|
|
|
|
"[%<in_count>s] (%<name>s) %<tree>s: %<stack_size>s%<separator>s ",
|
|
|
|
in_count: _pry_.input_ring.count,
|
|
|
|
name: prompt_name(_pry_.config.prompt_name),
|
|
|
|
tree: tree.join(' / '),
|
|
|
|
stack_size: _pry_.binding_stack.size - 1,
|
|
|
|
separator: sep
|
|
|
|
)
|
|
|
|
end
|
2014-03-19 09:06:26 -04:00
|
|
|
|
2018-11-03 09:58:16 -04:00
|
|
|
add(:shell, <<DESC, %w[$ *]) do |context, nesting, _pry_, sep|
|
|
|
|
A prompt that displays the binding stack as a path and
|
|
|
|
includes information about _in_ and _out_.
|
|
|
|
DESC
|
|
|
|
format(
|
|
|
|
"%<name>s %<context>s:%<pwd>s %<separator>s ",
|
|
|
|
name: prompt_name(_pry_.config.prompt_name),
|
|
|
|
context: Pry.view_clip(context),
|
|
|
|
pwd: Dir.pwd,
|
|
|
|
separator: sep
|
|
|
|
)
|
|
|
|
end
|
2014-03-19 09:06:26 -04:00
|
|
|
|
2018-11-03 09:58:16 -04:00
|
|
|
add(:none, 'Wave goodbye to the Pry prompt.', Array.new(2)) { '' }
|
2018-10-27 17:04:13 -04:00
|
|
|
end
|
2014-03-19 09:06:26 -04:00
|
|
|
end
|