From 9c5b8c1471590525291827694f591b5c91ecff3c Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Wed, 18 Mar 2026 14:24:39 +1300 Subject: [PATCH 01/17] fix: include_project_adds (default: false) --- lib/ruby_lsp/server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 170c755da..1fbbe839b 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -166,7 +166,7 @@ def process_response(message) end #: (?include_project_addons: bool) -> void - def load_addons(include_project_addons: true) + def load_addons(include_project_addons: false) # If invoking Bundler.setup failed, then the load path will not be configured properly and trying to load add-ons # with Gem.find_files will find every single version installed of an add-on, leading to requiring several # different versions of the same files. We cannot load add-ons if Bundler.setup failed From f7b2f1726f0476dab09fd7893d0abb4231a1e35a Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 06:49:17 +1300 Subject: [PATCH 02/17] debug+ --- Gemfile | 1 + Gemfile.lock | 4 ++++ .../lib/ruby_indexer/configuration.rb | 14 +++++++++++++- lib/ruby_indexer/lib/ruby_indexer/index.rb | 10 ++++++++-- lib/ruby_lsp/server.rb | 18 ++++++++++++------ 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index d61d2166f..c95f6ebfd 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,7 @@ gemspec gem "bundler", "~> 4.0.0" gem "minitest", "~> 6.0" gem "test-unit", require: false +gem "byebug" group :development do gem "debug", "~> 1.9", require: false diff --git a/Gemfile.lock b/Gemfile.lock index 90dd0e7aa..f8b5512c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,6 +11,8 @@ GEM specs: ast (2.4.3) benchmark (0.5.0) + byebug (13.0.0) + reline (>= 0.6.0) date (3.5.1) debug (1.11.1) irb (~> 1.10) @@ -141,6 +143,7 @@ PLATFORMS DEPENDENCIES bundler (~> 4.0.0) + byebug debug (~> 1.9) minitest (~> 6.0) mocha (~> 2.3) @@ -160,6 +163,7 @@ DEPENDENCIES CHECKSUMS ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c + byebug (13.0.0) sha256=d2263efe751941ca520fa29744b71972d39cbc41839496706f5d9b22e92ae05d date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5 diff --git a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb index 46afacca9..5587c3691 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb @@ -56,7 +56,7 @@ def initialize end #: -> Array[URI::Generic] - def indexable_uris + def indexable_uris(&block) excluded_gems = @excluded_gems - @included_gems locked_gems = Bundler.locked_gems&.specs @@ -65,6 +65,9 @@ def indexable_uris flags = File::FNM_PATHNAME | File::FNM_EXTGLOB + block.call(0, debug: "spotting uris of included_patterns") + sleep(1.5) + uris = @included_patterns.flat_map do |pattern| load_path_entry = nil #: String? @@ -81,6 +84,9 @@ def indexable_uris end end + block.call(0, debug: "spotted included_patterns") + sleep(1.5) + # If the patterns are relative, we make it relative to the workspace path. If they are absolute, then we shouldn't # concatenate anything excluded_patterns = @excluded_patterns.map do |pattern| @@ -91,6 +97,9 @@ def indexable_uris end end + block.call(0, debug: "spotted excluded_patterns") + sleep(1.5) + # Remove user specified patterns bundle_path = Bundler.settings["path"]&.gsub(/[\\]+/, "/") uris.reject! do |indexable| @@ -100,6 +109,9 @@ def indexable_uris excluded_patterns.any? { |pattern| File.fnmatch?(pattern, path, flags) } end + block.call(0, debug: "rejected excluded_patterns") + sleep(1.5) + # Add default gems to the list of files to be indexed Dir.glob(File.join(RbConfig::CONFIG["rubylibdir"], "*")).each do |default_path| # The default_path might be a Ruby file or a folder with the gem's name. For example: diff --git a/lib/ruby_indexer/lib/ruby_indexer/index.rb b/lib/ruby_indexer/lib/ruby_indexer/index.rb index 4cf8895d6..aaff35fee 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/index.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/index.rb @@ -354,7 +354,13 @@ def resolve(name, nesting, seen_names = []) # indexing progress. That block is invoked with the current progress percentage and should return `true` to continue # indexing or `false` to stop indexing. #: (?uris: Array[URI::Generic]) ?{ (Integer progress) -> bool } -> void - def index_all(uris: @configuration.indexable_uris, &block) + def index_all(uris: [], &block) + block.call(0, debug: "in '#{__method__}'...") + sleep 5 + uris = @configuration.indexable_uris(&block) if uris.empty? + + block.call(0, debug: "spotted indexable_uris") + # When troubleshooting an indexing issue, e.g. through irb, it's not obvious that `index_all` will augment the # existing index values, meaning it may contain 'stale' entries. This check ensures that the user is aware of this # behavior and can take appropriate action. @@ -370,7 +376,7 @@ def index_all(uris: @configuration.indexable_uris, &block) uris.each_with_index do |uri, index| if block && index % progress_step == 0 progress = (index / progress_step) + 1 - break unless block.call(progress) + break unless block.call(progress, debug: "#{index} Indexing '#{uri}'") end index_file(uri, collect_comments: false) diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 1fbbe839b..416f71a2f 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -1232,8 +1232,8 @@ def perform_initial_indexing # stuck indexing files Thread.new do begin - @global_state.index.index_all do |percentage| - progress("indexing-progress", percentage) + @global_state.index.index_all do |percentage, debug: nil| + progress("indexing-progress", percentage, debug: debug) true rescue ClosedQueueError # Since we run indexing on a separate thread, it's possible to kill the server before indexing is complete. @@ -1275,7 +1275,7 @@ def perform_initial_indexing end #: (String id, String title, ?percentage: Integer) -> void - def begin_progress(id, title, percentage: 0) + def begin_progress(id, title, percentage: 0, debug: nil) return unless @global_state.client_capabilities.supports_progress send_message(Request.new( @@ -1284,14 +1284,20 @@ def begin_progress(id, title, percentage: 0) params: Interface::WorkDoneProgressCreateParams.new(token: id), )) - send_message(Notification.progress_begin(id, title, percentage: percentage, message: "#{percentage}% completed")) + message = "#{percentage}% completed" + message << "(#{debug})" if debug + + send_message(Notification.progress_begin(id, title, percentage: percentage, message: message)) end #: (String id, Integer percentage) -> void - def progress(id, percentage) + def progress(id, percentage, debug: nil) return unless @global_state.client_capabilities.supports_progress - send_message(Notification.progress_report(id, percentage: percentage, message: "#{percentage}% completed")) + message = "#{percentage}% completed" + message << "(#{debug})" if debug + + send_message(Notification.progress_report(id, percentage: percentage, message: message)) end #: (String id) -> void From 1f558b1faa9fd0ed4c95c8cf206eae075f27b4ec Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 07:15:58 +1300 Subject: [PATCH 03/17] more feedback on indexation issues --- .../lib/ruby_indexer/configuration.rb | 24 +++++++++---------- lib/ruby_lsp/server.rb | 20 +++++++--------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb index 5587c3691..5462ed7d0 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb @@ -56,7 +56,7 @@ def initialize end #: -> Array[URI::Generic] - def indexable_uris(&block) + def indexable_uris(&logging) excluded_gems = @excluded_gems - @included_gems locked_gems = Bundler.locked_gems&.specs @@ -65,13 +65,22 @@ def indexable_uris(&block) flags = File::FNM_PATHNAME | File::FNM_EXTGLOB - block.call(0, debug: "spotting uris of included_patterns") + logging.call(log: "Spotting uris of included_patterns...") sleep(1.5) uris = @included_patterns.flat_map do |pattern| load_path_entry = nil #: String? - Dir.glob(File.join(@workspace_path, pattern), flags).map! do |path| + begin + glob_pattern = File.join(@workspace_path, pattern) + glob_results = Dir.glob(glob_pattern, flags) + rescue StandardError => error + message = "Failed to spot uris of included_pattern: '#{pattern}': (#{error.class.name} - #{error.message})" + logging.call(log: message) + next + end + + glob_results.map! do |path| # All entries for the same pattern match the same $LOAD_PATH entry. Since searching the $LOAD_PATH for every # entry is expensive, we memoize it until we find a path that doesn't belong to that $LOAD_PATH. This happens # on repositories that define multiple gems, like Rails. All frameworks are defined inside the current @@ -84,9 +93,6 @@ def indexable_uris(&block) end end - block.call(0, debug: "spotted included_patterns") - sleep(1.5) - # If the patterns are relative, we make it relative to the workspace path. If they are absolute, then we shouldn't # concatenate anything excluded_patterns = @excluded_patterns.map do |pattern| @@ -97,9 +103,6 @@ def indexable_uris(&block) end end - block.call(0, debug: "spotted excluded_patterns") - sleep(1.5) - # Remove user specified patterns bundle_path = Bundler.settings["path"]&.gsub(/[\\]+/, "/") uris.reject! do |indexable| @@ -109,9 +112,6 @@ def indexable_uris(&block) excluded_patterns.any? { |pattern| File.fnmatch?(pattern, path, flags) } end - block.call(0, debug: "rejected excluded_patterns") - sleep(1.5) - # Add default gems to the list of files to be indexed Dir.glob(File.join(RbConfig::CONFIG["rubylibdir"], "*")).each do |default_path| # The default_path might be a Ruby file or a folder with the gem's name. For example: diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 416f71a2f..f35c7b887 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -1232,8 +1232,8 @@ def perform_initial_indexing # stuck indexing files Thread.new do begin - @global_state.index.index_all do |percentage, debug: nil| - progress("indexing-progress", percentage, debug: debug) + @global_state.index.index_all do |percentage = 0, log: nil| + progress("indexing-progress", percentage, log: log) true rescue ClosedQueueError # Since we run indexing on a separate thread, it's possible to kill the server before indexing is complete. @@ -1244,6 +1244,7 @@ def perform_initial_indexing rescue StandardError => error message = "Error while indexing (see [troubleshooting steps]" \ "(https://shopify.github.io/ruby-lsp/troubleshooting#indexing)): #{error.message}" + send_log_message("#{message}\n\n#{error.backtrace.join("\n")}") send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR)) end @@ -1275,7 +1276,7 @@ def perform_initial_indexing end #: (String id, String title, ?percentage: Integer) -> void - def begin_progress(id, title, percentage: 0, debug: nil) + def begin_progress(id, title, percentage: 0) return unless @global_state.client_capabilities.supports_progress send_message(Request.new( @@ -1284,20 +1285,15 @@ def begin_progress(id, title, percentage: 0, debug: nil) params: Interface::WorkDoneProgressCreateParams.new(token: id), )) - message = "#{percentage}% completed" - message << "(#{debug})" if debug - - send_message(Notification.progress_begin(id, title, percentage: percentage, message: message)) + send_message(Notification.progress_begin(id, title, percentage: percentage, message: "#{percentage}% completed")) end #: (String id, Integer percentage) -> void - def progress(id, percentage, debug: nil) + def progress(id, percentage, log: nil) return unless @global_state.client_capabilities.supports_progress - message = "#{percentage}% completed" - message << "(#{debug})" if debug - - send_message(Notification.progress_report(id, percentage: percentage, message: message)) + send_log_message(log) if log + send_message(Notification.progress_report(id, percentage: percentage, message: "#{percentage}% completed")) end #: (String id) -> void From 547ed3881bc21b7aa81cb64a833f1cad2362c44d Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 07:26:01 +1300 Subject: [PATCH 04/17] debug- --- lib/ruby_indexer/lib/ruby_indexer/index.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/index.rb b/lib/ruby_indexer/lib/ruby_indexer/index.rb index aaff35fee..21a0ce155 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/index.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/index.rb @@ -355,12 +355,8 @@ def resolve(name, nesting, seen_names = []) # indexing or `false` to stop indexing. #: (?uris: Array[URI::Generic]) ?{ (Integer progress) -> bool } -> void def index_all(uris: [], &block) - block.call(0, debug: "in '#{__method__}'...") - sleep 5 uris = @configuration.indexable_uris(&block) if uris.empty? - block.call(0, debug: "spotted indexable_uris") - # When troubleshooting an indexing issue, e.g. through irb, it's not obvious that `index_all` will augment the # existing index values, meaning it may contain 'stale' entries. This check ensures that the user is aware of this # behavior and can take appropriate action. @@ -376,7 +372,7 @@ def index_all(uris: [], &block) uris.each_with_index do |uri, index| if block && index % progress_step == 0 progress = (index / progress_step) + 1 - break unless block.call(progress, debug: "#{index} Indexing '#{uri}'") + break unless block.call(progress) end index_file(uri, collect_comments: false) From e7eadd0188ed59150613b42e2bef0b91acd5b019 Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 07:48:57 +1300 Subject: [PATCH 05/17] fix: respect exclusive patterns --- lib/ruby_indexer/lib/ruby_indexer/configuration.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb index 5462ed7d0..331631119 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb @@ -39,7 +39,7 @@ def initialize # We start the included patterns with only the non excluded directories so that we can avoid paying the price of # traversing large directories that don't include Ruby files like `node_modules` - @included_patterns = ["{#{top_level_directories.join(",")}}/**/*.rb", "*.rb"] #: Array[String] + @included_patterns = ["*.rb", *top_level_directories.map {|name| "#{name}/**/*.rb"}] #: Array[String] @excluded_magic_comments = [ "frozen_string_literal:", "typed:", @@ -189,8 +189,11 @@ def apply_config(config) @excluded_gems.concat(config["excluded_gems"]) if config["excluded_gems"] @included_gems.concat(config["included_gems"]) if config["included_gems"] - @excluded_patterns.concat(config["excluded_patterns"]) if config["excluded_patterns"] @included_patterns.concat(config["included_patterns"]) if config["included_patterns"] + if config["excluded_patterns"] + @excluded_patterns.concat(config["excluded_patterns"]) + @included_patterns -= config["excluded_patterns"] + end @excluded_magic_comments.concat(config["excluded_magic_comments"]) if config["excluded_magic_comments"] end From 0c566569a8ede32a9179dd83fdf71aa35e8e0a93 Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 07:55:51 +1300 Subject: [PATCH 06/17] fix: skipped patterns require compact --- lib/ruby_indexer/lib/ruby_indexer/configuration.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb index 331631119..da9cd43a3 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb @@ -91,7 +91,7 @@ def indexable_uris(&logging) URI::Generic.from_path(path: path, load_path_entry: load_path_entry) end - end + end.compact # If the patterns are relative, we make it relative to the workspace path. If they are absolute, then we shouldn't # concatenate anything From 9602e09621a41986987a94bebbcde0404dd46a43 Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 07:57:23 +1300 Subject: [PATCH 07/17] debug+ --- lib/ruby_indexer/lib/ruby_indexer/configuration.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb index da9cd43a3..5f2200cec 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb @@ -75,7 +75,8 @@ def indexable_uris(&logging) glob_pattern = File.join(@workspace_path, pattern) glob_results = Dir.glob(glob_pattern, flags) rescue StandardError => error - message = "Failed to spot uris of included_pattern: '#{pattern}': (#{error.class.name} - #{error.message})" + message = "Failed to spot uris of included_pattern: '#{pattern}': (#{error.class.name} - #{error.message})" + message << "\nExcluded patterns: #{@excluded_patterns.join(', ')}" logging.call(log: message) next end From 6c8f089f50fffbb7d676cf8932143b5e05101c6c Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:29:12 +1300 Subject: [PATCH 08/17] debug- --- .../lib/ruby_indexer/configuration.rb | 8 ++------ lib/ruby_lsp/server.rb | 16 +++++++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb index 5f2200cec..9e229e245 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb @@ -65,9 +65,6 @@ def indexable_uris(&logging) flags = File::FNM_PATHNAME | File::FNM_EXTGLOB - logging.call(log: "Spotting uris of included_patterns...") - sleep(1.5) - uris = @included_patterns.flat_map do |pattern| load_path_entry = nil #: String? @@ -75,9 +72,8 @@ def indexable_uris(&logging) glob_pattern = File.join(@workspace_path, pattern) glob_results = Dir.glob(glob_pattern, flags) rescue StandardError => error - message = "Failed to spot uris of included_pattern: '#{pattern}': (#{error.class.name} - #{error.message})" - message << "\nExcluded patterns: #{@excluded_patterns.join(', ')}" - logging.call(log: message) + message = "Indexation error on included_pattern: '#{pattern}': (#{error.class.name} - #{error.message})" + logging.call(error: message) next end diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index f35c7b887..7028500aa 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -1232,8 +1232,15 @@ def perform_initial_indexing # stuck indexing files Thread.new do begin - @global_state.index.index_all do |percentage = 0, log: nil| - progress("indexing-progress", percentage, log: log) + @global_state.index.index_all do |percentage = 0, log: nil, error: nil| + send_log_message(log) if log + if error + send_log_message(error, type: Constant::MessageType::ERROR) + send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR)) + end + + progress("indexing-progress", percentage) + true rescue ClosedQueueError # Since we run indexing on a separate thread, it's possible to kill the server before indexing is complete. @@ -1244,7 +1251,7 @@ def perform_initial_indexing rescue StandardError => error message = "Error while indexing (see [troubleshooting steps]" \ "(https://shopify.github.io/ruby-lsp/troubleshooting#indexing)): #{error.message}" - send_log_message("#{message}\n\n#{error.backtrace.join("\n")}") + send_log_message("#{message}\n\n#{error.backtrace.join("\n")}", type: Constant::MessageType::ERROR) send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR)) end @@ -1289,10 +1296,9 @@ def begin_progress(id, title, percentage: 0) end #: (String id, Integer percentage) -> void - def progress(id, percentage, log: nil) + def progress(id, percentage) return unless @global_state.client_capabilities.supports_progress - send_log_message(log) if log send_message(Notification.progress_report(id, percentage: percentage, message: "#{percentage}% completed")) end From b2192f179d7460e0cfe0665c05aad006c3d88fdd Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:29:29 +1300 Subject: [PATCH 09/17] Revert "fix: include_project_adds (default: false)" This reverts commit 9c5b8c1471590525291827694f591b5c91ecff3c. --- lib/ruby_lsp/server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 7028500aa..996d3aaba 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -166,7 +166,7 @@ def process_response(message) end #: (?include_project_addons: bool) -> void - def load_addons(include_project_addons: false) + def load_addons(include_project_addons: true) # If invoking Bundler.setup failed, then the load path will not be configured properly and trying to load add-ons # with Gem.find_files will find every single version installed of an add-on, leading to requiring several # different versions of the same files. We cannot load add-ons if Bundler.setup failed From 513c5d50451e67ca83117ca3d004185b0e103daa Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:34:55 +1300 Subject: [PATCH 10/17] load_adds: add logging --- lib/ruby_lsp/addon.rb | 2 +- lib/ruby_lsp/server.rb | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/ruby_lsp/addon.rb b/lib/ruby_lsp/addon.rb index c346d6ea6..da7d4e8f0 100644 --- a/lib/ruby_lsp/addon.rb +++ b/lib/ruby_lsp/addon.rb @@ -49,7 +49,7 @@ def inherited(child_class) # Discovers and loads all add-ons. Returns a list of errors when trying to require add-ons #: (GlobalState global_state, Thread::Queue outgoing_queue, ?include_project_addons: bool) -> Array[StandardError] - def load_addons(global_state, outgoing_queue, include_project_addons: true) + def load_addons(global_state, outgoing_queue, include_project_addons: true, &logging) # Require all add-ons entry points, which should be placed under # `some_gem/lib/ruby_lsp/your_gem_name/addon.rb` or in the workspace under # `your_project/ruby_lsp/project_name/addon.rb` diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 996d3aaba..75f9c9337 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -172,7 +172,18 @@ def load_addons(include_project_addons: true) # different versions of the same files. We cannot load add-ons if Bundler.setup failed return if @setup_error - errors = Addon.load_addons(@global_state, @outgoing_queue, include_project_addons: include_project_addons) + errors = Addon.load_addons( + @global_state, + @outgoing_queue, + include_project_addons: include_project_addons + ) do |log: nil, error: nil| + send_log_message(log) if log + if error + send_log_message(error, type: Constant::MessageType::ERROR) + send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR)) + end + end + return if test_mode? if errors.any? From 4c7445935ea7ef528417733cf2ab94a55e682fc0 Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:53:26 +1300 Subject: [PATCH 11/17] improve: log load_addons errors and continue --- lib/ruby_lsp/addon.rb | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/ruby_lsp/addon.rb b/lib/ruby_lsp/addon.rb index da7d4e8f0..916329aba 100644 --- a/lib/ruby_lsp/addon.rb +++ b/lib/ruby_lsp/addon.rb @@ -56,7 +56,19 @@ def load_addons(global_state, outgoing_queue, include_project_addons: true, &log addon_files = Gem.find_files("ruby_lsp/**/addon.rb") if include_project_addons - project_addons = Dir.glob("#{global_state.workspace_path}/**/ruby_lsp/**/addon.rb") + workspace_path = global_state.workspace_path + spaces = top_level_directories.map do |space| + "#{workspace_path}/#{space}/**/ruby_lsp/**/addon.rb" + end + + project_addons = spaces.flat_map do |pattern| + Dir.glob(pattern) + rescue StandardError => error + message = "Addon discovery failed with pattern: '#{pattern}': (#{error.class.name} - #{error.message})" + logging.call(error: message) + next + end.compact + bundle_path = Bundler.bundle_path.to_s gems_dir = Bundler.bundle_path.join("gems") @@ -273,5 +285,15 @@ def create_discover_tests_listener(response_builder, dispatcher, uri); end def resolve_test_commands(items) [] end + + #: -> Array[String] + def top_level_directories + Dir.glob("#{Dir.pwd}/*").filter_map do |path| + dir_name = File.basename(path) + next unless File.directory?(path) + + dir_name + end + end end end From 5bd0dde6c759e7554b42840a56b053fba41a8c97 Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:58:14 +1300 Subject: [PATCH 12/17] fix: move to private class method --- lib/ruby_lsp/addon.rb | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/ruby_lsp/addon.rb b/lib/ruby_lsp/addon.rb index 916329aba..a565f4a23 100644 --- a/lib/ruby_lsp/addon.rb +++ b/lib/ruby_lsp/addon.rb @@ -174,6 +174,18 @@ def depend_on_ruby_lsp!(*version_constraints) "Add-on is not compatible with this version of the Ruby LSP. Skipping its activation" end end + + private + + #: -> Array[String] + def top_level_directories + Dir.glob("#{Dir.pwd}/*").filter_map do |path| + dir_name = File.basename(path) + next unless File.directory?(path) + + dir_name + end + end end #: -> void @@ -285,15 +297,5 @@ def create_discover_tests_listener(response_builder, dispatcher, uri); end def resolve_test_commands(items) [] end - - #: -> Array[String] - def top_level_directories - Dir.glob("#{Dir.pwd}/*").filter_map do |path| - dir_name = File.basename(path) - next unless File.directory?(path) - - dir_name - end - end end end From 60f4cae0c3956993f3a4c10e279504520be3d10d Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Thu, 19 Mar 2026 13:03:28 +1300 Subject: [PATCH 13/17] fix: typo --- lib/ruby_indexer/lib/ruby_indexer/configuration.rb | 2 +- lib/ruby_lsp/server.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb index 9e229e245..70a8407d4 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb @@ -72,7 +72,7 @@ def indexable_uris(&logging) glob_pattern = File.join(@workspace_path, pattern) glob_results = Dir.glob(glob_pattern, flags) rescue StandardError => error - message = "Indexation error on included_pattern: '#{pattern}': (#{error.class.name} - #{error.message})" + message = "Indexation error on included_pattern: '#{pattern}': (#{error.class.name} - #{error.message})" logging.call(error: message) next end diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 75f9c9337..4557c1b94 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -180,7 +180,7 @@ def load_addons(include_project_addons: true) send_log_message(log) if log if error send_log_message(error, type: Constant::MessageType::ERROR) - send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR)) + send_message(Notification.window_show_message(error, type: Constant::MessageType::ERROR)) end end @@ -1247,7 +1247,7 @@ def perform_initial_indexing send_log_message(log) if log if error send_log_message(error, type: Constant::MessageType::ERROR) - send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR)) + send_message(Notification.window_show_message(error, type: Constant::MessageType::ERROR)) end progress("indexing-progress", percentage) From 74d212bb360c6957ecb4963283e7e86dc6116135 Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Fri, 20 Mar 2026 06:10:17 +1300 Subject: [PATCH 14/17] add project ruby_lsp root --- lib/ruby_lsp/addon.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ruby_lsp/addon.rb b/lib/ruby_lsp/addon.rb index a565f4a23..a1dd23cbf 100644 --- a/lib/ruby_lsp/addon.rb +++ b/lib/ruby_lsp/addon.rb @@ -60,6 +60,7 @@ def load_addons(global_state, outgoing_queue, include_project_addons: true, &log spaces = top_level_directories.map do |space| "#{workspace_path}/#{space}/**/ruby_lsp/**/addon.rb" end + spaces << "#{workspace_path}/ruby_lsp/**/addon.rb" project_addons = spaces.flat_map do |pattern| Dir.glob(pattern) From d231c5490a1de118bb1ecf1432f9ec2a55655a46 Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Fri, 20 Mar 2026 06:14:30 +1300 Subject: [PATCH 15/17] fix: don't update progress unless there's a percentage --- lib/ruby_lsp/server.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 4557c1b94..48232906b 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -1243,14 +1243,14 @@ def perform_initial_indexing # stuck indexing files Thread.new do begin - @global_state.index.index_all do |percentage = 0, log: nil, error: nil| + @global_state.index.index_all do |percentage = nil, log: nil, error: nil| send_log_message(log) if log if error send_log_message(error, type: Constant::MessageType::ERROR) send_message(Notification.window_show_message(error, type: Constant::MessageType::ERROR)) end - progress("indexing-progress", percentage) + progress("indexing-progress", percentage) unless percentage.nil? true rescue ClosedQueueError From a5c3a5b6ac8dc34bbbcd948a65e4395f01c25c5c Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Fri, 20 Mar 2026 06:27:37 +1300 Subject: [PATCH 16/17] remove byebug --- Gemfile | 1 - Gemfile.lock | 4 ---- 2 files changed, 5 deletions(-) diff --git a/Gemfile b/Gemfile index c95f6ebfd..d61d2166f 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,6 @@ gemspec gem "bundler", "~> 4.0.0" gem "minitest", "~> 6.0" gem "test-unit", require: false -gem "byebug" group :development do gem "debug", "~> 1.9", require: false diff --git a/Gemfile.lock b/Gemfile.lock index f8b5512c3..90dd0e7aa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,8 +11,6 @@ GEM specs: ast (2.4.3) benchmark (0.5.0) - byebug (13.0.0) - reline (>= 0.6.0) date (3.5.1) debug (1.11.1) irb (~> 1.10) @@ -143,7 +141,6 @@ PLATFORMS DEPENDENCIES bundler (~> 4.0.0) - byebug debug (~> 1.9) minitest (~> 6.0) mocha (~> 2.3) @@ -163,7 +160,6 @@ DEPENDENCIES CHECKSUMS ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c - byebug (13.0.0) sha256=d2263efe751941ca520fa29744b71972d39cbc41839496706f5d9b22e92ae05d date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5 From 9a5097e81682b3b97373af3443115ebb0c952f58 Mon Sep 17 00:00:00 2001 From: oss <30378924+rellampec@users.noreply.github.com> Date: Fri, 20 Mar 2026 06:43:41 +1300 Subject: [PATCH 17/17] I have signed the CLA! --- lib/ruby_lsp/server.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 48232906b..88317dd9c 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -1262,6 +1262,7 @@ def perform_initial_indexing rescue StandardError => error message = "Error while indexing (see [troubleshooting steps]" \ "(https://shopify.github.io/ruby-lsp/troubleshooting#indexing)): #{error.message}" + send_log_message("#{message}\n\n#{error.backtrace.join("\n")}", type: Constant::MessageType::ERROR) send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR)) end