Class: RubyLsp::Requests::DocumentLink

Inherits:
BaseRequest
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/ruby_lsp/requests/document_link.rb

Overview

![Document link demo](../../misc/document_link.gif)

The [document link](microsoft.github.io/language-server-protocol/specification#textDocument_documentLink) makes ‘# source://PATH_TO_FILE:line` comments in a Ruby/RBI file clickable if the file exists. When the user clicks the link, it’ll open that location.

# Example

“‘ruby # source://syntax_tree-3.2.1/lib/syntax_tree.rb:51 <- it will be clickable and will take the user to that location def format(source, maxwidth = T.unsafe(nil)) end “`

Constant Summary collapse

RUBY_ROOT =
"RUBY_ROOT"

Instance Method Summary collapse

Methods inherited from BaseRequest

#range_from_syntax_tree_node

Constructor Details

#initialize(document) ⇒ DocumentLink

Returns a new instance of DocumentLink.



25
26
27
28
29
# File 'lib/ruby_lsp/requests/document_link.rb', line 25

def initialize(document)
  super

  @links = T.let([], T::Array[LanguageServer::Protocol::Interface::DocumentLink])
end

Instance Method Details

#runObject



32
33
34
35
# File 'lib/ruby_lsp/requests/document_link.rb', line 32

def run
  visit(@document.tree)
  @links
end

#visit_comment(node) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/ruby_lsp/requests/document_link.rb', line 38

def visit_comment(node)
  match = node.value.match(%r{source://(?<path>.*):(?<line>\d+)$})
  return unless match

  file_path = if match[:path].start_with?(RUBY_ROOT)
    match[:path].sub(RUBY_ROOT, RbConfig::CONFIG["rubylibdir"])
  else
    File.join(Bundler.bundle_path, "gems", match[:path])
  end
  return unless File.exist?(file_path)

  target = "file://#{file_path}##{match[:line]}"

  @links << LanguageServer::Protocol::Interface::DocumentLink.new(
    range: range_from_syntax_tree_node(node),
    target: target,
    tooltip: "Jump to #{target.delete_prefix("file://")}"
  )
end