Skip to content

Add IRB.doc_providers, a hook for external documentation providers - #1258

Open
znz wants to merge 2 commits into
ruby:masterfrom
znz:doc-providers
Open

znz wants to merge 2 commits into
ruby:masterfrom
znz:doc-providers

Conversation

@znz

@znz znz commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Implements the proposal in #1243: a small public extension point so that documentation backends other than RI can plug into show_doc and the documentation dialog of the autocompletion (Alt+d) without monkey-patching irb internals.

API

IRB.doc_providers is the ordered list of providers consulted by show_doc NAME and by the completion dialog. It defaults to [IRB::RDocDocumentProvider.new], so nothing changes out of the box. A library or .irbrc can add its own provider; earlier providers win:

IRB.doc_providers.unshift(MyDocProvider.new)

A provider is a duck type:

class MyDocProvider
  # name is RI-style: "Array", "Array#each", "Array.new", "String.gsub"
  # (the completion uses a dot even for instance methods).
  # Return a String (shown through IRB::Pager, ANSI allowed) or nil to let
  # the next provider answer.
  def document(name) end

  # Optional: lines for the completion dialog that fit in `width` columns, or nil.
  def dialog_contents(name, width) end
end

IRB::RDocDocumentProvider is the existing RI code moved behind this interface (driver construction honoring IRB.conf[:EXTRA_DOC_DIRS], document, dialog_contents, interactive, and not_found_message, which reproduces the "maybe you meant" suggestions of ri). show_doc without an argument still starts RI's interactive session directly; it is RI-specific and does not consult providers. This is documented in doc/EXTEND_IRB.md.

Changes

  • lib/irb/doc_provider.rb (new): IRB.doc_providers and IRB::RDocDocumentProvider.
  • lib/irb/command/show_doc.rb: asks the providers in order and pages the first result with IRB::Pager. When nothing is found it prints RI's suggestions ("X not found, maybe you meant:" / "Nothing known about X"), or the existing "Can't display document because rdoc is not installed." warning when RDoc is missing.
  • lib/irb/input-method.rb: the dialog (doc_dialog_contents) and the Alt+d full document (display_document) go through the providers. The dialog is registered when any provider can serve it, so a non-RDoc provider also works without rdoc. The error fallback from Keep completion alive when RDoc document retrieval fails #1229 is kept (a raising provider shows the error in the dialog instead of breaking completion) and no longer needs RDoc to render it.
  • Tests: test/irb/test_doc_provider.rb (new), plus provider-based tests in test/irb/test_input_method.rb and test/irb/test_command.rb using stub providers, so the dialog and show_doc code paths are now exercised even on CI without RI data. with_doc_providers helper in test/irb/helper.rb.

Behavior notes

Mostly a refactor, with these visible differences:

  • show_doc NAME output is paged by IRB::Pager (honoring IRB.conf[:USE_PAGER]) instead of RI's own pager, and uses ANSI bold on a color terminal (like the dialog already did). When stdout is not a tty the text is the same backspace-bold text as before.
  • Names are resolved with RI's expand_name like the ri command does, so show_doc StringI shows StringIO and show_doc Strin lists similar classes (both printed nothing before). Unknown names are still reported as "Nothing known about NAME".
  • The "rdoc is not installed" warning is only printed when no provider could answer, and Ctrl-C in the interactive RI session (show_doc without arguments) no longer prints that warning by mistake.

With this in place, bitclust-irb (rurema/bitclust#326) can register a provider instead of a separate refe command, so show_doc String#gsub shows the Japanese manual when available and falls back to RI.

日本語要約

#1243 の提案の実装です。IRB.doc_providers(既定は [IRB::RDocDocumentProvider.new])に登録したプロバイダを show_doc と補完のドキュメントダイアログ(Alt+d)が順に問い合わせます。プロバイダは document(name)(必須・String か nil)と dialog_contents(name, width)(任意)を持つ duck type です。既存の RI 実装は IRB::RDocDocumentProvider に移動し、show_doc 引数なしの対話モードは従来どおり RI 直結です。

🤖 Generated with Claude Code

znz and others added 2 commits September 30, 2026 08:27
`show_doc` and the documentation dialog of the autocompletion were
hard-wired to RDoc::RI::Driver, so other documentation backends (a
manual in another language, YARD, a project-local doc store) could not
plug into them without monkey-patching irb internals.

`IRB.doc_providers` is the ordered list of providers they consult; it
defaults to `[IRB::RDocDocumentProvider.new]`, the existing RI code
moved behind a small duck type: `document(name)` returns a String or
nil, and the optional `dialog_contents(name, width)` returns the lines
of the completion dialog. Earlier providers win, so a library can
`IRB.doc_providers.unshift(MyDocProvider.new)`.

`show_doc NAME` pages the first result with IRB::Pager and prints RI's
"maybe you meant" suggestions when nothing is found; `show_doc` without
an argument still starts RI's interactive session. The dialog is
registered whenever a provider can serve it, so a non-RDoc provider also
works without `rdoc`, and the error fallback of the dialog no longer
needs RDoc to render.

Closes ruby#1243

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`RDocDocumentProvider#not_found_message` expanded the class part of
the name to reproduce ri's "Did you mean?", so without RI data (as on
CI) `show_doc String#gsub` printed "Nothing known about String" instead
of "Nothing known about String#gsub" like before. Report the name as
given, as show_doc always did, and keep only the "maybe you meant"
suggestions.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant