pry 0.9.12.2 → 0.14.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 (237) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1141 -0
  3. data/LICENSE +2 -2
  4. data/README.md +466 -0
  5. data/bin/pry +4 -7
  6. data/lib/pry/basic_object.rb +10 -0
  7. data/lib/pry/block_command.rb +22 -0
  8. data/lib/pry/class_command.rb +194 -0
  9. data/lib/pry/cli.rb +97 -92
  10. data/lib/pry/code/code_file.rb +114 -0
  11. data/lib/pry/code/code_range.rb +7 -4
  12. data/lib/pry/code/loc.rb +27 -14
  13. data/lib/pry/code.rb +62 -90
  14. data/lib/pry/code_object.rb +83 -39
  15. data/lib/pry/color_printer.rb +66 -0
  16. data/lib/pry/command.rb +202 -371
  17. data/lib/pry/command_set.rb +151 -133
  18. data/lib/pry/command_state.rb +31 -0
  19. data/lib/pry/commands/amend_line.rb +86 -82
  20. data/lib/pry/commands/bang.rb +18 -14
  21. data/lib/pry/commands/bang_pry.rb +15 -11
  22. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  23. data/lib/pry/commands/cat/exception_formatter.rb +85 -73
  24. data/lib/pry/commands/cat/file_formatter.rb +56 -63
  25. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  26. data/lib/pry/commands/cat.rb +64 -47
  27. data/lib/pry/commands/cd.rb +42 -26
  28. data/lib/pry/commands/change_inspector.rb +34 -0
  29. data/lib/pry/commands/change_prompt.rb +51 -0
  30. data/lib/pry/commands/clear_screen.rb +20 -0
  31. data/lib/pry/commands/code_collector.rb +148 -131
  32. data/lib/pry/commands/disable_pry.rb +23 -19
  33. data/lib/pry/commands/easter_eggs.rb +23 -34
  34. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  35. data/lib/pry/commands/edit/file_and_line_locator.rb +33 -24
  36. data/lib/pry/commands/edit.rb +183 -167
  37. data/lib/pry/commands/exit.rb +40 -35
  38. data/lib/pry/commands/exit_all.rb +24 -20
  39. data/lib/pry/commands/exit_program.rb +20 -17
  40. data/lib/pry/commands/find_method.rb +167 -167
  41. data/lib/pry/commands/fix_indent.rb +16 -12
  42. data/lib/pry/commands/help.rb +140 -133
  43. data/lib/pry/commands/hist.rb +153 -132
  44. data/lib/pry/commands/import_set.rb +20 -15
  45. data/lib/pry/commands/jump_to.rb +25 -21
  46. data/lib/pry/commands/list_inspectors.rb +42 -0
  47. data/lib/pry/commands/ls/constants.rb +75 -0
  48. data/lib/pry/commands/ls/formatter.rb +55 -0
  49. data/lib/pry/commands/ls/globals.rb +50 -0
  50. data/lib/pry/commands/ls/grep.rb +23 -0
  51. data/lib/pry/commands/ls/instance_vars.rb +40 -0
  52. data/lib/pry/commands/ls/interrogatable.rb +24 -0
  53. data/lib/pry/commands/ls/jruby_hacks.rb +55 -0
  54. data/lib/pry/commands/ls/local_names.rb +37 -0
  55. data/lib/pry/commands/ls/local_vars.rb +47 -0
  56. data/lib/pry/commands/ls/ls_entity.rb +65 -0
  57. data/lib/pry/commands/ls/methods.rb +55 -0
  58. data/lib/pry/commands/ls/methods_helper.rb +50 -0
  59. data/lib/pry/commands/ls/self_methods.rb +34 -0
  60. data/lib/pry/commands/ls.rb +100 -303
  61. data/lib/pry/commands/nesting.rb +21 -17
  62. data/lib/pry/commands/play.rb +93 -49
  63. data/lib/pry/commands/pry_backtrace.rb +22 -18
  64. data/lib/pry/commands/pry_version.rb +15 -11
  65. data/lib/pry/commands/raise_up.rb +33 -27
  66. data/lib/pry/commands/reload_code.rb +57 -48
  67. data/lib/pry/commands/reset.rb +16 -12
  68. data/lib/pry/commands/ri.rb +57 -38
  69. data/lib/pry/commands/save_file.rb +45 -43
  70. data/lib/pry/commands/shell_command.rb +66 -34
  71. data/lib/pry/commands/shell_mode.rb +22 -20
  72. data/lib/pry/commands/show_doc.rb +80 -65
  73. data/lib/pry/commands/show_info.rb +193 -159
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +113 -33
  76. data/lib/pry/commands/stat.rb +35 -31
  77. data/lib/pry/commands/switch_to.rb +21 -15
  78. data/lib/pry/commands/toggle_color.rb +21 -13
  79. data/lib/pry/commands/watch_expression/expression.rb +43 -0
  80. data/lib/pry/commands/watch_expression.rb +110 -0
  81. data/lib/pry/commands/whereami.rb +157 -134
  82. data/lib/pry/commands/wtf.rb +78 -40
  83. data/lib/pry/config/attributable.rb +22 -0
  84. data/lib/pry/config/lazy_value.rb +29 -0
  85. data/lib/pry/config/memoized_value.rb +34 -0
  86. data/lib/pry/config/value.rb +24 -0
  87. data/lib/pry/config.rb +290 -220
  88. data/lib/pry/control_d_handler.rb +28 -0
  89. data/lib/pry/core_extensions.rb +50 -27
  90. data/lib/pry/editor.rb +130 -102
  91. data/lib/pry/env.rb +18 -0
  92. data/lib/pry/exception_handler.rb +43 -0
  93. data/lib/pry/exceptions.rb +73 -0
  94. data/lib/pry/forwardable.rb +27 -0
  95. data/lib/pry/helpers/base_helpers.rb +22 -151
  96. data/lib/pry/helpers/command_helpers.rb +55 -63
  97. data/lib/pry/helpers/documentation_helpers.rb +21 -13
  98. data/lib/pry/helpers/options_helpers.rb +15 -8
  99. data/lib/pry/helpers/platform.rb +55 -0
  100. data/lib/pry/helpers/table.rb +44 -32
  101. data/lib/pry/helpers/text.rb +96 -86
  102. data/lib/pry/helpers.rb +3 -0
  103. data/lib/pry/history.rb +101 -70
  104. data/lib/pry/hooks.rb +67 -137
  105. data/lib/pry/indent.rb +79 -73
  106. data/lib/pry/input_completer.rb +283 -0
  107. data/lib/pry/input_lock.rb +129 -0
  108. data/lib/pry/inspector.rb +39 -0
  109. data/lib/pry/last_exception.rb +61 -0
  110. data/lib/pry/method/disowned.rb +19 -5
  111. data/lib/pry/{commands/edit/method_patcher.rb → method/patcher.rb} +51 -42
  112. data/lib/pry/method/weird_method_locator.rb +80 -44
  113. data/lib/pry/method.rb +225 -176
  114. data/lib/pry/object_path.rb +91 -0
  115. data/lib/pry/output.rb +136 -0
  116. data/lib/pry/pager.rb +227 -68
  117. data/lib/pry/prompt.rb +214 -0
  118. data/lib/pry/pry_class.rb +216 -289
  119. data/lib/pry/pry_instance.rb +438 -500
  120. data/lib/pry/repl.rb +256 -0
  121. data/lib/pry/repl_file_loader.rb +34 -35
  122. data/lib/pry/ring.rb +89 -0
  123. data/lib/pry/slop/LICENSE +20 -0
  124. data/lib/pry/slop/commands.rb +190 -0
  125. data/lib/pry/slop/option.rb +210 -0
  126. data/lib/pry/slop.rb +672 -0
  127. data/lib/pry/syntax_highlighter.rb +26 -0
  128. data/lib/pry/system_command_handler.rb +17 -0
  129. data/lib/pry/testable/evalable.rb +24 -0
  130. data/lib/pry/testable/mockable.rb +22 -0
  131. data/lib/pry/testable/pry_tester.rb +88 -0
  132. data/lib/pry/testable/utility.rb +34 -0
  133. data/lib/pry/testable/variables.rb +52 -0
  134. data/lib/pry/testable.rb +68 -0
  135. data/lib/pry/version.rb +3 -1
  136. data/lib/pry/warning.rb +20 -0
  137. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +36 -43
  138. data/lib/pry/wrapped_module.rb +102 -103
  139. data/lib/pry.rb +135 -261
  140. metadata +94 -283
  141. data/.document +0 -2
  142. data/.gitignore +0 -16
  143. data/.travis.yml +0 -21
  144. data/.yardopts +0 -1
  145. data/CHANGELOG +0 -534
  146. data/CONTRIBUTORS +0 -55
  147. data/Gemfile +0 -9
  148. data/Guardfile +0 -62
  149. data/README.markdown +0 -400
  150. data/Rakefile +0 -140
  151. data/TODO +0 -117
  152. data/lib/pry/commands/disabled_commands.rb +0 -2
  153. data/lib/pry/commands/gem_cd.rb +0 -26
  154. data/lib/pry/commands/gem_install.rb +0 -29
  155. data/lib/pry/commands/gem_list.rb +0 -33
  156. data/lib/pry/commands/gem_open.rb +0 -29
  157. data/lib/pry/commands/gist.rb +0 -102
  158. data/lib/pry/commands/install_command.rb +0 -51
  159. data/lib/pry/commands/simple_prompt.rb +0 -22
  160. data/lib/pry/commands.rb +0 -6
  161. data/lib/pry/completion.rb +0 -304
  162. data/lib/pry/custom_completions.rb +0 -6
  163. data/lib/pry/history_array.rb +0 -116
  164. data/lib/pry/plugins.rb +0 -103
  165. data/lib/pry/rbx_method.rb +0 -13
  166. data/lib/pry/rbx_path.rb +0 -22
  167. data/lib/pry/rubygem.rb +0 -74
  168. data/lib/pry/terminal.rb +0 -78
  169. data/lib/pry/test/helper.rb +0 -185
  170. data/man/pry.1 +0 -195
  171. data/man/pry.1.html +0 -204
  172. data/man/pry.1.ronn +0 -141
  173. data/pry.gemspec +0 -30
  174. data/spec/Procfile +0 -3
  175. data/spec/cli_spec.rb +0 -78
  176. data/spec/code_object_spec.rb +0 -277
  177. data/spec/code_spec.rb +0 -219
  178. data/spec/command_helpers_spec.rb +0 -29
  179. data/spec/command_integration_spec.rb +0 -644
  180. data/spec/command_set_spec.rb +0 -627
  181. data/spec/command_spec.rb +0 -821
  182. data/spec/commands/amend_line_spec.rb +0 -247
  183. data/spec/commands/bang_spec.rb +0 -19
  184. data/spec/commands/cat_spec.rb +0 -164
  185. data/spec/commands/cd_spec.rb +0 -250
  186. data/spec/commands/disable_pry_spec.rb +0 -25
  187. data/spec/commands/edit_spec.rb +0 -727
  188. data/spec/commands/exit_all_spec.rb +0 -34
  189. data/spec/commands/exit_program_spec.rb +0 -19
  190. data/spec/commands/exit_spec.rb +0 -34
  191. data/spec/commands/find_method_spec.rb +0 -70
  192. data/spec/commands/gem_list_spec.rb +0 -26
  193. data/spec/commands/gist_spec.rb +0 -79
  194. data/spec/commands/help_spec.rb +0 -56
  195. data/spec/commands/hist_spec.rb +0 -181
  196. data/spec/commands/jump_to_spec.rb +0 -15
  197. data/spec/commands/ls_spec.rb +0 -181
  198. data/spec/commands/play_spec.rb +0 -140
  199. data/spec/commands/raise_up_spec.rb +0 -56
  200. data/spec/commands/save_file_spec.rb +0 -177
  201. data/spec/commands/show_doc_spec.rb +0 -510
  202. data/spec/commands/show_input_spec.rb +0 -17
  203. data/spec/commands/show_source_spec.rb +0 -782
  204. data/spec/commands/whereami_spec.rb +0 -203
  205. data/spec/completion_spec.rb +0 -239
  206. data/spec/control_d_handler_spec.rb +0 -58
  207. data/spec/documentation_helper_spec.rb +0 -73
  208. data/spec/editor_spec.rb +0 -79
  209. data/spec/exception_whitelist_spec.rb +0 -21
  210. data/spec/fixtures/candidate_helper1.rb +0 -11
  211. data/spec/fixtures/candidate_helper2.rb +0 -8
  212. data/spec/fixtures/example.erb +0 -5
  213. data/spec/fixtures/example_nesting.rb +0 -33
  214. data/spec/fixtures/show_source_doc_examples.rb +0 -15
  215. data/spec/fixtures/testrc +0 -2
  216. data/spec/fixtures/testrcbad +0 -2
  217. data/spec/fixtures/whereami_helper.rb +0 -6
  218. data/spec/helper.rb +0 -34
  219. data/spec/helpers/bacon.rb +0 -86
  220. data/spec/helpers/mock_pry.rb +0 -43
  221. data/spec/helpers/table_spec.rb +0 -105
  222. data/spec/history_array_spec.rb +0 -67
  223. data/spec/hooks_spec.rb +0 -522
  224. data/spec/indent_spec.rb +0 -301
  225. data/spec/input_stack_spec.rb +0 -90
  226. data/spec/method_spec.rb +0 -482
  227. data/spec/prompt_spec.rb +0 -60
  228. data/spec/pry_defaults_spec.rb +0 -419
  229. data/spec/pry_history_spec.rb +0 -99
  230. data/spec/pry_output_spec.rb +0 -95
  231. data/spec/pry_spec.rb +0 -504
  232. data/spec/run_command_spec.rb +0 -25
  233. data/spec/sticky_locals_spec.rb +0 -157
  234. data/spec/syntax_checking_spec.rb +0 -81
  235. data/spec/wrapped_module_spec.rb +0 -261
  236. data/wiki/Customizing-pry.md +0 -397
  237. data/wiki/Home.md +0 -4
