rdoc 8.0.0 → 8.1.0

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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +1 -3
  3. data/RI.md +75 -75
  4. data/exe/rdoc +2 -2
  5. data/lib/rdoc/code_object/alias.rb +71 -69
  6. data/lib/rdoc/code_object/any_method.rb +305 -303
  7. data/lib/rdoc/code_object/attr.rb +150 -148
  8. data/lib/rdoc/code_object/class_module.rb +798 -792
  9. data/lib/rdoc/code_object/constant.rb +175 -173
  10. data/lib/rdoc/code_object/context/section.rb +142 -138
  11. data/lib/rdoc/code_object/context.rb +926 -958
  12. data/lib/rdoc/code_object/extend.rb +7 -5
  13. data/lib/rdoc/code_object/include.rb +7 -5
  14. data/lib/rdoc/code_object/method_attr.rb +326 -319
  15. data/lib/rdoc/code_object/mixin.rb +97 -95
  16. data/lib/rdoc/code_object/normal_class.rb +77 -78
  17. data/lib/rdoc/code_object/normal_module.rb +61 -59
  18. data/lib/rdoc/code_object/require.rb +23 -39
  19. data/lib/rdoc/code_object/single_class.rb +21 -19
  20. data/lib/rdoc/code_object/top_level.rb +212 -219
  21. data/lib/rdoc/code_object.rb +305 -303
  22. data/lib/rdoc/comment.rb +275 -273
  23. data/lib/rdoc/cross_reference.rb +192 -190
  24. data/lib/rdoc/encoding.rb +105 -103
  25. data/lib/rdoc/erb_partial.rb +13 -11
  26. data/lib/rdoc/erbio.rb +29 -27
  27. data/lib/rdoc/generator/aliki.rb +161 -153
  28. data/lib/rdoc/generator/darkfish.rb +645 -635
  29. data/lib/rdoc/generator/json_index.rb +233 -229
  30. data/lib/rdoc/generator/markup.rb +164 -146
  31. data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
  32. data/lib/rdoc/generator/pot/po.rb +52 -51
  33. data/lib/rdoc/generator/pot/po_entry.rb +138 -132
  34. data/lib/rdoc/generator/pot.rb +85 -81
  35. data/lib/rdoc/generator/ri.rb +23 -19
  36. data/lib/rdoc/generator/template/aliki/DESIGN.md +6 -4
  37. data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
  38. data/lib/rdoc/generator/template/aliki/_head.rhtml +10 -10
  39. data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
  40. data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
  41. data/lib/rdoc/generator/template/aliki/css/rdoc.css +207 -178
  42. data/lib/rdoc/generator/template/aliki/js/aliki.js +60 -84
  43. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
  44. data/lib/rdoc/generator.rb +48 -46
  45. data/lib/rdoc/i18n/locale.rb +99 -95
  46. data/lib/rdoc/i18n/text.rb +109 -105
  47. data/lib/rdoc/i18n.rb +7 -5
  48. data/lib/rdoc/markdown/byte_runtime.rb +80 -0
  49. data/lib/rdoc/markdown.kpeg +15 -11
  50. data/lib/rdoc/markdown.rb +40 -47
  51. data/lib/rdoc/markup/block_quote.rb +12 -8
  52. data/lib/rdoc/markup/document.rb +127 -123
  53. data/lib/rdoc/markup/formatter.rb +219 -215
  54. data/lib/rdoc/markup/include.rb +33 -29
  55. data/lib/rdoc/markup/indented_paragraph.rb +37 -33
  56. data/lib/rdoc/markup/inline_parser.rb +281 -277
  57. data/lib/rdoc/markup/list.rb +80 -88
  58. data/lib/rdoc/markup/list_item.rb +73 -85
  59. data/lib/rdoc/markup/paragraph.rb +23 -19
  60. data/lib/rdoc/markup/parser.rb +501 -497
  61. data/lib/rdoc/markup/pre_process.rb +283 -279
  62. data/lib/rdoc/markup/raw.rb +2 -2
  63. data/lib/rdoc/markup/rule.rb +16 -12
  64. data/lib/rdoc/markup/to_ansi.rb +143 -139
  65. data/lib/rdoc/markup/to_bs.rb +72 -68
  66. data/lib/rdoc/markup/to_html.rb +594 -565
  67. data/lib/rdoc/markup/to_html_crossref.rb +234 -230
  68. data/lib/rdoc/markup/to_html_snippet.rb +232 -227
  69. data/lib/rdoc/markup/to_joined_paragraph.rb +36 -32
  70. data/lib/rdoc/markup/to_label.rb +63 -59
  71. data/lib/rdoc/markup/to_markdown.rb +212 -208
  72. data/lib/rdoc/markup/to_rdoc.rb +336 -332
  73. data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
  74. data/lib/rdoc/markup/to_test.rb +60 -56
  75. data/lib/rdoc/markup/to_tt_only.rb +84 -80
  76. data/lib/rdoc/markup/verbatim.rb +62 -58
  77. data/lib/rdoc/markup.rb +198 -196
  78. data/lib/rdoc/options.rb +1063 -1061
  79. data/lib/rdoc/parser/c.rb +1039 -1037
  80. data/lib/rdoc/parser/changelog.rb +319 -315
  81. data/lib/rdoc/parser/markdown.rb +17 -13
  82. data/lib/rdoc/parser/rbs.rb +239 -235
  83. data/lib/rdoc/parser/rd.rb +17 -13
  84. data/lib/rdoc/parser/ruby.rb +1245 -1124
  85. data/lib/rdoc/parser/ruby_colorizer.rb +263 -213
  86. data/lib/rdoc/parser/simple.rb +31 -27
  87. data/lib/rdoc/parser/text.rb +12 -8
  88. data/lib/rdoc/parser.rb +228 -220
  89. data/lib/rdoc/rbs_helper.rb +1 -1
  90. data/lib/rdoc/rd/inline.rb +57 -53
  91. data/lib/rdoc/rd.rb +90 -88
  92. data/lib/rdoc/rdoc.rb +500 -491
  93. data/lib/rdoc/ri/driver.rb +1140 -1135
  94. data/lib/rdoc/ri/formatter.rb +7 -3
  95. data/lib/rdoc/ri/paths.rb +140 -136
  96. data/lib/rdoc/ri/servlet.rb +354 -350
  97. data/lib/rdoc/ri/store.rb +4 -2
  98. data/lib/rdoc/ri/task.rb +55 -51
  99. data/lib/rdoc/ri.rb +14 -12
  100. data/lib/rdoc/rubygems_hook.rb +183 -181
  101. data/lib/rdoc/server.rb +349 -347
  102. data/lib/rdoc/stats/normal.rb +46 -42
  103. data/lib/rdoc/stats/quiet.rb +39 -35
  104. data/lib/rdoc/stats/verbose.rb +35 -31
  105. data/lib/rdoc/stats.rb +365 -363
  106. data/lib/rdoc/store.rb +888 -902
  107. data/lib/rdoc/task.rb +260 -256
  108. data/lib/rdoc/text.rb +135 -133
  109. data/lib/rdoc/token_stream.rb +101 -93
  110. data/lib/rdoc/tom_doc.rb +203 -201
  111. data/lib/rdoc/version.rb +1 -1
  112. metadata +4 -5
  113. data/lib/rdoc/markdown/literals.kpeg +0 -21
  114. data/lib/rdoc/markdown/literals.rb +0 -454
@@ -4,119 +4,121 @@ require 'optparse'
4
4
  require_relative '../../rdoc'
5
5
 
6
6
  require_relative 'formatter' # For RubyGems backwards compatibility
7
- # TODO: Fix weird documentation with `require_relative`
8
-
9
- ##
10
- # The RI driver implements the command-line ri tool.
11
- #
12
- # The driver supports:
13
- # * loading RI data from:
14
- # * Ruby's standard library
15
- # * RubyGems
16
- # * ~/.rdoc
17
- # * A user-supplied directory
18
- # * Paging output (uses RI_PAGER environment variable, PAGER environment
19
- # variable or the less, more and pager programs)
20
- # * Interactive mode with tab-completion
21
- # * Abbreviated names (ri Zl shows Zlib documentation)
22
- # * Colorized output
23
- # * Merging output from multiple RI data sources
24
-
25
- class RDoc::RI::Driver
26
-
27
- ##
28
- # Base Driver error class
29
-
30
- class Error < RDoc::RI::Error; end
31
-
32
- ##
33
- # Raised when a name isn't found in the ri data stores
34
-
35
- class NotFoundError < Error
36
-
37
- def initialize(klass, suggestion_proc = nil) # :nodoc:
38
- @klass = klass
39
- @suggestion_proc = suggestion_proc
40
- end
7
+ module RDoc
8
+ module RI
9
+ # TODO: Fix weird documentation with `require_relative`
41
10
 
42
11
  ##
43
- # Name that wasn't found
12
+ # The RI driver implements the command-line ri tool.
13
+ #
14
+ # The driver supports:
15
+ # * loading RI data from:
16
+ # * Ruby's standard library
17
+ # * RubyGems
18
+ # * ~/.rdoc
19
+ # * A user-supplied directory
20
+ # * Paging output (uses RI_PAGER environment variable, PAGER environment
21
+ # variable or the less, more and pager programs)
22
+ # * Interactive mode with tab-completion
23
+ # * Abbreviated names (ri Zl shows Zlib documentation)
24
+ # * Colorized output
25
+ # * Merging output from multiple RI data sources
26
+
27
+ class Driver
28
+
29
+ ##
30
+ # Base Driver error class
31
+
32
+ class Error < RI::Error; end
33
+
34
+ ##
35
+ # Raised when a name isn't found in the ri data stores
36
+
37
+ class NotFoundError < Error
38
+
39
+ def initialize(klass, suggestion_proc = nil) # :nodoc:
40
+ @klass = klass
41
+ @suggestion_proc = suggestion_proc
42
+ end
44
43
 
45
- def name
46
- @klass
47
- end
44
+ ##
45
+ # Name that wasn't found
48
46
 
49
- def message # :nodoc:
50
- str = "Nothing known about #{@klass}"
51
- suggestions = @suggestion_proc&.call
52
- if suggestions and !suggestions.empty?
53
- str += "\nDid you mean? #{suggestions.join("\n ")}"
47
+ def name
48
+ @klass
49
+ end
50
+
51
+ def message # :nodoc:
52
+ str = "Nothing known about #{@klass}"
53
+ suggestions = @suggestion_proc&.call
54
+ if suggestions and !suggestions.empty?
55
+ str += "\nDid you mean? #{suggestions.join("\n ")}"
56
+ end
57
+ str
58
+ end
54
59
  end
55
- str
56
- end
57
- end
58
60
 
59
- ##
60
- # Show all method documentation following a class or module
61
+ ##
62
+ # Show all method documentation following a class or module
61
63
 
62
- attr_accessor :show_all
64
+ attr_accessor :show_all
63
65
 
64
- ##
65
- # An RDoc::RI::Store for each entry in the RI path
66
+ ##
67
+ # An RDoc::RI::Store for each entry in the RI path
66
68
 
67
- attr_accessor :stores
69
+ attr_accessor :stores
68
70
 
69
- ##
70
- # Controls the user of the pager vs $stdout
71
+ ##
72
+ # Controls the user of the pager vs $stdout
71
73
 
72
- attr_accessor :use_stdout
74
+ attr_accessor :use_stdout
73
75
 
74
- ##
75
- # Default options for ri
76
+ ##
77
+ # Default options for ri
76
78
 
77
- def self.default_options
78
- options = {}
79
- options[:interactive] = false
80
- options[:profile] = false
81
- options[:show_all] = false
82
- options[:expand_refs] = true
83
- options[:use_stdout] = !$stdout.tty?
84
- options[:width] = 72
79
+ def self.default_options
80
+ options = {}
81
+ options[:interactive] = false
82
+ options[:profile] = false
83
+ options[:show_all] = false
84
+ options[:expand_refs] = true
85
+ options[:use_stdout] = !$stdout.tty?
86
+ options[:width] = 72
85
87
 
86
- # By default all standard paths are used.
87
- options[:use_system] = true
88
- options[:use_site] = true
89
- options[:use_home] = true
90
- options[:use_gems] = true
91
- options[:extra_doc_dirs] = []
88
+ # By default all standard paths are used.
89
+ options[:use_system] = true
90
+ options[:use_site] = true
91
+ options[:use_home] = true
92
+ options[:use_gems] = true
93
+ options[:extra_doc_dirs] = []
92
94
 
