pry 0.10.0.pre2-universal-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +702 -0
- data/LICENSE +25 -0
- data/README.md +406 -0
- data/bin/pry +16 -0
- data/lib/pry.rb +161 -0
- data/lib/pry/cli.rb +220 -0
- data/lib/pry/code.rb +346 -0
- data/lib/pry/code/code_file.rb +103 -0
- data/lib/pry/code/code_range.rb +71 -0
- data/lib/pry/code/loc.rb +92 -0
- data/lib/pry/code_object.rb +172 -0
- data/lib/pry/color_printer.rb +55 -0
- data/lib/pry/command.rb +692 -0
- data/lib/pry/command_set.rb +443 -0
- data/lib/pry/commands.rb +6 -0
- data/lib/pry/commands/amend_line.rb +99 -0
- data/lib/pry/commands/bang.rb +20 -0
- data/lib/pry/commands/bang_pry.rb +17 -0
- data/lib/pry/commands/cat.rb +62 -0
- data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
- data/lib/pry/commands/cat/exception_formatter.rb +77 -0
- data/lib/pry/commands/cat/file_formatter.rb +67 -0
- data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
- data/lib/pry/commands/cd.rb +41 -0
- data/lib/pry/commands/change_inspector.rb +27 -0
- data/lib/pry/commands/change_prompt.rb +26 -0
- data/lib/pry/commands/code_collector.rb +165 -0
- data/lib/pry/commands/disable_pry.rb +27 -0
- data/lib/pry/commands/disabled_commands.rb +2 -0
- data/lib/pry/commands/easter_eggs.rb +112 -0
- data/lib/pry/commands/edit.rb +195 -0
- data/lib/pry/commands/edit/exception_patcher.rb +25 -0
- data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
- data/lib/pry/commands/exit.rb +42 -0
- data/lib/pry/commands/exit_all.rb +29 -0
- data/lib/pry/commands/exit_program.rb +23 -0
- data/lib/pry/commands/find_method.rb +193 -0
- data/lib/pry/commands/fix_indent.rb +19 -0
- data/lib/pry/commands/gem_cd.rb +26 -0
- data/lib/pry/commands/gem_install.rb +32 -0
- data/lib/pry/commands/gem_list.rb +33 -0
- data/lib/pry/commands/gem_open.rb +29 -0
- data/lib/pry/commands/gist.rb +101 -0
- data/lib/pry/commands/help.rb +164 -0
- data/lib/pry/commands/hist.rb +180 -0
- data/lib/pry/commands/import_set.rb +22 -0
- data/lib/pry/commands/install_command.rb +53 -0
- data/lib/pry/commands/jump_to.rb +29 -0
- data/lib/pry/commands/list_inspectors.rb +35 -0
- data/lib/pry/commands/list_prompts.rb +35 -0
- data/lib/pry/commands/ls.rb +114 -0
- data/lib/pry/commands/ls/constants.rb +47 -0
- data/lib/pry/commands/ls/formatter.rb +49 -0
- data/lib/pry/commands/ls/globals.rb +48 -0
- data/lib/pry/commands/ls/grep.rb +21 -0
- data/lib/pry/commands/ls/instance_vars.rb +39 -0
- data/lib/pry/commands/ls/interrogatable.rb +18 -0
- data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
- data/lib/pry/commands/ls/local_names.rb +35 -0
- data/lib/pry/commands/ls/local_vars.rb +39 -0
- data/lib/pry/commands/ls/ls_entity.rb +70 -0
- data/lib/pry/commands/ls/methods.rb +57 -0
- data/lib/pry/commands/ls/methods_helper.rb +46 -0
- data/lib/pry/commands/ls/self_methods.rb +32 -0
- data/lib/pry/commands/nesting.rb +25 -0
- data/lib/pry/commands/play.rb +103 -0
- data/lib/pry/commands/pry_backtrace.rb +25 -0
- data/lib/pry/commands/pry_version.rb +17 -0
- data/lib/pry/commands/raise_up.rb +32 -0
- data/lib/pry/commands/reload_code.rb +62 -0
- data/lib/pry/commands/reset.rb +18 -0
- data/lib/pry/commands/ri.rb +60 -0
- data/lib/pry/commands/save_file.rb +61 -0
- data/lib/pry/commands/shell_command.rb +48 -0
- data/lib/pry/commands/shell_mode.rb +25 -0
- data/lib/pry/commands/show_doc.rb +83 -0
- data/lib/pry/commands/show_info.rb +195 -0
- data/lib/pry/commands/show_input.rb +17 -0
- data/lib/pry/commands/show_source.rb +50 -0
- data/lib/pry/commands/simple_prompt.rb +22 -0
- data/lib/pry/commands/stat.rb +40 -0
- data/lib/pry/commands/switch_to.rb +23 -0
- data/lib/pry/commands/toggle_color.rb +24 -0
- data/lib/pry/commands/watch_expression.rb +105 -0
- data/lib/pry/commands/watch_expression/expression.rb +38 -0
- data/lib/pry/commands/whereami.rb +190 -0
- data/lib/pry/commands/wtf.rb +57 -0
- data/lib/pry/config.rb +24 -0
- data/lib/pry/config/behavior.rb +139 -0
- data/lib/pry/config/convenience.rb +26 -0
- data/lib/pry/config/default.rb +165 -0
- data/lib/pry/core_extensions.rb +131 -0
- data/lib/pry/editor.rb +133 -0
- data/lib/pry/exceptions.rb +77 -0
- data/lib/pry/helpers.rb +5 -0
- data/lib/pry/helpers/base_helpers.rb +113 -0
- data/lib/pry/helpers/command_helpers.rb +156 -0
- data/lib/pry/helpers/documentation_helpers.rb +75 -0
- data/lib/pry/helpers/options_helpers.rb +27 -0
- data/lib/pry/helpers/table.rb +109 -0
- data/lib/pry/helpers/text.rb +107 -0
- data/lib/pry/history.rb +125 -0
- data/lib/pry/history_array.rb +121 -0
- data/lib/pry/hooks.rb +230 -0
- data/lib/pry/indent.rb +406 -0
- data/lib/pry/input_completer.rb +242 -0
- data/lib/pry/input_lock.rb +132 -0
- data/lib/pry/inspector.rb +27 -0
- data/lib/pry/last_exception.rb +61 -0
- data/lib/pry/method.rb +546 -0
- data/lib/pry/method/disowned.rb +53 -0
- data/lib/pry/method/patcher.rb +125 -0
- data/lib/pry/method/weird_method_locator.rb +186 -0
- data/lib/pry/module_candidate.rb +136 -0
- data/lib/pry/object_path.rb +82 -0
- data/lib/pry/output.rb +50 -0
- data/lib/pry/pager.rb +234 -0
- data/lib/pry/plugins.rb +103 -0
- data/lib/pry/prompt.rb +26 -0
- data/lib/pry/pry_class.rb +375 -0
- data/lib/pry/pry_instance.rb +654 -0
- data/lib/pry/rbx_path.rb +22 -0
- data/lib/pry/repl.rb +202 -0
- data/lib/pry/repl_file_loader.rb +74 -0
- data/lib/pry/rubygem.rb +82 -0
- data/lib/pry/terminal.rb +79 -0
- data/lib/pry/test/helper.rb +170 -0
- data/lib/pry/version.rb +3 -0
- data/lib/pry/wrapped_module.rb +373 -0
- metadata +248 -0
data/lib/pry/editor.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
class Pry
|
2
|
+
class Editor
|
3
|
+
include Pry::Helpers::BaseHelpers
|
4
|
+
include Pry::Helpers::CommandHelpers
|
5
|
+
|
6
|
+
attr_reader :_pry_
|
7
|
+
|
8
|
+
def initialize(_pry_)
|
9
|
+
@_pry_ = _pry_
|
10
|
+
end
|
11
|
+
|
12
|
+
def edit_tempfile_with_content(initial_content, line=1)
|
13
|
+
temp_file do |f|
|
14
|
+
f.puts(initial_content)
|
15
|
+
f.flush
|
16
|
+
f.close(false)
|
17
|
+
invoke_editor(f.path, line, true)
|
18
|
+
File.read(f.path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def invoke_editor(file, line, blocking=true)
|
23
|
+
raise CommandError, "Please set Pry.config.editor or export $VISUAL or $EDITOR" unless _pry_.config.editor
|
24
|
+
|
25
|
+
editor_invocation = build_editor_invocation_string(file, line, blocking)
|
26
|
+
return nil unless editor_invocation
|
27
|
+
|
28
|
+
if jruby?
|
29
|
+
open_editor_on_jruby(editor_invocation)
|
30
|
+
else
|
31
|
+
open_editor(editor_invocation)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Generate the string that's used to start the editor. This includes
|
38
|
+
# all the flags we want as well as the file and line number we
|
39
|
+
# want to open at.
|
40
|
+
def build_editor_invocation_string(file, line, blocking)
|
41
|
+
|
42
|
+
if _pry_.config.editor.respond_to?(:call)
|
43
|
+
args = [file, line, blocking][0...(_pry_.config.editor.arity)]
|
44
|
+
_pry_.config.editor.call(*args)
|
45
|
+
else
|
46
|
+
sanitized_file = if windows?
|
47
|
+
file.gsub(/\//, '\\')
|
48
|
+
else
|
49
|
+
Shellwords.escape(file)
|
50
|
+
end
|
51
|
+
|
52
|
+
"#{_pry_.config.editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Start the editor running, using the calculated invocation string
|
57
|
+
def open_editor(editor_invocation)
|
58
|
+
# Note we dont want to use Pry.config.system here as that
|
59
|
+
# may be invoked non-interactively (i.e via Open4), whereas we want to
|
60
|
+
# ensure the editor is always interactive
|
61
|
+
system(*Shellwords.split(editor_invocation)) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}"
|
62
|
+
end
|
63
|
+
|
64
|
+
# We need JRuby specific code here cos just shelling out using
|
65
|
+
# system() appears to be pretty broken :/
|
66
|
+
def open_editor_on_jruby(editor_invocation)
|
67
|
+
begin
|
68
|
+
require 'spoon'
|
69
|
+
pid = Spoon.spawnp(*Shellwords.split(editor_invocation))
|
70
|
+
Process.waitpid(pid)
|
71
|
+
rescue FFI::NotFoundError
|
72
|
+
system(editor_invocation)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Some editors that run outside the terminal allow you to control whether or
|
77
|
+
# not to block the process from which they were launched (in this case, Pry).
|
78
|
+
# For those editors, return the flag that produces the desired behavior.
|
79
|
+
def blocking_flag_for_editor(blocking)
|
80
|
+
case editor_name
|
81
|
+
when /^emacsclient/
|
82
|
+
'--no-wait' unless blocking
|
83
|
+
when /^[gm]vim/
|
84
|
+
'--nofork' if blocking
|
85
|
+
when /^jedit/
|
86
|
+
'-wait' if blocking
|
87
|
+
when /^mate/, /^subl/
|
88
|
+
'-w' if blocking
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Return the syntax for a given editor for starting the editor
|
93
|
+
# and moving to a particular line within that file
|
94
|
+
def start_line_syntax_for_editor(file_name, line_number)
|
95
|
+
# special case for 1st line
|
96
|
+
return file_name if line_number <= 1
|
97
|
+
|
98
|
+
case editor_name
|
99
|
+
when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/
|
100
|
+
"+#{line_number} #{file_name}"
|
101
|
+
when /^mate/, /^geany/
|
102
|
+
"-l #{line_number} #{file_name}"
|
103
|
+
when /^subl/
|
104
|
+
"#{file_name}:#{line_number}"
|
105
|
+
when /^uedit32/
|
106
|
+
"#{file_name}/#{line_number}"
|
107
|
+
when /^jedit/
|
108
|
+
"#{file_name} +line:#{line_number}"
|
109
|
+
else
|
110
|
+
if windows?
|
111
|
+
"#{file_name}"
|
112
|
+
else
|
113
|
+
"+#{line_number} #{file_name}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Get the name of the binary that Pry.config.editor points to.
|
119
|
+
#
|
120
|
+
# This is useful for deciding which flags we pass to the editor as
|
121
|
+
# we can just use the program's name and ignore any absolute paths.
|
122
|
+
#
|
123
|
+
# @example
|
124
|
+
# Pry.config.editor="/home/conrad/bin/textmate -w"
|
125
|
+
# editor_name
|
126
|
+
# # => textmate
|
127
|
+
#
|
128
|
+
def editor_name
|
129
|
+
File.basename(_pry_.config.editor).split(" ").first
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class Pry
|
2
|
+
|
3
|
+
# As a REPL, we often want to catch any unexpected exceptions that may have
|
4
|
+
# been raised; however we don't want to go overboard and prevent the user
|
5
|
+
# from exiting Pry when they want to.
|
6
|
+
module RescuableException
|
7
|
+
def self.===(exception)
|
8
|
+
case exception
|
9
|
+
# Catch when the user hits ^C (Interrupt < SignalException), and assume
|
10
|
+
# that they just wanted to stop the in-progress command (just like bash
|
11
|
+
# etc.)
|
12
|
+
when Interrupt
|
13
|
+
true
|
14
|
+
# Don't catch signals (particularly not SIGTERM) as these are unlikely
|
15
|
+
# to be intended for pry itself. We should also make sure that
|
16
|
+
# Kernel#exit works.
|
17
|
+
when *Pry.config.exception_whitelist
|
18
|
+
false
|
19
|
+
# All other exceptions will be caught.
|
20
|
+
else
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Catches SecurityErrors if $SAFE is set
|
27
|
+
module Pry::TooSafeException
|
28
|
+
def self.===(exception)
|
29
|
+
$SAFE > 0 && SecurityError === exception
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# An Exception Tag (cf. Exceptional Ruby) that instructs Pry to show the error
|
34
|
+
# in a more user-friendly manner. This should be used when the exception
|
35
|
+
# happens within Pry itself as a direct consequence of the user typing
|
36
|
+
# something wrong.
|
37
|
+
#
|
38
|
+
# This allows us to distinguish between the user typing:
|
39
|
+
#
|
40
|
+
# pry(main)> def )
|
41
|
+
# SyntaxError: unexpected )
|
42
|
+
#
|
43
|
+
# pry(main)> method_that_evals("def )")
|
44
|
+
# SyntaxError: (eval):1: syntax error, unexpected ')'
|
45
|
+
# from ./a.rb:2 in `eval'
|
46
|
+
module UserError; end
|
47
|
+
|
48
|
+
# When we try to get a binding for an object, we try to define a method on
|
49
|
+
# that Object's singleton class. This doesn't work for "frozen" Object's, and
|
50
|
+
# the exception is just a vanilla RuntimeError.
|
51
|
+
module FrozenObjectException
|
52
|
+
def self.===(exception)
|
53
|
+
["can't modify frozen class/module",
|
54
|
+
"can't modify frozen Class",
|
55
|
+
].include?(exception.message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Don't catch these exceptions
|
60
|
+
DEFAULT_EXCEPTION_WHITELIST = [SystemExit,
|
61
|
+
SignalException,
|
62
|
+
Pry::TooSafeException]
|
63
|
+
|
64
|
+
# CommandErrors are caught by the REPL loop and displayed to the user. They
|
65
|
+
# indicate an exceptional condition that's fatal to the current command.
|
66
|
+
class CommandError < StandardError; end
|
67
|
+
class MethodNotFound < CommandError; end
|
68
|
+
|
69
|
+
# indicates obsolete API
|
70
|
+
class ObsoleteError < StandardError; end
|
71
|
+
|
72
|
+
# This is to keep from breaking under Rails 3.2 for people who are doing that
|
73
|
+
# IRB = Pry thing.
|
74
|
+
module ExtendCommandBundle
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/lib/pry/helpers.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
class Pry
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
module BaseHelpers
|
5
|
+
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def silence_warnings
|
9
|
+
old_verbose = $VERBOSE
|
10
|
+
$VERBOSE = nil
|
11
|
+
begin
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
$VERBOSE = old_verbose
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Acts like send but ignores any methods defined below Object or Class in the
|
19
|
+
# inheritance hierarchy.
|
20
|
+
# This is required to introspect methods on objects like Net::HTTP::Get that
|
21
|
+
# have overridden the `method` method.
|
22
|
+
def safe_send(obj, method, *args, &block)
|
23
|
+
(Module === obj ? Module : Object).instance_method(method).bind(obj).call(*args, &block)
|
24
|
+
end
|
25
|
+
public :safe_send
|
26
|
+
|
27
|
+
def find_command(name, set = Pry::Commands)
|
28
|
+
command_match = set.find do |_, command|
|
29
|
+
(listing = command.options[:listing]) == name && listing != nil
|
30
|
+
end
|
31
|
+
command_match.last if command_match
|
32
|
+
end
|
33
|
+
|
34
|
+
def not_a_real_file?(file)
|
35
|
+
file =~ /(\(.*\))|<.*>/ || file =~ /__unknown__/ || file == "" || file == "-e"
|
36
|
+
end
|
37
|
+
|
38
|
+
def command_dependencies_met?(options)
|
39
|
+
return true if !options[:requires_gem]
|
40
|
+
Array(options[:requires_gem]).all? do |g|
|
41
|
+
Rubygem.installed?(g)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def use_ansi_codes?
|
46
|
+
windows_ansi? || ENV['TERM'] && ENV['TERM'] != "dumb"
|
47
|
+
end
|
48
|
+
|
49
|
+
def colorize_code(code)
|
50
|
+
CodeRay.scan(code, :ruby).term
|
51
|
+
end
|
52
|
+
|
53
|
+
def highlight(string, regexp, highlight_color=:bright_yellow)
|
54
|
+
string.gsub(regexp) { |match| "<#{highlight_color}>#{match}</#{highlight_color}>" }
|
55
|
+
end
|
56
|
+
|
57
|
+
# formatting
|
58
|
+
def heading(text)
|
59
|
+
text = "#{text}\n--"
|
60
|
+
"\e[1m#{text}\e[0m"
|
61
|
+
end
|
62
|
+
|
63
|
+
# have fun on the Windows platform.
|
64
|
+
def windows?
|
65
|
+
RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
|
66
|
+
end
|
67
|
+
|
68
|
+
# are we able to use ansi on windows?
|
69
|
+
def windows_ansi?
|
70
|
+
defined?(Win32::Console) || ENV['ANSICON'] || (windows? && mri_2?)
|
71
|
+
end
|
72
|
+
|
73
|
+
def jruby?
|
74
|
+
RbConfig::CONFIG['ruby_install_name'] == 'jruby'
|
75
|
+
end
|
76
|
+
|
77
|
+
def jruby_19?
|
78
|
+
jruby? && RbConfig::CONFIG['ruby_version'] == '1.9'
|
79
|
+
end
|
80
|
+
|
81
|
+
def rbx?
|
82
|
+
RbConfig::CONFIG['ruby_install_name'] == 'rbx'
|
83
|
+
end
|
84
|
+
|
85
|
+
def mri?
|
86
|
+
RbConfig::CONFIG['ruby_install_name'] == 'ruby'
|
87
|
+
end
|
88
|
+
|
89
|
+
def mri_19?
|
90
|
+
mri? && RUBY_VERSION =~ /^1\.9/
|
91
|
+
end
|
92
|
+
|
93
|
+
def mri_2?
|
94
|
+
mri? && RUBY_VERSION =~ /^2/
|
95
|
+
end
|
96
|
+
|
97
|
+
def mri_20?
|
98
|
+
mri? && RUBY_VERSION =~ /^2\.0/
|
99
|
+
end
|
100
|
+
|
101
|
+
def mri_21?
|
102
|
+
mri? && RUBY_VERSION =~ /^2\.1/
|
103
|
+
end
|
104
|
+
|
105
|
+
# Send the given text through the best available pager (if Pry.config.pager is
|
106
|
+
# enabled). Infers where to send the output if used as a mixin.
|
107
|
+
# DEPRECATED.
|
108
|
+
def stagger_output(text, out = nil)
|
109
|
+
Pry.new.pager.page text
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
class Pry
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
module CommandHelpers
|
5
|
+
include OptionsHelpers
|
6
|
+
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# Open a temp file and yield it to the block, closing it after
|
10
|
+
# @return [String] The path of the temp file
|
11
|
+
def temp_file(ext='.rb')
|
12
|
+
file = Tempfile.new(['pry', ext])
|
13
|
+
yield file
|
14
|
+
ensure
|
15
|
+
file.close(true) if file
|
16
|
+
end
|
17
|
+
|
18
|
+
def internal_binding?(target)
|
19
|
+
m = target.eval("::Kernel.__method__").to_s
|
20
|
+
# class_eval is here because of http://jira.codehaus.org/browse/JRUBY-6753
|
21
|
+
["__binding__", "__pry__", "class_eval"].include?(m)
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_method_or_raise(name, target, opts={}, omit_help=false)
|
25
|
+
meth = Pry::Method.from_str(name, target, opts)
|
26
|
+
|
27
|
+
if name && !meth
|
28
|
+
command_error("The method '#{name}' could not be found.", omit_help, MethodNotFound)
|
29
|
+
end
|
30
|
+
|
31
|
+
(opts[:super] || 0).times do
|
32
|
+
if meth.super
|
33
|
+
meth = meth.super
|
34
|
+
else
|
35
|
+
command_error("'#{meth.name_with_owner}' has no super method.", omit_help, MethodNotFound)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if !meth || (!name && internal_binding?(target))
|
40
|
+
command_error("No method name given, and context is not a method.", omit_help, MethodNotFound)
|
41
|
+
end
|
42
|
+
|
43
|
+
set_file_and_dir_locals(meth.source_file)
|
44
|
+
meth
|
45
|
+
end
|
46
|
+
|
47
|
+
def command_error(message, omit_help, klass=CommandError)
|
48
|
+
message += " Type `#{command_name} --help` for help." unless omit_help
|
49
|
+
raise klass, message
|
50
|
+
end
|
51
|
+
|
52
|
+
# Remove any common leading whitespace from every line in `text`.
|
53
|
+
#
|
54
|
+
# This can be used to make a HEREDOC line up with the left margin, without
|
55
|
+
# sacrificing the indentation level of the source code.
|
56
|
+
#
|
57
|
+
# e.g.
|
58
|
+
# opt.banner unindent <<-USAGE
|
59
|
+
# Lorem ipsum dolor sit amet, consectetur adipisicing elit,
|
60
|
+
# sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
61
|
+
# "Ut enim ad minim veniam."
|
62
|
+
# USAGE
|
63
|
+
#
|
64
|
+
# Heavily based on textwrap.dedent from Python, which is:
|
65
|
+
# Copyright (C) 1999-2001 Gregory P. Ward.
|
66
|
+
# Copyright (C) 2002, 2003 Python Software Foundation.
|
67
|
+
# Written by Greg Ward <gward@python.net>
|
68
|
+
#
|
69
|
+
# Licensed under <http://docs.python.org/license.html>
|
70
|
+
# From <http://hg.python.org/cpython/file/6b9f0a6efaeb/Lib/textwrap.py>
|
71
|
+
#
|
72
|
+
# @param [String] text The text from which to remove indentation
|
73
|
+
# @return [String] The text with indentation stripped.
|
74
|
+
def unindent(text, left_padding = 0)
|
75
|
+
# Empty blank lines
|
76
|
+
text = text.sub(/^[ \t]+$/, '')
|
77
|
+
|
78
|
+
# Find the longest common whitespace to all indented lines
|
79
|
+
# Ignore lines containing just -- or ++ as these seem to be used by
|
80
|
+
# comment authors as delimeters.
|
81
|
+
margin = text.scan(/^[ \t]*(?!--\n|\+\+\n)(?=[^ \t\n])/).inject do |current_margin, next_indent|
|
82
|
+
if next_indent.start_with?(current_margin)
|
83
|
+
current_margin
|
84
|
+
elsif current_margin.start_with?(next_indent)
|
85
|
+
next_indent
|
86
|
+
else
|
87
|
+
""
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
text.gsub(/^#{margin}/, ' ' * left_padding)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Restrict a string to the given range of lines (1-indexed)
|
95
|
+
# @param [String] content The string.
|
96
|
+
# @param [Range, Fixnum] lines The line(s) to restrict it to.
|
97
|
+
# @return [String] The resulting string.
|
98
|
+
def restrict_to_lines(content, lines)
|
99
|
+
line_range = one_index_range_or_number(lines)
|
100
|
+
Array(content.lines.to_a[line_range]).join
|
101
|
+
end
|
102
|
+
|
103
|
+
def one_index_number(line_number)
|
104
|
+
if line_number > 0
|
105
|
+
line_number - 1
|
106
|
+
else
|
107
|
+
line_number
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# convert a 1-index range to a 0-indexed one
|
112
|
+
def one_index_range(range)
|
113
|
+
Range.new(one_index_number(range.begin), one_index_number(range.end))
|
114
|
+
end
|
115
|
+
|
116
|
+
def one_index_range_or_number(range_or_number)
|
117
|
+
case range_or_number
|
118
|
+
when Range
|
119
|
+
one_index_range(range_or_number)
|
120
|
+
else
|
121
|
+
one_index_number(range_or_number)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def absolute_index_number(line_number, array_length)
|
126
|
+
if line_number >= 0
|
127
|
+
line_number
|
128
|
+
else
|
129
|
+
[array_length + line_number, 0].max
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def absolute_index_range(range_or_number, array_length)
|
134
|
+
case range_or_number
|
135
|
+
when Range
|
136
|
+
a = absolute_index_number(range_or_number.begin, array_length)
|
137
|
+
b = absolute_index_number(range_or_number.end, array_length)
|
138
|
+
else
|
139
|
+
a = b = absolute_index_number(range_or_number, array_length)
|
140
|
+
end
|
141
|
+
|
142
|
+
Range.new(a, b)
|
143
|
+
end
|
144
|
+
|
145
|
+
def set_file_and_dir_locals(file_name, _pry_=_pry_(), target=target())
|
146
|
+
return if !target or !file_name
|
147
|
+
_pry_.last_file = File.expand_path(file_name)
|
148
|
+
_pry_.inject_local("_file_", _pry_.last_file, target)
|
149
|
+
|
150
|
+
_pry_.last_dir = File.dirname(_pry_.last_file)
|
151
|
+
_pry_.inject_local("_dir_", _pry_.last_dir, target)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|