Class: Mui::Lsp::TextDocumentSync

Inherits:
Object
  • Object
show all
Defined in:
lib/mui/lsp/text_document_sync.rb

Overview

Manages text document synchronization with LSP server Handles didOpen, didChange, didSave, didClose notifications with debouncing support for change notifications

Constant Summary collapse

DEFAULT_DEBOUNCE_MS =
300

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client:, server_config:, debounce_ms: DEFAULT_DEBOUNCE_MS) ⇒ TextDocumentSync



11
12
13
14
15
16
17
18
19
# File 'lib/mui/lsp/text_document_sync.rb', line 11

def initialize(client:, server_config:, debounce_ms: DEFAULT_DEBOUNCE_MS)
  @client = client
  @server_config = server_config
  @debounce_ms = debounce_ms
  @open_documents = {}
  @pending_changes = {}
  @debounce_timers = {}
  @mutex = Mutex.new
end

Class Method Details

.path_to_uri(path) ⇒ Object



95
96
97
# File 'lib/mui/lsp/text_document_sync.rb', line 95

def self.path_to_uri(path)
  "file://#{File.expand_path(path)}"
end

.uri_to_path(uri) ⇒ Object



99
100
101
102
103
# File 'lib/mui/lsp/text_document_sync.rb', line 99

def self.uri_to_path(uri)
  return nil unless uri&.start_with?("file://")

  URI.decode_www_form_component(uri.sub("file://", ""))
end

Instance Method Details

#close_allObject



90
91
92
93
# File 'lib/mui/lsp/text_document_sync.rb', line 90

def close_all
  uris = @mutex.synchronize { @open_documents.keys.dup }
  uris.each { |uri| did_close(uri: uri) }
end

#did_change(uri:, text:, debounce: true, force: false) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/mui/lsp/text_document_sync.rb', line 41

def did_change(uri:, text:, debounce: true, force: false)
  # Skip if sync_on_change is disabled for this server (unless forced)
  return unless force || @server_config.sync_on_change

  @mutex.synchronize do
    return unless @open_documents.key?(uri)

    @open_documents[uri][:version] += 1
    @open_documents[uri][:text] = text
    @pending_changes[uri] = text
  end

  if debounce
    schedule_debounced_change(uri)
  else
    flush_change(uri)
  end
end

#did_close(uri:) ⇒ Object



66
67
68
69
70
71
72
73
74
75
# File 'lib/mui/lsp/text_document_sync.rb', line 66

def did_close(uri:)
  cancel_debounce_timer(uri)

  @mutex.synchronize do
    @open_documents.delete(uri)
    @pending_changes.delete(uri)
  end

  @client.did_close(uri: uri)
end

#did_open(uri:, text:) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/mui/lsp/text_document_sync.rb', line 21

def did_open(uri:, text:)
  file_path = uri_to_path(uri)
  language_id = @server_config.language_id_for(file_path)

  @mutex.synchronize do
    @open_documents[uri] = {
      version: 1,
      text: text,
      language_id: language_id
    }
  end

  @client.did_open(
    uri: uri,
    language_id: language_id,
    version: 1,
    text: text
  )
end

#did_save(uri:, text: nil) ⇒ Object



60
61
62
63
64
# File 'lib/mui/lsp/text_document_sync.rb', line 60

def did_save(uri:, text: nil)
  # Flush any pending changes first
  flush_change(uri)
  @client.did_save(uri: uri, text: text)
end

#flush_allObject



85
86
87
88
# File 'lib/mui/lsp/text_document_sync.rb', line 85

def flush_all
  uris = @mutex.synchronize { @pending_changes.keys.dup }
  uris.each { |uri| flush_change(uri) }
end

#open?(uri) ⇒ Boolean



77
78
79
# File 'lib/mui/lsp/text_document_sync.rb', line 77

def open?(uri)
  @mutex.synchronize { @open_documents.key?(uri) }
end

#version(uri) ⇒ Object



81
82
83
# File 'lib/mui/lsp/text_document_sync.rb', line 81

def version(uri)
  @mutex.synchronize { @open_documents.dig(uri, :version) }
end