Class: RubyLsp::Requests::WorkspaceSymbol

Inherits:
Request
  • Object
show all
Extended by:
T::Sig
Includes:
Support::Common
Defined in:
lib/ruby_lsp/requests/workspace_symbol.rb

Overview

![Workspace symbol demo](../../workspace_symbol.gif)

The [workspace symbol](microsoft.github.io/language-server-protocol/specification#workspace_symbol) request allows fuzzy searching declarations in the entire project. On VS Code, use CTRL/CMD + T to search for symbols.

# Example

“‘ruby # Searching for `Floo` will fuzzy match and return all declarations according to the query, including this `Foo` class class Foo end “`

Instance Method Summary collapse

Methods included from Support::Common

#categorized_markdown_from_index_entries, #constant_name, #create_code_lens, #each_constant_path_part, #kind_for_entry, #markdown_from_index_entries, #namespace_constant_name, #not_in_dependencies?, #range_from_location, #range_from_node, #self_receiver?, #sorbet_level_true_or_higher?, #visible?

Constructor Details

#initialize(global_state, query) ⇒ WorkspaceSymbol

Returns a new instance of WorkspaceSymbol.



26
27
28
29
30
31
# File 'lib/ruby_lsp/requests/workspace_symbol.rb', line 26

def initialize(global_state, query)
  super()
  @global_state = global_state
  @query = query
  @index = T.let(global_state.index, RubyIndexer::Index)
end

Instance Method Details

#performObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ruby_lsp/requests/workspace_symbol.rb', line 34

def perform
  @index.fuzzy_search(@query).filter_map do |entry|
    file_path = entry.file_path

    # We only show symbols declared in the workspace
    in_dependencies = !not_in_dependencies?(file_path)
    next if in_dependencies

    # We should never show private symbols when searching the entire workspace
    next if entry.private?

    kind = kind_for_entry(entry)
    loc = entry.location

    # We use the namespace as the container name, but we also use the full name as the regular name. The reason we
    # do this is to allow people to search for fully qualified names (e.g.: `Foo::Bar`). If we only included the
    # short name `Bar`, then searching for `Foo::Bar` would not return any results
    *container, _short_name = entry.name.split("::")

    Interface::WorkspaceSymbol.new(
      name: entry.name,
      container_name: container.join("::"),
      kind: kind,
      location: Interface::Location.new(
        uri: URI::Generic.from_path(path: file_path).to_s,
        range:  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
end