From d5536b5effaec6276fd30fd5b4720db5ce017c17 Mon Sep 17 00:00:00 2001 From: Rafay Qayyum Date: Sun, 8 Nov 2026 21:25:06 +0500 Subject: [PATCH] Send ERB virtual state when a document is opened --- lib/ruby_lsp/server.rb | 15 +++++++++++++++ test/server_test.rb | 22 ++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index c700fc6c55..7e7817ada9 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -413,6 +413,21 @@ def text_document_did_open(message) ), ) end + + # Documents are parsed on creation, so the virtual state would otherwise only be sent after the first edit + if document.is_a?(ERBDocument) && @global_state.client_capabilities.supports_request_delegation + send_message( + Notification.new( + method: "delegate/textDocument/virtualState", + params: { + textDocument: { + uri: text_document[:uri].to_s, + text: document.host_language_source, + }, + }, + ), + ) + end end #: (Hash[Symbol, untyped] message) -> void diff --git a/test/server_test.rb b/test/server_test.rb index 1301c8b59c..0c7f2714b0 100644 --- a/test/server_test.rb +++ b/test/server_test.rb @@ -1779,6 +1779,28 @@ def test_does_not_crash_when_a_document_uri_cannot_be_parsed server&.run_shutdown end + def test_did_open_sends_the_virtual_state_of_erb_documents + @server.global_state.apply_options({ capabilities: { experimental: { requestDelegation: true } } }) + uri = URI("file:///foo.html.erb") + + @server.process_message({ + method: "textDocument/didOpen", + params: { + textDocument: { + uri: uri, + text: "
<%= foo %>
", + version: 1, + languageId: "erb", + }, + }, + }) + + notification = find_message(RubyLsp::Notification, "delegate/textDocument/virtualState") + document = @server.instance_variable_get(:@store).get(uri) + assert_equal(uri.to_s, notification.params[:textDocument][:uri]) + assert_equal(document.host_language_source, notification.params[:textDocument][:text]) + end + private def run_initialize_server_with_setup_error(error)