Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Proposal: public hook for external documentation providers in show_doc and the completion doc dialog

Abierto
#1,243 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
38/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
ruby

Línea de trabajo

Empieza leyendo lib/irb/command/show_doc.rb, lib/irb/input-method.rb y lib/irb/completion.rb, centrándote en ShowDoc#execute, RelineInputMethod y las clases de destino de documentación. Traza las rutas existentes de RDoc::RI::Driver y el manejo de errores relacionado antes de decidir la estructura del registro. Se considera terminado cuando los proveedores externos pueden servir show_doc y el diálogo de completado, mientras RI sigue siendo el predeterminado y se conserva el comportamiento existente cuando no se encuentra algo.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Summary

show_doc and the Alt+d documentation dialog shown by autocompletion are hard-wired to RDoc::RI::Driver. This proposes a small public extension point, a list of "document providers", so that other documentation backends (RI-compatible or not) can plug into the same UI without monkey-patching irb internals.

Motivation

irb currently has exactly one way to influence where documentation comes from: IRB.conf[:EXTRA_DOC_DIRS], which only adds more RI data directories. There is no way to serve documentation from a different format or source (a different language's manual, YARD-generated docs, RBS-embedded comments, a project-local doc store, etc.) through show_doc or the completion dialog.

Rurema (the Japanese Ruby reference manual) ships bitclust-irb, added in rurema/bitclust#326 (merged 2026-08-20, released in bitclust 1.7.0). Because there was no hook into show_doc, it had to register an entirely separate refe command through the public IRB::Command.register API instead of extending show_doc itself. A follow-up PR (rurema/bitclust#332) adds a fallback that searches docs.ruby-lang.org (its search index plus the Markdown pages) when no local database is present. Users have to remember two commands (show_doc for RI, refe for the Japanese manual) and only one of them gets the Alt+d dialog treatment.

A provider hook would let show_doc NAME and the completion dialog consult multiple backends in order, with RI as the default, so bitclust-irb (and similarly YARD's yri, or other translated manuals) could integrate directly instead of bolting on a parallel command.

Current implementation

lib/irb/command/show_doc.rb (ShowDoc#execute) always does:

require 'rdoc/ri/driver'
opts = RDoc::RI::Driver.process_args([])
ShowDoc.const_set(:Ri, RDoc::RI::Driver.new(opts))
...
Ri.display_name(name)   # or Ri.interactive when name is nil

and warns "Can't display document because rdoc is not installed." when rdoc can't be required.

lib/irb/input-method.rb (RelineInputMethod) independently drives the same backend for the Alt+d dialog:

  • rdoc_ri_driver builds an RDoc::RI::Driver.new(options), honoring IRB.conf[:EXTRA_DOC_DIRS].
  • retrieve_rdoc_document(name) calls driver.expand_name(name) then driver.add_method / driver.class_document to build an RDoc::Markup::Document.
  • rdoc_dialog_contents(name, width) renders that document with RDoc::Markup::ToAnsi for the popup.
  • display_document(matched) handles the Alt+d full-screen view: CommandDocument targets go through IRB::Command.load_command, MethodDocument targets go through the RI driver's display_names (or add_method + display when there are several candidate names, e.g. ambiguous receivers like {}.any?).
  • The whole dialog proc is only installed when require 'rdoc' succeeds (start in RelineInputMethod).

lib/irb/completion.rb supplies the names passed to the above. DocumentTarget, CommandDocument, and MethodDocument (MethodDocument#names can hold more than one name for an ambiguous receiver) came from #1180 ("Display command description in doc dialog on tab completion", merged 2026-03-13); rdoc_error_document for failed lookups was added by #1229 ("Keep completion alive when RDoc document retrieval fails", 2026-07-16). The names themselves are RI-style: the regexp completor emits things like "String.gsub" (a dot even for instance methods: RI's expand_name resolves it), "Array.new", or ["Hash.any?", "Proc.any?"] for an ambiguous {}.any?; the type-based completor gets the same shape from ReplTypeCompletor#doc_namespace. show_doc itself accepts anything RI accepts (Array, Array#each, Array.new, Array::new).

Proposal

Add a small ordered registry of document providers, defaulting to just the existing RDoc/RI behavior so nothing changes out of the box:

IRB.doc_providers                              # => [IRB::RDocDocumentProvider.new]
IRB.doc_providers.unshift(MyProvider.new)       # e.g. in ~/.irbrc; earlier providers win

(An alternative shape would be IRB.conf[:DOC_PROVIDERS], consistent with EXTRA_DOC_DIRS; either works, but a plain array with push/unshift seems simpler to use and to reason about ordering with.)

A provider is a duck type, no base class required:

class MyProvider
  # name is whatever show_doc / the completor already produce today (RI-style
  # names such as "String#gsub", "String.gsub", "Array.new", "Array"). Return
  # a String to be shown via IRB::Pager, or nil if this provider has nothing
  # for the name, so the next provider gets a chance.
  def document(name) end

  # Optional. A short preview for the completion dialog: an array of lines
  # that fit within `width` columns (ANSI escapes allowed). Return nil to
  # skip the dialog for this name. Providers may omit this method entirely.
  def dialog_contents(name, width) end
end

Resolution: providers are asked in order, and the first non-nil document/dialog_contents result wins. show_doc with no argument would keep starting RI's interactive session directly (providers are not consulted for that case, since "interactive" is RI-specific). When no provider returns anything, today's "not found" / "rdoc not installed" messages are kept.

The built-in IRB::RDocDocumentProvider would just be the existing code moved behind this interface: document wrapping Ri.display_name (captured instead of printed directly), dialog_contents wrapping retrieve_rdoc_document + RDoc::Markup::ToAnsi. So most of this is a refactor, not new behavior. A MethodDocument with multiple candidate names (ambiguous receivers) can be handled by calling document/dialog_contents once per name and combining, same as display_document does today with driver.add_method in a loop.

Sketch of ShowDoc#execute after the change, just to illustrate the shape (not final):

def execute(arg)
  name = unwrap_string_literal(arg)
  if name.nil?
    # unchanged: still delegates straight to RI's interactive session
    IRB::RDocDocumentProvider.new.interactive
    return
  end
  IRB.doc_providers.each do |provider|
    if (doc = provider.document(name))
      Pager.page_content(doc)
      return
    end
  end
  # not found: keep today's messages (RI's "Nothing known about ...")
end

With this in place, bitclust-irb could register a provider instead of a separate refe command, and show_doc String#gsub would show the Japanese manual page when available, falling back to RI.

Notes / open questions

  • Naming: IRB.doc_providers vs. IRB.conf[:DOC_PROVIDERS], and the provider method names (document/dialog_contents vs. something else), are open to bikeshedding.
  • Whether show_doc with no argument (RI's interactive mode) should also become pluggable, or stay RI-only as sketched above.
  • This is related to, but does not by itself solve, #1242 ("Consider letting help fall back to RI documentation"): a provider abstraction would let help fall back to "documentation from some provider" rather than specifically RI, but that's a separate change to the help command.
  • Other plausible providers besides bitclust-irb: YARD's yri, RBS-embedded documentation, project-local documentation, or manuals translated into other languages.
  • I'm happy to send a PR implementing this if the direction looks acceptable to maintainers; bitclust-irb would be the first external consumer.

Related

  • #1180: introduced DocumentTarget / CommandDocument / MethodDocument in lib/irb/completion.rb.
  • #1229: added rdoc_error_document for failed RDoc lookups.
  • #1242: asks for help to fall back to RI docs; a provider hook is related but doesn't itself implement that fallback.
  • rurema/bitclust#326: added the bitclust-irb gem, which today registers a separate refe command because there is no show_doc extension point.

日本語要約

show_doc コマンドおよび自動補完の Alt+d ドキュメントダイアログは RDoc::RI::Driver に直結しており、他のドキュメント源(翻訳マニュアルや YARD など)を差し込む手段がありません。本 issue は、RI をデフォルトとしつつ外部の「ドキュメントプロバイダ」を登録できる小さな公開フック(IRB.doc_providers 案)を提案します。rurema 側では bitclust-irb(rurema/bitclust#326)が該当フックの不在によりやむを得ず別コマンド refe を登録している経緯があり、本提案が採用されれば show_doc から直接日本語マニュアルを引けるようになります。実装の方向性が受け入れられるなら PR を送る用意があります。

🤖 Generated with Claude Code

Lenguaje dominante
Ruby
Estrellas
478
Forks
158
Merge medio
22 h 56 min
PR fusionados (30 d)
12

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de ruby/irb

Todos los issues de ruby/irb

Issues similares

Más issues de Ruby

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.