Module: MilkTea::LSP::Server::ServerTextDocuments
- Included in:
- MilkTea::LSP::Server
- Defined in:
- lib/milk_tea/lsp/server/text_documents.rb
Instance Method Summary collapse
- #handle_did_change(params) ⇒ Object
- #handle_did_close(params) ⇒ Object
- #handle_did_open(params) ⇒ Object
- #handle_did_save(params) ⇒ Object
- #handle_document_context(params) ⇒ Object
- #handle_will_save_wait_until(params) ⇒ Object
Instance Method Details
#handle_did_change(params) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/milk_tea/lsp/server/text_documents.rb', line 36 def handle_did_change(params) uri = params['textDocument']['uri'] changes = params['contentChanges'] || [] previous_content = @workspace.get_content(uri) @workspace.apply_incremental_changes(uri, changes, warm_facts: false) invalidate_document_caches(uri) current_content = @workspace.get_content(uri) refresh_open_document_dependency_state(uri, previous_content: previous_content, current_content: current_content) # This server is always pull-based (diagnosticProvider), so the # client's textDocument/diagnostic request asks for the full tier. # Scheduling a lighter tier here computes in the worker and then # duplicates the full lint on the request thread; keep the tiers # aligned so the pull can serve the worker's result. schedule_diagnostics(uri, lint_tier: :full) unless @workspace.background_document?(uri) nil end |
#handle_did_close(params) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/milk_tea/lsp/server/text_documents.rb', line 71 def handle_did_close(params) uri = params['textDocument']['uri'] previous_content = @workspace.get_content(uri) cancel_diagnostics(uri) @workspace.close_document(uri) invalidate_document_caches(uri) @diagnostic_report_cache.delete(uri) @workspace_diagnostic_cache.delete(uri) # Once closed, the buffer is no longer authoritative. If it differed # from disk, module analyses computed against it (for dependents and # the file itself) are stale; drop the whole shared cache. Closing is # a rare per-file event, so an unconditional clear is cheap and safe. disk_content = begin path = uri_to_path(uri) path && File.file?(path) ? File.read(path) : nil rescue StandardError nil end @workspace.clear_shared_module_cache if previous_content != disk_content unless defined?(@pull_diagnostics_active) && @pull_diagnostics_active @protocol.write_notification('textDocument/publishDiagnostics', { uri: uri, diagnostics: [] }) end nil end |
#handle_did_open(params) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/milk_tea/lsp/server/text_documents.rb', line 7 def handle_did_open(params) total_start = monotonic_time uri = params['textDocument']['uri'] content = params['textDocument']['text'] source = @workspace.document_source(uri) || 'unknown' open_start = monotonic_time open_stats = @workspace.open_document(uri, content, warm_facts: false) open_ms = elapsed_ms(open_start) @semantic_tokens_cache.delete(uri) @semantic_tokens_delta_cache.delete(uri) @fixall_cache.delete(uri) diagnostics_start = monotonic_time schedule_diagnostics(uri, lint_tier: :full) unless @workspace.background_document?(uri) elapsed = elapsed_ms(total_start) short_uri = shorten_uri(uri) || uri facts_detail = if open_stats[:eager_facts] "on(#{open_stats[:facts_mode] || :unknown})" else "off(#{open_stats[:skip_reason] || :unknown})" end log_perf_breakdown( 'textDocument/didOpen', elapsed, "uri=#{short_uri} source=#{source} bytes=#{open_stats[:bytes]} lines=#{open_stats[:lines]} imports=#{open_stats[:import_count]} shared_modules=#{open_stats[:shared_module_cache_size]} eager_facts=#{facts_detail} stages_ms=open:#{open_ms},facts:#{open_stats[:facts_ms] || 0.0},diagnostics_enqueue:#{elapsed_ms(diagnostics_start)}" ) nil end |
#handle_did_save(params) ⇒ Object
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/milk_tea/lsp/server/text_documents.rb', line 99 def handle_did_save(params) uri = params.dig('textDocument', 'uri') return nil unless uri invalidate_document_caches(uri) affected = refresh_open_document_dependency_state(uri) refresh_client_semantic_tokens if affected.any? schedule_diagnostics(uri, force: true, lint_tier: :full) unless @workspace.background_document?(uri) nil end |
#handle_document_context(params) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/milk_tea/lsp/server/text_documents.rb', line 55 def handle_document_context(params) uri = params.dig('textDocument', 'uri') || params['uri'] source = params['source'] return nil unless uri && source previous_source = @workspace.set_document_source(uri, source) if previous_source == 'background-document' && source != 'background-document' && !@workspace.get_content(uri).empty? @semantic_tokens_cache.delete(uri) @semantic_tokens_delta_cache.delete(uri) @fixall_cache.delete(uri) schedule_diagnostics(uri, force: true, lint_tier: :full) end nil end |
#handle_will_save_wait_until(params) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/milk_tea/lsp/server/text_documents.rb', line 110 def handle_will_save_wait_until(params) uri = params.dig('textDocument', 'uri') return nil unless uri content = @workspace.get_content(uri) return nil if content.nil? || content.empty? return nil if skip_expensive_work_reason(uri, content) begin formatted = Timeout.timeout(0.5) do Formatter.format_source(content, path: uri, mode: @format_mode) end return nil if formatted == content line_count = content.count("\n") [{ range: { start: { line: 0, character: 0 }, end: { line: line_count + 1, character: 0 } }, newText: formatted }] rescue Timeout::Error, StandardError nil end end |