Skip to content

feat(lsp): fixing LspToPosition via clamping and moving it to helper - #2700

Open
gat0sy wants to merge 1 commit into
Acode-Foundation:mainfrom
gat0sy:feat/lsp-core
Open

feat(lsp): fixing LspToPosition via clamping and moving it to helper#2700
gat0sy wants to merge 1 commit into
Acode-Foundation:mainfrom
gat0sy:feat/lsp-core

Conversation

@gat0sy

@gat0sy gat0sy commented Aug 8, 2026

Copy link
Copy Markdown

Fix lspPositionToOffset when LSP servers return EOF positions one line past the document via clamping

Extract lspPositionToOffset() and applyTextEdits() into a shared helper so clientManager and transport use the same bounds-safe logic of the new lspPositionToOffset

Send workspaceFolders when rootUri is available

Declare missing applyEdit, workspaceFolders, and code action resolve capabilities

Re-send workspace/didChangeConfiguration after initialization

Normalize SFTP URIs before sending them to LSP servers ( Assuming the LSP runs on the same machine as the sftp directory )

These fixes improve compatibility with servers that rely on workspace folders, applyEdit, resolvable code actions, post-init configuration, or full-document edits. They may need some polishing.

Note: CodeActions feature times out if more than one lsp are running at the same time when using the built-In LSPs

LspToPosition threw range error on format error.
We attempt to fix it here with by clamping so we get the correct line count between the client and server.

applyTextEdit as also been extracted so both transport and client manager can import it from the helper.
@greptile-apps

greptile-apps Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR centralizes bounds-safe LSP text-edit conversion and expands LSP initialization, workspace-edit, URI-normalization, and idle-client behavior.

  • Clamps out-of-range LSP positions to document bounds.
  • Advertises and handles workspace/applyEdit and additional code-action/workspace capabilities.
  • Sends workspace folders and post-initialization configuration.
  • Delays idle-client disposal and normalizes SFTP document URIs.

Confidence Score: 3/5

The PR should not merge until server-initiated workspace edits are bound to the originating LSP client and unsupported resource operations are handled or rejected atomically.

The new workspace-edit path can map edits through another client's document state in multi-server sessions and can report success after dropping requested file operations.

Files Needing Attention: src/cm/lsp/transport.ts, src/cm/lsp/clientManager.ts

Important Files Changed

Filename Overview
src/cm/lsp/clientManager.ts Adds capabilities, workspace-folder/configuration initialization behavior, delayed idle disposal, and SFTP normalization; advertising unrestricted applyEdit exposes unsupported resource operations.
src/cm/lsp/textEditUtils.ts Extracts shared text-edit application and safely clamps LSP positions at document boundaries.
src/cm/lsp/transport.ts Adds asynchronous workspace/applyEdit handling, but loses server-client identity in multi-client views and silently omits resource operations.

Sequence Diagram

sequenceDiagram
  participant Server as LSP Server
  participant Transport
  participant View as EditorView
  participant Plugin as Selected LSPPlugin
  Server->>Transport: workspace/applyEdit
  Transport->>View: locate/open target URI
  Transport->>Plugin: LSPPlugin.get(view)
  Plugin->>Plugin: map positions via syncedDoc/unsyncedChanges
  Plugin->>View: dispatch text changes
  Transport-->>Server: ApplyWorkspaceEditResponse
Loading

Reviews (1): Last reviewed commit: "feat(lsp): fixing LspToPosition adding a..." | Re-trigger Greptile

Comment thread src/cm/lsp/transport.ts
Comment on lines +217 to +223
const plugin = LSPPlugin.get(view);
if (!plugin) {
failures.push(uri);
continue;
}

const applied = applyTextEdits(plugin, view, edits);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Workspace edits use wrong client

When multiple LSP clients are attached to a document, LSPPlugin.get(view) does not select the client that sent workspace/applyEdit, so positions are mapped through another client's syncedDoc and unsyncedChanges, causing edits to target incorrect offsets, be skipped, or fail file lookup.

Knowledge Base Used: LSP Integration

Comment thread src/cm/lsp/transport.ts
Comment on lines +171 to +176
ctx: TransportContext,
): Promise<{ applied: boolean; failureReason?: string }> {
if (!edit) return { applied: false, failureReason: "No edit provided" };

const changesByUri: Record<string, TextEdit[]> =
edit.changes ??

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Resource operations are silently dropped

When documentChanges contains CreateFile, RenameFile, or DeleteFile operations, this filter discards them and evaluates success using only the remaining text edits, so the client can return applied: true after executing only part of the requested workspace edit.

Knowledge Base Used: LSP Integration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant