pry 0.9.12.6 → 0.10.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +702 -0
  3. data/LICENSE +2 -2
  4. data/{README.markdown → README.md} +37 -31
  5. data/lib/pry.rb +38 -151
  6. data/lib/pry/cli.rb +35 -17
  7. data/lib/pry/code.rb +24 -63
  8. data/lib/pry/code/code_file.rb +103 -0
  9. data/lib/pry/code/code_range.rb +2 -1
  10. data/lib/pry/code/loc.rb +2 -2
  11. data/lib/pry/code_object.rb +40 -21
  12. data/lib/pry/color_printer.rb +55 -0
  13. data/lib/pry/command.rb +12 -9
  14. data/lib/pry/command_set.rb +81 -38
  15. data/lib/pry/commands.rb +1 -1
  16. data/lib/pry/commands/amend_line.rb +2 -2
  17. data/lib/pry/commands/bang.rb +1 -1
  18. data/lib/pry/commands/cat.rb +11 -2
  19. data/lib/pry/commands/cat/exception_formatter.rb +5 -6
  20. data/lib/pry/commands/cat/file_formatter.rb +15 -32
  21. data/lib/pry/commands/cd.rb +14 -3
  22. data/lib/pry/commands/change_inspector.rb +27 -0
  23. data/lib/pry/commands/change_prompt.rb +26 -0
  24. data/lib/pry/commands/code_collector.rb +4 -4
  25. data/lib/pry/commands/easter_eggs.rb +3 -3
  26. data/lib/pry/commands/edit.rb +10 -22
  27. data/lib/pry/commands/edit/exception_patcher.rb +2 -2
  28. data/lib/pry/commands/edit/file_and_line_locator.rb +0 -2
  29. data/lib/pry/commands/exit_program.rb +0 -1
  30. data/lib/pry/commands/find_method.rb +16 -22
  31. data/lib/pry/commands/gem_install.rb +5 -2
  32. data/lib/pry/commands/gem_open.rb +1 -1
  33. data/lib/pry/commands/gist.rb +10 -11
  34. data/lib/pry/commands/help.rb +14 -14
  35. data/lib/pry/commands/hist.rb +27 -8
  36. data/lib/pry/commands/install_command.rb +14 -12
  37. data/lib/pry/commands/list_inspectors.rb +35 -0
  38. data/lib/pry/commands/list_prompts.rb +35 -0
  39. data/lib/pry/commands/ls.rb +72 -296
  40. data/lib/pry/commands/ls/constants.rb +47 -0
  41. data/lib/pry/commands/ls/formatter.rb +49 -0
  42. data/lib/pry/commands/ls/globals.rb +48 -0
  43. data/lib/pry/commands/ls/grep.rb +21 -0
  44. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  45. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  46. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  47. data/lib/pry/commands/ls/local_names.rb +35 -0
  48. data/lib/pry/commands/ls/local_vars.rb +39 -0
  49. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  50. data/lib/pry/commands/ls/methods.rb +57 -0
  51. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  52. data/lib/pry/commands/ls/self_methods.rb +32 -0
  53. data/lib/pry/commands/play.rb +44 -10
  54. data/lib/pry/commands/pry_backtrace.rb +1 -2
  55. data/lib/pry/commands/raise_up.rb +2 -2
  56. data/lib/pry/commands/reload_code.rb +16 -19
  57. data/lib/pry/commands/ri.rb +7 -3
  58. data/lib/pry/commands/shell_command.rb +18 -13
  59. data/lib/pry/commands/shell_mode.rb +2 -4
  60. data/lib/pry/commands/show_doc.rb +5 -0
  61. data/lib/pry/commands/show_info.rb +8 -13
  62. data/lib/pry/commands/show_source.rb +15 -3
  63. data/lib/pry/commands/simple_prompt.rb +1 -1
  64. data/lib/pry/commands/toggle_color.rb +8 -4
  65. data/lib/pry/commands/watch_expression.rb +105 -0
  66. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  67. data/lib/pry/commands/whereami.rb +18 -10
  68. data/lib/pry/commands/wtf.rb +3 -3
  69. data/lib/pry/config.rb +20 -254
  70. data/lib/pry/config/behavior.rb +139 -0
  71. data/lib/pry/config/convenience.rb +26 -0
  72. data/lib/pry/config/default.rb +165 -0
  73. data/lib/pry/core_extensions.rb +31 -21
  74. data/lib/pry/editor.rb +107 -103
  75. data/lib/pry/exceptions.rb +77 -0
  76. data/lib/pry/helpers/base_helpers.rb +22 -109
  77. data/lib/pry/helpers/command_helpers.rb +10 -8
  78. data/lib/pry/helpers/documentation_helpers.rb +1 -2
  79. data/lib/pry/helpers/text.rb +4 -5
  80. data/lib/pry/history.rb +46 -45
  81. data/lib/pry/history_array.rb +6 -1
  82. data/lib/pry/hooks.rb +9 -29
  83. data/lib/pry/indent.rb +6 -6
  84. data/lib/pry/input_completer.rb +242 -0
  85. data/lib/pry/input_lock.rb +132 -0
  86. data/lib/pry/inspector.rb +27 -0
  87. data/lib/pry/last_exception.rb +61 -0
  88. data/lib/pry/method.rb +82 -87
  89. data/lib/pry/{commands/edit/method_patcher.rb → method/patcher.rb} +41 -38
  90. data/lib/pry/module_candidate.rb +4 -14
  91. data/lib/pry/object_path.rb +82 -0
  92. data/lib/pry/output.rb +50 -0
  93. data/lib/pry/pager.rb +191 -47
  94. data/lib/pry/plugins.rb +1 -1
  95. data/lib/pry/prompt.rb +26 -0
  96. data/lib/pry/pry_class.rb +149 -230
  97. data/lib/pry/pry_instance.rb +302 -413
  98. data/lib/pry/rbx_path.rb +1 -1
  99. data/lib/pry/repl.rb +202 -0
  100. data/lib/pry/repl_file_loader.rb +20 -26
  101. data/lib/pry/rubygem.rb +13 -5
  102. data/lib/pry/terminal.rb +2 -1
  103. data/lib/pry/test/helper.rb +26 -41
  104. data/lib/pry/version.rb +1 -1
  105. data/lib/pry/wrapped_module.rb +45 -59
  106. metadata +61 -224
  107. data/.document +0 -2
  108. data/.gitignore +0 -16
  109. data/.travis.yml +0 -25
  110. data/.yardopts +0 -1
  111. data/CHANGELOG +0 -534
  112. data/CONTRIBUTORS +0 -55
  113. data/Gemfile +0 -12
  114. data/Rakefile +0 -140
  115. data/TODO +0 -117
  116. data/lib/pry/completion.rb +0 -321
  117. data/lib/pry/custom_completions.rb +0 -6
  118. data/lib/pry/rbx_method.rb +0 -13
  119. data/man/pry.1 +0 -195
  120. data/man/pry.1.html +0 -204
  121. data/man/pry.1.ronn +0 -141
  122. data/pry.gemspec +0 -29
  123. data/spec/Procfile +0 -3
  124. data/spec/cli_spec.rb +0 -78
  125. data/spec/code_object_spec.rb +0 -277
  126. data/spec/code_spec.rb +0 -219
  127. data/spec/command_helpers_spec.rb +0 -29
  128. data/spec/command_integration_spec.rb +0 -644
  129. data/spec/command_set_spec.rb +0 -627
  130. data/spec/command_spec.rb +0 -821
  131. data/spec/commands/amend_line_spec.rb +0 -247
  132. data/spec/commands/bang_spec.rb +0 -19
  133. data/spec/commands/cat_spec.rb +0 -164
  134. data/spec/commands/cd_spec.rb +0 -250
  135. data/spec/commands/disable_pry_spec.rb +0 -25
  136. data/spec/commands/edit_spec.rb +0 -727
  137. data/spec/commands/exit_all_spec.rb +0 -34
  138. data/spec/commands/exit_program_spec.rb +0 -19
  139. data/spec/commands/exit_spec.rb +0 -34
  140. data/spec/commands/find_method_spec.rb +0 -70
  141. data/spec/commands/gem_list_spec.rb +0 -26
  142. data/spec/commands/gist_spec.rb +0 -79
  143. data/spec/commands/help_spec.rb +0 -56
  144. data/spec/commands/hist_spec.rb +0 -181
  145. data/spec/commands/jump_to_spec.rb +0 -15
  146. data/spec/commands/ls_spec.rb +0 -181
  147. data/spec/commands/play_spec.rb +0 -140
  148. data/spec/commands/raise_up_spec.rb +0 -56
  149. data/spec/commands/save_file_spec.rb +0 -177
  150. data/spec/commands/show_doc_spec.rb +0 -510
  151. data/spec/commands/show_input_spec.rb +0 -17
  152. data/spec/commands/show_source_spec.rb +0 -782
  153. data/spec/commands/whereami_spec.rb +0 -203
  154. data/spec/completion_spec.rb +0 -241
  155. data/spec/control_d_handler_spec.rb +0 -58
  156. data/spec/documentation_helper_spec.rb +0 -73
  157. data/spec/editor_spec.rb +0 -79
  158. data/spec/exception_whitelist_spec.rb +0 -21
  159. data/spec/fixtures/candidate_helper1.rb +0 -11
  160. data/spec/fixtures/candidate_helper2.rb +0 -8
  161. data/spec/fixtures/example.erb +0 -5
  162. data/spec/fixtures/example_nesting.rb +0 -33
  163. data/spec/fixtures/show_source_doc_examples.rb +0 -15
  164. data/spec/fixtures/testrc +0 -2
  165. data/spec/fixtures/testrcbad +0 -2
  166. data/spec/fixtures/whereami_helper.rb +0 -6
  167. data/spec/helper.rb +0 -34
  168. data/spec/helpers/bacon.rb +0 -86
  169. data/spec/helpers/mock_pry.rb +0 -43
  170. data/spec/helpers/table_spec.rb +0 -105
  171. data/spec/history_array_spec.rb +0 -67
  172. data/spec/hooks_spec.rb +0 -522
  173. data/spec/indent_spec.rb +0 -301
  174. data/spec/input_stack_spec.rb +0 -90
  175. data/spec/method_spec.rb +0 -482
  176. data/spec/prompt_spec.rb +0 -60
  177. data/spec/pry_defaults_spec.rb +0 -419
  178. data/spec/pry_history_spec.rb +0 -99
  179. data/spec/pry_output_spec.rb +0 -95
  180. data/spec/pry_spec.rb +0 -515
  181. data/spec/run_command_spec.rb +0 -25
  182. data/spec/sticky_locals_spec.rb +0 -157
  183. data/spec/syntax_checking_spec.rb +0 -81
  184. data/spec/wrapped_module_spec.rb +0 -261
  185. data/wiki/Customizing-pry.md +0 -397
  186. data/wiki/Home.md +0 -4
@@ -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
@@ -42,25 +42,12 @@ class Pry
42
42
  end
43
43
  end
44
44
 
45
- def set_file_and_dir_locals(file_name, _pry_=_pry_(), target=target())
46
- return if !target or !file_name
47
- _pry_.last_file = File.expand_path(file_name)
48
- _pry_.inject_local("_file_", _pry_.last_file, target)
49
-
50
- _pry_.last_dir = File.dirname(_pry_.last_file)
51
- _pry_.inject_local("_dir_", _pry_.last_dir, target)
52
- end
53
-
54
45
  def use_ansi_codes?
55
46
  windows_ansi? || ENV['TERM'] && ENV['TERM'] != "dumb"
56
47
  end
57
48
 
58
49
  def colorize_code(code)
59
- if Pry.color
60
- CodeRay.scan(code, :ruby).term
61
- else
62
- code
63
- end
50
+ CodeRay.scan(code, :ruby).term
64
51
  end
65
52
 
66
53
  def highlight(string, regexp, highlight_color=:bright_yellow)
@@ -70,7 +57,7 @@ class Pry
70
57
  # formatting
71
58
  def heading(text)
72
59
  text = "#{text}\n--"
73
- Pry.color ? "\e[1m#{text}\e[0m": text
60
+ "\e[1m#{text}\e[0m"
74
61
  end
