Class: Rigor::LanguageServer::DiagnosticPublisher

Inherits:
Object
  • Object
show all
Defined in:
lib/rigor/language_server/diagnostic_publisher.rb

Overview

Converts buffer state into textDocument/publishDiagnostics notifications. Owns the Rigor Analysis::Runner orchestration for the per-buffer single-file scope path that editor mode v1 already supports โ€” every publish_for(uri) call materialises a BufferBinding from the BufferTable entry, runs the Runner, and pushes the resulting LSP Diagnostic[] through the writer.

Debouncing is wired via an optional Debouncer injected at construction (delay defaults to 200ms quiet-time); without a debouncer each call blocks synchronously (primarily for specs). Ractor-pool dispatch is queued.

Constant Summary collapse

SEVERITY_MAP =

Maps Rigor severity symbols to LSP DiagnosticSeverity integers per spec ยง "Diagnostic":

1 = Error, 2 = Warning, 3 = Information, 4 = Hint.
{
  error: 1,
  warning: 2,
  info: 3,
  hint: 4
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(writer:, buffer_table:, project_context:, debouncer: nil, debounce_seconds: 0.2) ⇒ DiagnosticPublisher

Returns a new instance of DiagnosticPublisher.

Parameters:

  • debouncer (Rigor::LanguageServer::Debouncer, nil) (defaults to: nil)

    when present, publish_for schedules its work through the debouncer (cancels prior pending task for the same URI, fires after debounce_seconds quiet-time). Nil keeps the slice 4-7 synchronous behaviour โ€” primarily useful for specs.

  • debounce_seconds (Numeric) (defaults to: 0.2)

    quiet-time before the debounced publish fires. 0 with a debouncer means "schedule on next-tick" (still async); without a debouncer the value is unused.



40
41
42
43
44
45
46
47
# File 'lib/rigor/language_server/diagnostic_publisher.rb', line 40

def initialize(writer:, buffer_table:, project_context:,
               debouncer: nil, debounce_seconds: 0.2)
  @writer = writer
  @buffer_table = buffer_table
  @project_context = project_context
  @debouncer = debouncer
  @debounce_seconds = debounce_seconds
end

Instance Method Details

#cancel_pendingObject

Cancels every in-flight debounced task. Called from Server#handle_shutdown so pending publishes don't fire against a closed STDOUT.



72
73
74
# File 'lib/rigor/language_server/diagnostic_publisher.rb', line 72

def cancel_pending
  @debouncer&.cancel_all
end

#publish_empty(uri) ⇒ Object

Publishes an EMPTY diagnostic array for uri. The LSP-spec idiom for "clear inline markers" โ€” called from didClose so clients drop stale highlights when the user closes a buffer.



66
67
68
# File 'lib/rigor/language_server/diagnostic_publisher.rb', line 66

def publish_empty(uri)
  notify(uri, [])
end

#publish_for(uri) ⇒ Object

Run analysis for the buffer at uri (looked up in the BufferTable) and push a textDocument/publishDiagnostics notification. No-op when the URI isn't a file:// form or the buffer isn't currently open. When a Debouncer is wired, the analysis is scheduled async per the configured debounce_seconds; otherwise it runs inline.



53
54
55
56
57
58
59
60
61
62
# File 'lib/rigor/language_server/diagnostic_publisher.rb', line 53

def publish_for(uri)
  path = Uri.to_path(uri)
  return if path.nil?

  if @debouncer
    @debouncer.schedule(uri, delay: @debounce_seconds) { run_and_notify(uri, path) }
  else
    run_and_notify(uri, path)
  end
end