mui-lsp 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +19 -0
- data/lib/mui/lsp/handlers/completion.rb +24 -9
- data/lib/mui/lsp/manager.rb +17 -0
- data/lib/mui/lsp/plugin.rb +61 -14
- data/lib/mui/lsp/text_document_sync.rb +3 -3
- data/lib/mui/lsp/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 265b2178245c88fe87ea19d4b97323cd4bc47cc104ed89258fed1e542d6c2c57
|
|
4
|
+
data.tar.gz: 762e6e1dcb1dc49f22bf866647b9a2c7637806e16d1f8070b46a899290db93f1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b20c948e1fe4171cf1a87db8d738f758375f5094b2463c64dbe3b9ed6c803fb666f5692158516d543b62acbed82cb1bfe5103a6224a4d2fb7435daaa124b14da
|
|
7
|
+
data.tar.gz: a24ed8994311f2db029ef9a9cde459a27fe9669eff27f332f60fedc7e51838d9647a37f40e61e2b2ba8e3707d5b84c6ff51237d9725d06d1155632d25f245d1b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.0] - 2025-12-12
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Insert mode LSP completion support:
|
|
7
|
+
- Auto-trigger completion after `.`, `@`, and `::` characters via `InsertCompletion` autocmd
|
|
8
|
+
- Uses `textEdit` for precise text replacement (e.g., `@user` replaces properly)
|
|
9
|
+
- `force_reopen` ensures LSP has latest buffer content before completion
|
|
10
|
+
- Completion items include `label`, `kind`, `detail`, `documentation`, and `text_edit`
|
|
11
|
+
- `Ctrl+Space` keymap in Insert mode to manually trigger LSP completion
|
|
12
|
+
|
|
13
|
+
## [0.1.1] - 2025-12-11
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- `Mui::Lsp::ConfigDsl` now imports configurations from `Mui::LspConfigStub`:
|
|
18
|
+
- Allows `Mui.lsp { ... }` to be called in `.muirc` before mui-lsp gem is loaded
|
|
19
|
+
- Configurations stored in the stub are automatically migrated when the gem loads
|
|
20
|
+
- Requires Mui v0.2.0+ which provides `LspConfigStub`
|
|
21
|
+
|
|
3
22
|
## [0.1.0] - 2025-12-11
|
|
4
23
|
|
|
5
24
|
### Added
|
|
@@ -84,8 +84,30 @@ module Mui
|
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
def display_completions(items)
|
|
87
|
-
#
|
|
88
|
-
|
|
87
|
+
# Use Mui's insert completion API if available
|
|
88
|
+
if @editor.respond_to?(:start_insert_completion)
|
|
89
|
+
prefix = get_current_prefix
|
|
90
|
+
@editor.start_insert_completion(items, prefix:)
|
|
91
|
+
else
|
|
92
|
+
# Fallback: show message
|
|
93
|
+
show_message_fallback(items)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def get_current_prefix
|
|
98
|
+
window = @editor.window
|
|
99
|
+
buffer = window.buffer
|
|
100
|
+
line = buffer.line(window.cursor_row)
|
|
101
|
+
col = window.cursor_col
|
|
102
|
+
|
|
103
|
+
# Find word start
|
|
104
|
+
start_col = col
|
|
105
|
+
start_col -= 1 while start_col > 0 && line[start_col - 1] =~ /\w/
|
|
106
|
+
|
|
107
|
+
line[start_col...col] || ""
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def show_message_fallback(items)
|
|
89
111
|
count = items.length
|
|
90
112
|
|
|
91
113
|
# Build a summary message
|
|
@@ -94,13 +116,6 @@ module Mui
|
|
|
94
116
|
summary += ", ..." if count > 3
|
|
95
117
|
|
|
96
118
|
@editor.message = "#{count} completion#{"s" unless count == 1}: #{summary}"
|
|
97
|
-
|
|
98
|
-
# Store items for potential insertion
|
|
99
|
-
store_completions(items)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def store_completions(items)
|
|
103
|
-
@editor.instance_variable_set(:@lsp_completions, items)
|
|
104
119
|
end
|
|
105
120
|
|
|
106
121
|
def kind_to_string(kind)
|
data/lib/mui/lsp/manager.rb
CHANGED
|
@@ -162,6 +162,23 @@ module Mui
|
|
|
162
162
|
end
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
+
# Sync immediately without debounce (for completion requests)
|
|
166
|
+
def sync_now(file_path:, text:)
|
|
167
|
+
uri = TextDocumentSync.path_to_uri(file_path)
|
|
168
|
+
text_syncs_for(file_path).each do |text_sync|
|
|
169
|
+
text_sync.did_change(uri: uri, text: text, debounce: false, force: true)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Force close and re-open document to reset LSP state
|
|
174
|
+
def force_reopen(file_path:, text:)
|
|
175
|
+
uri = TextDocumentSync.path_to_uri(file_path)
|
|
176
|
+
text_syncs_for(file_path).each do |text_sync|
|
|
177
|
+
text_sync.did_close(uri: uri) if text_sync.open?(uri)
|
|
178
|
+
text_sync.did_open(uri: uri, text: text)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
165
182
|
def did_save(file_path:, text: nil)
|
|
166
183
|
uri = TextDocumentSync.path_to_uri(file_path)
|
|
167
184
|
# Broadcast to all matching servers
|
data/lib/mui/lsp/plugin.rb
CHANGED
|
@@ -157,6 +157,12 @@ module Mui
|
|
|
157
157
|
false
|
|
158
158
|
end
|
|
159
159
|
end
|
|
160
|
+
|
|
161
|
+
# Insert mode: Ctrl+Space - Trigger LSP completion
|
|
162
|
+
keymap(:insert, "\x00") do |ctx|
|
|
163
|
+
handle_lsp_completion(ctx)
|
|
164
|
+
true
|
|
165
|
+
end
|
|
160
166
|
end
|
|
161
167
|
|
|
162
168
|
def register_autocmds
|
|
@@ -194,6 +200,11 @@ module Mui
|
|
|
194
200
|
|
|
195
201
|
get_manager(ctx.editor).did_close(file_path: file_path)
|
|
196
202
|
end
|
|
203
|
+
|
|
204
|
+
# Hook into insert completion trigger (. and @ characters)
|
|
205
|
+
autocmd(:InsertCompletion) do |ctx|
|
|
206
|
+
handle_lsp_completion(ctx)
|
|
207
|
+
end
|
|
197
208
|
end
|
|
198
209
|
|
|
199
210
|
def setup_default_servers
|
|
@@ -291,9 +302,15 @@ module Mui
|
|
|
291
302
|
return
|
|
292
303
|
end
|
|
293
304
|
|
|
305
|
+
mgr = get_manager(ctx.editor)
|
|
306
|
+
text = ctx.buffer.lines.join("\n")
|
|
307
|
+
|
|
308
|
+
# Force re-open document to ensure LSP has latest content
|
|
309
|
+
mgr.force_reopen(file_path: file_path, text: text)
|
|
310
|
+
|
|
294
311
|
line = ctx.window.cursor_row
|
|
295
312
|
character = ctx.window.cursor_col
|
|
296
|
-
|
|
313
|
+
mgr.completion(file_path: file_path, line: line, character: character)
|
|
297
314
|
end
|
|
298
315
|
|
|
299
316
|
def handle_lsp_diagnostics(ctx)
|
|
@@ -485,26 +502,17 @@ end
|
|
|
485
502
|
Mui.plugin_manager.register(:lsp, Mui::Lsp::Plugin)
|
|
486
503
|
|
|
487
504
|
# DSL for .muirc configuration
|
|
505
|
+
# This replaces Mui.lsp stub method from mui core with the real implementation
|
|
488
506
|
module Mui
|
|
489
|
-
class << self
|
|
490
|
-
def lsp(&block)
|
|
491
|
-
@lsp_config ||= Lsp::ConfigDsl.new
|
|
492
|
-
@lsp_config.instance_eval(&block) if block
|
|
493
|
-
@lsp_config
|
|
494
|
-
end
|
|
495
|
-
|
|
496
|
-
def lsp_server_configs
|
|
497
|
-
@lsp_config&.server_configs || []
|
|
498
|
-
end
|
|
499
|
-
end
|
|
500
|
-
|
|
501
507
|
module Lsp
|
|
502
508
|
# DSL class for configuring LSP in .muirc
|
|
503
509
|
class ConfigDsl
|
|
504
510
|
attr_reader :server_configs
|
|
505
511
|
|
|
506
|
-
def initialize
|
|
512
|
+
def initialize(existing_configs = [])
|
|
507
513
|
@server_configs = []
|
|
514
|
+
# Import configs from LspConfigStub if any were defined before gem load
|
|
515
|
+
import_stub_configs(existing_configs)
|
|
508
516
|
end
|
|
509
517
|
|
|
510
518
|
def use(name, sync_on_change: nil)
|
|
@@ -534,6 +542,45 @@ module Mui
|
|
|
534
542
|
sync_on_change: sync_on_change
|
|
535
543
|
)
|
|
536
544
|
end
|
|
545
|
+
|
|
546
|
+
private
|
|
547
|
+
|
|
548
|
+
def import_stub_configs(configs)
|
|
549
|
+
configs.each do |cfg|
|
|
550
|
+
case cfg[:type]
|
|
551
|
+
when :preset
|
|
552
|
+
use(cfg[:name], **cfg.fetch(:options, {}))
|
|
553
|
+
when :custom
|
|
554
|
+
server(
|
|
555
|
+
name: cfg[:name],
|
|
556
|
+
command: cfg[:command],
|
|
557
|
+
language_ids: cfg[:language_ids],
|
|
558
|
+
file_patterns: cfg[:file_patterns],
|
|
559
|
+
auto_start: cfg.fetch(:auto_start, true),
|
|
560
|
+
sync_on_change: cfg.fetch(:sync_on_change, true)
|
|
561
|
+
)
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
class << self
|
|
569
|
+
def lsp(&block)
|
|
570
|
+
# Migrate from LspConfigStub to real ConfigDsl on first access after gem load
|
|
571
|
+
if @lsp_config.is_a?(LspConfigStub)
|
|
572
|
+
existing_configs = @lsp_config.server_configs
|
|
573
|
+
@lsp_config = Lsp::ConfigDsl.new(existing_configs)
|
|
574
|
+
end
|
|
575
|
+
@lsp_config ||= Lsp::ConfigDsl.new
|
|
576
|
+
@lsp_config.instance_eval(&block) if block
|
|
577
|
+
@lsp_config
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def lsp_server_configs
|
|
581
|
+
# Ensure migration happens
|
|
582
|
+
lsp unless @lsp_config.is_a?(Lsp::ConfigDsl)
|
|
583
|
+
@lsp_config&.server_configs || []
|
|
537
584
|
end
|
|
538
585
|
end
|
|
539
586
|
end
|
|
@@ -38,9 +38,9 @@ module Mui
|
|
|
38
38
|
)
|
|
39
39
|
end
|
|
40
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
|
|
41
|
+
def did_change(uri:, text:, debounce: true, force: false)
|
|
42
|
+
# Skip if sync_on_change is disabled for this server (unless forced)
|
|
43
|
+
return unless force || @server_config.sync_on_change
|
|
44
44
|
|
|
45
45
|
@mutex.synchronize do
|
|
46
46
|
return unless @open_documents.key?(uri)
|
data/lib/mui/lsp/version.rb
CHANGED