mui-lsp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop_todo.yml +73 -0
- data/CHANGELOG.md +61 -0
- data/LICENSE.txt +21 -0
- data/README.md +188 -0
- data/Rakefile +12 -0
- data/lib/mui/lsp/client.rb +290 -0
- data/lib/mui/lsp/handlers/base.rb +92 -0
- data/lib/mui/lsp/handlers/completion.rb +139 -0
- data/lib/mui/lsp/handlers/definition.rb +99 -0
- data/lib/mui/lsp/handlers/diagnostics.rb +161 -0
- data/lib/mui/lsp/handlers/hover.rb +55 -0
- data/lib/mui/lsp/handlers/references.rb +65 -0
- data/lib/mui/lsp/handlers.rb +8 -0
- data/lib/mui/lsp/highlighters/diagnostic_highlighter.rb +71 -0
- data/lib/mui/lsp/json_rpc_io.rb +120 -0
- data/lib/mui/lsp/manager.rb +366 -0
- data/lib/mui/lsp/plugin.rb +539 -0
- data/lib/mui/lsp/protocol/diagnostic.rb +88 -0
- data/lib/mui/lsp/protocol/location.rb +42 -0
- data/lib/mui/lsp/protocol/position.rb +31 -0
- data/lib/mui/lsp/protocol/range.rb +34 -0
- data/lib/mui/lsp/protocol.rb +6 -0
- data/lib/mui/lsp/request_manager.rb +72 -0
- data/lib/mui/lsp/server_config.rb +115 -0
- data/lib/mui/lsp/text_document_sync.rb +149 -0
- data/lib/mui/lsp/version.rb +7 -0
- data/lib/mui/lsp.rb +19 -0
- data/lib/mui_lsp.rb +3 -0
- data/sig/mui/lsp.rbs +6 -0
- metadata +89 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mui
|
|
4
|
+
module Lsp
|
|
5
|
+
module Protocol
|
|
6
|
+
# LSP Range (start and end positions)
|
|
7
|
+
class Range
|
|
8
|
+
attr_accessor :start, :end
|
|
9
|
+
|
|
10
|
+
def initialize(start:, end_pos:)
|
|
11
|
+
@start = start.is_a?(Position) ? start : Position.from_hash(start)
|
|
12
|
+
@end = end_pos.is_a?(Position) ? end_pos : Position.from_hash(end_pos)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_h
|
|
16
|
+
{ start: @start.to_h, end: @end.to_h }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.from_hash(hash)
|
|
20
|
+
new(
|
|
21
|
+
start: hash["start"] || hash[:start],
|
|
22
|
+
end_pos: hash["end"] || hash[:end]
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def ==(other)
|
|
27
|
+
return false unless other.is_a?(Range)
|
|
28
|
+
|
|
29
|
+
@start == other.start && @end == other.end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mui
|
|
4
|
+
module Lsp
|
|
5
|
+
# Manages pending JSON-RPC requests and their callbacks
|
|
6
|
+
class RequestManager
|
|
7
|
+
def initialize
|
|
8
|
+
@next_id = 1
|
|
9
|
+
@pending_requests = {}
|
|
10
|
+
@mutex = Mutex.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def register(callback)
|
|
14
|
+
@mutex.synchronize do
|
|
15
|
+
id = @next_id
|
|
16
|
+
@next_id += 1
|
|
17
|
+
@pending_requests[id] = {
|
|
18
|
+
callback: callback,
|
|
19
|
+
registered_at: Time.now
|
|
20
|
+
}
|
|
21
|
+
id
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def handle_response(id, result: nil, error: nil)
|
|
26
|
+
request = @mutex.synchronize { @pending_requests.delete(id) }
|
|
27
|
+
return false unless request
|
|
28
|
+
|
|
29
|
+
if error
|
|
30
|
+
request[:callback].call(nil, error)
|
|
31
|
+
else
|
|
32
|
+
request[:callback].call(result, nil)
|
|
33
|
+
end
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def pending?(id)
|
|
38
|
+
@mutex.synchronize { @pending_requests.key?(id) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def pending_count
|
|
42
|
+
@mutex.synchronize { @pending_requests.size }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def cancel(id)
|
|
46
|
+
@mutex.synchronize { !@pending_requests.delete(id).nil? }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def cancel_all
|
|
50
|
+
@mutex.synchronize { @pending_requests.clear }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def cleanup_stale(timeout_seconds)
|
|
54
|
+
now = Time.now
|
|
55
|
+
timed_out = []
|
|
56
|
+
|
|
57
|
+
@mutex.synchronize do
|
|
58
|
+
@pending_requests.each do |id, request|
|
|
59
|
+
timed_out << id if now - request[:registered_at] > timeout_seconds
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
timed_out.each do |id|
|
|
63
|
+
request = @pending_requests.delete(id)
|
|
64
|
+
request[:callback]&.call(nil, { "code" => -32_603, "message" => "Request timed out" })
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
timed_out
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mui
|
|
4
|
+
module Lsp
|
|
5
|
+
# Configuration for different LSP servers
|
|
6
|
+
class ServerConfig
|
|
7
|
+
attr_reader :name, :command, :language_ids, :file_patterns, :auto_start, :sync_on_change
|
|
8
|
+
|
|
9
|
+
def initialize(name:, command:, language_ids:, file_patterns:, auto_start: true, sync_on_change: true)
|
|
10
|
+
@name = name
|
|
11
|
+
@command = command
|
|
12
|
+
@language_ids = Array(language_ids)
|
|
13
|
+
@file_patterns = Array(file_patterns)
|
|
14
|
+
@auto_start = auto_start
|
|
15
|
+
@sync_on_change = sync_on_change
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def handles_file?(file_path)
|
|
19
|
+
@file_patterns.any? do |pattern|
|
|
20
|
+
File.fnmatch?(pattern, file_path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def language_id_for(file_path)
|
|
25
|
+
ext = File.extname(file_path).downcase
|
|
26
|
+
case ext
|
|
27
|
+
when ".rb", ".rake", ".gemspec", ".ru"
|
|
28
|
+
"ruby"
|
|
29
|
+
when ".js"
|
|
30
|
+
"javascript"
|
|
31
|
+
when ".ts"
|
|
32
|
+
"typescript"
|
|
33
|
+
when ".py"
|
|
34
|
+
"python"
|
|
35
|
+
when ".go"
|
|
36
|
+
"go"
|
|
37
|
+
when ".rs"
|
|
38
|
+
"rust"
|
|
39
|
+
when ".c"
|
|
40
|
+
"c"
|
|
41
|
+
when ".cpp", ".cc", ".cxx"
|
|
42
|
+
"cpp"
|
|
43
|
+
when ".java"
|
|
44
|
+
"java"
|
|
45
|
+
else
|
|
46
|
+
@language_ids.first
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def to_h
|
|
51
|
+
{
|
|
52
|
+
name: @name,
|
|
53
|
+
command: @command,
|
|
54
|
+
language_ids: @language_ids,
|
|
55
|
+
file_patterns: @file_patterns,
|
|
56
|
+
auto_start: @auto_start
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class << self
|
|
61
|
+
def solargraph(auto_start: false)
|
|
62
|
+
new(
|
|
63
|
+
name: "solargraph",
|
|
64
|
+
command: "solargraph stdio",
|
|
65
|
+
language_ids: ["ruby"],
|
|
66
|
+
file_patterns: ["**/*.rb", "**/*.rake", "**/Gemfile", "**/Rakefile", "**/*.gemspec"],
|
|
67
|
+
auto_start: auto_start
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def ruby_lsp(auto_start: false, sync_on_change: false)
|
|
72
|
+
new(
|
|
73
|
+
name: "ruby-lsp",
|
|
74
|
+
command: "ruby-lsp",
|
|
75
|
+
language_ids: ["ruby"],
|
|
76
|
+
file_patterns: ["**/*.rb", "**/*.rake", "**/Gemfile", "**/Rakefile", "**/*.gemspec"],
|
|
77
|
+
auto_start: auto_start,
|
|
78
|
+
sync_on_change: sync_on_change
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def kanayago(auto_start: false)
|
|
83
|
+
new(
|
|
84
|
+
name: "kanayago",
|
|
85
|
+
command: "kanayago --lsp",
|
|
86
|
+
language_ids: ["ruby"],
|
|
87
|
+
file_patterns: ["**/*.rb", "**/*.rake", "**/Gemfile", "**/Rakefile", "**/*.gemspec"],
|
|
88
|
+
auto_start: auto_start
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def rubocop_lsp(auto_start: false)
|
|
93
|
+
new(
|
|
94
|
+
name: "rubocop",
|
|
95
|
+
command: "rubocop --lsp",
|
|
96
|
+
language_ids: ["ruby"],
|
|
97
|
+
file_patterns: ["**/*.rb", "**/*.rake", "**/Gemfile", "**/Rakefile", "**/*.gemspec"],
|
|
98
|
+
auto_start: auto_start
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def custom(name:, command:, language_ids:, file_patterns:, auto_start: true, sync_on_change: true)
|
|
103
|
+
new(
|
|
104
|
+
name: name,
|
|
105
|
+
command: command,
|
|
106
|
+
language_ids: language_ids,
|
|
107
|
+
file_patterns: file_patterns,
|
|
108
|
+
auto_start: auto_start,
|
|
109
|
+
sync_on_change: sync_on_change
|
|
110
|
+
)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mui
|
|
4
|
+
module Lsp
|
|
5
|
+
# Manages text document synchronization with LSP server
|
|
6
|
+
# Handles didOpen, didChange, didSave, didClose notifications
|
|
7
|
+
# with debouncing support for change notifications
|
|
8
|
+
class TextDocumentSync
|
|
9
|
+
DEFAULT_DEBOUNCE_MS = 300
|
|
10
|
+
|
|
11
|
+
def initialize(client:, server_config:, debounce_ms: DEFAULT_DEBOUNCE_MS)
|
|
12
|
+
@client = client
|
|
13
|
+
@server_config = server_config
|
|
14
|
+
@debounce_ms = debounce_ms
|
|
15
|
+
@open_documents = {}
|
|
16
|
+
@pending_changes = {}
|
|
17
|
+
@debounce_timers = {}
|
|
18
|
+
@mutex = Mutex.new
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def did_open(uri:, text:)
|
|
22
|
+
file_path = uri_to_path(uri)
|
|
23
|
+
language_id = @server_config.language_id_for(file_path)
|
|
24
|
+
|
|
25
|
+
@mutex.synchronize do
|
|
26
|
+
@open_documents[uri] = {
|
|
27
|
+
version: 1,
|
|
28
|
+
text: text,
|
|
29
|
+
language_id: language_id
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
@client.did_open(
|
|
34
|
+
uri: uri,
|
|
35
|
+
language_id: language_id,
|
|
36
|
+
version: 1,
|
|
37
|
+
text: text
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def did_change(uri:, text:, debounce: true)
|
|
42
|
+
# Skip if sync_on_change is disabled for this server
|
|
43
|
+
return unless @server_config.sync_on_change
|
|
44
|
+
|
|
45
|
+
@mutex.synchronize do
|
|
46
|
+
return unless @open_documents.key?(uri)
|
|
47
|
+
|
|
48
|
+
@open_documents[uri][:version] += 1
|
|
49
|
+
@open_documents[uri][:text] = text
|
|
50
|
+
@pending_changes[uri] = text
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if debounce
|
|
54
|
+
schedule_debounced_change(uri)
|
|
55
|
+
else
|
|
56
|
+
flush_change(uri)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def did_save(uri:, text: nil)
|
|
61
|
+
# Flush any pending changes first
|
|
62
|
+
flush_change(uri)
|
|
63
|
+
@client.did_save(uri: uri, text: text)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def did_close(uri:)
|
|
67
|
+
cancel_debounce_timer(uri)
|
|
68
|
+
|
|
69
|
+
@mutex.synchronize do
|
|
70
|
+
@open_documents.delete(uri)
|
|
71
|
+
@pending_changes.delete(uri)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
@client.did_close(uri: uri)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def open?(uri)
|
|
78
|
+
@mutex.synchronize { @open_documents.key?(uri) }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def version(uri)
|
|
82
|
+
@mutex.synchronize { @open_documents.dig(uri, :version) }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def flush_all
|
|
86
|
+
uris = @mutex.synchronize { @pending_changes.keys.dup }
|
|
87
|
+
uris.each { |uri| flush_change(uri) }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def close_all
|
|
91
|
+
uris = @mutex.synchronize { @open_documents.keys.dup }
|
|
92
|
+
uris.each { |uri| did_close(uri: uri) }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def self.path_to_uri(path)
|
|
96
|
+
"file://#{File.expand_path(path)}"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def self.uri_to_path(uri)
|
|
100
|
+
return nil unless uri&.start_with?("file://")
|
|
101
|
+
|
|
102
|
+
URI.decode_www_form_component(uri.sub("file://", ""))
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
private
|
|
106
|
+
|
|
107
|
+
def uri_to_path(uri)
|
|
108
|
+
self.class.uri_to_path(uri)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def schedule_debounced_change(uri)
|
|
112
|
+
cancel_debounce_timer(uri)
|
|
113
|
+
|
|
114
|
+
timer = Thread.new do
|
|
115
|
+
sleep(@debounce_ms / 1000.0)
|
|
116
|
+
flush_change(uri)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
@mutex.synchronize { @debounce_timers[uri] = timer }
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def cancel_debounce_timer(uri)
|
|
123
|
+
timer = @mutex.synchronize { @debounce_timers.delete(uri) }
|
|
124
|
+
timer&.kill
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def flush_change(uri)
|
|
128
|
+
cancel_debounce_timer(uri)
|
|
129
|
+
|
|
130
|
+
doc_info = nil
|
|
131
|
+
text = nil
|
|
132
|
+
|
|
133
|
+
@mutex.synchronize do
|
|
134
|
+
text = @pending_changes.delete(uri)
|
|
135
|
+
doc_info = @open_documents[uri]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
return unless text && doc_info
|
|
139
|
+
|
|
140
|
+
# Send full document sync (TextDocumentSyncKind.Full = 1)
|
|
141
|
+
@client.did_change(
|
|
142
|
+
uri: uri,
|
|
143
|
+
version: doc_info[:version],
|
|
144
|
+
changes: [{ text: text }]
|
|
145
|
+
)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
data/lib/mui/lsp.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lsp/version"
|
|
4
|
+
require_relative "lsp/protocol"
|
|
5
|
+
require_relative "lsp/json_rpc_io"
|
|
6
|
+
require_relative "lsp/request_manager"
|
|
7
|
+
require_relative "lsp/server_config"
|
|
8
|
+
require_relative "lsp/client"
|
|
9
|
+
require_relative "lsp/text_document_sync"
|
|
10
|
+
require_relative "lsp/handlers"
|
|
11
|
+
require_relative "lsp/highlighters/diagnostic_highlighter"
|
|
12
|
+
require_relative "lsp/manager"
|
|
13
|
+
require_relative "lsp/plugin"
|
|
14
|
+
|
|
15
|
+
module Mui
|
|
16
|
+
module Lsp
|
|
17
|
+
class Error < StandardError; end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/mui_lsp.rb
ADDED
data/sig/mui/lsp.rbs
ADDED
metadata
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mui-lsp
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- S-H-GAMELINKS
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: mui
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.1'
|
|
26
|
+
description: Provides LSP integration for Mui editor including hover, definition,
|
|
27
|
+
references, diagnostics, and completion
|
|
28
|
+
email:
|
|
29
|
+
- gamelinks007@gmail.com
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- ".rubocop_todo.yml"
|
|
35
|
+
- CHANGELOG.md
|
|
36
|
+
- LICENSE.txt
|
|
37
|
+
- README.md
|
|
38
|
+
- Rakefile
|
|
39
|
+
- lib/mui/lsp.rb
|
|
40
|
+
- lib/mui/lsp/client.rb
|
|
41
|
+
- lib/mui/lsp/handlers.rb
|
|
42
|
+
- lib/mui/lsp/handlers/base.rb
|
|
43
|
+
- lib/mui/lsp/handlers/completion.rb
|
|
44
|
+
- lib/mui/lsp/handlers/definition.rb
|
|
45
|
+
- lib/mui/lsp/handlers/diagnostics.rb
|
|
46
|
+
- lib/mui/lsp/handlers/hover.rb
|
|
47
|
+
- lib/mui/lsp/handlers/references.rb
|
|
48
|
+
- lib/mui/lsp/highlighters/diagnostic_highlighter.rb
|
|
49
|
+
- lib/mui/lsp/json_rpc_io.rb
|
|
50
|
+
- lib/mui/lsp/manager.rb
|
|
51
|
+
- lib/mui/lsp/plugin.rb
|
|
52
|
+
- lib/mui/lsp/protocol.rb
|
|
53
|
+
- lib/mui/lsp/protocol/diagnostic.rb
|
|
54
|
+
- lib/mui/lsp/protocol/location.rb
|
|
55
|
+
- lib/mui/lsp/protocol/position.rb
|
|
56
|
+
- lib/mui/lsp/protocol/range.rb
|
|
57
|
+
- lib/mui/lsp/request_manager.rb
|
|
58
|
+
- lib/mui/lsp/server_config.rb
|
|
59
|
+
- lib/mui/lsp/text_document_sync.rb
|
|
60
|
+
- lib/mui/lsp/version.rb
|
|
61
|
+
- lib/mui_lsp.rb
|
|
62
|
+
- sig/mui/lsp.rbs
|
|
63
|
+
homepage: https://github.com/S-H-GAMELINKS/mui-lsp
|
|
64
|
+
licenses:
|
|
65
|
+
- MIT
|
|
66
|
+
metadata:
|
|
67
|
+
allowed_push_host: https://rubygems.org
|
|
68
|
+
homepage_uri: https://github.com/S-H-GAMELINKS/mui-lsp
|
|
69
|
+
source_code_uri: https://github.com/S-H-GAMELINKS/mui-lsp
|
|
70
|
+
changelog_uri: https://github.com/S-H-GAMELINKS/mui-lsp/blob/main/CHANGELOG.md
|
|
71
|
+
rubygems_mfa_required: 'true'
|
|
72
|
+
rdoc_options: []
|
|
73
|
+
require_paths:
|
|
74
|
+
- lib
|
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: 3.2.0
|
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '0'
|
|
85
|
+
requirements: []
|
|
86
|
+
rubygems_version: 3.6.9
|
|
87
|
+
specification_version: 4
|
|
88
|
+
summary: LSP (Language Server Protocol) plugin for Mui editor
|
|
89
|
+
test_files: []
|