@@ -1,36 +1,42 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
4
  module Helpers
3
- def self.tablify_or_one_line(heading, things)
5
+ def self.tablify_or_one_line(heading, things, pry_instance = Pry.new)
4
6
  plain_heading = Pry::Helpers::Text.strip_color(heading)
5
- attempt = Table.new(things, :column_count => things.size)
6
- if attempt.fits_on_line?(Terminal.width! - plain_heading.size - 2)
7
+ attempt = Table.new(things, column_count: things.size)
8
+ if attempt.fits_on_line?(pry_instance.output.width - plain_heading.size - 2)
7
9
  "#{heading}: #{attempt}\n"
8
10
  else
9
- "#{heading}: \n#{tablify_to_screen_width(things, :indent => ' ')}\n"
11
+ content = tablify_to_screen_width(things, { indent: ' ' }, pry_instance)
12
+ "#{heading}: \n#{content}\n"
10
13
  end
11
14
  end
12
15
 
13
- def self.tablify_to_screen_width(things, options = {})
16
+ def self.tablify_to_screen_width(things, options, pry_instance = Pry.new)
17
+ options ||= {}
14
18
  things = things.compact
15
- if indent = options[:indent]
16
- usable_width = Terminal.width! - indent.size
17
- tablify(things, usable_width).to_s.gsub(/^/, indent)
19
+ if (indent = options[:indent])
20
+ usable_width = pry_instance.output.width - indent.size
21
+ tablify(things, usable_width, pry_instance).to_s.gsub(/^/, indent)
18
22
  else
19
- tablify(things, Terminal.width!).to_s
23
+ tablify(things, pry_instance.output.width, pry_instance).to_s
20
24
  end
21
25
  end
22
26
 
23
- def self.tablify(things, line_length)
24
- table = Table.new(things, :column_count => things.size)
25
- table.column_count -= 1 until 1 == table.column_count or
26
- table.fits_on_line?(line_length)
27
+ def self.tablify(things, line_length, pry_instance = Pry.new)
28
+ table = Table.new(things, { column_count: things.size }, pry_instance)
29
+ until (table.column_count == 1) || table.fits_on_line?(line_length)
30
+ table.column_count -= 1
31
+ end
27
32
  table
28
33
  end
29
34
 
30
35
  class Table
31
36
  attr_reader :items, :column_count
32
- def initialize items, args = {}
37
+ def initialize(items, args, pry_instance = Pry.new)
33
38
  @column_count = args[:column_count]
39
+ @config = pry_instance.config
34
40
  self.items = items
35
41
  end
36
42
 
@@ -38,44 +44,50 @@ class Pry
38
44
  rows_to_s.join("\n")
39
45
  end
40
46
 
41
- def rows_to_s style = :color_on
42
- widths = columns.map{|e| _max_width(e)}
47
+ def rows_to_s(style = :color_on)
48
+ widths = columns.map { |e| _max_width(e) }
43
49
  @rows_without_colors.map do |r|