93
- return options
94
- end
95
+ return options
96
+ end
95
97
 
96
- ##
97
- # Dump +data_path+ using pp
98
+ ##
99
+ # Dump +data_path+ using pp
98
100
 
99
- def self.dump(data_path)
100
- require 'pp'
101
+ def self.dump(data_path)
102
+ require 'pp'
101
103
 
102
- File.open data_path, 'rb' do |io|
103
- pp Marshal.load(io.read)
104
- end
105
- end
104
+ File.open data_path, 'rb' do |io|
105
+ pp Marshal.load(io.read)
106
+ end
107
+ end
106
108
 
107
- ##
108
- # Parses +argv+ and returns a Hash of options
109
+ ##
110
+ # Parses +argv+ and returns a Hash of options
109
111
 
110
- def self.process_args(argv)
111
- options = default_options
112
+ def self.process_args(argv)
113
+ options = default_options
112
114
 
113
- opts = OptionParser.new do |opt|
114
- opt.program_name = File.basename $0
115
- opt.version = RDoc::VERSION
116
- opt.release = nil
117
- opt.summary_indent = ' ' * 4
115
+ opts = OptionParser.new do |opt|
116
+ opt.program_name = File.basename $0
117
+ opt.version = VERSION
118
+ opt.release = nil
119
+ opt.summary_indent = ' ' * 4
118
120
 
119
- opt.banner = <<-EOT
121
+ opt.banner = <<-EOT
120
122
  Usage: #{opt.program_name} [options] [name ...]
121
123
 
122
124
  Where name can be:
@@ -172,1401 +174,1404 @@ The ri pager can be set with the RI_PAGER environment variable
172
174
  or the PAGER environment variable.
173
175
  EOT
174
176
 
175
- opt.separator nil
176
- opt.separator "Options:"
177
+ opt.separator nil
178
+ opt.separator "Options:"
177
179
 
178
- opt.separator nil
180
+ opt.separator nil
179
181
 
180
- opt.on("--[no-]interactive", "-i",
181
- "In interactive mode you can repeatedly",
182
- "look up methods with autocomplete.") do |interactive|
183
- options[:interactive] = interactive
184
- end
182
+ opt.on("--[no-]interactive", "-i",
183
+ "In interactive mode you can repeatedly",
184
+ "look up methods with autocomplete.") do |interactive|
185
+ options[:interactive] = interactive
186
+ end
185
187
 
186
- opt.separator nil
188
+ opt.separator nil
187
189
 
188
- opt.on("--[no-]all", "-a",
189
- "Show all documentation for a class or",
190
- "module.") do |show_all|
191
- options[:show_all] = show_all
192
- end
190
+ opt.on("--[no-]all", "-a",
191
+ "Show all documentation for a class or",
192
+ "module.") do |show_all|
193
+ options[:show_all] = show_all
194
+ end
193
195
 
194
- opt.separator nil
196
+ opt.separator nil
195
197
 
196
- opt.on("--[no-]list", "-l",
197
- "List classes ri knows about.") do |list|
198
- options[:list] = list
199
- end
198
+ opt.on("--[no-]list", "-l",
199
+ "List classes ri knows about.") do |list|
200
+ options[:list] = list
201
+ end
200
202
 
201
- opt.separator nil
203
+ opt.separator nil
202
204
 
203
- opt.on("--[no-]pager",
204
- "Send output to a pager,",
205
- "rather than directly to stdout.") do |use_pager|
206
- options[:use_stdout] = !use_pager
207
- end
205
+ opt.on("--[no-]pager",
206
+ "Send output to a pager,",
207
+ "rather than directly to stdout.") do |use_pager|
208
+ options[:use_stdout] = !use_pager
209
+ end
208
210
 
209
- opt.separator nil
211
+ opt.separator nil
210
212
 
211
- opt.on("-T",
212
- "Synonym for --no-pager.") do
213
- options[:use_stdout] = true
214
- end
213
+ opt.on("-T",
214
+ "Synonym for --no-pager.") do
215
+ options[:use_stdout] = true
216
+ end
215
217
 
216
- opt.separator nil
218
+ opt.separator nil
217
219
 
218
- opt.on("--width=WIDTH", "-w", OptionParser::DecimalInteger,
219
- "Set the width of the output.") do |width|
220
- options[:width] = width
221
- end
220
+ opt.on("--width=WIDTH", "-w", OptionParser::DecimalInteger,
221
+ "Set the width of the output.") do |width|
222
+ options[:width] = width
223
+ end
222
224
 
223
- opt.separator nil
225
+ opt.separator nil
224
226
 
225
- opt.on("--server[=PORT]", Integer,
226
- "Run RDoc server on the given port.",
227
- "The default port is 8214.") do |port|
228
- options[:server] = port || 8214
229
- end
227
+ opt.on("--server[=PORT]", Integer,
228
+ "Run RDoc server on the given port.",
229
+ "The default port is 8214.") do |port|
230
+ options[:server] = port || 8214
231
+ end
230
232
 
231
- opt.separator nil
233
+ opt.separator nil
232
234
 
233
- formatters = RDoc::Markup.constants.grep(/^To[A-Z][a-z]+$/).sort
234
- formatters = formatters.sort.map do |formatter|
235
- formatter.to_s.sub('To', '').downcase
236
- end
237
- formatters -= %w[html label test] # remove useless output formats
238
-
239
- opt.on("--format=NAME", "-f",
240
- "Use the selected formatter. The default",
241
- "formatter is bs for paged output and ansi",
242
- "otherwise. Valid formatters are:",
243
- "#{formatters.join(', ')}.", formatters) do |value|
244
- options[:formatter] = RDoc::Markup.const_get "To#{value.capitalize}"
245
- end
235
+ formatters = Markup.constants.grep(/^To[A-Z][a-z]+$/).sort
236
+ formatters = formatters.sort.map do |formatter|
237
+ formatter.to_s.sub('To', '').downcase
238
+ end
239
+ formatters -= %w[html label test] # remove useless output formats
240
+
241
+ opt.on("--format=NAME", "-f",
242
+ "Use the selected formatter. The default",
243
+ "formatter is bs for paged output and ansi",
244
+ "otherwise. Valid formatters are:",
245
+ "#{formatters.join(', ')}.", formatters) do |value|
246
+ options[:formatter] = Markup.const_get "To#{value.capitalize}"
247
+ end
246
248
 
247
- opt.separator nil
249
+ opt.separator nil
248
250
 
249
- opt.on("--[no-]expand-refs", "Expand rdoc-refs at the end of output") do |value|
250
- options[:expand_refs] = value
251
- end
251
+ opt.on("--[no-]expand-refs", "Expand rdoc-refs at the end of output") do |value|
252
+ options[:expand_refs] = value
253
+ end
252
254
 
253
- opt.separator nil
255
+ opt.separator nil
254
256
 
255
- opt.on("--help", "-h",
256
- "Show help and exit.") do
257
- puts opts
258
- exit
259
- end
257
+ opt.on("--help", "-h",
258
+ "Show help and exit.") do
259
+ puts opts
260
+ exit
261
+ end
260
262
 
261
- opt.separator nil
263
+ opt.separator nil
262
264
 
263
- opt.on("--version", "-v",
264
- "Output version information and exit.") do
265
- puts "#{opts.program_name} #{opts.version}"
266
- exit
267
- end
265
+ opt.on("--version", "-v",
266
+ "Output version information and exit.") do
267
+ puts "#{opts.program_name} #{opts.version}"
268
+ exit
269
+ end
268
270
 
269
- opt.separator nil
270
- opt.separator "Data source options:"
271
- opt.separator nil
271
+ opt.separator nil
272
+ opt.separator "Data source options:"
273
+ opt.separator nil
272
274
 
273
- opt.on("--[no-]list-doc-dirs",
274
- "List the directories from which ri will",
275
- "source documentation on stdout and exit.") do |list_doc_dirs|
276
- options[:list_doc_dirs] = list_doc_dirs
277
- end
275
+ opt.on("--[no-]list-doc-dirs",
276
+ "List the directories from which ri will",
277
+ "source documentation on stdout and exit.") do |list_doc_dirs|
278
+ options[:list_doc_dirs] = list_doc_dirs
279
+ end
278
280
 
279
- opt.separator nil
281
+ opt.separator nil
280
282
 
281
- opt.on("--doc-dir=DIRNAME", "-d", Array,
282
- "List of directories from which to source",
283
- "documentation in addition to the standard",
284
- "directories. May be repeated.") do |value|
285
- value.each do |dir|
286
- unless File.directory? dir then
287
- raise OptionParser::InvalidArgument, "#{dir} is not a directory"
283
+ opt.on("--doc-dir=DIRNAME", "-d", Array,
284
+ "List of directories from which to source",
285
+ "documentation in addition to the standard",
286
+ "directories. May be repeated.") do |value|
287
+ value.each do |dir|
288
+ unless File.directory? dir
289
+ raise OptionParser::InvalidArgument, "#{dir} is not a directory"
290
+ end
291
+
292
+ options[:extra_doc_dirs] << File.expand_path(dir)
293
+ end
288
294
  end
289
295
 
290
- options[:extra_doc_dirs] << File.expand_path(dir)
291
- end
292
- end
296
+ opt.separator nil
297
+
298
+ opt.on("--no-standard-docs",
299
+ "Do not include documentation from",
300
+ "the Ruby standard library, site_lib,",
301
+ "installed gems, or ~/.rdoc.",
302
+ "Use with --doc-dir.") do
303
+ options[:use_system] = false
304
+ options[:use_site] = false
305
+ options[:use_gems] = false
306
+ options[:use_home] = false
307
+ end
293
308
 
294
- opt.separator nil
295
-
296
- opt.on("--no-standard-docs",
297
- "Do not include documentation from",
298
- "the Ruby standard library, site_lib,",
299
- "installed gems, or ~/.rdoc.",
300
- "Use with --doc-dir.") do
301
- options[:use_system] = false
302
- options[:use_site] = false
303
- options[:use_gems] = false
304
- options[:use_home] = false
305
- end
309
+ opt.separator nil
306
310
 
307
- opt.separator nil
311
+ opt.on("--[no-]system",
312
+ "Include documentation from Ruby's",
313
+ "standard library. Defaults to true.") do |value|
314
+ options[:use_system] = value
315
+ end
308
316
 
309
- opt.on("--[no-]system",
310
- "Include documentation from Ruby's",
311
- "standard library. Defaults to true.") do |value|
312
- options[:use_system] = value
313
- end
317
+ opt.separator nil
314
318
 
315
- opt.separator nil
319
+ opt.on("--[no-]site",
320
+ "Include documentation from libraries",
321
+ "installed in site_lib.",
322
+ "Defaults to true.") do |value|
323
+ options[:use_site] = value
324
+ end
316
325
 
317
- opt.on("--[no-]site",
318
- "Include documentation from libraries",
319
- "installed in site_lib.",
320
- "Defaults to true.") do |value|
321
- options[:use_site] = value
322
- end
326
+ opt.separator nil
323
327
 
324
- opt.separator nil
328
+ opt.on("--[no-]gems",
329
+ "Include documentation from RubyGems.",
330
+ "Defaults to true.") do |value|
331
+ options[:use_gems] = value
332
+ end
325
333
 
326
- opt.on("--[no-]gems",
327
- "Include documentation from RubyGems.",
328
- "Defaults to true.") do |value|
329
- options[:use_gems] = value
330
- end
334
+ opt.separator nil
331
335
 
332
- opt.separator nil
336
+ opt.on("--[no-]home",
337
+ "Include documentation stored in ~/.rdoc.",
338
+ "Defaults to true.") do |value|
339
+ options[:use_home] = value
340
+ end
333
341
 
334
- opt.on("--[no-]home",
335
- "Include documentation stored in ~/.rdoc.",
336
- "Defaults to true.") do |value|
337
- options[:use_home] = value
338
- end
342
+ opt.separator nil
343
+ opt.separator "Debug options:"
344
+ opt.separator nil
339
345
 
340
- opt.separator nil
341
- opt.separator "Debug options:"
342
- opt.separator nil
346
+ opt.on("--[no-]profile",
347
+ "Run with the ruby profiler.") do |value|
348
+ options[:profile] = value
349
+ end
343
350
 
