-
-
Notifications
You must be signed in to change notification settings - Fork 195
fix support ghost text #686 #830
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Implements end-to-end LSP inline completion (“ghost text”) support, including capability negotiation, rendering without padding, and Tab-to-accept behavior while keeping inlay hints from clearing unrelated virtual text.
Changes:
- Added inline completion LSP request/response plumbing and per-language capability tracking.
- Rendered ghost text as inline virtual text without automatic padding; ensured inlay hints only clear their own virtual text.
- Implemented Tab acceptance to apply inline completion edits with snippet expansion, plus added tests.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/fresh-editor/src/view/virtual_text.rs | Adds pad_inline control and a new API for inline virtual text insertion with padding configuration. |
| crates/fresh-editor/src/view/ui/split_rendering.rs | Respects pad_inline to render ghost text without added spaces. |
| crates/fresh-editor/src/services/lsp/manager.rs | Tracks inline completion support per language. |
| crates/fresh-editor/src/services/lsp/async_handler.rs | Negotiates inline completion capabilities and implements textDocument/inlineCompletion request handling. |
| crates/fresh-editor/src/services/async_bridge.rs | Adds async message types and payloads for inline completion initialization and responses. |
| crates/fresh-editor/src/app/toggle_actions.rs | Stops clearing all virtual text when disabling inlay hints; clears only inlay-hint virtual texts. |
| crates/fresh-editor/src/app/mod.rs | Adds editor state for pending/active inline completion and routes async inline completion responses. |
| crates/fresh-editor/src/app/lsp_requests.rs | Requests inline completions, renders ghost text, accepts via LSP edits/snippet expansion, and adds tests. |
| crates/fresh-editor/src/app/input.rs | Adds Tab acceptance path and ensures ghost text is cleared on most edits/actions. |
| Cargo.toml | Enables lsp-types proposed features required for inline completion types/capabilities. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| self.apply_event_to_active_buffer(&move_event); | ||
| self.active_event_log_mut().append(move_event); |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
accept_inline_completion applies the cursor move via apply_event_to_active_buffer and appends to active_event_log_mut(). If buffer_id differs from the active buffer (e.g., user switched buffers after ghost text appeared), this will move/log against the wrong buffer and break undo/cursor state. Apply the move event to buffer_id’s state and append it to that buffer’s event log instead (consistent with other cursor move handling).
| self.apply_event_to_active_buffer(&move_event); | |
| self.active_event_log_mut().append(move_event); | |
| self.apply_event_to_buffer(buffer_id, &move_event); | |
| self.event_log_for_buffer_mut(buffer_id).append(move_event); |
| if sent { | ||
| self.next_lsp_request_id += 1; | ||
| self.pending_inline_completion_request = Some(request_id); | ||
| } |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
request_inline_completion overwrites pending_inline_completion_request when a new request is sent. If a previous inline completion request is still pending, its ID is lost so it can’t be canceled and the eventual response will be ignored, causing unnecessary server work. Consider canceling the previous pending inline-completion request (or skipping sending a new one) before setting a new pending request ID.
| priority: i32, | ||
| string_id: String, | ||
| pad_inline: bool, | ||
| ) -> VirtualTextId { |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add_inline_with_id accepts any VirtualTextPosition but its name implies it should only be used with inline positions. Add a debug_assert!(vtext_position.is_inline(), ...) (similar to add_line) to prevent accidental misuse (e.g., passing LineAbove/LineBelow, where pad_inline is meaningless).
| ) -> VirtualTextId { | |
| ) -> VirtualTextId { | |
| debug_assert!( | |
| vtext_position.is_inline(), | |
| "add_inline_with_id requires BeforeChar or AfterChar" | |
| ); |
|
I'm trying it but don't see anything - can you give an example I can try where it kicks in? |
fix #686
Implemented LSP inline completion (ghost text) end‑to‑end and added Tab acceptance.
Inline completions are now requested on trigger/quick‑suggestion input and on manual completion, rendered as unpadded virtual text, and applied as proper LSP edits with snippet expansion.
Inlay hints no longer clear unrelated virtual text, so ghost text stays intact.
Updated LSP capability negotiation and tracking for inline completion support.