From 9ec8835cf35d5a46101a62ae93285aeb37a2f382 Mon Sep 17 00:00:00 2001 From: Mark Sujew Date: Wed, 25 May 2022 13:49:08 +0200 Subject: [PATCH] Display correct file system path for Windows (#11180) --- .../core/src/browser/label-provider.spec.ts | 7 +++++- packages/core/src/browser/label-provider.ts | 2 +- packages/core/src/common/uri.ts | 2 +- .../debug/src/browser/model/debug-source.ts | 2 +- .../src/browser/editor-widget-factory.ts | 2 +- .../src/browser/quick-editor-service.ts | 2 +- .../browser/location/location-renderer.tsx | 4 ++-- .../marker-tree-label-provider.spec.ts | 14 ++++++++++-- .../src/browser/problem/problem-decorator.ts | 4 ++-- .../navigator-open-editors-widget.tsx | 4 ++-- .../src/browser/preferences-contribution.ts | 2 +- .../views/components/preference-file-input.ts | 2 +- .../resource-property-view-tree-widget.tsx | 2 +- packages/scm/src/browser/scm-tree-widget.tsx | 8 +++---- ...search-in-workspace-result-tree-widget.tsx | 8 +++---- .../workspace-frontend-contribution.ts | 2 +- .../src/browser/workspace-input-dialog.ts | 2 +- .../workspace-uri-contribution.spec.ts | 22 ++++++++++++++++--- 18 files changed, 61 insertions(+), 30 deletions(-) diff --git a/packages/core/src/browser/label-provider.spec.ts b/packages/core/src/browser/label-provider.spec.ts index e6cf6b92f82db..98cd4eb5eb098 100644 --- a/packages/core/src/browser/label-provider.spec.ts +++ b/packages/core/src/browser/label-provider.spec.ts @@ -17,6 +17,7 @@ import { expect } from 'chai'; import { DefaultUriLabelProviderContribution, URIIconReference } from './label-provider'; import URI from '../common/uri'; +import { OS } from '../common/os'; describe('DefaultUriLabelProviderContribution', function (): void { @@ -31,7 +32,11 @@ describe('DefaultUriLabelProviderContribution', function (): void { const prov = new DefaultUriLabelProviderContribution(); const longName = prov.getLongName(new URI('file:///tmp/hello/you.txt')); - expect(longName).eq('/tmp/hello/you.txt'); + if (OS.backend.isWindows) { + expect(longName).eq('\\tmp\\hello\\you.txt'); + } else { + expect(longName).eq('/tmp/hello/you.txt'); + } }); it('should return icon class for something that seems to be a file', function (): void { diff --git a/packages/core/src/browser/label-provider.ts b/packages/core/src/browser/label-provider.ts index 87e55e1fb425d..ee87a214c9652 100644 --- a/packages/core/src/browser/label-provider.ts +++ b/packages/core/src/browser/label-provider.ts @@ -179,7 +179,7 @@ export class DefaultUriLabelProviderContribution implements LabelProviderContrib return this.formatUri(uri, formatting); } } - return uri && uri.path.toString(); + return uri && uri.path.fsPath(); } protected getUri(element: URI | URIIconReference): URI | undefined { diff --git a/packages/core/src/common/uri.ts b/packages/core/src/common/uri.ts index 1241abd22c72e..f83699f7a4c2a 100644 --- a/packages/core/src/common/uri.ts +++ b/packages/core/src/common/uri.ts @@ -45,7 +45,7 @@ export class URI { return base; } if (this.path.isRoot) { - return this.path.toString(); + return this.path.fsPath(); } return ''; } diff --git a/packages/debug/src/browser/model/debug-source.ts b/packages/debug/src/browser/model/debug-source.ts index fe557a15ca54c..fa2010e2d522d 100644 --- a/packages/debug/src/browser/model/debug-source.ts +++ b/packages/debug/src/browser/model/debug-source.ts @@ -63,7 +63,7 @@ export class DebugSource extends DebugSourceData { get name(): string { if (this.inMemory) { - return this.raw.name || this.uri.path.base || this.uri.path.toString(); + return this.raw.name || this.uri.path.base || this.uri.path.fsPath(); } return this.labelProvider.getName(this.uri); } diff --git a/packages/editor/src/browser/editor-widget-factory.ts b/packages/editor/src/browser/editor-widget-factory.ts index 2f9fe3eb908b5..da30689b14bf3 100644 --- a/packages/editor/src/browser/editor-widget-factory.ts +++ b/packages/editor/src/browser/editor-widget-factory.ts @@ -71,7 +71,7 @@ export class EditorWidgetFactory implements WidgetFactory { } private setLabels(editor: EditorWidget, uri: URI): void { - editor.title.caption = uri.path.toString(); + editor.title.caption = uri.path.fsPath(); const icon = this.labelProvider.getIcon(uri); editor.title.label = this.labelProvider.getName(uri); editor.title.iconClass = icon + ' file-icon'; diff --git a/packages/editor/src/browser/quick-editor-service.ts b/packages/editor/src/browser/quick-editor-service.ts index f3293b987fb87..270e30b376f99 100644 --- a/packages/editor/src/browser/quick-editor-service.ts +++ b/packages/editor/src/browser/quick-editor-service.ts @@ -80,7 +80,7 @@ export class QuickEditorService implements QuickAccessContribution, QuickAccessP label: this.labelProvider.getName(uri), description: description, iconClasses, - ariaLabel: uri.path.toString(), + ariaLabel: uri.path.fsPath(), alwaysShow: true, execute: () => this.openFile(uri) }; diff --git a/packages/filesystem/src/browser/location/location-renderer.tsx b/packages/filesystem/src/browser/location/location-renderer.tsx index 45c19a440e150..5f4992546191b 100644 --- a/packages/filesystem/src/browser/location/location-renderer.tsx +++ b/packages/filesystem/src/browser/location/location-renderer.tsx @@ -187,7 +187,7 @@ export class LocationListRenderer extends ReactRenderer { protected renderTextInput(): React.ReactNode { return ( {isDrive ? uri.path.toString() : uri.displayName}; + return ; } protected onLocationChanged(e: React.ChangeEvent): void { diff --git a/packages/markers/src/browser/marker-tree-label-provider.spec.ts b/packages/markers/src/browser/marker-tree-label-provider.spec.ts index 9d0a370711997..9f1cfa2e1870c 100644 --- a/packages/markers/src/browser/marker-tree-label-provider.spec.ts +++ b/packages/markers/src/browser/marker-tree-label-provider.spec.ts @@ -40,6 +40,7 @@ import { FileStat } from '@theia/filesystem/lib/common/files'; import { EnvVariablesServer } from '@theia/core/lib/common/env-variables'; import { MockEnvVariablesServerImpl } from '@theia/core/lib/browser/test/mock-env-variables-server'; import { FileUri } from '@theia/core/lib/node'; +import { OS } from '@theia/core/lib/common/os'; import * as temp from 'temp'; disableJSDOM(); @@ -131,7 +132,11 @@ describe('Marker Tree Label Provider', () => { const label = markerTreeLabelProvider.getLongName( createMarkerInfoNode('file:///home/b/foo.ts') ); - expect(label).equals('/home/b'); + if (OS.backend.isWindows) { + expect(label).eq('\\home\\b'); + } else { + expect(label).eq('/home/b'); + } }); }); describe('multi-root workspace', () => { @@ -165,7 +170,12 @@ describe('Marker Tree Label Provider', () => { const label = markerTreeLabelProvider.getLongName( createMarkerInfoNode('file:///home/a/b/foo.ts') ); - expect(label).equals('/home/a/b'); + + if (OS.backend.isWindows) { + expect(label).eq('\\home\\a\\b'); + } else { + expect(label).eq('/home/a/b'); + } }); }); }); diff --git a/packages/markers/src/browser/problem/problem-decorator.ts b/packages/markers/src/browser/problem/problem-decorator.ts index 394756fbfa074..67f4d647ff586 100644 --- a/packages/markers/src/browser/problem/problem-decorator.ts +++ b/packages/markers/src/browser/problem/problem-decorator.ts @@ -109,10 +109,10 @@ export class ProblemDecorator implements TreeDecorator { if (parentWorkspace) { const relativeDirFromWorkspace = parentWorkspace.relative(nodeURIDir); workspacePrefixString = workspaceRoots.length > 1 ? this.labelProvider.getName(parentWorkspace) : ''; - filePathString = relativeDirFromWorkspace?.toString() ?? ''; + filePathString = relativeDirFromWorkspace?.fsPath() ?? ''; separator = filePathString && workspacePrefixString ? ' \u2022 ' : ''; // add a bullet point between workspace and path } else { - workspacePrefixString = nodeURIDir.path.toString(); + workspacePrefixString = nodeURIDir.path.fsPath(); } return `${workspacePrefixString}${separator}${filePathString}`; } diff --git a/packages/navigator/src/browser/open-editors-widget/navigator-open-editors-widget.tsx b/packages/navigator/src/browser/open-editors-widget/navigator-open-editors-widget.tsx index cf108eb9da25d..96ce35f324801 100644 --- a/packages/navigator/src/browser/open-editors-widget/navigator-open-editors-widget.tsx +++ b/packages/navigator/src/browser/open-editors-widget/navigator-open-editors-widget.tsx @@ -143,10 +143,10 @@ export class OpenEditorsWidget extends FileTreeWidget { if (parentWorkspace) { const relativeDirFromWorkspace = parentWorkspace.relative(nodeURIDir); workspacePrefixString = workspaceRoots.length > 1 ? this.labelProvider.getName(parentWorkspace) : ''; - filePathString = relativeDirFromWorkspace?.toString() ?? ''; + filePathString = relativeDirFromWorkspace?.fsPath() ?? ''; separator = filePathString && workspacePrefixString ? ' \u2022 ' : ''; // add a bullet point between workspace and path } else { - workspacePrefixString = nodeURIDir.path.toString(); + workspacePrefixString = nodeURIDir.path.fsPath(); } return [{ fontData: { color }, diff --git a/packages/preferences/src/browser/preferences-contribution.ts b/packages/preferences/src/browser/preferences-contribution.ts index 16102c13c8e48..1b7fe8b5497f2 100644 --- a/packages/preferences/src/browser/preferences-contribution.ts +++ b/packages/preferences/src/browser/preferences-contribution.ts @@ -226,7 +226,7 @@ export class PreferencesContribution extends AbstractViewContribution ({ label: root.name, - description: root.resource.path.toString(), + description: root.resource.path.fsPath(), execute: () => callback(root) })); this.quickInputService?.showQuickPick(items, { placeholder: 'Select workspace folder' }); diff --git a/packages/preferences/src/browser/views/components/preference-file-input.ts b/packages/preferences/src/browser/views/components/preference-file-input.ts index f6ee04468ac57..9187cbc5c112f 100644 --- a/packages/preferences/src/browser/views/components/preference-file-input.ts +++ b/packages/preferences/src/browser/views/components/preference-file-input.ts @@ -93,7 +93,7 @@ export class PreferenceSingleFilePathInputRenderer extends PreferenceStringInput const title = selectionProps?.title ?? selectionProps?.canSelectFolders ? WorkspaceCommands.OPEN_FOLDER.dialogLabel : WorkspaceCommands.OPEN_FILE.dialogLabel; const selection = await this.fileDialogService.showOpenDialog({ title, ...selectionProps }); if (selection) { - this.setPreferenceImmediately(selection.path.toString()); + this.setPreferenceImmediately(selection.path.fsPath()); } } diff --git a/packages/property-view/src/browser/resource-property-view/resource-property-view-tree-widget.tsx b/packages/property-view/src/browser/resource-property-view/resource-property-view-tree-widget.tsx index ffeb1ce1c8b24..490802646c849 100644 --- a/packages/property-view/src/browser/resource-property-view/resource-property-view-tree-widget.tsx +++ b/packages/property-view/src/browser/resource-property-view/resource-property-view-tree-widget.tsx @@ -116,7 +116,7 @@ export class ResourcePropertyViewTreeWidget extends TreeWidget implements Proper } protected getLocationString(fileStat: FileStat): string { - return fileStat.resource.path.toString(); + return fileStat.resource.path.fsPath(); } protected getFileName(fileStat: FileStat): string { diff --git a/packages/scm/src/browser/scm-tree-widget.tsx b/packages/scm/src/browser/scm-tree-widget.tsx index 5dea9f6d6bd72..ffab5333b78c6 100644 --- a/packages/scm/src/browser/scm-tree-widget.tsx +++ b/packages/scm/src/browser/scm-tree-widget.tsx @@ -525,10 +525,10 @@ export class ScmResourceComponent extends ScmElement const letter = decoration && decoration.letter || ''; const tooltip = decoration && decoration.tooltip || ''; const relativePath = parentPath.relative(resourceUri.parent); - const path = relativePath ? relativePath.toString() : labelProvider.getLongName(resourceUri.parent); + const path = relativePath ? relativePath.fsPath() : labelProvider.getLongName(resourceUri.parent); const title = tooltip.length !== 0 - ? `${resourceUri.path.toString()} • ${tooltip}` - : resourceUri.path.toString(); + ? `${resourceUri.path.fsPath()} • ${tooltip}` + : resourceUri.path.fsPath(); return
+ title={new URI(node.fileUri).path.fsPath()}>
diff --git a/packages/workspace/src/browser/workspace-frontend-contribution.ts b/packages/workspace/src/browser/workspace-frontend-contribution.ts index 2f0338386ee6b..8c2b92f69390a 100644 --- a/packages/workspace/src/browser/workspace-frontend-contribution.ts +++ b/packages/workspace/src/browser/workspace-frontend-contribution.ts @@ -440,7 +440,7 @@ export class WorkspaceFrontendContribution implements CommandContribution, Keybi await this.workspaceService.save(selected); return true; } catch { - this.messageService.error(nls.localizeByDefault("Unable to save workspace '{0}'", selected.path.toString())); + this.messageService.error(nls.localizeByDefault("Unable to save workspace '{0}'", selected.path.fsPath())); } } return false; diff --git a/packages/workspace/src/browser/workspace-input-dialog.ts b/packages/workspace/src/browser/workspace-input-dialog.ts index d3fe50e39fc2f..bdff19779b746 100644 --- a/packages/workspace/src/browser/workspace-input-dialog.ts +++ b/packages/workspace/src/browser/workspace-input-dialog.ts @@ -51,7 +51,7 @@ export class WorkspaceInputDialog extends SingleTextInputDialog { icon.style.marginRight = '0.5em'; icon.style.verticalAlign = 'middle'; element.style.verticalAlign = 'middle'; - element.title = this.props.parentUri.path.toString(); + element.title = this.props.parentUri.path.fsPath(); element.appendChild(icon); element.appendChild(document.createTextNode(label)); // Add the path and icon div before the `inputField`. diff --git a/packages/workspace/src/browser/workspace-uri-contribution.spec.ts b/packages/workspace/src/browser/workspace-uri-contribution.spec.ts index 6bf27a6acccf4..65c2e341bbe4a 100644 --- a/packages/workspace/src/browser/workspace-uri-contribution.spec.ts +++ b/packages/workspace/src/browser/workspace-uri-contribution.spec.ts @@ -32,6 +32,7 @@ import { FileStat } from '@theia/filesystem/lib/common/files'; import { EnvVariablesServer } from '@theia/core/lib/common/env-variables'; import { MockEnvVariablesServerImpl } from '@theia/core/lib/browser/test/mock-env-variables-server'; import { FileUri } from '@theia/core/lib/node'; +import { OS } from '@theia/core/lib/common/os'; import * as temp from 'temp'; after(() => disableJSDOM()); @@ -155,20 +156,35 @@ describe('WorkspaceUriLabelProviderContribution class', () => { it('should return the absolute path of a file from the file\'s URI if the file is not in the workspace', () => { const file = new URI('file:///tmp/prout.txt'); const longName = labelProvider.getLongName(file); - expect(longName).eq('/tmp/prout.txt'); + + if (OS.backend.isWindows) { + expect(longName).eq('\\tmp\\prout.txt'); + } else { + expect(longName).eq('/tmp/prout.txt'); + } }); it('should return the absolute path of a file from the file\'s FileStat if the file is not in the workspace', () => { const file: FileStat = FileStat.file('file:///tmp/prout.txt'); const longName = labelProvider.getLongName(file); - expect(longName).eq('/tmp/prout.txt'); + + if (OS.backend.isWindows) { + expect(longName).eq('\\tmp\\prout.txt'); + } else { + expect(longName).eq('/tmp/prout.txt'); + } }); it('should return the path of a file if WorkspaceService returns no roots', () => { roots = []; const file = new URI('file:///tmp/prout.txt'); const longName = labelProvider.getLongName(file); - expect(longName).eq('/tmp/prout.txt'); + + if (OS.backend.isWindows) { + expect(longName).eq('\\tmp\\prout.txt'); + } else { + expect(longName).eq('/tmp/prout.txt'); + } }); });