pry 0.10.0.pre4-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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 +341 -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
|