Skip to content

Commit

Permalink
Request diagnostic refresh when RuboCop configs change
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Jan 16, 2025
1 parent 60390ec commit 5dfbc44
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 8 deletions.
8 changes: 7 additions & 1 deletion lib/ruby_lsp/client_capabilities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class ClientCapabilities
attr_reader :supports_watching_files,
:supports_request_delegation,
:window_show_message_supports_extra_properties,
:supports_progress
:supports_progress,
:supports_diagnostic_refresh

sig { void }
def initialize
Expand All @@ -32,6 +33,9 @@ def initialize

# The editor supports displaying progress requests
@supports_progress = T.let(false, T::Boolean)

# The editor supports server initiated refresh for diagnostics
@supports_diagnostic_refresh = T.let(false, T::Boolean)
end

sig { params(capabilities: T::Hash[Symbol, T.untyped]).void }
Expand All @@ -57,6 +61,8 @@ def apply_client_capabilities(capabilities)

progress = capabilities.dig(:window, :workDoneProgress)
@supports_progress = progress if progress

@supports_diagnostic_refresh = workspace_capabilities.dig(:diagnostics, :refreshSupport) || false
end

sig { returns(T::Boolean) }
Expand Down
14 changes: 9 additions & 5 deletions lib/ruby_lsp/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1039,16 +1039,20 @@ def handle_ruby_file_change(index, file_path, change_type)
def handle_rubocop_config_change(uri)
return unless defined?(Requests::Support::RuboCopFormatter)

send_log_message("Reloading RuboCop since #{uri} changed")
# Register a new runner to reload configurations
@global_state.register_formatter("rubocop", Requests::Support::RuboCopFormatter.new)

# Clear all existing diagnostics since the config changed. This has to happen under a mutex because the `state`
# hash cannot be mutated during iteration or that will throw an error
# Clear all document caches for pull diagnostics
@global_state.synchronize do
@store.each do |uri, _document|
send_message(Notification.publish_diagnostics(uri.to_s, []))
@store.each do |_uri, document|
document.cache_set("textDocument/diagnostic", Document::EMPTY_CACHE)
end
end

# Request a pull diagnostic refresh from the editor
if @global_state.client_capabilities.supports_diagnostic_refresh
send_message(Request.new(id: @current_request_id, method: "workspace/diagnostic/refresh", params: nil))
end
end

sig { params(message: T::Hash[Symbol, T.untyped]).void }
Expand Down
8 changes: 6 additions & 2 deletions lib/ruby_lsp/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ def publish_diagnostics(uri, diagnostics, version: nil)

sig { override.returns(T::Hash[Symbol, T.untyped]) }
def to_hash
{ method: @method, params: T.unsafe(@params).to_hash }
hash = { method: @method }
hash[:params] = T.unsafe(@params).to_hash if @params
hash
end
end

Expand Down Expand Up @@ -206,7 +208,9 @@ def initialize(id:, method:, params:)

sig { override.returns(T::Hash[Symbol, T.untyped]) }
def to_hash
{ id: @id, method: @method, params: T.unsafe(@params).to_hash }
hash = { id: @id, method: @method }
hash[:params] = T.unsafe(@params).to_hash if @params
hash
end
end

Expand Down
33 changes: 33 additions & 0 deletions test/server_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,39 @@ def test_edits_outside_of_declarations_do_not_trigger_indexing
assert_equal(1, entries.length)
end

def test_rubocop_config_changes_trigger_workspace_diagnostic_refresh
uri = URI::Generic.from_path(path: File.join(Dir.pwd, ".rubocop.yml"))

@server.process_message({
id: 1,
method: "initialize",
params: {
initializationOptions: {},
capabilities: {
general: {
positionEncodings: ["utf-8"],
},
workspace: { diagnostics: { refreshSupport: true } },
},
},
})

@server.process_message({
method: "workspace/didChangeWatchedFiles",
params: {
changes: [
{
uri: uri,
type: RubyLsp::Constant::FileChangeType::CHANGED,
},
],
},
})

request = find_message(RubyLsp::Request)
assert_equal("workspace/diagnostic/refresh", request.method)
end

private

def with_uninstalled_rubocop(&block)
Expand Down

0 comments on commit 5dfbc44

Please sign in to comment.