344
- opt.on("--[no-]profile",
345
- "Run with the ruby profiler.") do |value|
346
- options[:profile] = value
347
- end
351
+ opt.separator nil
348
352
 
349
- opt.separator nil
353
+ opt.on("--dump=CACHE",
354
+ "Dump data from an ri cache or data file.") do |value|
355
+ unless File.readable?(value)
356
+ abort "#{value.inspect} is not readable"
357
+ end
350
358
 
351
- opt.on("--dump=CACHE",
352
- "Dump data from an ri cache or data file.") do |value|
353
- unless File.readable?(value)
354
- abort "#{value.inspect} is not readable"
355
- end
359
+ if File.directory?(value)
360
+ abort "#{value.inspect} is a directory"
361
+ end
356
362
 
357
- if File.directory?(value)
358
- abort "#{value.inspect} is a directory"
363
+ options[:dump_path] = File.new(value)
364
+ end
359
365
  end
360
366
 
361
- options[:dump_path] = File.new(value)
362
- end
363
- end
364
-
365
- argv = ENV['RI'].to_s.split(' ').concat argv
367
+ argv = ENV['RI'].to_s.split(' ').concat argv
366
368
 
367
- opts.parse! argv
369
+ opts.parse! argv
368
370
 
369
- options[:names] = argv
371
+ options[:names] = argv
370
372
 
371
- options[:use_stdout] ||= !$stdout.tty?
372
- options[:use_stdout] ||= options[:interactive]
373
- options[:width] ||= 72
373
+ options[:use_stdout] ||= !$stdout.tty?
374
+ options[:use_stdout] ||= options[:interactive]
375
+ options[:width] ||= 72
374
376
 
375
- options
377
+ options
376
378
 
377
- rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e
378
- puts opts
379
- puts
380
- puts e
381
- exit 1
382
- end
379
+ rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e
380
+ puts opts
381
+ puts
382
+ puts e
383
+ exit 1
384
+ end
383
385
 
384
- ##
385
- # Runs the ri command line executable using +argv+
386
+ ##
387
+ # Runs the ri command line executable using +argv+
386
388
 
387
- def self.run(argv = ARGV)
388
- options = process_args argv
389
+ def self.run(argv = ARGV)
390
+ options = process_args argv
389
391
 
390
- if options[:dump_path] then
391
- dump options[:dump_path]
392
- return
393
- end
392
+ if options[:dump_path]
393
+ dump options[:dump_path]
394
+ return
395
+ end
394
396
 
395
- ri = new options
396
- ri.run
397
- end
397
+ ri = new options
398
+ ri.run
399
+ end
398
400
 
399
- ##
400
- # Creates a new driver using +initial_options+ from ::process_args
401
+ ##
402
+ # Creates a new driver using +initial_options+ from ::process_args
401
403
 
402
- def initialize(initial_options = {})
403
- @paging = false
404
- @classes = nil
404
+ def initialize(initial_options = {})
405
+ @paging = false
406
+ @classes = nil
405
407
 
406
- options = self.class.default_options.update(initial_options)
408
+ options = self.class.default_options.update(initial_options)
407
409
 
408
- @formatter_klass = options[:formatter]
410
+ @formatter_klass = options[:formatter]
409
411
 
410
- require 'profile' if options[:profile]
412
+ require 'profile' if options[:profile]
411
413
 
412
- @names = options[:names]
413
- @list = options[:list]
414
+ @names = options[:names]
415
+ @list = options[:list]
414
416
 
415
- @doc_dirs = []
416
- @stores = []
417
+ @doc_dirs = []
418
+ @stores = []
417
419
 
418
- RDoc::RI::Paths.each(options[:use_system], options[:use_site],
419
- options[:use_home], options[:use_gems],
420
- *options[:extra_doc_dirs]) do |path, type|
421
- @doc_dirs << path
420
+ RI::Paths.each(options[:use_system], options[:use_site],
421
+ options[:use_home], options[:use_gems],
422
+ *options[:extra_doc_dirs]) do |path, type|
423
+ @doc_dirs << path
422
424
 
423
- store = RDoc::RI::Store.new(RDoc::Options.new, path: path, type: type)
424
- store.load_cache
425
- @stores << store
426
- end
425
+ store = RI::Store.new(Options.new, path: path, type: type)
426
+ store.load_cache
427
+ @stores << store
428
+ end
427
429
 
428
- @list_doc_dirs = options[:list_doc_dirs]
430
+ @list_doc_dirs = options[:list_doc_dirs]
429
431
 
430
- @interactive = options[:interactive]
431
- @server = options[:server]
432
- @use_stdout = options[:use_stdout]
433
- @show_all = options[:show_all]
434
- @width = options[:width]
435
- @expand_refs = options[:expand_refs]
436
- end
432
+ @interactive = options[:interactive]
433
+ @server = options[:server]
434
+ @use_stdout = options[:use_stdout]
435
+ @show_all = options[:show_all]
436
+ @width = options[:width]
437
+ @expand_refs = options[:expand_refs]
438
+ end
437
439
 
438
- ##
439
- # Adds paths for undocumented classes +also_in+ to +out+
440
+ ##
441
+ # Adds paths for undocumented classes +also_in+ to +out+
440
442
 
441
- def add_also_in(out, also_in)
442
- return if also_in.empty?
443
+ def add_also_in(out, also_in)
444
+ return if also_in.empty?
443
445
 
444
- out << RDoc::Markup::Rule.new(1)
445
- out << RDoc::Markup::Paragraph.new("Also found in:")
446
+ out << Markup::Rule.new(1)
447
+ out << Markup::Paragraph.new("Also found in:")
446
448
 
447
- paths = RDoc::Markup::Verbatim.new
448
- also_in.each do |store|
449
- paths.parts.push store.friendly_path, "\n"
450
- end
451
- out << paths
452
- end
449
+ paths = Markup::Verbatim.new
450
+ also_in.each do |store|
451
+ paths.parts.push store.friendly_path, "\n"
452
+ end
453
+ out << paths
454
+ end
453
455
 
454
- ##
455
- # Adds a class header to +out+ for class +name+ which is described in
456
- # +classes+.
456
+ ##
457
+ # Adds a class header to +out+ for class +name+ which is described in
458
+ # +classes+.
457
459
 
458
- def add_class(out, name, classes)
459
- heading = if classes.all? { |klass| klass.module? } then
460
- name
461
- else
462
- superclass = classes.map do |klass|
463
- klass.superclass unless klass.module?
464
- end.compact.shift || 'Object'
460
+ def add_class(out, name, classes)
461
+ heading = if classes.all? { |klass| klass.module? }
462
+ name
463
+ else
464
+ superclass = classes.map do |klass|
465
+ klass.superclass unless klass.module?
466
+ end.compact.shift || 'Object'
465
467
 
466
- superclass = superclass.full_name unless String === superclass
468
+ superclass = superclass.full_name unless String === superclass
467
469
 
468
- "#{name} < #{superclass}"
469
- end
470
+ "#{name} < #{superclass}"
471
+ end
470
472
 
471
- out << RDoc::Markup::Heading.new(1, heading)
472
- out << RDoc::Markup::BlankLine.new
473
- end
473
+ out << Markup::Heading.new(1, heading)
474
+ out << Markup::BlankLine.new
475
+ end
474
476
 
475
- ##
476
- # Adds "(from ...)" to +out+ for +store+
477
+ ##
478
+ # Adds "(from ...)" to +out+ for +store+
477
479
 
478
- def add_from(out, store)
479
- out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})")
480
- end
480
+ def add_from(out, store)
481
+ out << Markup::Paragraph.new("(from #{store.friendly_path})")
482
+ end
481
483
 
482
- ##
483
- # Adds +extends+ to +out+
484
+ ##
485
+ # Adds +extends+ to +out+
484
486
 
485
- def add_extends(out, extends)
486
- add_extension_modules out, 'Extended by', extends
487
- end
487
+ def add_extends(out, extends)
488
+ add_extension_modules out, 'Extended by', extends
489
+ end
488
490
 
489
- ##
490
- # Adds a list of +extensions+ to this module of the given +type+ to +out+.
491
- # add_includes and add_extends call this, so you should use those directly.
491
+ ##
492
+ # Adds a list of +extensions+ to this module of the given +type+ to +out+.
493
+ # add_includes and add_extends call this, so you should use those directly.
492
494
 
493
- def add_extension_modules(out, type, extensions)
494
- return if extensions.empty?
495
+ def add_extension_modules(out, type, extensions)
496
+ return if extensions.empty?
495
497
 
496
- out << RDoc::Markup::Rule.new(1)
497
- out << RDoc::Markup::Heading.new(1, "#{type}:")
498
+ out << Markup::Rule.new(1)
499
+ out << Markup::Heading.new(1, "#{type}:")
498
500
 
499
- extensions.each do |modules, store|
500
- if modules.length == 1 then
501
- add_extension_modules_single out, store, modules.first
502
- else
503
- add_extension_modules_multiple out, store, modules
501
+ extensions.each do |modules, store|
502
+ if modules.length == 1
503
+ add_extension_modules_single out, store, modules.first
504
+ else
505
+ add_extension_modules_multiple out, store, modules
506
+ end
507
+ end
504
508
  end
505
- end
506
- end
507
509
 
508
- ##
509
- # Renders multiple included +modules+ from +store+ to +out+.
510
+ ##
511
+ # Renders multiple included +modules+ from +store+ to +out+.
510
512
 
511
- def add_extension_modules_multiple(out, store, modules) # :nodoc:
512
- out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})")
513
+ def add_extension_modules_multiple(out, store, modules) # :nodoc:
514
+ out << Markup::Paragraph.new("(from #{store.friendly_path})")
513
515
 
514
- wout, with = modules.partition { |incl| incl.comment.empty? }
516
+ wout, with = modules.partition { |incl| incl.comment.empty? }
515
517
 
516
- out << RDoc::Markup::BlankLine.new unless with.empty?
518
+ out << Markup::BlankLine.new unless with.empty?
517
519
 
518
- with.each do |incl|
519
- out << RDoc::Markup::Paragraph.new(incl.name)
520
- out << RDoc::Markup::BlankLine.new
521
- out << incl.comment.parse
522
- end
520
+ with.each do |incl|
521
+ out << Markup::Paragraph.new(incl.name)
522
+ out << Markup::BlankLine.new
523
+ out << incl.comment.parse
524
+ end
523
525
 
524
- unless wout.empty? then
525
- verb = RDoc::Markup::Verbatim.new
526
+ unless wout.empty?
527
+ verb = Markup::Verbatim.new
526
528
 
527
- wout.each do |incl|
528
- verb.push incl.name, "\n"
529
- end
529
+ wout.each do |incl|
530
+ verb.push incl.name, "\n"
531
+ end
530
532
 
531
- out << verb
532
- end
533
- end
533
+ out << verb
534
+ end
535
+ end
534
536
 
535
- ##
536
- # Adds a single extension module +include+ from +store+ to +out+
537
+ ##
538
+ # Adds a single extension module +include+ from +store+ to +out+
537
539
 
538
- def add_extension_modules_single(out, store, include) # :nodoc:
539
- name = include.name
540
- path = store.friendly_path
541
- out << RDoc::Markup::Paragraph.new("#{name} (from #{path})")
540
+ def add_extension_modules_single(out, store, include) # :nodoc:
541
+ name = include.name
542
+ path = store.friendly_path
543
+ out << Markup::Paragraph.new("#{name} (from #{path})")
542
544
 
543
- if include.comment then
544
- out << RDoc::Markup::BlankLine.new
545
- out << include.comment.parse
546
- end
547
- end
545
+ if include.comment
546
+ out << Markup::BlankLine.new
547
+ out << include.comment.parse
548
+ end
549
+ end
548
550
 
549
- ##
550
- # Adds +includes+ to +out+
551
+ ##
552
+ # Adds +includes+ to +out+
551
553
 
552
- def add_includes(out, includes)
553
- add_extension_modules out, 'Includes', includes
554
- end
554
+ def add_includes(out, includes)
555
+ add_extension_modules out, 'Includes', includes
556
+ end
555
557
 
556
- ##
557
- # Looks up the method +name+ and adds it to +out+
558
+ ##
559
+ # Looks up the method +name+ and adds it to +out+
558
560
 
