diff options
Diffstat (limited to 'lib/pry')
| -rw-r--r-- | lib/pry/command.rb | 26 | ||||
| -rw-r--r-- | lib/pry/command_set.rb | 25 | ||||
| -rw-r--r-- | lib/pry/commands/pipe_cuties.rb | 101 | ||||
| -rw-r--r-- | lib/pry/commands/play.rb | 4 | ||||
| -rw-r--r-- | lib/pry/helpers/module_introspection_helpers.rb | 6 |
5 files changed, 158 insertions, 4 deletions
diff --git a/lib/pry/command.rb b/lib/pry/command.rb index b10b6147..31d4e1bc 100644 --- a/lib/pry/command.rb +++ b/lib/pry/command.rb @@ -6,6 +6,20 @@ class Pry # {Pry::CommandSet#command} which creates a BlockCommand or {Pry::CommandSet#create_command} # which creates a ClassCommand. Please don't use this class directly. class Command + class Pipe + attr_accessor :in + attr_accessor :out + attr_accessor :use_pipe_for_output + + def read + @in + end + + def write(obj) + @out = obj + end + end + extend Helpers::DocumentationHelpers # represents a void return value for a command @@ -185,6 +199,9 @@ class Pry attr_accessor :command_set attr_accessor :_pry_ + # @return [Pry::Command::Pipe] The pipe object. + attr_accessor :pipe + # The block we pass *into* a command so long as `:takes_block` is # not equal to `false` # @example @@ -193,6 +210,14 @@ class Pry # end attr_accessor :command_block + def in_pipe? + !!pipe.in + end + + def out_pipe? + !!pipe.use_pipe_for_output + end + # Run a command from another command. # @param [String] command_string The string that invokes the command # @param [Array] args Further arguments to pass to the command @@ -225,6 +250,7 @@ class Pry # Instantiate a command, in preparation for calling it. # @param [Hash] context The runtime context to use with this command. def initialize(context={}) + self.pipe = Pipe.new self.context = context self.target = context[:target] self.output = context[:output] diff --git a/lib/pry/command_set.rb b/lib/pry/command_set.rb index 49d9fb63..b51f8864 100644 --- a/lib/pry/command_set.rb +++ b/lib/pry/command_set.rb @@ -8,6 +8,9 @@ class Pry # This class is used to create sets of commands. Commands can be imported from # different sets, aliased, removed, etc. class CommandSet + + PIPE = /(?<=[^'"])(?<=.)*?\|(?=.*)(?<=[^'"])/ + include Enumerable include Pry::Helpers::BaseHelpers @@ -340,9 +343,25 @@ class Pry # @param [Hash] context The context to execute the commands with # @return [CommandSet::Result] def process_line(val, context={}) - if command = find_command(val) - context = context.merge(:command_set => self) - retval = command.new(context).process_line(val) + context = context.merge(:command_set => self) + + pipe_chain = val.split(PIPE).map(&:strip).map { |v| [find_command(v), v] } + + if pipe_chain.any? && pipe_chain[0].first + retval = nil + + pipe_chain.each_with_index.inject(nil) do |previous_pipe_out, (command_info, idx)| + command_class, invocation = command_info + command = command_class.new(context) + + command.pipe.in = previous_pipe_out + command.pipe.use_pipe_for_output = true if idx < (pipe_chain.size - 1) + + retval = command.process_line(invocation) + + command.pipe.out + end + Result.new(true, retval) else Result.new(false) diff --git a/lib/pry/commands/pipe_cuties.rb b/lib/pry/commands/pipe_cuties.rb new file mode 100644 index 00000000..deefc5e6 --- /dev/null +++ b/lib/pry/commands/pipe_cuties.rb @@ -0,0 +1,101 @@ +Pry::Commands.block_command "grep", "grep stuff" do + if in_pipe? + obj = pipe.read + + if obj.respond_to?(:grep) + grepped = obj.grep Regexp.new(arg_string) + elsif obj.is_a?(String) + grepped = obj.lines.to_a.grep Regexp.new(arg_string) + else + raise Pry::CommandError, "Can't grep passed object!" + end + + if out_pipe? + pipe.write grepped.join + else + output.puts grepped.join + end + + else + raise Pry::CommandError, "grep can only be used with piped input!" + end +end + +Pry::Commands.block_command "sort", "sort stuff" do + if in_pipe? + obj = pipe.read + + if obj.respond_to?(:sort_by) + sorted = obj.sort_by { |v| text.strip_color(v.strip) }.join + elsif obj.is_a?(String) + sorted = obj.lines.to_a.sort_by { |v| text.strip_color(v.strip) }.join + else + raise Pry::CommandError, "Can't sort passed object!" + end + + if out_pipe? + pipe.write sorted + else + output.puts sorted + end + + else + raise Pry::CommandError, "sort can only be used with piped input!" + end +end + +Pry::Commands.block_command "less", "page stuff" do + if in_pipe? + obj = pipe.read + + if out_pipe? + pipe.write obj + else + stagger_output obj.to_s + end + + else + raise Pry::CommandError, "can only be used with piped input!" + end +end + +Pry::Commands.block_command "wc", "page stuff" do + if in_pipe? + obj = pipe.read + + if obj.is_a?(String) + count = obj.lines.count + elsif obj.respond_to?(:count) + count = obj.count + else + raise Pry::CommandError, "Can't count the object!" + end + + if out_pipe? + pipe.write count.to_s + else + output.puts "Number of lines: #{count.to_s}" + end + + else + raise Pry::CommandError, "can only be used with piped input!" + end +end + + +Pry::Commands.block_command "less2", "page stuff" do + if in_pipe? + obj = pipe.read + + binding.pry + + if out_pipe? + pipe.write obj + else + stagger_output obj.to_s + end + + else + raise Pry::CommandError, "sort can only be used with piped input!" + end +end diff --git a/lib/pry/commands/play.rb b/lib/pry/commands/play.rb index 9dc18731..abaac722 100644 --- a/lib/pry/commands/play.rb +++ b/lib/pry/commands/play.rb @@ -71,6 +71,10 @@ class Pry def perform_play process_non_opt + if in_pipe? + self.content = pipe.read + end + if opts.present?(:lines) self.content = restrict_to_lines(self.content, opts[:l]) end diff --git a/lib/pry/helpers/module_introspection_helpers.rb b/lib/pry/helpers/module_introspection_helpers.rb index 77e31df9..e44d2369 100644 --- a/lib/pry/helpers/module_introspection_helpers.rb +++ b/lib/pry/helpers/module_introspection_helpers.rb @@ -69,7 +69,11 @@ class Pry command_error("#{saught_in_vain} `#{input}'", true) end - render_output(code_or_doc, opts) + if !out_pipe? + render_output(code_or_doc, opts) + else + pipe.write(code_or_doc) + end end def process_blank |
