Skip to content

Commit 5da9d3d

Browse files
Merge pull request #551 from gjsjohnmurray/enh-450
implement isfs://server:namespace/ alternative syntax (#450)
2 parents 67483b7 + ae0f008 commit 5da9d3d

File tree

5 files changed

+50
-29
lines changed

5 files changed

+50
-29
lines changed

src/api/index.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,16 @@ export class AtelierAPI {
100100
if (wsOrFile instanceof vscode.Uri) {
101101
if (schemas.includes(wsOrFile.scheme)) {
102102
workspaceFolderName = wsOrFile.authority;
103-
const { query } = url.parse(decodeURIComponent(wsOrFile.toString()), true);
104-
if (query) {
105-
if (query.ns && query.ns !== "") {
106-
namespace = query.ns.toString();
103+
const parts = workspaceFolderName.split(":");
104+
if (parts.length === 2 && config("intersystems.servers").has(parts[0].toLowerCase())) {
105+
workspaceFolderName = parts[0];
106+
namespace = parts[1];
107+
} else {
108+
const { query } = url.parse(wsOrFile.toString(true), true);
109+
if (query) {
110+
if (query.ns && query.ns !== "") {
111+
namespace = query.ns.toString();
112+
}
107113
}
108114
}
109115
}

src/debug/debugSession.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,19 @@ interface AttachRequestArguments extends DebugProtocol.AttachRequestArguments {
3737
stopOnEntry?: boolean;
3838
}
3939

40-
/** converts a local path from VS Code to a server-side XDebug file URI with respect to source root settings */
41-
export async function convertClientPathToDebugger(localPath: string, namespace: string): Promise<string> {
42-
const { protocol, pathname, query } = url.parse(decodeURIComponent(localPath), true, true);
43-
let fileName = localPath;
44-
if (protocol && schemas.includes(protocol.slice(0, -1))) {
40+
/** converts a uri from VS Code to a server-side XDebug file URI with respect to source root settings */
41+
async function convertClientPathToDebugger(uri: vscode.Uri, namespace: string): Promise<string> {
42+
const { scheme, path } = uri;
43+
const { query } = url.parse(uri.toString(true), true);
44+
let fileName: string;
45+
if (scheme && schemas.includes(scheme)) {
4546
if (query.ns && query.ns !== "") {
4647
namespace = query.ns.toString();
4748
}
48-
fileName = pathname.slice(1).replace(/\//, ".");
49+
fileName = path.slice(1).replace(/\//, ".");
4950
} else {
5051
fileName = await vscode.workspace
51-
.openTextDocument(localPath)
52+
.openTextDocument(uri)
5253
.then(currentFile)
5354
.then((curFile) => {
5455
return curFile.name;
@@ -241,10 +242,9 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
241242
await this._debugTargetSet.wait(1000);
242243

243244
const filePath = args.source.path;
244-
const { protocol } = url.parse(decodeURIComponent(filePath), true, true);
245-
const uri =
246-
protocol && schemas.includes(protocol.slice(0, -1)) ? vscode.Uri.parse(filePath) : vscode.Uri.file(filePath);
247-
const fileUri = await convertClientPathToDebugger(args.source.path, this._namespace);
245+
const scheme = filePath.split(":")[0];
246+
const uri = schemas.includes(scheme) ? vscode.Uri.parse(filePath) : vscode.Uri.file(filePath);
247+
const fileUri = await convertClientPathToDebugger(uri, this._namespace);
248248
const [, fileName] = fileUri.match(/\|([^|]+)$/);
249249

250250
const currentList = await this._connection.sendBreakpointListCommand();

src/providers/DocumentContentProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export class DocumentContentProvider implements vscode.TextDocumentContentProvid
108108

109109
public provideTextDocumentContent(uri: vscode.Uri, token: vscode.CancellationToken): vscode.ProviderResult<string> {
110110
const api = new AtelierAPI(uri);
111-
const query = url.parse(decodeURIComponent(uri.toString()), true).query;
111+
const query = url.parse(uri.toString(true), true).query;
112112
const fileName = query && query.csp ? uri.path.substring(1) : uri.path.split("/").slice(1).join(".");
113113
if (query) {
114114
if (query.ns && query.ns !== "") {

src/providers/FileSystemPovider/FileSystemProvider.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
4747
return;
4848
}
4949
const sql = `CALL %Library.RoutineMgr_StudioOpenDialog(?,?,?,?,?,?,?)`;
50-
const { query } = url.parse(decodeURIComponent(uri.toString()), true);
50+
const { query } = url.parse(uri.toString(true), true);
5151
const type = query.type && query.type != "" ? query.type.toString() : "all";
5252
const csp = query.csp === "" || query.csp === "1";
5353
let filter = "";
@@ -181,7 +181,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
181181
if (uri.path.startsWith("/.")) {
182182
throw vscode.FileSystemError.NoPermissions("dot-folders not supported by server");
183183
}
184-
const { query } = url.parse(decodeURIComponent(uri.toString()), true);
184+
const { query } = url.parse(uri.toString(true), true);
185185
const csp = query.csp === "" || query.csp === "1";
186186
const fileName = csp ? uri.path : uri.path.slice(1).replace(/\//g, ".");
187187
if (fileName.startsWith(".")) {
@@ -244,7 +244,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
244244
}
245245

246246
public delete(uri: vscode.Uri, options: { recursive: boolean }): void | Thenable<void> {
247-
const { query } = url.parse(decodeURIComponent(uri.toString()), true);
247+
const { query } = url.parse(uri.toString(true), true);
248248
const csp = query.csp === "" || query.csp === "1";
249249
const fileName = csp ? uri.path : uri.path.slice(1).replace(/\//g, ".");
250250
if (fileName.startsWith(".")) {
@@ -330,7 +330,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
330330
throw vscode.FileSystemError.NoPermissions("dot-folders not supported by server");
331331
}
332332

333-
const { query } = url.parse(decodeURIComponent(uri.toString()), true);
333+
const { query } = url.parse(uri.toString(true), true);
334334
const csp = query.csp === "" || query.csp === "1";
335335
const fileName = csp ? uri.path : uri.path.slice(1).replace(/\//g, ".");
336336
const name = path.basename(uri.path);

src/utils/index.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export function currentFile(document?: vscode.TextDocument): CurrentFile {
8181
const content = document.getText();
8282
let name = "";
8383
let ext = "";
84-
const { query } = url.parse(decodeURIComponent(uri.toString()), true);
84+
const { query } = url.parse(uri.toString(true), true);
8585
const csp = query.csp === "" || query.csp === "1";
8686
if (csp) {
8787
name = uri.path;
@@ -167,7 +167,8 @@ export function connectionTarget(uri?: vscode.Uri): ConnectionTarget {
167167
}
168168
} else if (schemas.includes(uri.scheme)) {
169169
result.apiTarget = uri;
170-
result.configName = uri.authority;
170+
const parts = uri.authority.split(":");
171+
result.configName = parts.length === 2 ? parts[0] : uri.authority;
171172
}
172173
}
173174

@@ -178,7 +179,8 @@ export function connectionTarget(uri?: vscode.Uri): ConnectionTarget {
178179
? vscode.workspace.workspaceFolders[0]
179180
: undefined;
180181
if (firstFolder && schemas.includes(firstFolder.uri.scheme)) {
181-
result.configName = firstFolder.uri.authority;
182+
const parts = firstFolder.uri.authority.split(":");
183+
result.configName = parts.length === 2 ? parts[0] : firstFolder.uri.authority;
182184
result.apiTarget = firstFolder.uri;
183185
} else {
184186
result.configName = workspaceState.get<string>("workspaceFolder") || firstFolder ? firstFolder.name : "";
@@ -350,7 +352,9 @@ export async function terminalWithDocker(): Promise<vscode.Terminal> {
350352
* Alter isfs-type uri.path of /.vscode/* files or subdirectories.
351353
* Rewrite `/.vscode/path/to/file` as `/_vscode/XYZ/path/to/file`
352354
* where XYZ comes from the `ns` queryparam of uri.
353-
* Also alter query to specify `ns=%SYS&csp=1`
355+
* Also alter query to specify `ns=%SYS&csp=1`
356+
* Also handles the alternative syntax isfs://server:namespace/
357+
* in which there is no ns queryparam
354358
*
355359
* @returns uri, altered if necessary.
356360
* @throws if `ns` queryparam is missing but required.
@@ -361,13 +365,24 @@ export function redirectDotvscodeRoot(uri: vscode.Uri): vscode.Uri {
361365
}
362366
const dotMatch = uri.path.match(/^\/(\.[^/]*)\/(.*)$/);
363367
if (dotMatch && dotMatch[1] === ".vscode") {
368+
let namespace: string;
364369
const nsMatch = `&${uri.query}&`.match(/&ns=([^&]+)&/);
365-
if (!nsMatch) {
366-
throw new Error("No 'ns' query parameter on uri");
370+
if (nsMatch) {
371+
namespace = nsMatch[1];
372+
const newQueryString = (("&" + uri.query).replace(`ns=${namespace}`, "ns=%SYS") + "&csp=1").slice(1);
373+
return uri.with({ path: `/_vscode/${namespace}/${dotMatch[2]}`, query: newQueryString });
374+
} else {
375+
const parts = uri.authority.split(":");
376+
if (parts.length === 2) {
377+
namespace = parts[1];
378+
return uri.with({
379+
authority: `${parts[0]}:%SYS`,
380+
path: `/_vscode/${namespace}/${dotMatch[2]}`,
381+
query: uri.query + "&csp=1",
382+
});
383+
}
367384
}
368-
const namespace = nsMatch[1];
369-
const newQueryString = (("&" + uri.query).replace(`ns=${namespace}`, "ns=%SYS") + "&csp=1").slice(1);
370-
return uri.with({ path: `/_vscode/${namespace}/${dotMatch[2]}`, query: newQueryString });
385+
throw new Error("No namespace determined from uri");
371386
} else {
372387
return uri;
373388
}

0 commit comments

Comments
 (0)