44
50
  padded = []
45
- r.each_with_index do |e,i|
51
+ r.each_with_index do |e, i|
46
52
  next unless e
53
+
47
54
  item = e.ljust(widths[i])
48
- item.sub! e, _recall_color_for(e) if :color_on == style
55
+ item.sub! e, _recall_color_for(e) if style == :color_on
49
56
  padded << item
50
57
  end
51
- padded.join(Pry.config.ls.separator)
58
+ padded.join(@config.ls.separator)
52
59
  end
53
60
  end
54
61
 
55
- def items= items
62
+ def items=(items)
56
63
  @items = items
57
64
  _rebuild_colorless_cache
58
65
  _recolumn
59
- items
60
66
  end
61
67
 
62
- def column_count= n
63
- @column_count = n
68
+ def column_count=(count)
69
+ @column_count = count
64
70
  _recolumn
65
71
  end
66
72
 
67
- def fits_on_line? line_length
68
- _max_width(rows_to_s :no_color) <= line_length
73
+ def fits_on_line?(line_length)
74
+ _max_width(rows_to_s(:no_color)) <= line_length
69
75
  end
70
76
 
71
77
  def columns
72
78
  @rows_without_colors.transpose
73
79
  end
74
80
 
75
- def ==(other); items == other.to_a end
76
- def to_a; items.to_a end
81
+ def ==(other)
82
+ items == other.to_a
83
+ end
84
+
85
+ def to_a
86
+ items.to_a
87
+ end
77
88
 
78
89
  private
90
+
79
91
  def _max_width(things)
80
92
  things.compact.map(&:size).max || 0
81
93
  end
@@ -93,17 +105,17 @@ class Pry
93
105
  def _recolumn
94
106
  @rows_without_colors = []
95
107
  return if items.size.zero?
96
- row_count = (items.size.to_f/column_count).ceil
108
+
109
+ row_count = (items.size.to_f / column_count).ceil
97
110
  row_count.times do |i|
98
- row_indices = (0...column_count).map{|e| row_count*e+i}
99
- @rows_without_colors << row_indices.map{|e| @plain_items[e]}
111
+ row_indices = (0...column_count).map { |e| row_count * e + i }
112
+ @rows_without_colors << row_indices.map { |e| @plain_items[e] }
100
113
  end
101
114
  end
102
115
 
103
- def _recall_color_for thing
116
+ def _recall_color_for(thing)
104
117
  @colorless_cache[thing]
105
118
  end
106
119
  end
107
-
108
120
  end
109
121
  end
@@ -1,108 +1,118 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
4
  module Helpers
3
-
4
- # The methods defined on {Text} are available to custom commands via {Pry::Command#text}.
5
+ # The methods defined on {Text} are available to custom commands via
6
+ # {Pry::Command#text}.
5
7
  module Text
8
+ extend self
6
9
 
7
- COLORS =
8
- {
9
- "black" => 0,
10
- "red" => 1,
11
- "green" => 2,
12
- "yellow" => 3,
13
- "blue" => 4,
14
- "purple" => 5,
10
+ COLORS = {
11
+ "black" => 0,
12
+ "red" => 1,
13
+ "green" => 2,
14
+ "yellow" => 3,
15
+ "blue" => 4,
16
+ "purple" => 5,
15
17
  "magenta" => 5,
16
- "cyan" => 6,
17
- "white" => 7
18
- }
18
+ "cyan" => 6,
19
+ "white" => 7
20
+ }.freeze
19
21
 
20
- class << self
22
+ COLORS.each_pair do |color, value|
23
+ define_method color do |text|
24
+ "\033[0;#{30 + value}m#{text}\033[0m"
25
+ end
21
26
 
