1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

implement cat --in (fixes #330)

This commit is contained in:
Ryan Fitzgerald 2011-11-06 00:59:49 -07:00
parent 1d68be6f64
commit fd488dfd01
5 changed files with 114 additions and 15 deletions

View file

@ -31,7 +31,7 @@ class Pry
alias_command "file-mode", "shell-mode" alias_command "file-mode", "shell-mode"
command "cat", "Show output of file FILE. Type `cat --help` for more information." do |*args| command "cat", "Show code from a file or Pry's input buffer. Type `cat --help` for more information." do |*args|
start_line = 0 start_line = 0
end_line = -1 end_line = -1
file_name = nil file_name = nil
@ -68,6 +68,8 @@ class Pry
end end
end end
opt.on :i, :in, "Show entries from Pry's input expression history. Takes an index or range.", :optional => true, :as => Range, :default => -5..-1
opt.on :l, "line-numbers", "Show line numbers." opt.on :l, "line-numbers", "Show line numbers."
opt.on :t, :type, "The specific file type for syntax higlighting (e.g ruby, python)", true, :as => Symbol opt.on :t, :type, "The specific file type for syntax higlighting (e.g ruby, python)", true, :as => Symbol
opt.on :f, :flood, "Do not use a pager to view text longer than one screen." opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
@ -86,19 +88,49 @@ class Pry
file_name = args.shift file_name = args.shift
end end
if !file_name if opts.in?
raise CommandError, "Must provide a file name." normalized_range = absolute_index_range(opts[:i], _pry_.input_array.length)
end input_items = _pry_.input_array[normalized_range] || []
zipped_items = normalized_range.zip(input_items).reject { |_, s| s.nil? || s == "" }
unless zipped_items.length > 0
raise CommandError, "No expressions found."
end
if opts[:i].is_a?(Range)
contents = ""
zipped_items.each do |i, s|
contents << "#{text.bold(i.to_s)}:\n"
code = syntax_highlight_by_file_type_or_specified(s, nil, :ruby)
if opts.l?
contents << text.indent(text.with_line_numbers(code, 1), 2)
else
contents << text.indent(code, 2)
end
end
else
contents = syntax_highlight_by_file_type_or_specified(zipped_items.first.last, nil, :ruby)
end
else
unless file_name
raise CommandError, "Must provide a file name."
end
begin
contents, _, _ = read_between_the_lines(file_name, start_line, end_line)
rescue Errno::ENOENT
raise CommandError, "Could not find file: #{file_name}"
end
begin
contents, _, _ = read_between_the_lines(file_name, start_line, end_line)
contents = syntax_highlight_by_file_type_or_specified(contents, file_name, opts[:type]) contents = syntax_highlight_by_file_type_or_specified(contents, file_name, opts[:type])
rescue Errno::ENOENT
raise CommandError, "Could not find file: #{file_name}"
end
if opts.l? if opts.l?
contents = text.with_line_numbers contents, start_line + 1 contents = text.with_line_numbers contents, start_line + 1
end
end end
# add the arrow pointing to line that caused the exception # add the arrow pointing to line that caused the exception

View file

@ -86,13 +86,16 @@ class Pry
end end
def syntax_highlight_by_file_type_or_specified(contents, file_name, file_type) def syntax_highlight_by_file_type_or_specified(contents, file_name, file_type)
_, language_detected = file_map.find do |k, v| if file_type
Array(k).any? do |matcher| language_detected = file_type
matcher == File.extname(file_name) || matcher == File.basename(file_name) else
_, language_detected = file_map.find do |k, v|
Array(k).any? do |matcher|
matcher == File.extname(file_name) || matcher == File.basename(file_name)
end
end end
end end
language_detected = file_type if file_type
if Pry.color if Pry.color
CodeRay.scan(contents, language_detected).term CodeRay.scan(contents, language_detected).term
else else
@ -247,6 +250,25 @@ class Pry
text.gsub(/^#{margin}/, '') text.gsub(/^#{margin}/, '')
end end
def absolute_index_number(line_number, array_length)
if line_number >= 0
line_number
else
[array_length + line_number, 0].max
end
end
def absolute_index_range(range_or_number, array_length)
case range_or_number
when Range
a = absolute_index_number(range_or_number.begin, array_length)
b = absolute_index_number(range_or_number.end, array_length)
else
a = b = absolute_index_number(range_or_number, array_length)
end
Range.new(a, b)
end
end end
end end

View file

@ -81,6 +81,14 @@ class Pry
"#{self.send(color, adjusted_index)}: #{line}" "#{self.send(color, adjusted_index)}: #{line}"
end.join end.join
end end
# Returns _text_ indented by _chars_ spaces.
#
# @param [String] text
# @param [Fixnum] chars
def indent(text, chars)
text.lines.map { |l| "#{' ' * chars}#{l}" }.join
end
end end
end end

View file

@ -72,6 +72,8 @@ class Pry
def size def size
@count @count
end end
alias count size
alias length size
def empty? def empty?
size == 0 size == 0

View file

@ -9,6 +9,41 @@ describe "Pry::DefaultCommands::Shell" do
end end
end end
describe "with --in" do
it 'should display the last few expressions with indices' do
output = mock_pry("10", "20", "cat --in")
output.should =~ /^1:/
output.should =~ /^ 10/
output.should =~ /^2:/
output.should =~ /^ 20/
end
end
describe "with --in 1" do
it 'should display the first expression with no index' do
output = mock_pry("10", "20", "cat --in 1")
output.should.not =~ /^\d+:/
output.should =~ /^10/
end
end
describe "with --in -1" do
it 'should display the last expression with no index' do
output = mock_pry("10", "20", "cat --in -1")
output.should.not =~ /^\d+:/
output.should =~ /^20/
end
end
describe "with --in 1..2" do
it 'should display the given range with indices, omitting nils' do
output = mock_pry("10", "20", "cat --ex", ":hello", "cat --in 1..4")
output.should =~ /^1:/
output.should.not =~ /^3:/
output.should =~ /^ :hello/
end
end
# this doesnt work so well on rbx due to differences in backtrace # this doesnt work so well on rbx due to differences in backtrace
# so we currently skip rbx until we figure out a workaround # so we currently skip rbx until we figure out a workaround
describe "with --ex" do describe "with --ex" do