Module: RubyLsp::Requests::Support::Common

Instance Method Summary collapse

Instance Method Details

#categorized_markdown_from_index_entries(title, entries, max_entries = nil) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/ruby_lsp/requests/support/common.rb', line 92

def categorized_markdown_from_index_entries(title, entries, max_entries = nil)
  markdown_title = "```ruby\n#{title}\n```"
  definitions = []
  content = +""
  entries = Array(entries)
  entries_to_format = max_entries ? entries.take(max_entries) : entries
  entries_to_format.each do |entry|
    loc = entry.location

    # We always handle locations as zero based. However, for file links in Markdown we need them to be one
    # based, which is why instead of the usual subtraction of 1 to line numbers, we are actually adding 1 to
    # columns. The format for VS Code file URIs is
    # `file:///path/to/file.rb#Lstart_line,start_column-end_line,end_column`
    uri = URI::Generic.from_path(
      path: entry.file_path,
      fragment: "L#{loc.start_line},#{loc.start_column + 1}-#{loc.end_line},#{loc.end_column + 1}",
    )

    definitions << "[#{entry.file_name}](#{uri})"
    content << "\n\n#{entry.comments.join("\n")}" unless entry.comments.empty?
  end

  additional_entries_text = if max_entries && entries.length > max_entries
    additional = entries.length - max_entries
    " | #{additional} other#{additional > 1 ? "s" : ""}"
  else
    ""
  end

  {
    title: markdown_title,
    links: "**Definitions**: #{definitions.join(" | ")}#{additional_entries_text}",
    documentation: content,
  }
end

#constant_name(node) ⇒ Object



160
161
162
163
164
165
# File 'lib/ruby_lsp/requests/support/common.rb', line 160

def constant_name(node)
  node.full_name
rescue Prism::ConstantPathNode::DynamicPartsInConstantPathError,
       Prism::ConstantPathNode::MissingNodesInConstantPathError
  nil
end

#create_code_lens(node, title:, command_name:, arguments:, data:) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/ruby_lsp/requests/support/common.rb', line 58

def create_code_lens(node, title:, command_name:, arguments:, data:)
  range = range_from_node(node)

  Interface::CodeLens.new(
    range: range,
    command: Interface::Command.new(
      title: title,
      command: command_name,
      arguments: arguments,
    ),
    data: data,
  )
end

#each_constant_path_part(node, &block) ⇒ Object



185
186
187
188
189
190
191
192
# File 'lib/ruby_lsp/requests/support/common.rb', line 185

def each_constant_path_part(node, &block)
  current = T.let(node, T.nilable(Prism::Node))

  while current.is_a?(Prism::ConstantPathNode)
    block.call(current)
    current = current.parent
  end
end

#kind_for_entry(entry) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/ruby_lsp/requests/support/common.rb', line 195

def kind_for_entry(entry)
  case entry
  when RubyIndexer::Entry::Class
    Constant::SymbolKind::CLASS
  when RubyIndexer::Entry::Module
    Constant::SymbolKind::NAMESPACE
  when RubyIndexer::Entry::Constant
    Constant::SymbolKind::CONSTANT
  when RubyIndexer::Entry::Method
    entry.name == "initialize" ? Constant::SymbolKind::CONSTRUCTOR : Constant::SymbolKind::METHOD
  when RubyIndexer::Entry::Accessor
    Constant::SymbolKind::PROPERTY
  when RubyIndexer::Entry::InstanceVariable
    Constant::SymbolKind::FIELD
  end
end

#markdown_from_index_entries(title, entries, max_entries = nil, extra_links: nil) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/ruby_lsp/requests/support/common.rb', line 136

def markdown_from_index_entries(title, entries, max_entries = nil, extra_links: nil)
  categorized_markdown = categorized_markdown_from_index_entries(title, entries, max_entries)

  markdown = +(categorized_markdown[:title] || "")
  markdown << "\n\n#{extra_links}" if extra_links

  "    \#{markdown}\n\n    \#{categorized_markdown[:links]}\n\n    \#{categorized_markdown[:documentation]}\n  MARKDOWN\nend\n".chomp

#namespace_constant_name(node) ⇒ Object



168
169
170
171
172
173
174
# File 'lib/ruby_lsp/requests/support/common.rb', line 168

def namespace_constant_name(node)
  path = node.constant_path
  case path
  when Prism::ConstantPathNode, Prism::ConstantReadNode, Prism::ConstantPathTargetNode
    constant_name(path)
  end
end

#not_in_dependencies?(file_path) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
76
77
# File 'lib/ruby_lsp/requests/support/common.rb', line 73

def not_in_dependencies?(file_path)
  BUNDLE_PATH &&
    !file_path.start_with?(T.must(BUNDLE_PATH)) &&
    !file_path.start_with?(RbConfig::CONFIG["rubylibdir"])
end

#range_from_location(location) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/ruby_lsp/requests/support/common.rb', line 30

def range_from_location(location)
  Interface::Range.new(
    start: Interface::Position.new(
      line: location.start_line - 1,
      character: location.start_column,
    ),
    end: Interface::Position.new(line: location.end_line - 1, character: location.end_column),
  )
end

#range_from_node(node) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/ruby_lsp/requests/support/common.rb', line 17

def range_from_node(node)
  loc = node.location

  Interface::Range.new(
    start: Interface::Position.new(
      line: loc.start_line - 1,
      character: loc.start_column,
    ),
    end: Interface::Position.new(line: loc.end_line - 1, character: loc.end_column),
  )
end

#self_receiver?(node) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
83
# File 'lib/ruby_lsp/requests/support/common.rb', line 80

def self_receiver?(node)
  receiver = node.receiver
  receiver.nil? || receiver.is_a?(Prism::SelfNode)
end

#sorbet_level_true_or_higher?(sorbet_level) ⇒ Boolean

Returns:

  • (Boolean)


213
214
215
# File 'lib/ruby_lsp/requests/support/common.rb', line 213

def sorbet_level_true_or_higher?(sorbet_level)
  sorbet_level == RubyDocument::SorbetLevel::True || sorbet_level == RubyDocument::SorbetLevel::Strict
end

#visible?(node, range) ⇒ Boolean

Returns:

  • (Boolean)


41
42
43
44
45
46
47
# File 'lib/ruby_lsp/requests/support/common.rb', line 41

def visible?(node, range)
  return true if range.nil?
  return false if node.nil?

  loc = node.location
  range.cover?(loc.start_line - 1) && range.cover?(loc.end_line - 1)
end