mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
edaa1383f2
This change brings some order to how we require files. Previously, we required app files from everywhere, including pry.rb. Now we require app files only from pry.rb. External and stdlib dependencies are required at places where they're used, not globally.
112 lines
3.3 KiB
Ruby
112 lines
3.3 KiB
Ruby
require 'method_source'
|
|
|
|
class Pry
|
|
class CodeFile
|
|
DEFAULT_EXT = '.rb'.freeze
|
|
|
|
# List of all supported languages.
|
|
# @return [Hash]
|
|
EXTENSIONS = {
|
|
%w[.py] => :python,
|
|
%w[.js] => :javascript,
|
|
%w[.css] => :css,
|
|
%w[.xml] => :xml,
|
|
%w[.php] => :php,
|
|
%w[.html] => :html,
|
|
%w[.diff] => :diff,
|
|
%w[.java] => :java,
|
|
%w[.json] => :json,
|
|
%w[.c .h] => :c,
|
|
%w[.rhtml] => :rhtml,
|
|
%w[.yaml .yml] => :yaml,
|
|
%w[.cpp .hpp .cc .h .cxx] => :cpp,
|
|
%w[.rb .ru .irbrc .gemspec .pryrc .rake] => :ruby
|
|
}.freeze
|
|
|
|
FILES = {
|
|
%w[Gemfile Rakefile Guardfile Capfile] => :ruby
|
|
}.freeze
|
|
|
|
# Store the current working directory. This allows show-source etc. to work if
|
|
# your process has changed directory since boot. [Issue #675]
|
|
INITIAL_PWD = Dir.pwd
|
|
|
|
# @return [Symbol] The type of code stored in this wrapper.
|
|
attr_reader :code_type
|
|
|
|
# @param [String] filename The name of a file with code to be detected
|
|
# @param [Symbol] code_type The type of code the `filename` contains
|
|
def initialize(filename, code_type = type_from_filename(filename))
|
|
@filename = filename
|
|
@code_type = code_type
|
|
end
|
|
|
|
# @return [String] The code contained in the current `@filename`.
|
|
def code
|
|
if @filename == Pry.eval_path
|
|
Pry.line_buffer.drop(1)
|
|
elsif Pry::Method::Patcher.code_for(@filename)
|
|
Pry::Method::Patcher.code_for(@filename)
|
|
else
|
|
path = abs_path
|
|
@code_type = type_from_filename(path)
|
|
File.read(path)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
# @raise [MethodSource::SourceNotFoundError] if the `filename` is not
|
|
# readable for some reason.
|
|
# @return [String] absolute path for the given `filename`.
|
|
def abs_path
|
|
code_path.detect { |path| readable?(path) } ||
|
|
raise(MethodSource::SourceNotFoundError,
|
|
"Cannot open #{@filename.inspect} for reading.")
|
|
end
|
|
|
|
# @param [String] path
|
|
# @return [Boolean] if the path, with or without the default ext,
|
|
# is a readable file then `true`, otherwise `false`.
|
|
def readable?(path)
|
|
File.readable?(path) && !File.directory?(path) ||
|
|
File.readable?(path << DEFAULT_EXT)
|
|
end
|
|
|
|
# @return [Array] All the paths that contain code that Pry can use for its
|
|
# API's. Skips directories.
|
|
def code_path
|
|
[from_pwd, from_pry_init_pwd, *from_load_path]
|
|
end
|
|
|
|
# @param [String] filename
|
|
# @param [Symbol] default (:unknown) the file type to assume if none could be
|
|
# detected.
|
|
# @return [Symbol, nil] The CodeRay type of a file from its extension, or
|
|
# `nil` if `:unknown`.
|
|
def type_from_filename(filename, default = :unknown)
|
|
_, @code_type = EXTENSIONS.find do |k, _|
|
|
k.any? { |ext| ext == File.extname(filename) }
|
|
end || FILES.find do |k, _|
|
|
k.any? { |file_name| file_name == File.basename(filename) }
|
|
end
|
|
|
|
code_type || default
|
|
end
|
|
|
|
# @return [String]
|
|
def from_pwd
|
|
File.expand_path(@filename, Dir.pwd)
|
|
end
|
|
|
|
# @return [String]
|
|
def from_pry_init_pwd
|
|
File.expand_path(@filename, INITIAL_PWD)
|
|
end
|
|
|
|
# @return [String]
|
|
def from_load_path
|
|
$LOAD_PATH.map { |path| File.expand_path(@filename, path) }
|
|
end
|
|
end
|
|
end
|