pry 0.9.12.6-i386-mswin32 → 0.10.0-i386-mswin32

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 (187) 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 +19 -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 +6 -7
  20. data/lib/pry/commands/cat/file_formatter.rb +15 -32
  21. data/lib/pry/commands/cat/input_expression_formatter.rb +1 -1
  22. data/lib/pry/commands/cd.rb +14 -3
  23. data/lib/pry/commands/change_inspector.rb +27 -0
  24. data/lib/pry/commands/change_prompt.rb +26 -0
  25. data/lib/pry/commands/code_collector.rb +4 -4
  26. data/lib/pry/commands/easter_eggs.rb +3 -3
  27. data/lib/pry/commands/edit.rb +10 -22
  28. data/lib/pry/commands/edit/exception_patcher.rb +2 -2
  29. data/lib/pry/commands/edit/file_and_line_locator.rb +0 -2
  30. data/lib/pry/commands/exit_program.rb +0 -1
  31. data/lib/pry/commands/find_method.rb +16 -22
  32. data/lib/pry/commands/gem_install.rb +5 -2
  33. data/lib/pry/commands/gem_open.rb +1 -1
  34. data/lib/pry/commands/gist.rb +10 -11
  35. data/lib/pry/commands/help.rb +14 -14
  36. data/lib/pry/commands/hist.rb +27 -8
  37. data/lib/pry/commands/install_command.rb +14 -12
  38. data/lib/pry/commands/list_inspectors.rb +35 -0
  39. data/lib/pry/commands/list_prompts.rb +35 -0
  40. data/lib/pry/commands/ls.rb +72 -296
  41. data/lib/pry/commands/ls/constants.rb +47 -0
  42. data/lib/pry/commands/ls/formatter.rb +49 -0
  43. data/lib/pry/commands/ls/globals.rb +48 -0
  44. data/lib/pry/commands/ls/grep.rb +21 -0
  45. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  46. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  47. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  48. data/lib/pry/commands/ls/local_names.rb +35 -0
  49. data/lib/pry/commands/ls/local_vars.rb +39 -0
  50. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  51. data/lib/pry/commands/ls/methods.rb +57 -0
  52. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  53. data/lib/pry/commands/ls/self_methods.rb +32 -0
  54. data/lib/pry/commands/play.rb +44 -10
  55. data/lib/pry/commands/pry_backtrace.rb +1 -2
  56. data/lib/pry/commands/raise_up.rb +2 -2
  57. data/lib/pry/commands/reload_code.rb +16 -19
  58. data/lib/pry/commands/ri.rb +7 -3
  59. data/lib/pry/commands/shell_command.rb +18 -13
  60. data/lib/pry/commands/shell_mode.rb +2 -4
  61. data/lib/pry/commands/show_doc.rb +5 -0
  62. data/lib/pry/commands/show_info.rb +8 -13
  63. data/lib/pry/commands/show_source.rb +15 -3
  64. data/lib/pry/commands/simple_prompt.rb +1 -1
  65. data/lib/pry/commands/toggle_color.rb +8 -4
  66. data/lib/pry/commands/watch_expression.rb +105 -0
  67. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  68. data/lib/pry/commands/whereami.rb +18 -10
  69. data/lib/pry/commands/wtf.rb +3 -3
  70. data/lib/pry/config.rb +20 -254
  71. data/lib/pry/config/behavior.rb +139 -0
  72. data/lib/pry/config/convenience.rb +26 -0
  73. data/lib/pry/config/default.rb +165 -0
  74. data/lib/pry/core_extensions.rb +31 -21
  75. data/lib/pry/editor.rb +107 -103
  76. data/lib/pry/exceptions.rb +77 -0
  77. data/lib/pry/helpers/base_helpers.rb +22 -109
  78. data/lib/pry/helpers/command_helpers.rb +10 -8
  79. data/lib/pry/helpers/documentation_helpers.rb +1 -2
  80. data/lib/pry/helpers/text.rb +4 -5
  81. data/lib/pry/history.rb +46 -45
  82. data/lib/pry/history_array.rb +6 -1
  83. data/lib/pry/hooks.rb +9 -29
  84. data/lib/pry/indent.rb +6 -6
  85. data/lib/pry/input_completer.rb +242 -0
  86. data/lib/pry/input_lock.rb +132 -0
  87. data/lib/pry/inspector.rb +27 -0
  88. data/lib/pry/last_exception.rb +61 -0
  89. data/lib/pry/method.rb +82 -87
  90. data/lib/pry/{commands/edit/method_patcher.rb → method/patcher.rb} +41 -38
  91. data/lib/pry/module_candidate.rb +4 -14
  92. data/lib/pry/object_path.rb +82 -0
  93. data/lib/pry/output.rb +50 -0
  94. data/lib/pry/pager.rb +193 -48
  95. data/lib/pry/plugins.rb +1 -1
  96. data/lib/pry/prompt.rb +26 -0
  97. data/lib/pry/pry_class.rb +149 -230
  98. data/lib/pry/pry_instance.rb +302 -413
  99. data/lib/pry/rbx_path.rb +1 -1
  100. data/lib/pry/repl.rb +202 -0
  101. data/lib/pry/repl_file_loader.rb +20 -26
  102. data/lib/pry/rubygem.rb +13 -5
  103. data/lib/pry/terminal.rb +2 -1
  104. data/lib/pry/test/helper.rb +26 -41
  105. data/lib/pry/version.rb +1 -1
  106. data/lib/pry/wrapped_module.rb +45 -59
  107. metadata +62 -225
  108. data/.document +0 -2
  109. data/.gitignore +0 -16
  110. data/.travis.yml +0 -25
  111. data/.yardopts +0 -1
  112. data/CHANGELOG +0 -534
  113. data/CONTRIBUTORS +0 -55
  114. data/Gemfile +0 -12
  115. data/Rakefile +0 -140
  116. data/TODO +0 -117
  117. data/lib/pry/completion.rb +0 -321
  118. data/lib/pry/custom_completions.rb +0 -6
  119. data/lib/pry/rbx_method.rb +0 -13
  120. data/man/pry.1 +0 -195
  121. data/man/pry.1.html +0 -204
  122. data/man/pry.1.ronn +0 -141
  123. data/pry.gemspec +0 -29
  124. data/spec/Procfile +0 -3
  125. data/spec/cli_spec.rb +0 -78
  126. data/spec/code_object_spec.rb +0 -277
  127. data/spec/code_spec.rb +0 -219
  128. data/spec/command_helpers_spec.rb +0 -29
  129. data/spec/command_integration_spec.rb +0 -644
  130. data/spec/command_set_spec.rb +0 -627
  131. data/spec/command_spec.rb +0 -821
  132. data/spec/commands/amend_line_spec.rb +0 -247
  133. data/spec/commands/bang_spec.rb +0 -19
  134. data/spec/commands/cat_spec.rb +0 -164
  135. data/spec/commands/cd_spec.rb +0 -250
  136. data/spec/commands/disable_pry_spec.rb +0 -25
  137. data/spec/commands/edit_spec.rb +0 -727
  138. data/spec/commands/exit_all_spec.rb +0 -34
  139. data/spec/commands/exit_program_spec.rb +0 -19
  140. data/spec/commands/exit_spec.rb +0 -34
  141. data/spec/commands/find_method_spec.rb +0 -70
  142. data/spec/commands/gem_list_spec.rb +0 -26
  143. data/spec/commands/gist_spec.rb +0 -79
  144. data/spec/commands/help_spec.rb +0 -56
  145. data/spec/commands/hist_spec.rb +0 -181
  146. data/spec/commands/jump_to_spec.rb +0 -15
  147. data/spec/commands/ls_spec.rb +0 -181
  148. data/spec/commands/play_spec.rb +0 -140
  149. data/spec/commands/raise_up_spec.rb +0 -56
  150. data/spec/commands/save_file_spec.rb +0 -177
  151. data/spec/commands/show_doc_spec.rb +0 -510
  152. data/spec/commands/show_input_spec.rb +0 -17
  153. data/spec/commands/show_source_spec.rb +0 -782
  154. data/spec/commands/whereami_spec.rb +0 -203
  155. data/spec/completion_spec.rb +0 -241
  156. data/spec/control_d_handler_spec.rb +0 -58
  157. data/spec/documentation_helper_spec.rb +0 -73
  158. data/spec/editor_spec.rb +0 -79
  159. data/spec/exception_whitelist_spec.rb +0 -21
  160. data/spec/fixtures/candidate_helper1.rb +0 -11
  161. data/spec/fixtures/candidate_helper2.rb +0 -8
  162. data/spec/fixtures/example.erb +0 -5
  163. data/spec/fixtures/example_nesting.rb +0 -33
  164. data/spec/fixtures/show_source_doc_examples.rb +0 -15
  165. data/spec/fixtures/testrc +0 -2
  166. data/spec/fixtures/testrcbad +0 -2
  167. data/spec/fixtures/whereami_helper.rb +0 -6
  168. data/spec/helper.rb +0 -34
  169. data/spec/helpers/bacon.rb +0 -86
  170. data/spec/helpers/mock_pry.rb +0 -43
  171. data/spec/helpers/table_spec.rb +0 -105
  172. data/spec/history_array_spec.rb +0 -67
  173. data/spec/hooks_spec.rb +0 -522
  174. data/spec/indent_spec.rb +0 -301
  175. data/spec/input_stack_spec.rb +0 -90
  176. data/spec/method_spec.rb +0 -482
  177. data/spec/prompt_spec.rb +0 -60
  178. data/spec/pry_defaults_spec.rb +0 -419
  179. data/spec/pry_history_spec.rb +0 -99
  180. data/spec/pry_output_spec.rb +0 -95
  181. data/spec/pry_spec.rb +0 -515
  182. data/spec/run_command_spec.rb +0 -25
  183. data/spec/sticky_locals_spec.rb +0 -157
  184. data/spec/syntax_checking_spec.rb +0 -81
  185. data/spec/wrapped_module_spec.rb +0 -261
  186. data/wiki/Customizing-pry.md +0 -397
  187. 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