559
- def add_method(out, name)
560
- filtered = lookup_method name
561
- method_document out, name, filtered
562
- end
561
+ def add_method(out, name)
562
+ filtered = lookup_method name
563
+ method_document out, name, filtered
564
+ end
563
565
 
564
- ##
565
- # Adds documentation for all methods in +klass+ to +out+
566
+ ##
567
+ # Adds documentation for all methods in +klass+ to +out+
566
568
 
567
- def add_method_documentation(out, klass)
568
- klass.method_list.each do |method|
569
- begin
570
- add_method out, method.full_name
571
- rescue NotFoundError
572
- next
569
+ def add_method_documentation(out, klass)
570
+ klass.method_list.each do |method|
571
+ begin
572
+ add_method out, method.full_name
573
+ rescue NotFoundError
574
+ next
575
+ end
576
+ end
573
577
  end
574
- end
575
- end
576
578
 
577
- ##
578
- # Adds a list of +methods+ to +out+ with a heading of +name+
579
+ ##
580
+ # Adds a list of +methods+ to +out+ with a heading of +name+
579
581
 
580
- def add_method_list(out, methods, name)
581
- return if methods.empty?
582
+ def add_method_list(out, methods, name)
583
+ return if methods.empty?
582
584
 
583
- out << RDoc::Markup::Heading.new(1, "#{name}:")
584
- out << RDoc::Markup::BlankLine.new
585
+ out << Markup::Heading.new(1, "#{name}:")
586
+ out << Markup::BlankLine.new
585
587
 
586
- if @use_stdout and !@interactive then
587
- out.concat methods.map { |method|
588
- RDoc::Markup::Verbatim.new method
589
- }
590
- else
591
- out << RDoc::Markup::IndentedParagraph.new(2, methods.join(', '))
592
- end
588
+ if @use_stdout and !@interactive
589
+ out.concat methods.map { |method|
590
+ Markup::Verbatim.new method
591
+ }
592
+ else
593
+ out << Markup::IndentedParagraph.new(2, methods.join(', '))
594
+ end
593
595
 
594
- out << RDoc::Markup::BlankLine.new
595
- end
596
+ out << Markup::BlankLine.new
597
+ end
596
598
 
597
- ##
598
- # Returns ancestor classes of +klass+
599
+ ##
600
+ # Returns ancestor classes of +klass+
599
601
 
600
- def ancestors_of(klass)
601
- ancestors = []
602
+ def ancestors_of(klass)
603
+ ancestors = []
602
604
 
603
- unexamined = [klass]
604
- seen = []
605
+ unexamined = [klass]
606
+ seen = []
605
607
 
606
- loop do
607
- break if unexamined.empty?
608
- current = unexamined.shift
609
- seen << current
608
+ loop do
609
+ break if unexamined.empty?
610
+ current = unexamined.shift
611
+ seen << current
610
612
 
611
- stores = classes[current]
613
+ stores = classes[current]
612
614
 
613
- next unless stores and not stores.empty?
615
+ next unless stores and not stores.empty?
614
616
 
615
- klasses = stores.flat_map do |store|
616
- store.ancestors[current] || []
617
- end.uniq
617
+ klasses = stores.flat_map do |store|
618
+ store.ancestors[current] || []
619
+ end.uniq
618
620
 
619
- klasses = klasses - seen
621
+ klasses = klasses - seen
620
622
 
621
- ancestors.concat klasses
622
- unexamined.concat klasses
623
- end
623
+ ancestors.concat klasses
624
+ unexamined.concat klasses
625
+ end
624
626
 
625
- ancestors.reverse
626
- end
627
+ ancestors.reverse
628
+ end
627
629
 
628
- ##
629
- # For RubyGems backwards compatibility
630
+ ##
631
+ # For RubyGems backwards compatibility
630
632
 
631
- def class_cache # :nodoc:
632
- end
633
+ def class_cache # :nodoc:
634
+ end
633
635
 
634
- ##
635
- # Builds a RDoc::Markup::Document from +found+, +klasess+ and +includes+
636
+ ##
637
+ # Builds a RDoc::Markup::Document from +found+, +klasess+ and +includes+
636
638
 
637
- def class_document(name, found, klasses, includes, extends)
638
- also_in = []
639
+ def class_document(name, found, klasses, includes, extends)
640
+ also_in = []
639
641
 
640
- out = RDoc::Markup::Document.new
642
+ out = Markup::Document.new
641
643
 
642
- add_class out, name, klasses
644
+ add_class out, name, klasses
643
645
 
644
- add_includes out, includes
645
- add_extends out, extends
646
+ add_includes out, includes
647
+ add_extends out, extends
646
648
 
647
- found.each do |store, klass|
648
- render_class out, store, klass, also_in
649
- end
649
+ found.each do |store, klass|
650
+ render_class out, store, klass, also_in
651
+ end
650
652
 
651
- add_also_in out, also_in
653
+ add_also_in out, also_in
652
654
 
653
- expand_rdoc_refs_at_the_bottom(out)
654
- out
655
- end
655
+ expand_rdoc_refs_at_the_bottom(out)
656
+ out
657
+ end
656
658
 
657
- ##
658
- # Adds the class +comment+ to +out+.
659
+ ##
660
+ # Adds the class +comment+ to +out+.
659
661
 
660
- def class_document_comment(out, document) # :nodoc:
661
- unless document.empty? then
662
- out << RDoc::Markup::Rule.new(1)
662
+ def class_document_comment(out, document) # :nodoc:
663
+ unless document.empty?
664
+ out << Markup::Rule.new(1)
663
665
 
664
- if document.merged? then
665
- parts = document.parts
666
- parts = parts.zip [RDoc::Markup::BlankLine.new] * parts.length
667
- parts.flatten!
668
- parts.pop
666
+ if document.merged?
667
+ parts = document.parts
668
+ parts = parts.zip [Markup::BlankLine.new] * parts.length
669
+ parts.flatten!
670
+ parts.pop
669
671
 
670
- out.concat parts
671
- else
672
- out << comment
672
+ out.concat parts
673
+ else
674
+ out << comment
675
+ end
676
+ end
673
677
  end
674
- end
675
- end
676
678
 
677
- ##
678
- # Adds the constants from +klass+ to the Document +out+.
679
+ ##
680
+ # Adds the constants from +klass+ to the Document +out+.
679
681
 
680
- def class_document_constants(out, klass) # :nodoc:
681
- return if klass.constants.empty?
682
+ def class_document_constants(out, klass) # :nodoc:
683
+ return if klass.constants.empty?
682
684
 
683
- out << RDoc::Markup::Heading.new(1, "Constants:")
684
- out << RDoc::Markup::BlankLine.new
685
- list = RDoc::Markup::List.new :NOTE
685
+ out << Markup::Heading.new(1, "Constants:")
686
+ out << Markup::BlankLine.new
687
+ list = Markup::List.new :NOTE
686
688
 
687
- constants = klass.constants.sort_by { |constant| constant.name }
689
+ constants = klass.constants.sort_by { |constant| constant.name }
688
690
 
689
- list.items.concat constants.map { |constant|
690
- parts = constant.comment.parse.parts
691
- parts << RDoc::Markup::Paragraph.new('[not documented]') if
692
- parts.empty?
691
+ list.items.concat constants.map { |constant|
692
+ parts = constant.comment.parse.parts
693
+ parts << Markup::Paragraph.new('[not documented]') if
694
+ parts.empty?
693
695
 
694
- RDoc::Markup::ListItem.new(constant.name, *parts)
695
- }
696
+ Markup::ListItem.new(constant.name, *parts)
697
+ }
696
698
 
697
- out << list
698
- out << RDoc::Markup::BlankLine.new
699
- end
699
+ out << list
700
+ out << Markup::BlankLine.new
701
+ end
700
702
 
701
- ##
702
- # Hash mapping a known class or module to the stores it can be loaded from
703
+ ##
704
+ # Hash mapping a known class or module to the stores it can be loaded from
703
705
 
704
- def classes
705
- return @classes if @classes
706
+ def classes
707
+ return @classes if @classes
706
708
 
707
- @classes = {}
709
+ @classes = {}
708
710
 
709
- @stores.each do |store|
710
- store.cache[:modules].each do |mod|
711
- # using default block causes searched-for modules to be added
712
- @classes[mod] ||= []
713
- @classes[mod] << store
714
- end
715
- end
716
-
717
- @classes
718
- end
711
+ @stores.each do |store|
712
+ store.cache[:modules].each do |mod|
713
+ # using default block causes searched-for modules to be added
714
+ @classes[mod] ||= []
715
+ @classes[mod] << store
716
+ end
717
+ end
719
718
 
720
- ##
721
- # Returns the stores wherein +name+ is found along with the classes,
722
- # extends and includes that match it
723
-
724
- def classes_and_includes_and_extends_for(name)
725
- klasses = []
726
- extends = []
727
- includes = []
728
-
729
- found = @stores.map do |store|
730
- begin
731
- klass = store.load_class name
732
- klasses << klass
733
- extends << [klass.extends, store] if klass.extends
734
- includes << [klass.includes, store] if klass.includes
735
- [store, klass]
736
- rescue RDoc::Store::MissingFileError
719
+ @classes
737
720
  end
738
- end.compact
739
721
 
740
- extends.reject! do |modules,| modules.empty? end
741
- includes.reject! do |modules,| modules.empty? end
722
+ ##
723
+ # Returns the stores wherein +name+ is found along with the classes,
724
+ # extends and includes that match it
725
+
726
+ def classes_and_includes_and_extends_for(name)
727
+ klasses = []
728
+ extends = []
729
+ includes = []
730
+
731
+ found = @stores.map do |store|
732
+ begin
733
+ klass = store.load_class name
734
+ klasses << klass
735
+ extends << [klass.extends, store] if klass.extends
736
+ includes << [klass.includes, store] if klass.includes
737
+ [store, klass]
738
+ rescue ::RDoc::Store::MissingFileError
739
+ end
740
+ end.compact
742
741
 
743
- [found, klasses, includes, extends]
744
- end
742
+ extends.reject! do |modules,| modules.empty? end
743
+ includes.reject! do |modules,| modules.empty? end
745
744
 
746
- ##
747
- # Completes +name+ based on the caches. For Readline
745
+ [found, klasses, includes, extends]
746
+ end
748
747
 
749
- def complete(name)
750
- completions = []
748
+ ##
749
+ # Completes +name+ based on the caches. For Readline
751
750
 
752
- klass, selector, method = parse_name name
751
+ def complete(name)
752
+ completions = []
753
753
 
754
- complete_klass name, klass, selector, method, completions
755
- complete_method name, klass, selector, completions
754
+ klass, selector, method = parse_name name
756
755
 
757
- completions.uniq.select {|s| s.start_with? name }.sort
758
- end
756
+ complete_klass name, klass, selector, method, completions
757
+ complete_method name, klass, selector, completions
759
758
 
760
- def complete_klass(name, klass, selector, method, completions) # :nodoc:
761
- klasses = classes.keys
759
+ completions.uniq.select {|s| s.start_with? name }.sort
760
+ end
762
761
 
763
- # may need to include Foo when given Foo::
764
- klass_name = method ? name : klass
762
+ def complete_klass(name, klass, selector, method, completions) # :nodoc:
763
+ klasses = classes.keys
765
764
 
