pry 0.9.12.2 → 0.14.2

Sign up to get free protection for your applications and to get access to all the features.
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