Repository navigation
Description
Summary
With the Rubydex indexer (0.27.0.beta5), there is no working way to reduce what
gets indexed. The documented initializationOptions.indexing settings
(excludedGems, excludedPatterns, includedPatterns) have no effect, and
because indexing now covers every locked gem, startup is dominated by vendored
gem code.
Environment
- Ruby LSP
0.27.0.beta5(--beta), gemrubydex 0.4.4 - Neovim 0.12.4, launched through a per-project Ruby (
rv), composed.ruby-lspbundle - Project: Rails 8.1 app, Ruby 4.0.0, bundle at
vendor/bundle, 189 gems
Reproduction
- Launch the server against a project with a vendored bundle.
- Send
initializewithinitializationOptions: { indexing: { excludedGems: ["<gem>"] } }. - Compare the index contents with a run that omits the option — identical.
An excluded gem is still indexed, so exclusion cannot be used to cut startup time.
Expected
excludedGems / excludedPatterns from the documented initialization options
removes those files from the index, as they did with RubyIndexer.
Actual
The options are ignored entirely with the Rubydex indexer.
Evidence
- Nothing in
ruby_lsp/under0.27.0.beta5reads theindexingoptions. The
only occurrences are progress notifications and
perform_initial_indexing, which callsgraph.index_workspaceunconditionally:benchmark("index_workspace") { @global_state.graph.index_workspace } benchmark("full_resolve") { @global_state.graph.resolve }
rubydex.tomlhas no index section; adding one fails:The Ruby config API only modelsRubydex::ConfigError: Invalid config file .../rubydex.toml: unknown section `index`[linter].Rubydex::Graphexposes no setter in0.4.4:NoMethodError: undefined method 'exclude_patterns=' for an instance of Rubydex::GraphGraph#workspace_pathsseeds the index from every top-level workspace
directory plus each locked gem's require paths, with no group filtering:This also means development and test gems are indexed again, whereas Automatically exclude transitive test dependencies from indexing #1078specs = Bundler.locked_gems&.specs specs.each do |lazy_spec| spec = Gem::Specification.find_by_name(lazy_spec.name) spec.require_paths.each { |path| paths << File.join(spec.full_gem_path, path) } end
excluded development and transitive development dependencies.
Measured impact
On a Rails 8 project with a vendored bundle:
| Observation | Result |
|---|---|
index_workspace |
1.7 s |
resolve |
0.9 s |
| Indexed documents | 48,826 total: 2,276 app, 46,549 vendored gem |
| First request after startup | 4.1–4.8 s |
| Subsequent requests | 3–7 ms |
The cost is paid once per server process, since the graph is not cached to disk
(see #1009), and 95% of it is gem code from vendor/bundle.
Suggestion
Either honor initializationOptions.indexing.excludedGems / excludedPatterns
in the Rubydex path, or restore the previous behavior of skipping development
and test groups. Both would cut startup substantially for vendored bundles.
Activity
jadibdev commentedon Nov 3, 2026
Hi @itisbryan, rubydex does support exclusions, just not under the names in the issue. The section is
[graph]rather than[index], and the Ruby method isGraph#exclude_patterns(patterns)(there's no=setter, hence theNoMethodError).I tried this on a fresh Rails 8.1 app (Ruby 4.0.5, 142 gems vendored in
vendor/bundle, rubydex 0.4.4):index_workspacewent from 1.57s to 0.76s. The document count only dropped from 7,570 to 6,317, though, because gemlib/code is still indexed through the require paths. Watch out forvendor/bundle/**instead: it matches the require paths too and dropped every gem for me (22 documents left).@vinistock, most of what's left is gem code, and there's no config for that. The old indexer skipped development-only gems and honored
excludedGems, and here the rubocop gems alone were 1,276 of the 7,570 documents. Excluding a gem's directory throughexclude_patternsdoes drop it (I checked with arubocop*pattern), so ruby-lsp could do this today, applying it afterload_rubydex_configsinceload_configreplaces the patterns. Would you rather have that in ruby-lsp, or a gem filter in rubydex? Happy to put up a PR for whichever you prefer.Scripts: https://github.com/jadibdev/ruby-lsp/tree/4253-verification/verification-4253