feat(lsp) Adds SFTP URI resolution to the runtime provider for LSP workspaces. - #2703
feat(lsp) Adds SFTP URI resolution to the runtime provider for LSP workspaces.#2703gat0sy wants to merge 6 commits into
Conversation
Greptile SummaryThe PR adds SFTP-aware URI resolution and expands LSP navigation, workspace-edit, lifecycle, and settings behavior. Two URI/client association paths remain ambiguous and can route edits or remote files through the wrong LSP or SFTP context.
Confidence Score: 3/5The PR is not yet safe to merge because workspace edits can still use the wrong LSP synchronization state and authority-free file URIs can resolve to the wrong SFTP connection. The workspace-edit fix retains an arbitrary plugin fallback, while SFTP reverse resolution matches same-path remote roots without preserving the requesting connection identity; these paths can misapply edits or open files from another host. Files Needing Attention: src/cm/lsp/transport.ts, src/components/referencesPanel/utils.js, src/cm/lsp/runtimes/sftpRemote.ts Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
SFTP["SFTP workspace URI<br/>authority + path"] --> Runtime["SFTP runtime"]
Runtime --> FileURI["file URI<br/>path only"]
FileURI --> LSP["External LSP server"]
LSP --> Response["Definition / reference / workspace edit"]
Response --> Resolve["Resolve against added folders"]
Resolve --> Target["SFTP target view"]
Target --> Plugin["Select requesting LSP plugin"]
Resolve -. "pathname-only first match" .-> WrongHost["Wrong SFTP connection"]
Plugin -. "fallback to first plugin" .-> WrongClient["Wrong synchronization state"]
Reviews (2): Last reviewed commit: "feat(lsp): add SFTP remote runtime provi..." | Re-trigger Greptile |
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.
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.
go to def and similar fonction have been added, a new interceptFileLink method has been created to solve an FileUriExposedException you may get if taping the signature link on the hover. if the link is a website, it skips and let the normal behavior occur ( open a web browser page ) if the link is a file, it modifies the uri so the tap behave like a go to instead of crashing the whole app. There are notably also some fixes for code actions, rename...ect, now they use the new lspPostionToOffset that uses clamping
5fa3ac0 to
3b11814
Compare
…actions menu Added resolveContentUriForFileUri() to map LSP file:// responses back to content:// and sftp:// URIs via addedFolder matching Refactor editorManager displayFile/openFile to resolve URIs before opening, enabling cross-workspace go-to-definition and references Added SFTP path-aware root URI resolution for remote workspace context Replace selection menu code-actions button with full LSP actions menu (definition, declaration, implementation, type-definition, references, rename, code-actions) with single-item auto-execution
Added sftpRemote.ts runtime provider that translates sftp:// URIs to file:// before sending to LSP servers, stripping host/credentials Register sftpRemoteRuntimeProvider in registerBuiltins.ts Delegate transport to external-websocket provider since SFTP LSP connections are handled via WebSocket tunnel
3b11814 to
ebfcfac
Compare
This comment was marked as outdated.
This comment was marked as outdated.
|
|
||
| // Find the plugin belonging to THIS server, not just any plugin | ||
| const allPlugins = LSPPlugin.getAll(view); | ||
| const plugin = | ||
| allPlugins.find( | ||
| (p) => (p.client as { | ||
| __acodeServerId?: string | ||
| }).__acodeServerId === server.id, | ||
| ) ?? allPlugins[0]; |
There was a problem hiding this comment.
Workspace edit still uses wrong client
When a workspace edit opens or retrieves a view without the requesting server's plugin, this fallback selects the view's first unrelated plugin. applyTextEdits then maps the server's ranges through that plugin's syncedDoc and unsyncedChanges, causing edits at incorrect offsets or rejecting valid edits.
Knowledge Base Used: LSP Integration
| if (rootUrl.startsWith("sftp:")) { | ||
| let parts; | ||
| try { | ||
| parts = Url.decodeUrl(rootUrl); | ||
| } catch { | ||
| continue; | ||
| } | ||
| const rootPath = (parts.pathname || "").replace(/\/+$/, ""); | ||
| if (!rootPath) continue; | ||
|
|
||
| let childPath = null; | ||
| if (targetPath === rootPath) { | ||
| childPath = rootPath; | ||
| } else if (targetPath.startsWith(`${rootPath}/`)) { | ||
| childPath = targetPath; | ||
| } else { | ||
| continue; | ||
| } | ||
|
|
||
| return Url.formate({ | ||
| protocol: "sftp:", | ||
| hostname: parts.hostname, | ||
| username: parts.username, | ||
| password: parts.password, | ||
| port: parts.port, | ||
| path: childPath, | ||
| query: parts.query, | ||
| }); |
There was a problem hiding this comment.
SFTP responses resolve to wrong connection
When two added SFTP folders have the same remote root path but different connection identities, this pathname-only search reconstructs the server's authority-free file:// URI with the first matching folder's credentials. Definitions, references, tooltip links, and workspace-edited files from the other workspace then open through the wrong SFTP host.
Knowledge Base Used:
This PR is based on PR #2702