Skip to content

Commit b653280

Browse files
committed
Data Explorer: Preserve non-file URIs when creating DuckDB clients.
Previously we encoded only the original path in the data explorer, losing the scheme (and other URI attributes) and fundamentally assuming that we could only open local files. This commit instead encodes the original URI in its entirety and adds a helper to retrieve it, which makes it possible to use the `Open as Plain Text` button even with files backed by a virtual filesystem provider. Double-encoding the URI here is pretty gross, of course, but it's consistent with what we were already doing. This is the last piece of #7351. Signed-off-by: Aaron Jacobs <[email protected]>
1 parent ec0707c commit b653280

File tree

5 files changed

+31
-16
lines changed

5 files changed

+31
-16
lines changed

src/vs/workbench/contrib/positronDataExplorerEditor/browser/positronDataExplorerActions.ts

+12-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import { PositronDataExplorerEditorInput } from './positronDataExplorerEditorInp
2121
import { POSITRON_DATA_EXPLORER_IS_ACTIVE_EDITOR, POSITRON_DATA_EXPLORER_IS_COLUMN_SORTING, POSITRON_DATA_EXPLORER_IS_PLAINTEXT, POSITRON_DATA_EXPLORER_LAYOUT } from './positronDataExplorerContextKeys.js';
2222
import { Codicon } from '../../../../base/common/codicons.js';
2323
import { PositronDataExplorerUri } from '../../../services/positronDataExplorer/common/positronDataExplorerUri.js';
24-
import { URI } from '../../../../base/common/uri.js';
2524
import { EditorOpenSource } from '../../../../platform/editor/common/editor.js';
2625
import { IPathService } from '../../../services/path/common/pathService.js';
2726
import { toLocalResource } from '../../../../base/common/resources.js';
@@ -750,22 +749,24 @@ class PositronDataExplorerOpenAsPlaintextAction extends Action2 {
750749
return;
751750
}
752751

753-
// Parse this URI - gives underlying FS URI if not memory-backed (scheme = duckdb)
754-
const parsedDataExplorerURI = PositronDataExplorerUri.parse(originalURI);
755-
if (!parsedDataExplorerURI) {
752+
let backingUri = PositronDataExplorerUri.backingUri(originalURI);
753+
if (!backingUri) {
756754
return;
757755
}
758756

759-
// Convert raw duckdb URI to appropriate file URI (scheme = file if local, vscode-remote if server)
760-
const localURI = toLocalResource(
761-
URI.parse(parsedDataExplorerURI),
762-
environmentService.remoteAuthority,
763-
pathService.defaultUriScheme
764-
);
757+
// Convert file URIs to the "local" scheme, i.e. vscode-remote when
758+
// running as a server.
759+
if (backingUri.scheme === 'file') {
760+
backingUri = toLocalResource(
761+
backingUri,
762+
environmentService.remoteAuthority,
763+
pathService.defaultUriScheme
764+
);
765+
}
765766

766767
// Invoke editor for file, using default editor (text) association
767768
await editorService.openEditor({
768-
resource: localURI,
769+
resource: backingUri,
769770
options: {
770771
override: DEFAULT_EDITOR_ASSOCIATION.id,
771772
source: EditorOpenSource.USER

src/vs/workbench/contrib/positronDataExplorerEditor/browser/positronDataExplorerEditor.contribution.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class PositronDataExplorerContribution extends Disposable {
9999

100100
// We create a data explorer URI that will use the DuckDB client
101101
// that we just created.
102-
const newResource = PositronDataExplorerUri.generate(`duckdb:${resource.path}`);
102+
const newResource = PositronDataExplorerUri.generate(`duckdb:${resource.toString()}`);
103103
return createDataExplorerEditor({
104104
resource: newResource,
105105
options

src/vs/workbench/contrib/positronDataExplorerEditor/browser/positronDataExplorerEditor.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import { IPositronDataExplorerService, PositronDataExplorerLayout } from '../../
3636
import { PositronDataExplorerEditorInput } from './positronDataExplorerEditorInput.js';
3737
import { PositronDataExplorerClosed, PositronDataExplorerClosedStatus } from '../../../browser/positronDataExplorer/components/dataExplorerClosed/positronDataExplorerClosed.js';
3838
import { POSITRON_DATA_EXPLORER_IS_COLUMN_SORTING, POSITRON_DATA_EXPLORER_IS_PLAINTEXT, POSITRON_DATA_EXPLORER_LAYOUT } from './positronDataExplorerContextKeys.js';
39-
import { URI } from '../../../../base/common/uri.js';
4039

4140
/**
4241
* IPositronDataExplorerEditorOptions interface.
@@ -362,8 +361,8 @@ export class PositronDataExplorerEditor extends EditorPane implements IPositronD
362361
positronDataExplorerInstance.tableDataDataGridInstance.isColumnSorting
363362
);
364363

365-
const uri = URI.parse(this._identifier);
366-
if (uri.scheme === 'duckdb') {
364+
const uri = PositronDataExplorerUri.backingUri(input.resource);
365+
if (uri) {
367366
this._isPlaintextContextKey.set(PLAINTEXT_EXTS.some(ext => uri.path.endsWith(ext)));
368367
} else {
369368
this._isPlaintextContextKey.reset();

src/vs/workbench/services/positronDataExplorer/common/positronDataExplorerDuckDBBackend.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export class PositronDataExplorerDuckDBBackend extends Disposable implements IDa
9797
private readonly uri: URI
9898
) {
9999
super();
100-
this.clientId = `duckdb:${this.uri.path}`;
100+
this.clientId = `duckdb:${this.uri.toString()}`;
101101
this.initialSetup = this.openDataset();
102102
}
103103

src/vs/workbench/services/positronDataExplorer/common/positronDataExplorerUri.ts

+15
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,19 @@ export class PositronDataExplorerUri {
5656
return undefined;
5757
}
5858
}
59+
60+
/**
61+
* Parses a Positron data explorer URI and retrieves the URI of the backing file, if any.
62+
* @param resource The data explorer resource.
63+
* @returns A URI for the backing file, if any.
64+
*/
65+
public static backingUri(resource: URI): URI | undefined {
66+
const identifier = PositronDataExplorerUri.parse(resource);
67+
// Runtime comm IDs have no originating URIs.
68+
if (!identifier || !identifier.startsWith('duckdb:')) {
69+
return undefined;
70+
}
71+
// This will be something like "duckdb:file:///path/to/file.csv".
72+
return URI.parse(identifier.replace('duckdb:', ''));
73+
}
5974
}

0 commit comments

Comments
 (0)