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:
parent
1d68be6f64
commit
fd488dfd01
5 changed files with 114 additions and 15 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue