pry 0.10.3 → 0.12.2

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.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +251 -16
  3. data/LICENSE +1 -1
  4. data/README.md +35 -51
  5. data/bin/pry +3 -11
  6. data/lib/pry/basic_object.rb +6 -0
  7. data/lib/pry/cli.rb +50 -52
  8. data/lib/pry/code/code_file.rb +13 -6
  9. data/lib/pry/code/code_range.rb +3 -3
  10. data/lib/pry/code/loc.rb +14 -8
  11. data/lib/pry/code.rb +12 -5
  12. data/lib/pry/code_object.rb +27 -4
  13. data/lib/pry/color_printer.rb +20 -10
  14. data/lib/pry/command.rb +76 -45
  15. data/lib/pry/command_set.rb +17 -45
  16. data/lib/pry/commands/amend_line.rb +3 -4
  17. data/lib/pry/commands/bang.rb +1 -1
  18. data/lib/pry/commands/cat/exception_formatter.rb +10 -8
  19. data/lib/pry/commands/cat/file_formatter.rb +7 -3
  20. data/lib/pry/commands/cat/input_expression_formatter.rb +1 -1
  21. data/lib/pry/commands/cat.rb +7 -6
  22. data/lib/pry/commands/change_prompt.rb +29 -9
  23. data/lib/pry/commands/clear_screen.rb +14 -0
  24. data/lib/pry/commands/code_collector.rb +25 -23
  25. data/lib/pry/commands/easter_eggs.rb +12 -12
  26. data/lib/pry/commands/edit/file_and_line_locator.rb +1 -1
  27. data/lib/pry/commands/edit.rb +15 -10
  28. data/lib/pry/commands/exit.rb +2 -1
  29. data/lib/pry/commands/find_method.rb +12 -14
  30. data/lib/pry/commands/gem_cd.rb +1 -1
  31. data/lib/pry/commands/gem_install.rb +2 -2
  32. data/lib/pry/commands/gem_list.rb +2 -2
  33. data/lib/pry/commands/gem_open.rb +2 -2
  34. data/lib/pry/commands/gem_readme.rb +25 -0
  35. data/lib/pry/commands/gem_search.rb +40 -0
  36. data/lib/pry/commands/gem_stats.rb +83 -0
  37. data/lib/pry/commands/gist.rb +7 -6
  38. data/lib/pry/commands/help.rb +3 -3
  39. data/lib/pry/commands/hist.rb +11 -10
  40. data/lib/pry/commands/import_set.rb +2 -1
  41. data/lib/pry/commands/install_command.rb +7 -6
  42. data/lib/pry/commands/jump_to.rb +7 -7
  43. data/lib/pry/commands/list_inspectors.rb +2 -2
  44. data/lib/pry/commands/ls/constants.rb +14 -3
  45. data/lib/pry/commands/ls/formatter.rb +4 -2
  46. data/lib/pry/commands/ls/globals.rb +0 -2
  47. data/lib/pry/commands/ls/grep.rb +0 -2
  48. data/lib/pry/commands/ls/instance_vars.rb +0 -1
  49. data/lib/pry/commands/ls/jruby_hacks.rb +2 -2
  50. data/lib/pry/commands/ls/local_names.rb +0 -2
  51. data/lib/pry/commands/ls/local_vars.rb +0 -2
  52. data/lib/pry/commands/ls/ls_entity.rb +0 -1
  53. data/lib/pry/commands/ls/methods.rb +0 -3
  54. data/lib/pry/commands/ls/methods_helper.rb +1 -1
  55. data/lib/pry/commands/ls/self_methods.rb +2 -1
  56. data/lib/pry/commands/ls.rb +30 -31
  57. data/lib/pry/commands/play.rb +3 -4
  58. data/lib/pry/commands/pry_backtrace.rb +1 -1
  59. data/lib/pry/commands/raise_up.rb +2 -1
  60. data/lib/pry/commands/reload_code.rb +2 -2
  61. data/lib/pry/commands/ri.rb +9 -4
  62. data/lib/pry/commands/shell_command.rb +36 -9
  63. data/lib/pry/commands/shell_mode.rb +6 -6
  64. data/lib/pry/commands/show_doc.rb +5 -7
  65. data/lib/pry/commands/show_info.rb +41 -20
  66. data/lib/pry/commands/show_source.rb +5 -2
  67. data/lib/pry/commands/stat.rb +1 -1
  68. data/lib/pry/commands/watch_expression/expression.rb +1 -1
  69. data/lib/pry/commands/watch_expression.rb +9 -7
  70. data/lib/pry/commands/whereami.rb +16 -9
  71. data/lib/pry/commands/wtf.rb +15 -2
  72. data/lib/pry/config/behavior.rb +230 -114
  73. data/lib/pry/config/convenience.rb +24 -21
  74. data/lib/pry/config/default.rb +151 -153
  75. data/lib/pry/config/memoization.rb +48 -0
  76. data/lib/pry/config.rb +30 -19
  77. data/lib/pry/core_extensions.rb +15 -4
  78. data/lib/pry/editor.rb +5 -12
  79. data/lib/pry/exceptions.rb +1 -3
  80. data/lib/pry/forwardable.rb +23 -0
  81. data/lib/pry/helpers/base_helpers.rb +197 -110
  82. data/lib/pry/helpers/command_helpers.rb +5 -4
  83. data/lib/pry/helpers/documentation_helpers.rb +3 -2
  84. data/lib/pry/helpers/options_helpers.rb +6 -6
  85. data/lib/pry/helpers/platform.rb +58 -0
  86. data/lib/pry/helpers/table.rb +20 -15
  87. data/lib/pry/helpers/text.rb +82 -74
  88. data/lib/pry/helpers.rb +1 -0
  89. data/lib/pry/history.rb +44 -10
  90. data/lib/pry/hooks.rb +50 -109
  91. data/lib/pry/indent.rb +21 -19
  92. data/lib/pry/input_completer.rb +146 -123
  93. data/lib/pry/input_lock.rb +0 -2
  94. data/lib/pry/last_exception.rb +2 -2
  95. data/lib/pry/method/disowned.rb +3 -1
  96. data/lib/pry/method/patcher.rb +2 -5
  97. data/lib/pry/method/weird_method_locator.rb +21 -11
  98. data/lib/pry/method.rb +44 -38
  99. data/lib/pry/object_path.rb +5 -4
  100. data/lib/pry/output.rb +37 -37
  101. data/lib/pry/pager.rb +195 -181
  102. data/lib/pry/platform.rb +91 -0
  103. data/lib/pry/plugins.rb +27 -8
  104. data/lib/pry/prompt.rb +144 -25
  105. data/lib/pry/pry_class.rb +83 -33
  106. data/lib/pry/pry_instance.rb +94 -59
  107. data/lib/pry/repl.rb +70 -11
  108. data/lib/pry/repl_file_loader.rb +2 -3
  109. data/lib/pry/ring.rb +84 -0
  110. data/lib/pry/rubygem.rb +9 -7
  111. data/lib/pry/slop/LICENSE +20 -0
  112. data/lib/pry/slop/commands.rb +195 -0
  113. data/lib/pry/slop/option.rb +206 -0
  114. data/lib/pry/slop.rb +661 -0
  115. data/lib/pry/terminal.rb +18 -6
  116. data/lib/pry/testable/evalable.rb +15 -0
  117. data/lib/pry/testable/mockable.rb +14 -0
  118. data/lib/pry/testable/pry_tester.rb +73 -0
  119. data/lib/pry/testable/utility.rb +26 -0
  120. data/lib/pry/testable/variables.rb +46 -0
  121. data/lib/pry/testable.rb +70 -0
  122. data/lib/pry/version.rb +1 -1
  123. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +9 -14
  124. data/lib/pry/wrapped_module.rb +22 -21
  125. data/lib/pry.rb +21 -50
  126. metadata +35 -46
  127. data/lib/pry/commands/list_prompts.rb +0 -35
  128. data/lib/pry/commands/simple_prompt.rb +0 -22
  129. data/lib/pry/history_array.rb +0 -121
  130. data/lib/pry/rbx_path.rb +0 -22
  131. data/lib/pry/test/helper.rb +0 -170
@@ -1,9 +1,8 @@
1
1
  class Pry
2
2
  module Helpers
3
-
4
3
  # The methods defined on {Text} are available to custom commands via {Pry::Command#text}.
5
4
  module Text
6
-
5
+ extend self
7
6
  COLORS =
8
7
  {
9
8
  "black" => 0,
@@ -17,91 +16,100 @@ class Pry
17
16
  "white" => 7
18
17
  }
19
18
 
20
- class << self
19
+ COLORS.each_pair do |color, value|
20
+ define_method color do |text|
21
+ "\033[0;#{30 + value}m#{text}\033[0m"
22
+ end
21
23
 
22
- COLORS.each_pair do |color, value|
23
- define_method color do |text|
24
- "\033[0;#{30+value}m#{text}\033[0m"
25
- end
24
+ define_method "bright_#{color}" do |text|
25
+ "\033[1;#{30 + value}m#{text}\033[0m"
26
+ end
26
27
 
27
- define_method "bright_#{color}" do |text|
28
- "\033[1;#{30+value}m#{text}\033[0m"
28
+ COLORS.each_pair do |bg_color, bg_value|
29
+ define_method "#{color}_on_#{bg_color}" do |text|
30
+ "\033[0;#{30 + value};#{40 + bg_value}m#{text}\033[0m"
29
31
  end
30
- end
31
32
 
32
- # Remove any color codes from _text_.
33
- #
34
- # @param [String, #to_s] text
35
- # @return [String] _text_ stripped of any color codes.
36
- def strip_color(text)
37
- text.to_s.gsub(/\e\[.*?(\d)+m/ , '')
33
+ define_method "bright_#{color}_on_#{bg_color}" do |text|
34
+ "\033[1;#{30 + value};#{40 + bg_value}m#{text}\033[0m"
35
+ end
38
36
  end
37
+ end
39
38
 
40
- # Returns _text_ as bold text for use on a terminal.
41
- #
42
- # @param [String, #to_s] text
43
- # @return [String] _text_
44
- def bold(text)
45
- "\e[1m#{text}\e[0m"
46
- end
39
+ # Remove any color codes from _text_.
40
+ #
41
+ # @param [String, #to_s] text
42
+ # @return [String] _text_ stripped of any color codes.
43
+ def strip_color(text)
44
+ text.to_s.gsub(/(\001)?\e\[.*?(\d)+m(\002)?/ , '')
45
+ end
47
46
 
48
- # Returns `text` in the default foreground colour.
49
- # Use this instead of "black" or "white" when you mean absence of colour.
50
- #
51
- # @param [String, #to_s] text
52
- # @return [String]
53
- def default(text)
54
- text.to_s
55
- end
56
- alias_method :bright_default, :bold
47
+ # Returns _text_ as bold text for use on a terminal.
48
+ #
49
+ # @param [String, #to_s] text
50
+ # @return [String] _text_
51
+ def bold(text)
52
+ "\e[1m#{text}\e[0m"
53
+ end
57
54
 
58
- # Executes the block with `Pry.config.color` set to false.
59
- # @yield
60
- # @return [void]
61
- def no_color(&block)
62
- boolean = Pry.config.color
63
- Pry.config.color = false
64
- yield
65
- ensure
66
- Pry.config.color = boolean
67
- end
55
+ # Returns `text` in the default foreground colour.
56
+ # Use this instead of "black" or "white" when you mean absence of colour.
57
+ #
58
+ # @param [String, #to_s] text
59
+ # @return [String]
60
+ def default(text)
61
+ text.to_s
62
+ end
68
63
 
69
- # Executes the block with `Pry.config.pager` set to false.
70
- # @yield
71
- # @return [void]
72
- def no_pager(&block)
73
- boolean = Pry.config.pager
74
- Pry.config.pager = false
75
- yield
76
- ensure
77
- Pry.config.pager = boolean
78
- end
64
+ #
65
+ # @yield
66
+ # Yields a block with color turned off.
67
+ #
68
+ # @return [void]
69
+ #
70
+ def no_color
71
+ boolean = Pry.config.color
72
+ Pry.config.color = false
73
+ yield
74
+ ensure
75
+ Pry.config.color = boolean
76
+ end
79
77
 
80
- # Returns _text_ in a numbered list, beginning at _offset_.
81
- #
82
- # @param [#each_line] text
83
- # @param [Fixnum] offset
84
- # @return [String]
85
- def with_line_numbers(text, offset, color=:blue)
86
- lines = text.each_line.to_a
87
- max_width = (offset + lines.count).to_s.length
88
- lines.each_with_index.map do |line, index|
89
- adjusted_index = (index + offset).to_s.rjust(max_width)
90
- "#{self.send(color, adjusted_index)}: #{line}"
91
- end.join
92
- end
78
+ #
79
+ # @yield
80
+ # Yields a block with paging turned off.
81
+ #
82
+ # @return [void]
83
+ #
84
+ def no_pager
85
+ boolean = Pry.config.pager
86
+ Pry.config.pager = false
87
+ yield
88
+ ensure
89
+ Pry.config.pager = boolean
90
+ end
93
91
 
94
- # Returns _text_ indented by _chars_ spaces.
95
- #
96
- # @param [String] text
97
- # @param [Fixnum] chars
98
- def indent(text, chars)
99
- text.lines.map { |l| "#{' ' * chars}#{l}" }.join
100
- end
92
+ # Returns _text_ in a numbered list, beginning at _offset_.
93
+ #
94
+ # @param [#each_line] text
95
+ # @param [Fixnum] offset
96
+ # @return [String]
97
+ def with_line_numbers(text, offset, color = :blue)
98
+ lines = text.each_line.to_a
99
+ max_width = (offset + lines.count).to_s.length
100
+ lines.each_with_index.map do |line, index|
101
+ adjusted_index = (index + offset).to_s.rjust(max_width)
102
+ "#{self.send(color, adjusted_index)}: #{line}"
103
+ end.join
101
104
  end
102
105
 
106
+ # Returns _text_ indented by _chars_ spaces.
107
+ #
108
+ # @param [String] text
109
+ # @param [Fixnum] chars
110
+ def indent(text, chars)
111
+ text.lines.map { |l| "#{' ' * chars}#{l}" }.join
112
+ end
103
113
  end
104
-
105
114
  end
106
115
  end
107
-
data/lib/pry/helpers.rb CHANGED
@@ -3,3 +3,4 @@ require "pry/helpers/options_helpers"
3
3
  require "pry/helpers/command_helpers"
4
4
  require "pry/helpers/text"
5
5
  require "pry/helpers/table"
6
+ require "pry/helpers/platform"
data/lib/pry/history.rb CHANGED
@@ -7,7 +7,7 @@ class Pry
7
7
  # @return [Fixnum] Number of lines in history when Pry first loaded.
8
8
  attr_reader :original_lines
9
9
 
10
- def initialize(options={})
10
+ def initialize(options = {})
11
11
  @history = []
12
12
  @original_lines = 0
13
13
  @file_path = options[:file_path]
@@ -25,8 +25,8 @@ class Pry
25
25
  @pusher = method(:push_to_readline)
26
26
  @clearer = method(:clear_readline)
27
27
  else
28
- @pusher = proc { }
29
- @clearer = proc { }
28
+ @pusher = proc {}
29
+ @clearer = proc {}
30
30
  end
31
31
  end
32
32
 
@@ -34,6 +34,8 @@ class Pry
34
34
  # @return [Integer] The number of lines loaded
35
35
  def load
36
36
  @loader.call do |line|
37
+ next if invalid_readline_line?(line)
38
+
37
39
  @pusher.call(line.chomp)
38
40
  @history << line.chomp
39
41
  @original_lines += 1
@@ -44,10 +46,14 @@ class Pry
44
46
  # @param [String] line
45
47
  # @return [String] The same line that was passed in
46
48
  def push(line)
47
- unless line.empty? || (@history.last && line == @history.last)
49
+ empty_or_invalid_line = line.empty? || invalid_readline_line?(line)
50
+
51
+ unless empty_or_invalid_line || (@history.last && line == @history.last)
48
52
  @pusher.call(line)
49
53
  @history << line
50
- @saver.call(line) if Pry.config.history.should_save
54
+ if !should_ignore?(line) && Pry.config.history.should_save
55
+ @saver.call(line)
56
+ end
51
57
  end
52
58
  line
53
59
  end
@@ -57,6 +63,7 @@ class Pry
57
63
  # history file.
58
64
  def clear
59
65
  @clearer.call
66
+ @original_lines = 0
60
67
  @history = []
61
68
  end
62
69
 
@@ -77,17 +84,35 @@ class Pry
77
84
  @history.dup
78
85
  end
79
86
 
87
+ # Filter the history with the histignore options
88
+ # @return [Array<String>] An array containing all the lines that are not
89
+ # included in the histignore.
90
+ def filter(history)
91
+ history.select { |l| l unless should_ignore?(l) }
92
+ end
93
+
80
94
  private
81
95
 
96
+ # Check if the line match any option in the histignore
97
+ # [Pry.config.history.histignore]
98
+ # @return [Boolean] a boolean that notifies if the line was found in the
99
+ # histignore array.
100
+ def should_ignore?(line)
101
+ hist_ignore = Pry.config.history.histignore
102
+ return false if hist_ignore.nil? || hist_ignore.empty?
103
+
104
+ hist_ignore.any? { |p| line.to_s.match(p) }
105
+ end
106
+
82
107
  # The default loader. Yields lines from `Pry.history.config.file`.
83
108
  def read_from_file
84
109
  path = history_file_path
85
110
 
86
- if File.exists?(path)
111
+ if File.exist?(path)
87
112
  File.foreach(path) { |line| yield(line) }
88
113
  end
89
- rescue => error
90
- warn "History file not loaded: #{error.message}"
114
+ rescue SystemCallError => error
115
+ warn "Unable to read history file: #{error.message}"
91
116
  end
92
117
 
93
118
  # The default pusher. Appends the given line to Readline::HISTORY.
@@ -111,17 +136,26 @@ class Pry
111
136
  if defined?(@history_file)
112
137
  @history_file
113
138
  else
139
+ unless File.exist?(history_file_path)
140
+ FileUtils.mkdir_p(File.dirname(history_file_path))
141
+ end
114
142
  @history_file = File.open(history_file_path, 'a', 0600).tap do |file|
115
143
  file.sync = true
116
144
  end
117
145
  end
118
- rescue Errno::EACCES
119
- warn 'History not saved; unable to open your history file for writing.'
146
+ rescue SystemCallError => error
147
+ warn "Unable to write history file: #{error.message}"
120
148
  @history_file = false
121
149
  end
122
150
 
123
151
  def history_file_path
124
152
  File.expand_path(@file_path || Pry.config.history.file)
125
153
  end
154
+
155
+ def invalid_readline_line?(line)
156
+ # `Readline::HISTORY << line` raises an `ArgumentError` if `line`
157
+ # includes a null byte
158
+ line.include?("\0")
159
+ end
126
160
  end
127
161
  end
data/lib/pry/hooks.rb CHANGED
@@ -1,37 +1,21 @@
1
1
  class Pry
2
-
3
- # Implements a hooks system for Pry. A hook is a callable that is
4
- # associated with an event. A number of events are currently
5
- # provided by Pry, these include: `:when_started`, `:before_session`, `:after_session`.
6
- # A hook must have a name, and is connected with an event by the
7
- # `Pry::Hooks#add_hook` method.
2
+ # Implements a hooks system for Pry. A hook is a callable that is associated
3
+ # with an event. A number of events are currently provided by Pry, these
4
+ # include: `:when_started`, `:before_session`, `:after_session`. A hook must
5
+ # have a name, and is connected with an event by the `Pry::Hooks#add_hook`
6
+ # method.
7
+ #
8
8
  # @example Adding a hook for the `:before_session` event.
9
9
  # Pry.config.hooks.add_hook(:before_session, :say_hi) do
10
10
  # puts "hello"
11
11
  # end
12
12
  class Hooks
13
-
14
- # Converts a hash to a `Pry::Hooks` instance. All hooks defined
15
- # this way are anonymous. This functionality is primarily to
16
- # provide backwards-compatibility with the old hash-based hook
17
- # system in Pry versions < 0.9.8
18
- # @param [Hash] hash The hash to convert to `Pry::Hooks`.
19
- # @return [Pry::Hooks] The resulting `Pry::Hooks` instance.
20
- def self.from_hash(hash)
21
- return hash if hash.instance_of?(self)
22
- instance = new
23
- hash.each do |k, v|
24
- instance.add_hook(k, nil, v)
25
- end
26
- instance
27
- end
28
-
29
13
  def initialize
30
- @hooks = {}
14
+ @hooks = Hash.new { |h, k| h[k] = [] }
31
15
  end
32
16
 
33
- # Ensure that duplicates have their @hooks object
34
- def initialize_copy(orig)
17
+ # Ensure that duplicates have their @hooks object.
18
+ def initialize_copy(_orig)
35
19
  hooks_dup = @hooks.dup
36
20
  @hooks.each do |k, v|
37
21
  hooks_dup[k] = v.dup
@@ -40,63 +24,49 @@ class Pry
40
24
  @hooks = hooks_dup
41
25
  end
42
26
 
43
- def hooks
44
- @hooks
45
- end
46
- protected :hooks
47
-
48
27
  def errors
49
28
  @errors ||= []
50
29
  end
51
30
 
52
31
  # Destructively merge the contents of two `Pry:Hooks` instances.
32
+ #
53
33
  # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
54
- # @return [Pry:Hooks] Returns the receiver.
55
- # @example
56
- # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
57
- # Pry::Hooks.new.merge!(hooks)
34
+ # @return [Pry:Hooks] The receiver.
35
+ # @see #merge
58
36
  def merge!(other)
59
- @hooks.merge!(other.dup.hooks) do |key, v1, v2|
60
- merge_arrays(v1, v2)
61
- end
37
+ @hooks.merge!(other.dup.hooks) do |key, array, other_array|
38
+ temp_hash, output = {}, []
62
39
 
63
- self
64
- end
40
+ (array + other_array).reverse_each do |pair|
41
+ temp_hash[pair.first] ||= output.unshift(pair)
42
+ end
65
43
 
66
- def merge_arrays(array1, array2)
67
- uniq_keeping_last(array1 + array2, &:first)
68
- end
69
- private :merge_arrays
44
+ output
45
+ end
70
46
 
71
- def uniq_keeping_last(input, &block)
72
- hash, output = {}, []
73
- input.reverse.each{ |i| hash[block[i]] ||= (output.unshift i) }
74
- output
47
+ self
75
48
  end
76
- private :uniq_keeping_last
77
49
 
78
- # Return a new `Pry::Hooks` instance containing a merge of the contents of two `Pry:Hooks` instances,
79
- # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
80
- # @return [Pry::Hooks] The new hash.
81
50
  # @example
82
51
  # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
83
52
  # Pry::Hooks.new.merge(hooks)
53
+ # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
54
+ # @return [Pry::Hooks] a new `Pry::Hooks` instance containing a merge of the
55
+ # contents of two `Pry:Hooks` instances.
84
56
  def merge(other)
85
57
  self.dup.tap do |v|
86
58
  v.merge!(other)
87
59
  end
88
60
  end
89
61
 
90
- # Add a new hook to be executed for the `name` even.
62
+ # Add a new hook to be executed for the `event_name` event.
91
63
  # @param [Symbol] event_name The name of the event.
92
64
  # @param [Symbol] hook_name The name of the hook.
93
65
  # @param [#call] callable The callable.
94
- # @yield The block to use as the callable (if `callable` parameter not provided)
95
- # @return [Pry:Hooks] Returns the receiver.
96
- # @example
97
- # Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
98
- def add_hook(event_name, hook_name, callable=nil, &block)
99
- @hooks[event_name] ||= []
66
+ # @yield The block to use as the callable (if no `callable` provided).
67
+ # @return [Pry:Hooks] The receiver.
68
+ def add_hook(event_name, hook_name, callable = nil, &block)
69
+ event_name = event_name.to_s
100
70
 
101
71
  # do not allow duplicates, but allow multiple `nil` hooks
102
72
  # (anonymous hooks)
@@ -124,13 +94,8 @@ class Pry
124
94
  # @param [Symbol] event_name The name of the event.
125
95
  # @param [Array] args The arguments to pass to each hook function.
126
96
  # @return [Object] The return value of the last executed hook.
127
- # @example
128
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
129
- # my_hooks.exec_hook(:before_session) #=> OUTPUT: "hi!"
130
97
  def exec_hook(event_name, *args, &block)
131
- @hooks[event_name] ||= []
132
-
133
- @hooks[event_name].map do |hook_name, callable|
98
+ @hooks[event_name.to_s].map do |hook_name, callable|
134
99
  begin
135
100
  callable.call(*args, &block)
136
101
  rescue RescuableException => e
@@ -140,56 +105,38 @@ class Pry
140
105
  end.last
141
106
  end
142
107
 
143
- # Return the number of hook functions registered for the `event_name` event.
144
108
  # @param [Symbol] event_name The name of the event.
145
109
  # @return [Fixnum] The number of hook functions for `event_name`.
146
- # @example
147
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
148
- # my_hooks.count(:before_session) #=> 1
149
110
  def hook_count(event_name)
150
- @hooks[event_name] ||= []
151
- @hooks[event_name].size
111
+ @hooks[event_name.to_s].size
152
112
  end
153
113
 
154
- # Return a specific hook for a given event.
155
114
  # @param [Symbol] event_name The name of the event.
156
115
  # @param [Symbol] hook_name The name of the hook
157
- # @return [#call] The requested hook.
158
- # @example
159
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
160
- # my_hooks.get_hook(:before_session, :say_hi).call #=> "hi!"
116
+ # @return [#call] a specific hook for a given event.
161
117
  def get_hook(event_name, hook_name)
162
- @hooks[event_name] ||= []
163
- hook = @hooks[event_name].find { |current_hook_name, callable| current_hook_name == hook_name }
118
+ hook = @hooks[event_name.to_s].find do |current_hook_name, callable|
119
+ current_hook_name == hook_name
120
+ end
164
121
  hook.last if hook
165
122
  end
166
123
 
167
- # Return the hash of hook names / hook functions for a
168
- # given event. (Note that modifying the returned hash does not
169
- # alter the hooks, use add_hook/delete_hook for that).
170
124
  # @param [Symbol] event_name The name of the event.
171
125
  # @return [Hash] The hash of hook names / hook functions.
172
- # @example
173
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
174
- # my_hooks.get_hooks(:before_session) #=> {:say_hi=>#<Proc:0x00000101645e18@(pry):9>}
126
+ # @note Modifying the returned hash does not alter the hooks, use
127
+ # `add_hook`/`delete_hook` for that.
175
128
  def get_hooks(event_name)
176
- @hooks[event_name] ||= []
177
- Hash[@hooks[event_name]]
129
+ Hash[@hooks[event_name.to_s]]
178
130
  end
179
131
 
180
- # Delete a hook for an event.
181
132
  # @param [Symbol] event_name The name of the event.
182
133
  # @param [Symbol] hook_name The name of the hook.
183
134
  # to delete.
184
135
  # @return [#call] The deleted hook.
185
- # @example
186
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
187
- # my_hooks.delete_hook(:before_session, :say_hi)
188
136
  def delete_hook(event_name, hook_name)
189
- @hooks[event_name] ||= []
190
137
  deleted_callable = nil
191
138
 
192
- @hooks[event_name].delete_if do |current_hook_name, callable|
139
+ @hooks[event_name.to_s].delete_if do |current_hook_name, callable|
193
140
  if current_hook_name == hook_name
194
141
  deleted_callable = callable
195
142
  true
@@ -201,30 +148,24 @@ class Pry
201
148
  end
202
149
 
203
150
  # Clear all hooks functions for a given event.
151
+ #
204
152
  # @param [String] event_name The name of the event.
205
- # @example
206
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
207
- # my_hooks.delete_hook(:before_session)
208
- def delete_hooks(event_name)
209
- @hooks[event_name] = []
210
- end
211
-
212
- alias_method :clear, :delete_hooks
213
-
214
- # Remove all events and hooks, clearing out the Pry::Hooks
215
- # instance completely.
216
- # @example
217
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
218
- # my_hooks.clear_all
219
- def clear_all
220
- @hooks = {}
153
+ # @return [void]
154
+ def clear_event_hooks(event_name)
155
+ @hooks[event_name.to_s] = []
221
156
  end
222
157
 
223
158
  # @param [Symbol] event_name Name of the event.
224
159
  # @param [Symbol] hook_name Name of the hook.
225
- # @return [Boolean] Whether the hook by the name `hook_name`
160
+ # @return [Boolean] Whether the hook by the name `hook_name`.
226
161
  def hook_exists?(event_name, hook_name)
227
- !!(@hooks[event_name] && @hooks[event_name].find { |name, _| name == hook_name })
162
+ @hooks[event_name.to_s].map(&:first).include?(hook_name)
163
+ end
164
+
165
+ protected
166
+
167
+ def hooks
168
+ @hooks
228
169
  end
229
170
  end
230
171
  end
data/lib/pry/indent.rb CHANGED
@@ -66,8 +66,10 @@ class Pry
66
66
  #
67
67
  # :reserved and :keywords are the CodeRay 0.9.8 and 1.0.0 respectively
68
68
  # classifications of "super", "next", "return", etc.
69
- STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float, :keyword,
70
- :delimiter, :reserved]
69
+ STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float,
70
+ :keyword, :delimiter, :reserved,
71
+ :instance_variable,
72
+ :class_variable, :global_variable]
71
73
 
72
74
  # Collection of tokens that should appear dedented even though they
73
75
  # don't affect the surrounding code.
@@ -141,10 +143,9 @@ class Pry
141
143
  prefix = indent_level
142
144
 
143
145
  input.lines.each do |line|
144
-
145
146
  if in_string?
146
147
  tokens = tokenize("#{open_delimiters_line}\n#{line}")
147
- tokens = tokens.drop_while{ |token, type| !(String === token && token.include?("\n")) }
148
+ tokens = tokens.drop_while { |token, type| !(String === token && token.include?("\n")) }
148
149
  previously_in_string = true
149
150
  else
150
151
  tokens = tokenize(line)
@@ -153,7 +154,7 @@ class Pry
153
154
 
154
155
  before, after = indentation_delta(tokens)
155
156
 
156
- before.times{ prefix.sub! SPACES, '' }
157
+ before.times { prefix.sub! SPACES, '' }
157
158
  new_prefix = prefix + SPACES * after
158
159
 
159
160
  line = prefix + line.lstrip unless previously_in_string
@@ -213,7 +214,7 @@ class Pry
213
214
  # If the list of tokens contains a matching closing token the line should
214
215
  # not be indented (and thus we should return true).
215
216
  tokens.each do |token, kind|
216
- is_singleline_if = (SINGLELINE_TOKENS.include?(token)) && end_of_statement?(last_token, last_kind)
217
+ is_singleline_if = (SINGLELINE_TOKENS.include?(token)) && end_of_statement?(last_token, last_kind)
217
218
  is_optional_do = (token == "do" && seen_for_at.include?(add_after - 1))
218
219
 
219
220
  last_token, last_kind = token, kind unless kind == :space
@@ -223,6 +224,8 @@ class Pry
223
224
 
224
225
  seen_for_at << add_after if OPTIONAL_DO_TOKENS.include?(token)
225
226
 
227
+ next if is_singleline_if
228
+
226
229
  if kind == :delimiter
227
230
  track_delimiter(token)
228
231
  elsif OPEN_TOKENS.keys.include?(token) && !is_optional_do && !is_singleline_if
@@ -354,7 +357,7 @@ class Pry
354
357
  #
355
358
  # @param [String] token a token from Coderay
356
359
  # @param [Symbol] kind the kind of that token
357
- def track_module_nesting_end(token, kind=:keyword)
360
+ def track_module_nesting_end(token, kind = :keyword)
358
361
  if kind == :keyword && (token == "class" || token == "module")
359
362
  @module_nesting.pop
360
363
  end
@@ -378,25 +381,24 @@ class Pry
378
381
  # the correct indentation. Mostly useful for fixing 'end'.
379
382
  #
380
383
  # @param [String] prompt The user's prompt
381
- # @param [String] code The code the user just typed in.
382
- # @param [Fixnum] overhang (0) The number of chars to erase afterwards (i.e.,
383
- # the difference in length between the old line and the new one).
384
- # @return [String]
385
- def correct_indentation(prompt, code, overhang=0)
384
+ # @param [String] code The code the user just typed in
385
+ # @param [Integer] overhang The number of characters to erase afterwards (the
386
+ # the difference in length between the old line and the new one)
387
+ #
388
+ # @return [String] correctly indented line
389
+ def correct_indentation(prompt, code, overhang = 0)
386
390
  prompt = prompt.delete("\001\002")
387
391
  line_to_measure = Pry::Helpers::Text.strip_color(prompt) << code
388
392
  whitespace = ' ' * overhang
389
393
 
390
- _, cols = Terminal.screen_size
391
-
392
- cols = cols.to_i
393
- lines = (cols != 0 ? (line_to_measure.length / cols + 1) : 1).to_i
394
+ cols = Terminal.width!
395
+ lines = cols == 0 ? 1 : (line_to_measure.length / cols + 1).to_i
394
396
 
395
- if Pry::Helpers::BaseHelpers.windows_ansi?
396
- move_up = "\e[#{lines}F"
397
+ if Helpers::Platform.windows_ansi?
398
+ move_up = "\e[#{lines}F"
397
399
  move_down = "\e[#{lines}E"
398
400
  else
399
- move_up = "\e[#{lines}A\e[0G"
401
+ move_up = "\e[#{lines}A\e[0G"
400
402
  move_down = "\e[#{lines}B\e[0G"
401
403
  end
402
404