22
- COLORS.each_pair do |color, value|
23
- define_method color do |text|
24
- Pry.color ? "\033[0;#{30+value}m#{text}\033[0m" : text.to_s
25
- end
27
+ define_method "bright_#{color}" do |text|
28
+ "\033[1;#{30 + value}m#{text}\033[0m"
29
+ end
26
30
 
27
- define_method "bright_#{color}" do |text|
28
- Pry.color ? "\033[1;#{30+value}m#{text}\033[0m" : text.to_s
31
+ COLORS.each_pair do |bg_color, bg_value|
32
+ define_method "#{color}_on_#{bg_color}" do |text|
33
+ "\033[0;#{30 + value};#{40 + bg_value}m#{text}\033[0m"
29
34
  end
30
- end
31
35
 
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/ , '')
36
+ define_method "bright_#{color}_on_#{bg_color}" do |text|
37
+ "\033[1;#{30 + value};#{40 + bg_value}m#{text}\033[0m"
38
+ end
38
39
  end
40
+ end
39
41
 
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
- #
43
- # @param [String, #to_s] text
44
- # @return [String] _text_
45
- def bold(text)
46
- Pry.color ? "\e[1m#{text}\e[0m" : text.to_s
47
- end
42
+ # Remove any color codes from _text_.
43
+ #
44
+ # @param [String, #to_s] text
45
+ # @return [String] _text_ stripped of any color codes.
46
+ def strip_color(text)
47
+ text.to_s.gsub(/(\001)?(\e\[(\d[;\d]?)*m)(\002)?/, '')
48
+ end
48
49
 
49
- # Returns `text` in the default foreground colour.
50
- # Use this instead of "black" or "white" when you mean absence of colour.
51
- #
52
- # @param [String, #to_s] text
53
- # @return [String]
54
- def default(text)
55
- text.to_s
56
- end
57
- alias_method :bright_default, :bold
50
+ # Returns _text_ as bold text for use on a terminal.
51
+ #
52
+ # @param [String, #to_s] text
53
+ # @return [String] _text_
54
+ def bold(text)
55
+ "\e[1m#{text}\e[0m"
56
+ end
58
57
 
59
- # Executes the block with `Pry.color` set to false.
60
- # @yield
61
- # @return [void]
62
- def no_color(&block)
63
- boolean = Pry.config.color
64
- Pry.config.color = false
65
- yield
66
- ensure
67
- Pry.config.color = boolean
68
- end
58
+ # Returns `text` in the default foreground colour.
59
+ # Use this instead of "black" or "white" when you mean absence of colour.
60
+ #
61
+ # @param [String, #to_s] text
62
+ # @return [String]
63
+ def default(text)
64
+ text.to_s
65
+ end
69
66
 
70
- # Executes the block with `Pry.config.pager` set to false.
71
- # @yield
72
- # @return [void]
73
- def no_pager(&block)
74
- boolean = Pry.config.pager
75
- Pry.config.pager = false
76
- yield
77
- ensure
78
- Pry.config.pager = boolean
79
- end
67
+ #
68
+ # @yield
69
+ # Yields a block with color turned off.
70
+ #
71
+ # @return [void]
72
+ #
73
+ def no_color
74
+ boolean = Pry.config.color
75
+ Pry.config.color = false
76
+ yield
77
+ ensure
78
+ Pry.config.color = boolean
79
+ end
80
80
 
81
- # Returns _text_ in a numbered list, beginning at _offset_.
82
- #
83
- # @param [#each_line] text
84
- # @param [Fixnum] offset
85
- # @return [String]
86
- def with_line_numbers(text, offset, color=:blue)
87
- lines = text.each_line.to_a
88
- max_width = (offset + lines.count).to_s.length
89
- lines.each_with_index.map do |line, index|
90
- adjusted_index = (index + offset).to_s.rjust(max_width)
91
- "#{self.send(color, adjusted_index)}: #{line}"
92
- end.join
93
- end
81
+ #
82
+ # @yield
83
+ # Yields a block with paging turned off.
84
+ #
85
+ # @return [void]
86
+ #
87
+ def no_pager
88
+ boolean = Pry.config.pager
89
+ Pry.config.pager = false
90
+ yield
91
+ ensure
92
+ Pry.config.pager = boolean
93
+ end
94
94
 
95
- # Returns _text_ indented by _chars_ spaces.
96
- #
97
- # @param [String] text
98
- # @param [Fixnum] chars
99
- def indent(text, chars)
100
- text.lines.map { |l| "#{' ' * chars}#{l}" }.join
101
- end
95
+ # Returns _text_ in a numbered list, beginning at _offset_.
96
+ #
97
+ # @param [#each_line] text
98
+ # @param [Fixnum] offset
99
+ # @return [String]
100
+ def with_line_numbers(text, offset, color = :blue)
101
+ lines = text.each_line.to_a
102
+ max_width = (offset + lines.count).to_s.length
103
+ lines.each_with_index.map do |line, index|
104
+ adjusted_index = (index + offset).to_s.rjust(max_width)
105
+ "#{send(color, adjusted_index)}: #{line}"
106
+ end.join
102
107
  end
103
108
 
109
+ # Returns _text_ indented by _chars_ spaces.
110
+ #
111
+ # @param [String] text
112
+ # @param [Fixnum] chars
113
+ def indent(text, chars)
114
+ text.lines.map { |l| "#{' ' * chars}#{l}" }.join
115
+ end
104
116
  end
105
-
106
117
  end
107
118
  end
108
-
data/lib/pry/helpers.rb CHANGED
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "pry/helpers/base_helpers"
2
4
  require "pry/helpers/options_helpers"
3
5
  require "pry/helpers/command_helpers"
4
6
  require "pry/helpers/text"
5
7
  require "pry/helpers/table"
8
+ require "pry/helpers/platform"
data/lib/pry/history.rb CHANGED
@@ -1,122 +1,153 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- # The History class is responsible for maintaining the user's input history, both
3
- # internally and within Readline.
4
+ # The History class is responsible for maintaining the user's input history,
5
+ # both internally and within Readline.
4
6
  class History
5
- attr_accessor :loader, :saver, :pusher, :clearer
7
+ def self.default_file
8
+ history_file =
9
+ if (xdg_home = Pry::Env['XDG_DATA_HOME'])
10
+ # See XDG Base Directory Specification at
11
+ # https://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
12
+ xdg_home + '/pry/pry_history'
13
+ elsif File.exist?(File.expand_path('~/.pry_history'))
14
+ '~/.pry_history'
15
+ else
16
+ '~/.local/share/pry/pry_history'
17
+ end
18
+ File.expand_path(history_file)
19
+ end
20
+
21
+ attr_accessor :loader, :saver
6
22
 
7
23
  # @return [Fixnum] Number of lines in history when Pry first loaded.
8
24
  attr_reader :original_lines
9
25
 
10
- def initialize
11
- @history = []
12
- @saved_lines = 0
13
- @original_lines = 0
14
- restore_default_behavior
15
- end
26
+ # @return [Integer] total number of lines, including original lines
27
+ attr_reader :history_line_count
16
28
 
17
- # Assign the default methods for loading, saving, pushing, and clearing.
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)
29
+ def initialize(options = {})
30
+ @history = options[:history] || []
31
+ @history_line_count = @history.count
32
+ @file_path = options[:file_path]
33
+ @original_lines = 0
34
+ @loader = method(:read_from_file)
35
+ @saver = method(:save_to_file)
23
36
  end
24
37
 
25
38
  # Load the input history using `History.loader`.
26
39
  # @return [Integer] The number of lines loaded
27
40
  def load
28
41
  @loader.call do |line|
29
- @pusher.call(line.chomp)
42
+ next if invalid_readline_line?(line)
43
+
30
44
  @history << line.chomp
45
+ @original_lines += 1
46
+ @history_line_count += 1
31
47
  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
48
  end
43
49
 
44
50
  # Add a line to the input history, ignoring blank and duplicate lines.
45
51
  # @param [String] line
46
52
  # @return [String] The same line that was passed in
47
53
  def push(line)
48
- unless line.empty? || (@history.last && line == @history.last)
49
- @pusher.call(line)
50
- @history << line
54
+ return line if line.empty? || invalid_readline_line?(line)
55
+
56
+ begin
57
+ last_line = @history[-1]
58
+ rescue IndexError
59
+ last_line = nil
51
60
  end
61
+
62
+ return line if line == last_line
63
+
64
+ @history << line
65
+ @history_line_count += 1
66
+ @saver.call(line) if !should_ignore?(line) && Pry.config.history_save
67
+
52
68
  line
53
69
  end
54
70
  alias << push
55
71
 
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.
72
+ # Clear this session's history. This won't affect the contents of the
73
+ # history file.
59
74
  def clear