75
62
 
76
63
  # have fun on the Windows platform.
@@ -80,7 +67,7 @@ class Pry
80
67
 
81
68
  # are we able to use ansi on windows?
82
69
  def windows_ansi?
83
- defined?(Win32::Console) || ENV['ANSICON']
70
+ defined?(Win32::Console) || ENV['ANSICON'] || (windows? && mri_2?)
84
71
  end
85
72
 
86
73
  def jruby?
@@ -88,113 +75,39 @@ class Pry
88
75
  end
89
76
 
90
77
  def jruby_19?
91
- RbConfig::CONFIG['ruby_install_name'] == 'jruby' &&
92
- RbConfig::CONFIG['ruby_version'] == '1.9'
78
+ jruby? && RbConfig::CONFIG['ruby_version'] == '1.9'
93
79
  end
94
80
 
95
81
  def rbx?
96
82
  RbConfig::CONFIG['ruby_install_name'] == 'rbx'
97
83
  end
98
84
 
99
- def mri_18?
100
- RUBY_VERSION =~ /1.8/ && RbConfig::CONFIG['ruby_install_name'] == 'ruby'
85
+ def mri?
86
+ RbConfig::CONFIG['ruby_install_name'] == 'ruby'
101
87
  end
102
88
 
103
89
  def mri_19?
