From 1e5029c07bfc6f5369e90ded223ee7d8c362804a Mon Sep 17 00:00:00 2001 From: Vinicius Stock Date: Fri, 23 Aug 2024 16:23:57 -0400 Subject: [PATCH] Disable diagnostics on large files --- lib/ruby_lsp/document.rb | 9 +++++++++ lib/ruby_lsp/requests/diagnostics.rb | 4 +++- lib/ruby_lsp/requests/semantic_highlighting.rb | 4 ---- lib/ruby_lsp/server.rb | 11 ++++++----- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/ruby_lsp/document.rb b/lib/ruby_lsp/document.rb index 61e6187b2..c85cbe11f 100644 --- a/lib/ruby_lsp/document.rb +++ b/lib/ruby_lsp/document.rb @@ -16,6 +16,10 @@ class LanguageId < T::Enum extend T::Generic ParseResultType = type_member + + # This maximum number of characters for providing expensive features, like semantic highlighting and diagnostics. + # This is the same number used by the TypeScript extension in VS Code + MAXIMUM_CHARACTERS_FOR_EXPENSIVE_FEATURES = 100_000 EMPTY_CACHE = T.let(Object.new.freeze, Object) abstract! @@ -113,6 +117,11 @@ def create_scanner Scanner.new(@source, @encoding) end + sig { returns(T::Boolean) } + def past_expensive_limit? + @source.length > MAXIMUM_CHARACTERS_FOR_EXPENSIVE_FEATURES + end + class Scanner extend T::Sig diff --git a/lib/ruby_lsp/requests/diagnostics.rb b/lib/ruby_lsp/requests/diagnostics.rb index 6bfa95a7d..3f2210311 100644 --- a/lib/ruby_lsp/requests/diagnostics.rb +++ b/lib/ruby_lsp/requests/diagnostics.rb @@ -46,7 +46,9 @@ def perform diagnostics.concat(syntax_error_diagnostics, syntax_warning_diagnostics) # Running RuboCop is slow, so to avoid excessive runs we only do so if the file is syntactically valid - return diagnostics if @document.syntax_error? || @active_linters.empty? + if @document.syntax_error? || @active_linters.empty? || @document.past_expensive_limit? + return diagnostics + end @active_linters.each do |linter| linter_diagnostics = linter.run_diagnostic(@uri, @document) diff --git a/lib/ruby_lsp/requests/semantic_highlighting.rb b/lib/ruby_lsp/requests/semantic_highlighting.rb index 906075b1e..eca1f0a91 100644 --- a/lib/ruby_lsp/requests/semantic_highlighting.rb +++ b/lib/ruby_lsp/requests/semantic_highlighting.rb @@ -33,10 +33,6 @@ module Requests class SemanticHighlighting < Request extend T::Sig - # This maximum number of characters for providing highlighting is the same limit imposed by the VS Code TypeScript - # extension. Even with delta requests, anything above this number lags the editor significantly - MAXIMUM_CHARACTERS_FOR_HIGHLIGHT = 100_000 - class << self extend T::Sig diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 774d4287a..15b8d65d1 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -315,13 +315,14 @@ def text_document_did_open(message) language_id: language_id, ) - if document.source.length > Requests::SemanticHighlighting::MAXIMUM_CHARACTERS_FOR_HIGHLIGHT + if document.past_expensive_limit? send_message( Notification.new( method: "window/showMessage", params: Interface::ShowMessageParams.new( type: Constant::MessageType::WARNING, - message: "This file is too long. For performance reasons, semantic highlighting will be disabled", + message: "This file is too long. For performance reasons, semantic highlighting and " \ + "diagnostics will be disabled", ), ), ) @@ -427,7 +428,7 @@ def run_combined_requests(message) def text_document_semantic_tokens_full(message) document = @store.get(message.dig(:params, :textDocument, :uri)) - if document.source.length > Requests::SemanticHighlighting::MAXIMUM_CHARACTERS_FOR_HIGHLIGHT + if document.past_expensive_limit? send_empty_response(message[:id]) return end @@ -448,7 +449,7 @@ def text_document_semantic_tokens_full(message) def text_document_semantic_tokens_delta(message) document = @store.get(message.dig(:params, :textDocument, :uri)) - if document.source.length > Requests::SemanticHighlighting::MAXIMUM_CHARACTERS_FOR_HIGHLIGHT + if document.past_expensive_limit? send_empty_response(message[:id]) return end @@ -476,7 +477,7 @@ def text_document_semantic_tokens_range(message) uri = params.dig(:textDocument, :uri) document = @store.get(uri) - if document.source.length > Requests::SemanticHighlighting::MAXIMUM_CHARACTERS_FOR_HIGHLIGHT + if document.past_expensive_limit? send_empty_response(message[:id]) return end