summaryrefslogtreecommitdiff
path: root/lib/pry
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pry')
-rw-r--r--lib/pry/command.rb26
-rw-r--r--lib/pry/command_set.rb25
-rw-r--r--lib/pry/commands/pipe_cuties.rb101
-rw-r--r--lib/pry/commands/play.rb4
-rw-r--r--lib/pry/helpers/module_introspection_helpers.rb6
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