104
- RUBY_VERSION =~ /1.9/ && RbConfig::CONFIG['ruby_install_name'] == 'ruby'
90
+ mri? && RUBY_VERSION =~ /^1\.9/
105
91
  end
106
92
 
107
- # Try to use `less` for paging, if it fails then use
108
- # simple_pager. Also do not page if Pry.pager is falsey
109
- def stagger_output(text, out = nil)
110
- out ||= case
111
- when respond_to?(:output)
112
- # Mixin.
113
- output
114
- when Pry.respond_to?(:output)
115
- # Parent.
116
- Pry.output
117
- else
118
- # Sys.
119
- $stdout
120
- end
121
-
122
- if text.lines.count < Pry::Pager.page_size || !Pry.pager
123
- out.puts text
124
- else
125
- Pry::Pager.page(text)
126
- end
127
- rescue Errno::ENOENT
128
- Pry::Pager.page(text, :simple)
129
- rescue Errno::EPIPE
130
- end
131
-
132
- # @param [String] arg_string The object path expressed as a string.
133
- # @param [Pry] _pry_ The relevant Pry instance.
134
- # @param [Array<Binding>] old_stack The state of the old binding stack
135
- # @return [Array<Array<Binding>, Array<Binding>>] An array
136
- # containing two elements: The new `binding_stack` and the old `binding_stack`.
137
- def context_from_object_path(arg_string, _pry_=nil, old_stack=[])
138
-
139
- # Extract command arguments. Delete blank arguments like " ", but
140
- # don't delete empty strings like "".
141
- path = arg_string.split(/\//).delete_if { |a| a =~ /\A\s+\z/ }
142
- stack = _pry_.binding_stack.dup
143
- state_old_stack = old_stack
144
-
145
- # Special case when we only get a single "/", return to root.
146
- if path.empty?
147
- state_old_stack = stack.dup unless old_stack.empty?
148
- stack = [stack.first]
149
- end
93
+ def mri_2?
94
+ mri? && RUBY_VERSION =~ /^2/
95
+ end
150
96
 
151
- path.each_with_index do |context, i|
152
- begin
153
- case context.chomp
154
- when ""
155
- state_old_stack = stack.dup
156
- stack = [stack.first]
157
- when "::"
158
- state_old_stack = stack.dup
159
- stack.push(TOPLEVEL_BINDING)
160
- when "."
161
- next
162
- when ".."
163
- unless stack.size == 1
164
- # Don't rewrite old_stack if we're in complex expression
165
- # (e.g.: `cd 1/2/3/../4).
166
- state_old_stack = stack.dup if path.first == ".."
167
- stack.pop
168
- end
169
- when "-"
170
- unless old_stack.empty?
171
- # Interchange current stack and old stack with each other.
172
- stack, state_old_stack = state_old_stack, stack
173
- end
174
- else
175
- state_old_stack = stack.dup if i == 0
176
- stack.push(Pry.binding_for(stack.last.eval(context)))
177
- end
178
-
179
- rescue RescuableException => e
180
- # Restore old stack to its initial values.
181
- state_old_stack = old_stack
182
-
183
- msg = [
184
- "Bad object path: #{arg_string}.",
185
- "Failed trying to resolve: #{context}.",
186
- e.inspect
187
- ].join(' ')
188
-
189
- CommandError.new(msg).tap do |err|
190
- err.set_backtrace e.backtrace
191
- raise err
192
- end
193
- end
194
- end
195
- return stack, state_old_stack
97
+ def mri_20?
98
+ mri? && RUBY_VERSION =~ /^2\.0/
99
+ end
100
+
101
+ def mri_21?
102
+ mri? && RUBY_VERSION =~ /^2\.1/
196
103
  end
197
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
198
111
  end
199
112
  end
200
113
  end
@@ -15,14 +15,6 @@ class Pry
15
15
  file.close(true) if file
16
16
  end
17
17
 
18
- def render_output(str, opts={})
19
- if opts[:flood]
20
- output.puts str
21
- else
22
- stagger_output str
23
- end
24
- end
25
-
26
18
  def internal_binding?(target)
27
19
  m = target.eval("::Kernel.__method__").to_s
28
20
  # class_eval is here because of http://jira.codehaus.org/browse/JRUBY-6753
@@ -149,6 +141,16 @@ class Pry
149
141
 
150
142
  Range.new(a, b)
151
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
152
153
  end
154
+
153
155
  end
154
156
  end
@@ -8,7 +8,6 @@ class Pry
8
8
  module_function
9
9
 
10
10
  def process_rdoc(comment)
11
- return comment unless Pry.color
12
11
  comment = comment.dup
13
12
  comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { CodeRay.scan($1, :ruby).term }.
14
13
  gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { "\e[1m#{$1}\e[0m" }.
@@ -37,7 +36,7 @@ class Pry
37
36
  yard_tags = ["param", "return", "option", "yield", "attr", "attr_reader", "attr_writer",
38
37
  "deprecate", "example", "raise"]
39
38
  (yard_tags - ["example"]).inject(comment) { |a, v| process_yardoc_tag(a, v) }.
40
- gsub(/^@(#{yard_tags.join("|")})/) { Pry.color ? "\e[33m#{$1}\e[0m": $1 }
39
+ gsub(/^@(#{yard_tags.join("|")})/) { "\e[33m#{$1}\e[0m" }
41
40
  end
42
41
 
43
42
  def process_comment_markup(comment)
@@ -21,11 +21,11 @@ class Pry
21
21
 
22
22
  COLORS.each_pair do |color, value|
23
23
  define_method color do |text|
24
- Pry.color ? "\033[0;#{30+value}m#{text}\033[0m" : text.to_s
24
+ "\033[0;#{30+value}m#{text}\033[0m"
25
25
  end
26
26
 
27
27
  define_method "bright_#{color}" do |text|
28
- Pry.color ? "\033[1;#{30+value}m#{text}\033[0m" : text.to_s
28
+ "\033[1;#{30+value}m#{text}\033[0m"
29
29
  end
30
30
  end
31
31
 
@@ -38,12 +38,11 @@ class Pry
38
38
  end
39
39
 
40
40
  # Returns _text_ as bold text for use on a terminal.
41
- # _Pry.color_ must be true for this method to perform any transformations.
42
41
  #
43
42
  # @param [String, #to_s] text
44
43
  # @return [String] _text_
45
44
  def bold(text)
46
- Pry.color ? "\e[1m#{text}\e[0m" : text.to_s
45
+ "\e[1m#{text}\e[0m"
47
46
  end
48
47
 
49
48
  # Returns `text` in the default foreground colour.
@@ -56,7 +55,7 @@ class Pry
56
55
  end
57
56
  alias_method :bright_default, :bold
58
57
 
59
- # Executes the block with `Pry.color` set to false.
58
+ # Executes the block with `Pry.config.color` set to false.
60
59
  # @yield
61
60
  # @return [void]
62
61
  def no_color(&block)
@@ -7,19 +7,27 @@ 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
10
+ def initialize(options={})
11
11
  @history = []
12
- @saved_lines = 0
13
12
  @original_lines = 0
13
+ @file_path = options[:file_path]
14
14
  restore_default_behavior
15
15
  end
16
16
 
17
17
  # Assign the default methods for loading, saving, pushing, and clearing.
18
18
  def restore_default_behavior
19
- @loader = method(:read_from_file)
20
- @saver = method(:write_to_file)
21
- @pusher = method(:push_to_readline)
22
- @clearer = method(:clear_readline)
19
+ Pry.config.input # force Readline to load if applicable
20
+
21
+ @loader = method(:read_from_file)
22
+ @saver = method(:save_to_file)
23
+
24
+ if defined?(Readline)
25
+ @pusher = method(:push_to_readline)
26
+ @clearer = method(:clear_readline)
27
+ else
28
+ @pusher = proc { }
29
+ @clearer = proc { }
30
+ end
23
31
  end
24
32
 
25
33
  # Load the input history using `History.loader`.
@@ -28,17 +36,8 @@ class Pry
28
36
  @loader.call do |line|
29
37
  @pusher.call(line.chomp)
30
38
  @history << line.chomp
39
+ @original_lines += 1
31
40
  end
32
- @saved_lines = @original_lines = @history.length
33
- end
34
-
35
- # Write this session's history using `History.saver`.
36
- # @return [Integer] The number of lines saved
37
- def save
38
- history_to_save = @history[@saved_lines..-1]
39
- @saver.call(history_to_save)
40
- @saved_lines = @history.length
41
- history_to_save.length
42
41
  end
43
42
 
44
43
  # Add a line to the input history, ignoring blank and duplicate lines.
@@ -48,18 +47,17 @@ class Pry
48
47
  unless line.empty? || (@history.last && line == @history.last)
49
48
  @pusher.call(line)
50
49
  @history << line
50
+ @saver.call(line) if Pry.config.history.should_save
51
51
  end
52
52
  line
53
53
  end
54
54
  alias << push
55
55
 
56
- # Clear all history. Anything the user entered before this point won't be
57
- # saved, but anything they put in afterwards will still be appended to the
58
- # history file on exit.
56
+ # Clear this session's history. This won't affect the contents of the
57
+ # history file.
59
58
  def clear
60
59
  @clearer.call
61
60
  @history = []
62
- @saved_lines = 0
63
61
  end
64
62
 
65
63
  # @return [Fixnum] The number of lines in history.
@@ -67,6 +65,7 @@ class Pry
67
65
  @history.count
68
66
  end
69
67
 
68
+ # @return [Fixnum] The number of lines in history from just this session.
70
69
  def session_line_count
71
70
  @history.count - @original_lines
72
71
  end
@@ -79,46 +78,48 @@ class Pry
79
78
  end
80
79
 
81
80
  private
81
+
82
82
  # The default loader. Yields lines from `Pry.history.config.file`.
83
83
  def read_from_file
84
- begin
85
- history_file = File.expand_path(Pry.config.history.file)
86
- if File.exists?(history_file)
87
- File.foreach(history_file) { |line| yield(line) }
88
- end
89
- rescue => error
90
- unless error.message.empty?
91
- warn "History file not loaded, received an error: #{error.message}"
92
- end
93
- end
94
- end
84
+ filename = File.expand_path(Pry.config.history.file)
95
85
 
96
- # The default saver. Appends the given lines to `Pry.history.config.file`.
97
- # @param [Array<String>] lines
98
- def write_to_file(lines)
99
- history_file = File.expand_path(Pry.config.history.file)
100
-
101
- begin
102
- File.open(history_file, 'a') do |f|
103
- lines.each { |ln| f.puts ln }
104
- end
105
- rescue Errno::EACCES
106
- # We should probably create an option Pry.show_warnings?!?!?!
107
- warn 'Unable to write to your history file, history not saved'
86
+ if File.exists?(filename)
87
+ File.foreach(filename) { |line| yield(line) }
108
88
  end
89
+ rescue => error
90
+ warn "History file not loaded: #{error.message}"
109
91
  end
110
92
 
111
93
  # The default pusher. Appends the given line to Readline::HISTORY.
112
94
  # @param [String] line
113
95
  def push_to_readline(line)
114
- Pry.require_readline
115
96
  Readline::HISTORY << line
116
97
  end
117
98
 
118
99
  # The default clearer. Clears Readline::HISTORY.
119
100
  def clear_readline
120
- Pry.require_readline
121
101
  Readline::HISTORY.shift until Readline::HISTORY.empty?
122
102
  end
103
+
104
+ # The default saver. Appends the given line to `Pry.history.config.file`.
105
+ def save_to_file(line)
106
+ history_file.puts line if history_file
107
+ end
108
+
109
+ # The history file, opened for appending.
110
+ def history_file
111
+ if defined?(@history_file)
112
+ @history_file
113
+ else
114
+ @history_file = File.open(file_path, 'a', 0600).tap { |f| f.sync = true }
115
+ end
116
+ rescue Errno::EACCES
117
+ warn 'History not saved; unable to open your history file for writing.'
118
+ @history_file = false
119
+ end
120
+
121
+ def file_path
122
+ @file_path || Pry.config.history.file
123
+ end
123
124
  end
124
125
  end