766
- if name !~ /#|\./ then
767
- completions.replace klasses.grep(/^#{Regexp.escape klass_name}[^:]*$/)
768
- completions.concat klasses.grep(/^#{Regexp.escape name}[^:]*$/) if
769
- name =~ /::$/
765
+ # may need to include Foo when given Foo::
766
+ klass_name = method ? name : klass
770
767
 
771
- completions << klass if classes.key? klass # to complete a method name
772
- elsif selector then
773
- completions << klass if classes.key? klass
774
- elsif classes.key? klass_name then
775
- completions << klass_name
776
- end
777
- end
768
+ if name !~ /#|\./
769
+ completions.replace klasses.grep(/^#{Regexp.escape klass_name}[^:]*$/)
770
+ completions.concat klasses.grep(/^#{Regexp.escape name}[^:]*$/) if
771
+ name =~ /::$/
778
772
 
779
- def complete_method(name, klass, selector, completions) # :nodoc:
780
- if completions.include? klass and name =~ /#|\.|::/ then
781
- methods = list_methods_matching name
782
-
783
- if not methods.empty? then
784
- # remove Foo if given Foo:: and a method was found
785
- completions.delete klass
786
- elsif selector then
787
- # replace Foo with Foo:: as given
788
- completions.delete klass
789
- completions << "#{klass}#{selector}"
773
+ completions << klass if classes.key? klass # to complete a method name
774
+ elsif selector
775
+ completions << klass if classes.key? klass
776
+ elsif classes.key? klass_name
777
+ completions << klass_name
778
+ end
790
779
  end
791
780
 
792
- methods.each do |klass_sel_method|
793
- match = klass_sel_method.match(/^(.+)(#|\.|::)([^#.:]+)$/)
794
- # match[2] is `::` for class method and `#` for instance method.
795
- # To be consistent with old completion that completes `['Foo#i', 'Foo::c']` for `Foo.`,
796
- # `.` should be a wildcard for both `#` and `::` here.
797
- if match && match[2] == selector || selector == '.'
798
- completions << match[1] + selector + match[3]
781
+ def complete_method(name, klass, selector, completions) # :nodoc:
782
+ if completions.include? klass and name =~ /#|\.|::/
783
+ methods = list_methods_matching name
784
+
785
+ if not methods.empty?
786
+ # remove Foo if given Foo:: and a method was found
787
+ completions.delete klass
788
+ elsif selector
789
+ # replace Foo with Foo:: as given
790
+ completions.delete klass
791
+ completions << "#{klass}#{selector}"
792
+ end
793
+
794
+ methods.each do |klass_sel_method|
795
+ match = klass_sel_method.match(/^(.+)(#|\.|::)([^#.:]+)$/)
796
+ # match[2] is `::` for class method and `#` for instance method.
797
+ # To be consistent with old completion that completes `['Foo#i', 'Foo::c']` for `Foo.`,
798
+ # `.` should be a wildcard for both `#` and `::` here.
799
+ if match && match[2] == selector || selector == '.'
800
+ completions << match[1] + selector + match[3]
801
+ end
802
+ end
799
803
  end
800
804
  end
801
- end
802
- end
803
805
 
804
- ##
805
- # Converts +document+ to text and writes it to the pager
806
+ ##
807
+ # Converts +document+ to text and writes it to the pager
806
808
 
807
- def display(document)
808
- page do |io|
809
- f = formatter(io)
810
- f.width = @width if @width and f.respond_to?(:width)
811
- text = document.accept f
809
+ def display(document)
810
+ page do |io|
811
+ f = formatter(io)
812
+ f.width = @width if @width and f.respond_to?(:width)
813
+ text = document.accept f
812
814
 
813
- io.write text
814
- end
815
- end
815
+ io.write text
816
+ end
817
+ end
816
818
 
817
- ##
818
- # Outputs formatted RI data for class +name+. Groups undocumented classes
819
+ ##
820
+ # Outputs formatted RI data for class +name+. Groups undocumented classes
819
821
 
820
- def display_class(name)
821
- return if name =~ /#|\./
822
+ def display_class(name)
823
+ _klass, selector, _method = parse_name name
824
+ return if selector
822
825
 
823
- found, klasses, includes, extends =
824
- classes_and_includes_and_extends_for name
826
+ found, klasses, includes, extends =
827
+ classes_and_includes_and_extends_for name
825
828
 
826
- return if found.empty?
829
+ return if found.empty?
827
830
 
828
- out = class_document name, found, klasses, includes, extends
831
+ out = class_document name, found, klasses, includes, extends
829
832
 
830
- display out
831
- end
833
+ display out
834
+ end
832
835
 
833
- ##
834
- # Outputs formatted RI data for method +name+
836
+ ##
837
+ # Outputs formatted RI data for method +name+
835
838
 
836
- def display_method(name)
837
- out = RDoc::Markup::Document.new
839
+ def display_method(name)
840
+ out = Markup::Document.new
838
841
 
839
- add_method out, name
842
+ add_method out, name
840
843
 
841
- expand_rdoc_refs_at_the_bottom(out)
844
+ expand_rdoc_refs_at_the_bottom(out)
842
845
 
843
- display out
844
- end
846
+ display out
847
+ end
845
848
 
846
- ##
847
- # Outputs formatted RI data for the class or method +name+.
848
- #
849
- # Returns true if +name+ was found, false if it was not an alternative could
850
- # be guessed, raises an error if +name+ couldn't be guessed.
849
+ ##
850
+ # Outputs formatted RI data for the class or method +name+.
851
+ #
852
+ # Returns true if +name+ was found, false if it was not an alternative could
853
+ # be guessed, raises an error if +name+ couldn't be guessed.
851
854
 
852
- def display_name(name)
853
- if name =~ /\w:(\w|$)/ then
854
- display_page name
855
- return true
856
- end
855
+ def display_name(name)
856
+ if name =~ /\w:(\w|$)/
857
+ display_page name
858
+ return true
859
+ end
857
860
 
858
- return true if display_class name
861
+ return true if display_class name
859
862
 
860
- display_method name if name =~ /::|#|\./
863
+ display_method name if name =~ /::|#|\./
861
864
 
862
- true
863
- rescue NotFoundError
864
- matches = list_methods_matching name if name =~ /::|#|\./
865
- matches = classes.keys.grep(/^#{Regexp.escape name}/) if matches.empty?
865
+ true
866
+ rescue NotFoundError
867
+ matches = list_methods_matching name if name =~ /::|#|\./
868
+ matches = classes.keys.grep(/^#{Regexp.escape name}/) if matches.empty?
866
869
 
867
- raise if matches.empty?
870
+ raise if matches.empty?
868
871
 
869
- page do |io|
870
- io.puts "#{name} not found, maybe you meant:"
871
- io.puts
872
- io.puts matches.sort.join("\n")
873
- end
872
+ page do |io|
873
+ io.puts "#{name} not found, maybe you meant:"
874
+ io.puts
875
+ io.puts matches.sort.join("\n")
876
+ end
874
877
 
875
- false
876
- end
878
+ false
879
+ end
877
880
 
878
- ##
879
- # Displays each name in +name+
881
+ ##
882
+ # Displays each name in +name+
880
883
 
881
- def display_names(names)
882
- names.each do |name|
883
- name = expand_name name
884
+ def display_names(names)
885
+ names.each do |name|
886
+ name = expand_name name
884
887
 
885
- display_name name
886
- end
887
- end
888
+ display_name name
889
+ end
890
+ end
888
891
 
889
- ##
890
- # Outputs formatted RI data for page +name+.
892
+ ##
893
+ # Outputs formatted RI data for page +name+.
891
894
 
892
- def display_page(name)
893
- store_name, page_name = name.split ':', 2
895
+ def display_page(name)
896
+ store_name, page_name = name.split ':', 2
894
897
 
895
- store = @stores.find { |s| s.source == store_name }
898
+ store = @stores.find { |s| s.source == store_name }
896
899
 
897
- return display_page_list store if page_name.empty?
900
+ return display_page_list store if page_name.empty?
898
901
 
899
- pages = store.cache[:pages]
902
+ pages = store.cache[:pages]
900
903
 
901
- unless pages.include? page_name then
902
- found_names = pages.select do |n|
903
- n =~ /#{Regexp.escape page_name}\.[^.]+$/
904
- end
904
+ unless pages.include? page_name
905
+ found_names = pages.select do |n|
906
+ n =~ /#{Regexp.escape page_name}\.[^.]+$/
907
+ end
905
908
 
906
- if found_names.length.zero? then
907
- return display_page_list store, pages
908
- elsif found_names.length > 1 then
909
- return display_page_list store, found_names, page_name
910
- end
909
+ if found_names.length.zero?
910
+ return display_page_list store, pages
911
+ elsif found_names.length > 1
912
+ return display_page_list store, found_names, page_name
913
+ end
911
914
 
912
- page_name = found_names.first
913
- end
915
+ page_name = found_names.first
916
+ end
914
917
 
915
- page = store.load_page page_name
918
+ page = store.load_page page_name
916
919
 
917
- display page.comment.parse
918
- end
920
+ display page.comment.parse
921
+ end
919
922
 
920
- ##
921
- # Outputs a formatted RI page list for the pages in +store+.
923
+ ##
924
+ # Outputs a formatted RI page list for the pages in +store+.
922
925
 
923
- def display_page_list(store, pages = store.cache[:pages], search = nil)
924
- out = RDoc::Markup::Document.new
926
+ def display_page_list(store, pages = store.cache[:pages], search = nil)
927
+ out = Markup::Document.new
925
928
 
926
- title = if search then
927
- "#{search} pages"
928
- else
929
- 'Pages'
930
- end
929
+ title = if search
930
+ "#{search} pages"
931
+ else
932
+ 'Pages'
933
+ end
931
934
 
932
- out << RDoc::Markup::Heading.new(1, "#{title} in #{store.friendly_path}")
933
- out << RDoc::Markup::BlankLine.new
935
+ out << Markup::Heading.new(1, "#{title} in #{store.friendly_path}")
936
+ out << Markup::BlankLine.new
934
937
 
935
- list = RDoc::Markup::List.new(:BULLET)
938
+ list = Markup::List.new(:BULLET)
936
939
 
937
- pages.each do |page|
938
- list << RDoc::Markup::Paragraph.new(page)
939
- end
940
+ pages.each do |page|
941
+ list << Markup::Paragraph.new(page)
942
+ end
940
943
 
941
- out << list
944
+ out << list
942
945
 
943
- display out
944
- end
946
+ display out
947
+ end
945
948
 
946
- def check_did_you_mean # :nodoc:
947
- if defined? DidYouMean::SpellChecker
948
- true
949
- else
950
- begin
951
- require 'did_you_mean'
949
+ def check_did_you_mean # :nodoc:
952
950
  if defined? DidYouMean::SpellChecker
953
951
  true
954
952
  else
955
- false
953
+ begin
954
+ require 'did_you_mean'
955
+ if defined? DidYouMean::SpellChecker
956
+ true
957
+ else
958
+ false
959
+ end
960
+ rescue LoadError
961
+ false
962
+ end
956
963
  end
957
- rescue LoadError
958
- false
959
964
  end
960
- end
961
- end
962
965
 
963
- ##
964
- # Expands abbreviated klass +klass+ into a fully-qualified class. "Zl::Da"
965
- # will be expanded to Zlib::DataError.
966
-
967
- def expand_class(klass)
968
- class_names = classes.keys
969
- ary = class_names.grep(Regexp.new("\\A#{klass.gsub(/(?=::|\z)/, '[^:]*')}\\z"))
970
- if ary.length != 1 && ary.first != klass
971
- if check_did_you_mean
972
- suggestion_proc = -> { DidYouMean::SpellChecker.new(dictionary: class_names).correct(klass) }
973
- raise NotFoundError.new(klass, suggestion_proc)
974
- else
975
- raise NotFoundError, klass
966
+ ##
967
+ # Expands abbreviated klass +klass+ into a fully-qualified class. "Zl::Da"
968
+ # will be expanded to Zlib::DataError.
969
+
970
+ def expand_class(klass)
971
+ class_names = classes.keys
972
+ ary = class_names.grep(Regexp.new("\\A#{klass.gsub(/(?=::|\z)/, '[^:]*')}\\z"))
973
+ if ary.length != 1 && ary.first != klass
974
+ if check_did_you_mean
975
+ suggestion_proc = -> { DidYouMean::SpellChecker.new(dictionary: class_names).correct(klass) }
976
+ raise NotFoundError.new(klass, suggestion_proc)
977
+ else
978
+ raise NotFoundError, klass
979
+ end
980
+ end
981
+ ary.first
976
982
  end
977
- end
978
- ary.first
979
- end
980
983
 
981
- ##
982
- # Expands the class portion of +name+ into a fully-qualified class. See
983
- # #expand_class.
984
+ ##
985
+ # Expands the class portion of +name+ into a fully-qualified class. See
986
+ # #expand_class.
984
987
 
985
- def expand_name(name)
986
- klass, selector, method = parse_name name
988
+ def expand_name(name)
989
+ klass, selector, method = parse_name name
987
990
 
988
- return [selector, method].join if klass.empty?
991
+ return [selector, method].join if klass.empty?
989
992
 
990
- case selector
991
- when ':' then
992
- [find_store(klass), selector, method]
993
- else
994
- [expand_class(klass), selector, method]
995
- end.join
996
- end
993
+ case selector
994
+ when ':'
995
+ [find_store(klass), selector, method]
996
+ else
997
+ [expand_class(klass), selector, method]
998
+ end.join
999
+ end
997
1000
 
998
- ##
999
- # Filters the methods in +found+ trying to find a match for +name+.
1001
+ ##
1002
+ # Filters the methods in +found+ trying to find a match for +name+.
1000
1003
 
1001
- def filter_methods(found, name)
1002
- regexp = name_regexp name
1004
+ def filter_methods(found, name)
1005
+ regexp = name_regexp name
1003
1006
 
1004
- filtered = found.find_all do |store, methods|
1005
- methods.any? { |method| method.full_name =~ regexp }
1006
- end
1007
+ filtered = found.find_all do |store, methods|
1008
+ methods.any? { |method| method.full_name =~ regexp }
1009
+ end
1007
1010
 
1008
- return filtered unless filtered.empty?
1011
+ return filtered unless filtered.empty?
1009
1012
 
1010
- found
1011
- end
1013
+ found
1014
+ end
1012
1015
 
1013
- ##
1014
- # Yields items matching +name+ including the store they were found in, the
1015
- # class being searched for, the class they were found in (an ancestor) the
1016
- # types of methods to look up (from #method_type), and the method name being
1017
- # searched for
1016
+ ##
1017
+ # Yields items matching +name+ including the store they were found in, the
1018
+ # class being searched for, the class they were found in (an ancestor) the
1019
+ # types of methods to look up (from #method_type), and the method name being
1020
+ # searched for
1018
1021
 
1019
- def find_methods(name)
1020
- klass, selector, method = parse_name name
1022
+ def find_methods(name)
1023
+ klass, selector, method = parse_name name
1021
1024
 
1022
- types = method_type selector
1025
+ types = method_type selector
1023
1026
 
1024
- klasses = nil
1025
- ambiguous = klass.empty?
1027
+ klasses = nil
1028
+ ambiguous = klass.empty?
1026
1029
 
1027
- if ambiguous then
1028
- klasses = classes.keys
1029
- else
1030
- klasses = ancestors_of klass
1031
- klasses.unshift klass
1032
- end
1030
+ if ambiguous
1031
+ klasses = classes.keys
1032
+ else
1033
+ klasses = ancestors_of klass
1034
+ klasses.unshift klass
1035
+ end
1033
1036
 
1034
- methods = []
1037
+ methods = []
1035
1038
 
1036
- klasses.each do |ancestor|
1037
- ancestors = classes[ancestor]
1039
+ klasses.each do |ancestor|
1040
+ ancestors = classes[ancestor]
1038
1041
 
1039
- next unless ancestors
1042
+ next unless ancestors
1040
1043
 
1041
- klass = ancestor if ambiguous
1044
+ klass = ancestor if ambiguous
1042
1045
 
1043
- ancestors.each do |store|
1044
- methods << [store, klass, ancestor, types, method]
1045
- end
1046
- end
1046
+ ancestors.each do |store|
1047
+ methods << [store, klass, ancestor, types, method]
1048
+ end
1049
+ end
1047
1050
 
1048
- methods = methods.sort_by do |_, k, a, _, m|
1049
- [k, a, m].compact
1050
- end
1051
+ methods = methods.sort_by do |_, k, a, _, m|
1052
+ [k, a, m].compact
1053
+ end
1051
1054
 
1052
- methods.each do |item|
1053
- yield(*item) # :yields: store, klass, ancestor, types, method
1054
- end
1055
+ methods.each do |item|
1056
+ yield(*item) # :yields: store, klass, ancestor, types, method
1057
+ end
1055
1058
 
1056
- self
1057
- end
1059
+ self
1060
+ end
1058
1061
 
1059
- ##
1060
- # Finds a store that matches +name+ which can be the name of a gem, "ruby",
1061
- # "home" or "site".
1062
- #
1063
- # See also RDoc::Store#source
1062
+ ##
1063
+ # Finds a store that matches +name+ which can be the name of a gem, "ruby",
1064
+ # "home" or "site".
1065
+ #
1066
+ # See also RDoc::Store#source
1064
1067
 
1065
- def find_store(name)
1066
- @stores.each do |store|
1067
- source = store.source
1068
+ def find_store(name)
1069
+ @stores.each do |store|
1070
+ source = store.source
1068
1071
 
1069
- return source if source == name
1072
+ return source if source == name
1070
1073
 
1071
- return source if
1072
- store.type == :gem and source =~ /^#{Regexp.escape name}-\d/
1073
- end
1074
+ return source if
1075
+ store.type == :gem and source =~ /^#{Regexp.escape name}-\d/
1076
+ end
1074
1077
 
1075
- raise RDoc::RI::Driver::NotFoundError, name
1076
- end
1078
+ raise RI::Driver::NotFoundError, name
1079
+ end
1077
1080
 
1078
- ##
1079
- # Creates a new RDoc::Markup::Formatter. If a formatter is given with -f,
1080
- # use it. If we're outputting to a pager, use bs, otherwise ansi.
1081
-
1082
- def formatter(io)
1083
- if @formatter_klass then
1084
- @formatter_klass.new
1085
- elsif paging? or !io.tty? then
1086
- RDoc::Markup::ToBs.new
1087
- else
1088
- RDoc::Markup::ToAnsi.new
1089
- end
1090
- end
1081
+ ##
1082
+ # Creates a new RDoc::Markup::Formatter. If a formatter is given with -f,
1083
+ # use it. If we're outputting to a pager, use bs, otherwise ansi.
1091
1084
 
1092
- ##
1093
- # Runs ri interactively using Readline if it is available.
1085
+ def formatter(io)
1086
+ if @formatter_klass
1087
+ @formatter_klass.new
1088
+ elsif paging? or !io.tty?
1089
+ Markup::ToBs.new
1090
+ else
1091
+ Markup::ToAnsi.new
1092
+ end
1093
+ end
1094
1094
 
1095
- def interactive
1096
- puts "\nEnter the method name you want to look up."
1095
+ ##
1096
+ # Runs ri interactively using Readline if it is available.
1097
1097
 
1098
- begin
1099
- require 'readline'
1100
- rescue LoadError
1101
- end
1102
- if defined? Readline then
1103
- Readline.completion_proc = method :complete
1104
- puts "You can use tab to autocomplete."
1105
- end
1098
+ def interactive
1099
+ puts "\nEnter the method name you want to look up."
1100
+
1101
+ begin
1102
+ require 'readline'
1103
+ rescue LoadError
1104
+ end
1105
+ if defined? Readline
1106
+ Readline.completion_proc = method :complete
1107
+ puts "You can use tab to autocomplete."
1108
+ end
1106
1109
 
1107
- puts "Enter a blank line to exit.\n\n"
1110
+ puts "Enter a blank line to exit.\n\n"
1108
1111
 
1109
- loop do
1110
- name = if defined? Readline then
1111
- Readline.readline ">> ", true
1112
- else
1113
- print ">> "
1114
- $stdin.gets
1115
- end
1112
+ loop do
1113
+ name = if defined? Readline
1114
+ Readline.readline ">> ", true
1115
+ else
1116
+ print ">> "
1117
+ $stdin.gets
1118
+ end
1116
1119
 
1117
- return if name.nil? or name.empty?
1120
+ return if name.nil? or name.empty?
1118
1121
 
1119
- begin
1120
- display_name expand_name(name.strip)
1121
- rescue NotFoundError => e
1122
- puts e.message
1122
+ begin
1123
+ display_name expand_name(name.strip)
1124
+ rescue NotFoundError => e
1125
+ puts e.message
1126
+ end
1127
+ end
1128
+
1129
+ rescue Interrupt
1130
+ exit
1123
1131
  end
1124
- end
1125
1132
 
1126
- rescue Interrupt
1127
- exit
1128
- end
1133
+ ##
1134
+ # Lists classes known to ri starting with +names+. If +names+ is empty all
1135
+ # known classes are shown.
1129
1136
 
1130
- ##
1131
- # Lists classes known to ri starting with +names+. If +names+ is empty all
1132
- # known classes are shown.
1137
+ def list_known_classes(names = [])
1138
+ classes = []
1133
1139
 
1134
- def list_known_classes(names = [])
1135
- classes = []
1140
+ stores.each do |store|
1141
+ classes << store.module_names
1142
+ end
1136
1143
 
1137
- stores.each do |store|
1138
- classes << store.module_names
1139
- end
1144
+ classes = classes.flatten.uniq.sort
1140
1145
 
1141
- classes = classes.flatten.uniq.sort
1146
+ unless names.empty?
1147
+ filter = Regexp.union names.map { |name| /^#{name}/ }
1142
1148
 
1143
- unless names.empty? then
1144
- filter = Regexp.union names.map { |name| /^#{name}/ }
1149
+ classes = classes.grep filter
1150
+ end
1145
1151
 
1146
- classes = classes.grep filter
1147
- end
1152
+ page do |io|
1153
+ if paging? or io.tty?
1154
+ if names.empty?
1155
+ io.puts "Classes and Modules known to ri:"
1156
+ else
1157
+ io.puts "Classes and Modules starting with #{names.join ', '}:"
1158
+ end
1159
+ io.puts
1160
+ end
1148
1161
 
1149
- page do |io|
1150
- if paging? or io.tty? then
1151
- if names.empty? then
1152
- io.puts "Classes and Modules known to ri:"
1153
- else
1154
- io.puts "Classes and Modules starting with #{names.join ', '}:"
1162
+ io.puts classes.join("\n")
1155
1163
  end
1156
- io.puts
1157
1164
  end
1158
1165
 
1159
- io.puts classes.join("\n")
1160
- end
1161
- end
1166
+ ##
1167
+ # Returns an Array of methods matching +name+
1162
1168
 
1163
- ##
1164
- # Returns an Array of methods matching +name+
1169
+ def list_methods_matching(name)
1170
+ found = []
1165
1171
 
1166
- def list_methods_matching(name)
1167
- found = []
1172
+ find_methods name do |store, klass, ancestor, types, method|
1173
+ if types == :instance or types == :both
1174
+ methods = store.instance_methods[ancestor]
1168
1175
 
1169
- find_methods name do |store, klass, ancestor, types, method|
1170
- if types == :instance or types == :both then
1171
- methods = store.instance_methods[ancestor]
1176
+ if methods
1177
+ matches = methods.grep(/^#{Regexp.escape method.to_s}/)
1172
1178
 
1173
- if methods then
1174
- matches = methods.grep(/^#{Regexp.escape method.to_s}/)
1179
+ matches = matches.map do |match|
1180
+ "#{klass}##{match}"
1181
+ end
1175
1182
 
1176
- matches = matches.map do |match|
1177
- "#{klass}##{match}"
1183
+ found.concat matches
1184
+ end
1178
1185
  end
1179
1186
 
1180
- found.concat matches
1181
- end
1182
- end
1187
+ if types == :class or types == :both
1188
+ methods = store.class_methods[ancestor]
1183
1189
 
1184
- if types == :class or types == :both then
1185
- methods = store.class_methods[ancestor]
1190
+ next unless methods
1191
+ matches = methods.grep(/^#{Regexp.escape method.to_s}/)
1186
1192
 
1187
- next unless methods
1188
- matches = methods.grep(/^#{Regexp.escape method.to_s}/)
1193
+ matches = matches.map do |match|
1194
+ "#{klass}::#{match}"
1195
+ end
1189
1196
 
1190
- matches = matches.map do |match|
1191
- "#{klass}::#{match}"
1197
+ found.concat matches
1198
+ end
1192
1199
  end
1193
1200
 
1194
- found.concat matches
1201
+ found.uniq
1195
1202
  end
1196
- end
1197
-
1198
- found.uniq
1199
- end
1200
1203
 
1201
- ##
1202
- # Loads RI data for method +name+ on +klass+ from +store+. +type+ and
1203
- # +cache+ indicate if it is a class or instance method.
1204
+ ##
1205
+ # Loads RI data for method +name+ on +klass+ from +store+. +type+ and
1206
+ # +cache+ indicate if it is a class or instance method.
1204
1207
 
1205
- def load_method(store, cache, klass, type, name)
1206
- methods = store.public_send(cache)[klass]
1208
+ def load_method(store, cache, klass, type, name)
1209
+ methods = store.public_send(cache)[klass]
1207
1210
 
1208
- return unless methods
1211
+ return unless methods
1209
1212
 
1210
- method = methods.find do |method_name|
1211
- method_name == name
1212
- end
1213
+ method = methods.find do |method_name|
1214
+ method_name == name
1215
+ end
1213
1216
 
1214
- return unless method
1217
+ return unless method
1215
1218
 
1216
- store.load_method klass, "#{type}#{method}"
1217
- rescue RDoc::Store::MissingFileError => e
1218
- comment = RDoc::Comment.new("missing documentation at #{e.file}")
1219
- comment.parse
1219
+ store.load_method klass, "#{type}#{method}"
1220
+ rescue ::RDoc::Store::MissingFileError => e
1221
+ comment = Comment.new("missing documentation at #{e.file}")
1222
+ comment.parse
1220
1223
 
1221
- method = RDoc::AnyMethod.new name
1222
- method.comment = comment
1223
- method
1224
- end
1224
+ method = AnyMethod.new name
1225
+ method.comment = comment
1226
+ method
1227
+ end
1225
1228
 
1226
- ##
1227
- # Returns an Array of RI data for methods matching +name+
1229
+ ##
1230
+ # Returns an Array of RI data for methods matching +name+
1228
1231
 
1229
- def load_methods_matching(name)
1230
- found = []
1232
+ def load_methods_matching(name)
1233
+ found = []
1231
1234
 
1232
- find_methods name do |store, klass, ancestor, types, method|
1233
- methods = []
1235
+ find_methods name do |store, klass, ancestor, types, method|
1236
+ methods = []
1234
1237
 
1235
- methods << load_method(store, :class_methods, ancestor, '::', method) if
1236
- [:class, :both].include? types
1238
+ methods << load_method(store, :class_methods, ancestor, '::', method) if
1239
+ [:class, :both].include? types
1237
1240
 
1238
- methods << load_method(store, :instance_methods, ancestor, '#', method) if
1239
- [:instance, :both].include? types
1241
+ methods << load_method(store, :instance_methods, ancestor, '#', method) if
1242
+ [:instance, :both].include? types
1240
1243
 
1241
- found << [store, methods.compact]
1242
- end
1244
+ found << [store, methods.compact]
1245
+ end
1243
1246
 
1244
- found.reject do |path, methods| methods.empty? end
1245
- end
1247
+ found.reject do |path, methods| methods.empty? end
1248
+ end
1246
1249
 
1247
- ##
1248
- # Returns a filtered list of methods matching +name+
1250
+ ##
1251
+ # Returns a filtered list of methods matching +name+
1249
1252
 
1250
- def lookup_method(name)
1251
- found = load_methods_matching name
1253
+ def lookup_method(name)
1254
+ found = load_methods_matching name
1252
1255
 
1253
- if found.empty?
1254
- if check_did_you_mean
1255
- methods = []
1256
- _, _, method_name = parse_name name
1257
- find_methods name do |store, klass, ancestor, types, method|
1258
- methods.push(*store.class_methods[klass]) if [:class, :both].include? types
1259
- methods.push(*store.instance_methods[klass]) if [:instance, :both].include? types
1256
+ if found.empty?
1257
+ if check_did_you_mean
1258
+ methods = []
1259
+ _, _, method_name = parse_name name
1260
+ find_methods name do |store, klass, ancestor, types, method|
1261
+ methods.push(*store.class_methods[klass]) if [:class, :both].include? types
1262
+ methods.push(*store.instance_methods[klass]) if [:instance, :both].include? types
1263
+ end
1264
+ methods = methods.uniq
1265
+ suggestion_proc = -> { DidYouMean::SpellChecker.new(dictionary: methods).correct(method_name) }
1266
+ raise NotFoundError.new(name, suggestion_proc)
1267
+ else
1268
+ raise NotFoundError, name
1269
+ end
1260
1270
  end
1261
- methods = methods.uniq
1262
- suggestion_proc = -> { DidYouMean::SpellChecker.new(dictionary: methods).correct(method_name) }
1263
- raise NotFoundError.new(name, suggestion_proc)
1264
- else
1265
- raise NotFoundError, name
1271
+
1272
+ filter_methods found, name
1266
1273
  end
1267
- end
1268
1274
 
1269
- filter_methods found, name
1270
- end
1275
+ ##
1276
+ # Builds a RDoc::Markup::Document from +found+, +klasses+ and +includes+
1271
1277
 
1272
- ##
1273
- # Builds a RDoc::Markup::Document from +found+, +klasses+ and +includes+
1278
+ def method_document(out, name, filtered)
1279
+ out << Markup::Heading.new(1, name)
1280
+ out << Markup::BlankLine.new
1274
1281
 
1275
- def method_document(out, name, filtered)
1276
- out << RDoc::Markup::Heading.new(1, name)
1277
- out << RDoc::Markup::BlankLine.new
1282
+ filtered.each do |store, methods|
1283
+ methods.each do |method|
1284
+ render_method out, store, method, name
1285
+ end
1286
+ end
1278
1287
 
1279
- filtered.each do |store, methods|
1280
- methods.each do |method|
1281
- render_method out, store, method, name
1288
+ out
1282
1289
  end
1283
- end
1284
1290
 
1285
- out
1286
- end
1287
-
1288
- ##
1289
- # Returns the type of method (:both, :instance, :class) for +selector+
1291
+ ##
1292
+ # Returns the type of method (:both, :instance, :class) for +selector+
1290
1293
 
1291
- def method_type(selector)
1292
- case selector
1293
- when '.', nil then :both
1294
- when '#' then :instance
1295
- else :class
1296
- end
1297
- end
1294
+ def method_type(selector)
1295
+ case selector
1296
+ when '.', nil then :both
1297
+ when '#' then :instance
1298
+ else :class
1299
+ end
1300
+ end
1298
1301
 
1299
- ##
1300
- # Returns a regular expression for +name+ that will match an
1301
- # RDoc::AnyMethod's name.
1302
+ ##
1303
+ # Returns a regular expression for +name+ that will match an
1304
+ # RDoc::AnyMethod's name.
1302
1305
 
1303
- def name_regexp(name)
1304
- klass, type, name = parse_name name
1306
+ def name_regexp(name)
1307
+ klass, type, name = parse_name name
1305
1308
 
1306
- case type
1307
- when '#', '::' then
1308
- /^#{klass}#{type}#{Regexp.escape name}$/
1309
- else
1310
- /^#{klass}(#|::)#{Regexp.escape name}$/
1311
- end
1312
- end
1309
+ case type
1310
+ when '#', '::'
1311
+ /^#{klass}#{type}#{Regexp.escape name}$/
1312
+ else
1313
+ /^#{klass}(#|::)#{Regexp.escape name}$/
1314
+ end
1315
+ end
1313
1316
 
1314
- ##
1315
- # Paginates output through a pager program.
1317
+ ##
1318
+ # Paginates output through a pager program.
1316
1319
 
1317
- def page
1318
- if pager = setup_pager then
1319
- begin
1320
- yield pager
1320
+ def page
1321
+ if pager = setup_pager
1322
+ begin
1323
+ yield pager
1324
+ ensure
1325
+ pager.close
1326
+ end
1327
+ else
1328
+ yield $stdout
1329
+ end
1330
+ rescue Errno::EPIPE
1321
1331
  ensure
1322
- pager.close
1332
+ @paging = false
1323
1333
  end
1324
- else
1325
- yield $stdout
1326
- end
1327
- rescue Errno::EPIPE
1328
- ensure
1329
- @paging = false
1330
- end
1331
1334
 
1332
- ##
1333
- # Are we using a pager?
1335
+ ##
1336
+ # Are we using a pager?
1334
1337
 
1335
- def paging?
1336
- @paging
1337
- end
1338
+ def paging?
1339
+ @paging
1340
+ end
1341
+
1342
+ ##
1343
+ # Extracts the class, selector and method name parts from +name+ like
1344
+ # Foo::Bar#baz.
1345
+ #
1346
+ # NOTE: Given Foo::Bar, Bar is considered a class even though it may be a
1347
+ # method
1348
+
1349
+ def parse_name(name)
1350
+ parts = name.split(/(::?|#|\.)/)
1351
+
1352
+ if parts.length == 1
1353
+ if parts.first =~ /^[a-z]|^([%&*+\/<>^`|~-]|\+@|-@|<<|<=>?|===?|=>|=~|>>|\[\]=?|~@)$/
1354
+ type = '.'
1355
+ meth = parts.pop
1356
+ else
1357
+ type = nil
1358
+ meth = nil
1359
+ end
1360
+ elsif parts.length == 2 or parts.last =~ /::|#|\./
1361
+ type = parts.pop
1362
+ meth = nil
1363
+ elsif parts[1] == ':'
1364
+ klass = parts.shift
1365
+ type = parts.shift
1366
+ meth = parts.join
1367
+ elsif parts[-2] != '::' or parts.last !~ /^[A-Z]/
1368
+ meth = parts.pop
1369
+ type = parts.pop
1370
+ end
1371
+
1372
+ klass ||= parts.join
1338
1373
 
1339
- ##
1340
- # Extracts the class, selector and method name parts from +name+ like
1341
- # Foo::Bar#baz.
1342
- #
1343
- # NOTE: Given Foo::Bar, Bar is considered a class even though it may be a
1344
- # method
1345
-
1346
- def parse_name(name)
1347
- parts = name.split(/(::?|#|\.)/)
1348
-
1349
- if parts.length == 1 then
1350
- if parts.first =~ /^[a-z]|^([%&*+\/<>^`|~-]|\+@|-@|<<|<=>?|===?|=>|=~|>>|\[\]=?|~@)$/ then
1351
- type = '.'
1352
- meth = parts.pop
1353
- else
1354
- type = nil
1355
- meth = nil
1374
+ [klass, type, meth]
1356
1375
  end
1357
- elsif parts.length == 2 or parts.last =~ /::|#|\./ then
1358
- type = parts.pop
1359
- meth = nil
1360
- elsif parts[1] == ':' then
1361
- klass = parts.shift
1362
- type = parts.shift
1363
- meth = parts.join
1364
- elsif parts[-2] != '::' or parts.last !~ /^[A-Z]/ then
1365
- meth = parts.pop
1366
- type = parts.pop
1367
- end
1368
1376
 
1369
- klass ||= parts.join
1377
+ ##
1378
+ # Renders the +klass+ from +store+ to +out+. If the klass has no
1379
+ # documentable items the class is added to +also_in+ instead.
1380
+
1381
+ def render_class(out, store, klass, also_in) # :nodoc:
1382
+ document = klass.comment.parse
1383
+ # TODO the store's cache should always return an empty Array
1384
+ class_methods = store.class_methods[klass.full_name] || []
1385
+ instance_methods = store.instance_methods[klass.full_name] || []
1386
+ attributes = store.attributes[klass.full_name] || []
1387
+
1388
+ if document.empty? and
1389
+ instance_methods.empty? and class_methods.empty?
1390
+ also_in << store
1391
+ return
1392
+ end
1370
1393
 
1371
- [klass, type, meth]
1372
- end
1394
+ add_from out, store
1373
1395
 
1374
- ##
1375
- # Renders the +klass+ from +store+ to +out+. If the klass has no
1376
- # documentable items the class is added to +also_in+ instead.
1377
-
1378
- def render_class(out, store, klass, also_in) # :nodoc:
1379
- document = klass.comment.parse
1380
- # TODO the store's cache should always return an empty Array
1381
- class_methods = store.class_methods[klass.full_name] || []
1382
- instance_methods = store.instance_methods[klass.full_name] || []
1383
- attributes = store.attributes[klass.full_name] || []
1384
-
1385
- if document.empty? and
1386
- instance_methods.empty? and class_methods.empty? then
1387
- also_in << store
1388
- return
1389
- end
1396
+ class_document_comment out, document
1390
1397
 
1391
- add_from out, store
1398
+ if class_methods or instance_methods or not klass.constants.empty?
1399
+ out << Markup::Rule.new(1)
1400
+ end
1392
1401
 
1393
- class_document_comment out, document
1402
+ class_document_constants out, klass
1394
1403
 
1395
- if class_methods or instance_methods or not klass.constants.empty? then
1396
- out << RDoc::Markup::Rule.new(1)
1397
- end
1404
+ add_method_list out, class_methods, 'Class methods'
1405
+ add_method_list out, instance_methods, 'Instance methods'
1406
+ add_method_list out, attributes, 'Attributes'
1398
1407
 
1399
- class_document_constants out, klass
1408
+ add_method_documentation out, klass if @show_all
1409
+ end
1400
1410
 
1401
- add_method_list out, class_methods, 'Class methods'
1402
- add_method_list out, instance_methods, 'Instance methods'
1403
- add_method_list out, attributes, 'Attributes'
1411
+ def render_method(out, store, method, name) # :nodoc:
1412
+ out << Markup::Paragraph.new("(from #{store.friendly_path})")
1404
1413
 
1405
- add_method_documentation out, klass if @show_all
1406
- end
1414
+ unless name =~ /^#{Regexp.escape method.parent_name}/
1415
+ out << Markup::Heading.new(3, "Implementation from #{method.parent_name}")
1416
+ end
1407
1417
 
1408
- def render_method(out, store, method, name) # :nodoc:
1409
- out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})")
1418
+ out << Markup::Rule.new(1)
1410
1419
 
1411
- unless name =~ /^#{Regexp.escape method.parent_name}/ then
1412
- out << RDoc::Markup::Heading.new(3, "Implementation from #{method.parent_name}")
1413
- end
1420
+ render_method_arguments out, method.arglists
1421
+ sig = method.type_signature_lines || store.rbs_signature_for(method)
1422
+ render_method_type_signature out, sig if sig
1423
+ render_method_superclass out, method
1424
+ if method.is_alias_for
1425
+ al = method.is_alias_for
1426
+ alias_for = store.load_method al.parent_name, "#{al.name_prefix}#{al.name}"
1427
+ render_method_comment out, method, alias_for
1428
+ else
1429
+ render_method_comment out, method
1430
+ end
1431
+ end
1414
1432
 
1415
- out << RDoc::Markup::Rule.new(1)
1416
-
1417
- render_method_arguments out, method.arglists
1418
- sig = method.type_signature_lines || store.rbs_signature_for(method)
1419
- render_method_type_signature out, sig if sig
1420
- render_method_superclass out, method
1421
- if method.is_alias_for
1422
- al = method.is_alias_for
1423
- alias_for = store.load_method al.parent_name, "#{al.name_prefix}#{al.name}"
1424
- render_method_comment out, method, alias_for
1425
- else
1426
- render_method_comment out, method
1427
- end
1428
- end
1433
+ def render_method_arguments(out, arglists) # :nodoc:
1434
+ return unless arglists
1429
1435
 
1430
- def render_method_arguments(out, arglists) # :nodoc:
1431
- return unless arglists
1436
+ arglists = arglists.chomp.split "\n"
1437
+ arglists = arglists.map { |line| line + "\n" }
1438
+ out << Markup::Verbatim.new(*arglists)
1439
+ out << Markup::Rule.new(1)
1440
+ end
1432
1441
 
1433
- arglists = arglists.chomp.split "\n"
1434
- arglists = arglists.map { |line| line + "\n" }
1435
- out << RDoc::Markup::Verbatim.new(*arglists)
1436
- out << RDoc::Markup::Rule.new(1)
1437
- end
1442
+ def render_method_comment(out, method, alias_for = nil)# :nodoc:
1443
+ if alias_for
1444
+ unless method.comment.nil? or method.comment.empty?
1445
+ out << Markup::BlankLine.new
1446
+ out << method.comment.parse
1447
+ end
1448
+ out << Markup::BlankLine.new
1449
+ out << Markup::Paragraph.new("(This method is an alias for #{alias_for.full_name}.)")
1450
+ out << Markup::BlankLine.new
1451
+ out << alias_for.comment.parse
1452
+ out << Markup::BlankLine.new
1453
+ else
1454
+ out << Markup::BlankLine.new
1455
+ out << method.comment.parse
1456
+ out << Markup::BlankLine.new
1457
+ end
1458
+ end
1438
1459
 
1439
- def render_method_comment(out, method, alias_for = nil)# :nodoc:
1440
- if alias_for
1441
- unless method.comment.nil? or method.comment.empty?
1442
- out << RDoc::Markup::BlankLine.new
1443
- out << method.comment.parse
1460
+ def render_method_type_signature(out, lines) # :nodoc:
1461
+ out << Markup::Verbatim.new(*lines.map { |s| s + "\n" })
1444
1462
  end
1445
- out << RDoc::Markup::BlankLine.new
1446
- out << RDoc::Markup::Paragraph.new("(This method is an alias for #{alias_for.full_name}.)")
1447
- out << RDoc::Markup::BlankLine.new
1448
- out << alias_for.comment.parse
1449
- out << RDoc::Markup::BlankLine.new
1450
- else
1451
- out << RDoc::Markup::BlankLine.new
1452
- out << method.comment.parse
1453
- out << RDoc::Markup::BlankLine.new
1454
- end
1455
- end
1456
1463
 
1457
- def render_method_type_signature(out, lines) # :nodoc:
1458
- out << RDoc::Markup::Verbatim.new(*lines.map { |s| s + "\n" })
1459
- end
1464
+ def render_method_superclass(out, method) # :nodoc:
1465
+ return unless
1466
+ method.respond_to?(:superclass_method) and method.superclass_method
1460
1467
 
1461
- def render_method_superclass(out, method) # :nodoc:
1462
- return unless
1463
- method.respond_to?(:superclass_method) and method.superclass_method
1468
+ out << Markup::BlankLine.new
1469
+ out << Markup::Heading.new(4, "(Uses superclass method #{method.superclass_method})")
1470
+ out << Markup::Rule.new(1)
1471
+ end
1464
1472
 
1465
- out << RDoc::Markup::BlankLine.new
1466
- out << RDoc::Markup::Heading.new(4, "(Uses superclass method #{method.superclass_method})")
1467
- out << RDoc::Markup::Rule.new(1)
1468
- end
1473
+ ##
1474
+ # Looks up and displays ri data according to the options given.
1475
+
1476
+ def run
1477
+ if @list_doc_dirs
1478
+ puts @doc_dirs
1479
+ elsif @list
1480
+ list_known_classes @names
1481
+ elsif @server
1482
+ start_server
1483
+ elsif @interactive or @names.empty?
1484
+ interactive
1485
+ else
1486
+ display_names @names
1487
+ end
1488
+ rescue NotFoundError => e
1489
+ abort e.message
1490
+ end
1469
1491
 
1470
- ##
1471
- # Looks up and displays ri data according to the options given.
1472
-
1473
- def run
1474
- if @list_doc_dirs then
1475
- puts @doc_dirs
1476
- elsif @list then
1477
- list_known_classes @names
1478
- elsif @server then
1479
- start_server
1480
- elsif @interactive or @names.empty? then
1481
- interactive
1482
- else
1483
- display_names @names
1484
- end
1485
- rescue NotFoundError => e
1486
- abort e.message
1487
- end
1492
+ ##
1493
+ # Sets up a pager program to pass output through. Tries the RI_PAGER and
1494
+ # PAGER environment variables followed by pager, less then more.
1488
1495
 
1489
- ##
1490
- # Sets up a pager program to pass output through. Tries the RI_PAGER and
1491
- # PAGER environment variables followed by pager, less then more.
1496
+ def setup_pager
1497
+ return if @use_stdout
1492
1498
 
1493
- def setup_pager
1494
- return if @use_stdout
1499
+ pagers = [ENV['RI_PAGER'], ENV['PAGER'], 'pager', 'less', 'more']
1495
1500
 
1496
- pagers = [ENV['RI_PAGER'], ENV['PAGER'], 'pager', 'less', 'more']
1501
+ require 'shellwords'
1502
+ pagers.compact.uniq.each do |pager|
1503
+ pager = Shellwords.split(pager)
1504
+ next if pager.empty?
1497
1505
 
1498
- require 'shellwords'
1499
- pagers.compact.uniq.each do |pager|
1500
- pager = Shellwords.split(pager)
1501
- next if pager.empty?
1506
+ io = IO.popen(pager, 'w') rescue next
1507
+ next if $? and $?.pid == io.pid and $?.exited? # pager didn't work
1502
1508
 
1503
- io = IO.popen(pager, 'w') rescue next
1504
- next if $? and $?.pid == io.pid and $?.exited? # pager didn't work
1509
+ @paging = true
1505
1510
 
1506
- @paging = true
1511
+ return io
1512
+ end
1507
1513
 
1508
- return io
1509
- end
1514
+ @use_stdout = true
1510
1515
 
1511
- @use_stdout = true
1516
+ nil
1517
+ end
1512
1518
 
1513
- nil
1514
- end
1519
+ ##
1520
+ # Starts a WEBrick server for ri.
1515
1521
 
1516
- ##
1517
- # Starts a WEBrick server for ri.
1522
+ def start_server
1523
+ begin
1524
+ require 'webrick'
1525
+ rescue LoadError
1526
+ abort "webrick is not found. You may need to `gem install webrick` to install webrick."
1527
+ end
1518
1528
 
1519
- def start_server
1520
- begin
1521
- require 'webrick'
1522
- rescue LoadError
1523
- abort "webrick is not found. You may need to `gem install webrick` to install webrick."
1524
- end
1529
+ server = WEBrick::HTTPServer.new :Port => @server
1525
1530
 
1526
- server = WEBrick::HTTPServer.new :Port => @server
1531
+ extra_doc_dirs = @stores.map {|s| s.type == :extra ? s.path : nil}.compact
1527
1532
 
1528
- extra_doc_dirs = @stores.map {|s| s.type == :extra ? s.path : nil}.compact
1533
+ server.mount '/', RI::Servlet, nil, extra_doc_dirs
1529
1534
 
1530
- server.mount '/', RDoc::RI::Servlet, nil, extra_doc_dirs
1535
+ trap 'INT' do server.shutdown end
1536
+ trap 'TERM' do server.shutdown end
1531
1537
 
1532
- trap 'INT' do server.shutdown end
1533
- trap 'TERM' do server.shutdown end
1538
+ server.start
1539
+ end
1534
1540
 
1535
- server.start
1536
- end
1541
+ RDOC_REFS_REGEXP = /\[rdoc-ref:([\w.]+)(@.*)?\]/
1537
1542
 
1538
- RDOC_REFS_REGEXP = /\[rdoc-ref:([\w.]+)(@.*)?\]/
1543
+ def expand_rdoc_refs_at_the_bottom(out)
1544
+ return unless @expand_refs
1539
1545
 
1540
- def expand_rdoc_refs_at_the_bottom(out)
1541
- return unless @expand_refs
1546
+ extracted_rdoc_refs = []
1542
1547
 
1543
- extracted_rdoc_refs = []
1548
+ out.each do |part|
1549
+ content = if part.respond_to?(:text)
1550
+ part.text
1551
+ else
1552
+ next
1553
+ end
1544
1554
 
1545
- out.each do |part|
1546
- content = if part.respond_to?(:text)
1547
- part.text
1548
- else
1549
- next
1550
- end
1555
+ rdoc_refs = content.scan(RDOC_REFS_REGEXP).uniq.map do |file_name, _anchor|
1556
+ file_name
1557
+ end
1551
1558
 
1552
- rdoc_refs = content.scan(RDOC_REFS_REGEXP).uniq.map do |file_name, _anchor|
1553
- file_name
1554
- end
1559
+ extracted_rdoc_refs.concat(rdoc_refs)
1560
+ end
1555
1561
 
1556
- extracted_rdoc_refs.concat(rdoc_refs)
1557
- end
1562
+ found_pages = extracted_rdoc_refs.map do |ref|
1563
+ begin
1564
+ @stores.first.load_page(ref)
1565
+ rescue ::RDoc::Store::MissingFileError
1566
+ end
1567
+ end.compact
1558
1568
 
1559
- found_pages = extracted_rdoc_refs.map do |ref|
1560
- begin
1561
- @stores.first.load_page(ref)
1562
- rescue RDoc::Store::MissingFileError
1569
+ found_pages.each do |page|
1570
+ out << Markup::Heading.new(4, "Expanded from #{page.full_name}")
1571
+ out << Markup::BlankLine.new
1572
+ out << page.comment.parse
1573
+ end
1563
1574
  end
1564
- end.compact
1565
-
1566
- found_pages.each do |page|
1567
- out << RDoc::Markup::Heading.new(4, "Expanded from #{page.full_name}")
1568
- out << RDoc::Markup::BlankLine.new
1569
- out << page.comment.parse
1570
1575
  end
1571
1576
  end
1572
1577
  end