60
- @clearer.call
61
- @history = []
62
- @saved_lines = 0
63
- end
64
-
65
- # @return [Fixnum] The number of lines in history.
66
- def history_line_count
67
- @history.count
75
+ @history.clear
76
+ @history_line_count = 0
77
+ @original_lines = 0
68
78
  end
69
79
 
80
+ # @return [Fixnum] The number of lines in history from just this session.
70
81
  def session_line_count
71
- @history.count - @original_lines
82
+ @history_line_count - @original_lines
72
83
  end
73
84
 
74
85
  # Return an Array containing all stored history.
75
86
  # @return [Array<String>] An Array containing all lines of history loaded
76
87
  # or entered by the user in the current session.
77
88
  def to_a
78
- @history.dup
89
+ @history.to_a
90
+ end
91
+
92
+ # Filter the history with the histignore options
93
+ # @return [Array<String>] An array containing all the lines that are not
94
+ # included in the histignore.
95
+ def filter(history)
96
+ history.select { |l| l unless should_ignore?(l) }
79
97
  end
80
98
 
81
99
  private
82
- # The default loader. Yields lines from `Pry.history.config.file`.
100
+
101
+ # Check if the line match any option in the histignore
102
+ # [Pry.config.history_ignorelist]
103
+ # @return [Boolean] a boolean that notifies if the line was found in the
104
+ # histignore array.
105
+ def should_ignore?(line)
106
+ hist_ignore = Pry.config.history_ignorelist
107
+ return false if hist_ignore.nil? || hist_ignore.empty?
108
+
109
+ hist_ignore.any? { |p| line.to_s.match(p) }
110
+ end
111
+
112
+ # The default loader. Yields lines from `Pry.config.history_file`.
83
113
  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
114
+ path = history_file_path
115
+
116
+ File.foreach(path) { |line| yield(line) } if File.exist?(path)
117
+ rescue SystemCallError => error
118
+ warn "Unable to read history file: #{error.message}"
94
119
  end
95
120
 
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)
121
+ # The default saver. Appends the given line to `Pry.config.history_file`.
122
+ def save_to_file(line)
123
+ history_file.puts line if history_file
124
+ end
100
125
 
101
- begin
102
- File.open(history_file, 'a') do |f|
103
- lines.each { |ln| f.puts ln }
126
+ # The history file, opened for appending.
127
+ def history_file
128
+ if defined?(@history_file)
129
+ @history_file
130
+ else
131
+ unless File.exist?(history_file_path)
132
+ FileUtils.mkdir_p(File.dirname(history_file_path))
133
+ end
134
+ @history_file = File.open(history_file_path, 'a', 0o600).tap do |file|
135
+ file.sync = true
104
136
  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'
108
137
  end
138
+ rescue SystemCallError => error
139
+ warn "Unable to write history file: #{error.message}"
140
+ @history_file = false
109
141
  end
110
142
 
111
- # The default pusher. Appends the given line to Readline::HISTORY.
112
- # @param [String] line
113
- def push_to_readline(line)
114
- Readline::HISTORY << line
143
+ def history_file_path
144
+ File.expand_path(@file_path || Pry.config.history_file)
115
145
  end
116
146
 
117
- # The default clearer. Clears Readline::HISTORY.
118
- def clear_readline
119
- Readline::HISTORY.shift until Readline::HISTORY.empty?
147
+ def invalid_readline_line?(line)
148
+ # `Readline::HISTORY << line` raises an `ArgumentError` if `line`
149
+ # includes a null byte
150
+ line.include?("\0")
120
151
  end
121
152
  end
122
153
  end