@@ -218,6 +218,82 @@ lsp.upsert({
218218});
219219` ` `
220220
221+ ## Custom URI Translation
222+
223+ Use ` rootUri` and ` documentUri` when the server does not see the same
224+ filesystem layout as Acode.
225+
226+ Typical cases:
227+
228+ - the server runs in Termux
229+ - the server runs behind a remote WebSocket bridge
230+ - the editor opens files as ` content: // ...` but the server expects `file://...`
231+ - the default cache- file fallback does not point at the real project path
232+
233+ ` rootUri` controls the workspace root sent during initialize and workspace
234+ folder handling.
235+
236+ ` documentUri` controls the URI used for opened documents, changes, formatting,
237+ and similar file- scoped LSP requests.
238+
239+ Both hooks may be synchronous or async .
240+
241+ ` documentUri(uri, context)` receives:
242+
243+ - ` uri` : the original file URI known to Acode
244+ - ` context.normalizedUri` : Acode' s default normalized URI, including
245+ `content:// -> file://` conversion or cache fallback when available
246+ - the same context fields available to `rootUri`, such as `file`, `view`,
247+ `languageId`, and `rootUri`
248+
249+ Example:
250+
251+ ```js
252+ const lsp = acode.require("lsp");
253+
254+ const termuxWorkspaceUri =
255+ "file:///data/data/com.termux/files/home/projects/my-project";
256+
257+ function toTermuxDocumentUri(uri, fallbackUri) {
258+ if (typeof uri !== "string") return fallbackUri || null;
259+
260+ if (uri.startsWith("file:///storage/emulated/0/")) {
261+ return uri.replace(
262+ "file:///storage/emulated/0/",
263+ "file:///data/data/com.termux/files/home/storage/shared/",
264+ );
265+ }
266+
267+ return fallbackUri || uri;
268+ }
269+
270+ const termuxServer = lsp.defineServer({
271+ id: "termux-typescript",
272+ label: "TypeScript (Termux)",
273+ languages: [
274+ "javascript",
275+ "javascriptreact",
276+ "typescript",
277+ "typescriptreact",
278+ "tsx",
279+ "jsx",
280+ ],
281+ useWorkspaceFolders: true,
282+ transport: {
283+ kind: "websocket",
284+ url: "ws://127.0.0.1:2087/",
285+ },
286+ rootUri() {
287+ return termuxWorkspaceUri;
288+ },
289+ documentUri(uri, context) {
290+ return toTermuxDocumentUri(uri, context.normalizedUri);
291+ },
292+ });
293+
294+ lsp.upsert(termuxServer);
295+ ```
296+
221297## Definition API
222298
223299### `lsp.defineServer(options)`
@@ -240,7 +316,10 @@ Common fields:
240316- `clientConfig`
241317- `startupTimeout`
242318- `capabilityOverrides`
243- - ` rootUri`
319+ - `rootUri`: optional workspace-root resolver; if provided it takes precedence
320+ over Acode' s default root detection
321+ - ` documentUri` : optional document URI resolver for translating file paths before
322+ they are sent to the server
244323- ` resolveLanguageId`
245324- ` useWorkspaceFolders`
246325
@@ -318,3 +397,5 @@ console.log(activeClients);
318397- Prefer structured installers over raw shell commands.
319398- Use a bundle when your plugin owns a family of related servers or custom install logic.
320399- Use ` useWorkspaceFolders: true` for heavy workspace- aware servers like TypeScript or Rust.
400+ - If your server runs outside Acode' s local filesystem view, define both `rootUri`
401+ and `documentUri` so the server receives paths it can resolve.
0 commit comments