diff options
author | 0xAB <0xAB@protonmail.com> | 2017-08-27 10:56:46 +0100 |
---|---|---|
committer | 0xAB <0xAB@protonmail.com> | 2017-08-27 10:56:46 +0100 |
commit | 5053b5a6d09635b9621c25407f1fc7b141504ad0 (patch) | |
tree | 03a3ad36bf3f27c7ac61209d7d77e7d2885b7e28 | |
parent | d3da637a902407dc1774316d1fc31d52fe3cc18a (diff) | |
download | pry-5053b5a6d09635b9621c25407f1fc7b141504ad0.tar.gz |
add Pry::Prompt.alias_prompt, ref #1628
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | lib/pry/commands/change_prompt.rb | 7 | ||||
-rw-r--r-- | lib/pry/commands/list_prompts.rb | 22 | ||||
-rw-r--r-- | lib/pry/prompt.rb | 78 | ||||
-rw-r--r-- | spec/prompt_spec.rb | 12 |
5 files changed, 95 insertions, 28 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 1137a5d4..332b6118 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ### HEAD -* Add `Pry::Prompt.add_prompt()`, `Pry::Prompt.get_prompt()`, and `Pry::Prompt.remove_prompt()`, for integrating custom prompts with Pry ([#1628](https://github.com/pry/pry/pull/1628)) +* Add `Pry::Prompt.add_prompt()`, `Pry::Prompt.get_prompt()`, `Pry::Prompt.alias_prompt` and + `Pry::Prompt.remove_prompt()`, for integrating custom prompts with Pry + ([#1628](https://github.com/pry/pry/pull/1628)) * Add text helpers for background colors ([#1624](https://github.com/pry/pry/pull/1624)) * Fix string literal methods completion. ([#1590](https://github.com/pry/pry/pull/1590)) * Make sure Pry::WrappedModule::Candidate#source_location returns non-nil value when `.name` has diff --git a/lib/pry/commands/change_prompt.rb b/lib/pry/commands/change_prompt.rb index 4fe32d71..240cd63e 100644 --- a/lib/pry/commands/change_prompt.rb +++ b/lib/pry/commands/change_prompt.rb @@ -11,16 +11,13 @@ class Pry::Command::ChangePrompt < Pry::ClassCommand BANNER def process(prompt) - if prompt_map.key?(prompt) - _pry_.prompt = prompt_map[prompt][:value] + if new_prompt = Pry::Prompt.get_prompt(prompt) + _pry_.prompt = new_prompt.proc_array else raise Pry::CommandError, "'#{prompt}' isn't a known prompt!" end end private - def prompt_map - Pry::Prompt::PROMPT_MAP - end Pry::Commands.add_command(self) end diff --git a/lib/pry/commands/list_prompts.rb b/lib/pry/commands/list_prompts.rb index 9177a629..169c58b9 100644 --- a/lib/pry/commands/list_prompts.rb +++ b/lib/pry/commands/list_prompts.rb @@ -10,26 +10,26 @@ class Pry::Command::ListPrompts < Pry::ClassCommand BANNER def process - output.puts heading("Available prompts") + "\n" - prompt_map.each do |name, prompt| - output.write "Name: #{text.bold(name)}" - output.puts selected_prompt?(prompt) ? selected_text : "" - output.puts prompt[:description] + output.puts heading("Available prompts") + "\n\n" + all_prompts.each do |prompt| + next if prompt.alias? + aliases = Pry::Prompt.aliases_for(prompt.name) + output.write "Name: #{text.bold(prompt.name)}" + output.puts selected_prompt?(prompt) ? text.green(" [active]") : "" + output.puts "Aliases: #{aliases.map(&:name).join(',')}" if aliases.any? + output.puts prompt.description output.puts end end private - def prompt_map - Pry::Prompt::PROMPT_MAP - end - def selected_text - text.red " (selected) " + def all_prompts + Pry::Prompt.all_prompts end def selected_prompt?(prompt) - _pry_.prompt == prompt[:value] + _pry_.prompt == prompt.proc_array end Pry::Commands.add_command(self) end diff --git a/lib/pry/prompt.rb b/lib/pry/prompt.rb index 2d8bcb36..f20d129d 100644 --- a/lib/pry/prompt.rb +++ b/lib/pry/prompt.rb @@ -1,6 +1,43 @@ module Pry::Prompt extend self PROMPT_MAP = {} + AliasError = Class.new(RuntimeError) + PromptInfo = Struct.new(:name, :description, :proc_array, :alias_for) do + # + # @return [Boolean] + # Returns true if the prompt is an alias of another prompt. + # + def alias? + alias_for != nil + end + end + + # + # @return [Array<PromptInfo>] + # Returns an Array of {PromptInfo} objects. + # + def all_prompts + PROMPT_MAP.values + end + + # + # @param [String] prompt + # The name of a prompt. + # + # @return [Array<PromptInfo>] + # Returns an array of aliases for _prompt_, as {PromptInfo} objects. + # + def aliases_for(prompt) + all_prompts.select{|prompt_info| prompt_info.alias_for == prompt.to_s} + end + + # + # @return [Array<PromptInfo>] + # Returns an array of all prompt aliases, as {PromptInfo} objects. + # + def aliased_prompts + all_prompts.select(&:alias?) + end # # Integrate a custom prompt with Pry. @@ -17,23 +54,20 @@ module Pry::Prompt # A prompt in the form of [proc {}, proc {}]. # def add_prompt(name, description, value) - PROMPT_MAP[name.to_s] = { - value: value, - description: description - } + PROMPT_MAP[name.to_s] = PromptInfo.new(name, description, value, nil) end # # @example # # # .pryrc - # Pry.config.prompt = Pry::Prompt.get_prompt('simple') + # Pry.config.prompt = Pry::Prompt.get_prompt('simple').proc_array # - # @return [Array<Proc,Proc>] - # Returns a prompt in the form of [proc{}, proc{}] + # @return [PromptInfo] + # Returns a prompt in the form of a PromptInfo object. # def get_prompt(name) - PROMPT_MAP.key?(name.to_s) and PROMPT_MAP[name.to_s][:value] + PROMPT_MAP.key?(name.to_s) and PROMPT_MAP[name.to_s] end # @@ -41,6 +75,9 @@ module Pry::Prompt # It will no longer be visible in the output of "list-prompts" or usable with the # "change-prompt" command. # + # @note + # Aliases are also removed. + # # @param [String] name # The name of a prompt. # @@ -48,7 +85,30 @@ module Pry::Prompt # Returns truthy if a prompt was deleted, otherwise nil. # def remove_prompt(name) - PROMPT_MAP.delete name.to_s if PROMPT_MAP.key?(name.to_s) + name = name.to_s + if PROMPT_MAP.key?(name) + aliases_for(name).each{|_alias| PROMPT_MAP.delete(_alias.name)} + PROMPT_MAP.delete name + end + end + + # + # Provide alternative name for a prompt, which can be used from the list-prompts + # and change-prompt commands. + # + # @param [String] prompt_name + # The name of the prompt to alias. + # + # @param [String] aliased_prompt + # The name of the aliased prompt. + # + def alias_prompt(prompt_name, aliased_prompt) + if prompt = get_prompt(prompt_name) + PROMPT_MAP[aliased_prompt] = PromptInfo.new *[aliased_prompt, prompt.description, + prompt.proc_array, prompt_name] + else + raise AliasError, "prompt '#{prompt}' cannot be aliased because it doesn't exist" + end end add_prompt "default", diff --git a/spec/prompt_spec.rb b/spec/prompt_spec.rb index 45c21fd6..f2a61604 100644 --- a/spec/prompt_spec.rb +++ b/spec/prompt_spec.rb @@ -16,10 +16,9 @@ RSpec.describe Pry::Prompt do describe ".add_prompt" do specify "it adds a new prompt to Pry" do new_prompt = described_class::PROMPT_MAP['prompt-name'] - expect(new_prompt).to eq(description: "prompt description", value: prompt_value) expect(pry_eval("list-prompts")).to include("prompt-name") expect(pry_eval("list-prompts")).to include("prompt description") - expect(pry_eval("change-prompt prompt-name", "_pry_.prompt")).to eq(prompt_value) + expect(pry_eval("change-prompt prompt-name", "_pry_.prompt")).to eq(new_prompt.proc_array) end end @@ -30,6 +29,15 @@ RSpec.describe Pry::Prompt do expect(pry_eval("list-prompts")).to_not include("prompt description") end end + + describe ".alias_prompt" do + specify "creates alias" do + described_class.alias_prompt "prompt-name", "prompt-alias" + expect(described_class.aliases_for("prompt-name").map(&:name)).to eq(["prompt-alias"]) + expect(pry_eval("list-prompts")).to include("Aliases: prompt-alias") + expect(pry_eval("change-prompt prompt-alias", "_pry_.prompt")).to eq(prompt_value) + end + end end describe "Prompts" do |