-
-
Notifications
You must be signed in to change notification settings - Fork 435
/
Copy pathworkspace-service.ts
160 lines (145 loc) · 5.92 KB
/
workspace-service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import * as remote from '@theia/core/electron-shared/@electron/remote';
import { injectable, inject } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { EditorWidget } from '@theia/editor/lib/browser';
import { LabelProvider } from '@theia/core/lib/browser/label-provider';
import { MessageService } from '@theia/core/lib/common/message-service';
import { ApplicationServer } from '@theia/core/lib/common/application-protocol';
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
import { FocusTracker, Widget } from '@theia/core/lib/browser';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { WorkspaceService as TheiaWorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { ConfigService } from '../../../common/protocol/config-service';
import {
SketchesService,
Sketch,
SketchContainer,
} from '../../../common/protocol/sketches-service';
import { ArduinoWorkspaceRootResolver } from '../../arduino-workspace-resolver';
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
import { BoardsConfig } from '../../boards/boards-config';
import { nls } from '@theia/core/lib/common';
import { URI as VSCodeUri } from '@theia/core/shared/vscode-uri';
@injectable()
export class WorkspaceService extends TheiaWorkspaceService {
@inject(SketchesService)
protected readonly sketchService: SketchesService;
@inject(ConfigService)
protected readonly configService: ConfigService;
@inject(LabelProvider)
protected readonly labelProvider: LabelProvider;
@inject(MessageService)
protected readonly messageService: MessageService;
@inject(ApplicationServer)
protected readonly applicationServer: ApplicationServer;
@inject(FrontendApplicationStateService)
protected readonly appStateService: FrontendApplicationStateService;
@inject(BoardsServiceProvider)
protected readonly boardsServiceProvider: BoardsServiceProvider;
private application: FrontendApplication;
private workspaceUri?: Promise<string | undefined>;
private version?: string;
async onStart(application: FrontendApplication): Promise<void> {
this.application = application;
const info = await this.applicationServer.getApplicationInfo();
this.version = info?.version;
application.shell.onDidChangeCurrentWidget(
this.onCurrentWidgetChange.bind(this)
);
const newValue = application.shell.currentWidget
? application.shell.currentWidget
: null;
this.onCurrentWidgetChange({ newValue, oldValue: null });
}
protected getDefaultWorkspaceUri(): Promise<string | undefined> {
if (this.workspaceUri) {
// Avoid creating a new sketch twice
return this.workspaceUri;
}
this.workspaceUri = (async () => {
try {
const hash = window.location.hash;
const [recentWorkspacesPaths, recentSketches] = await Promise.all([
this.server.getRecentWorkspaces(),
this.sketchService
.getSketches({})
.then((container) =>
SketchContainer.toArray(container).map((s) => s.uri)
),
]);
// On Dindows, `getRecentWorkspaces` returns only file paths, not URIs as expected by the `isValid` method.
const recentWorkspaces = recentWorkspacesPaths.map((e) =>
VSCodeUri.file(e).toString()
);
const toOpen = await new ArduinoWorkspaceRootResolver({
isValid: this.isValid.bind(this),
}).resolve({ hash, recentWorkspaces, recentSketches });
if (toOpen) {
const { uri } = toOpen;
await this.server.setMostRecentlyUsedWorkspace(uri);
return toOpen.uri;
}
return (await this.sketchService.createNewSketch()).uri;
} catch (err) {
this.appStateService
.reachedState('ready')
.then(() => this.application.shell.update());
this.logger.fatal(`Failed to determine the sketch directory: ${err}`);
this.messageService.error(
nls.localize(
'theia/workspace/sketchDirectoryError',
'There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected.'
)
);
return super.getDefaultWorkspaceUri();
}
})();
return this.workspaceUri;
}
protected openNewWindow(workspacePath: string): void {
const { boardsConfig } = this.boardsServiceProvider;
const url = BoardsConfig.Config.setConfig(
boardsConfig,
new URL(window.location.href)
); // Set the current boards config for the new browser window.
url.hash = workspacePath;
this.windowService.openNewWindow(url.toString());
}
private async isValid(uri: string): Promise<boolean> {
const exists = await this.fileService.exists(new URI(uri));
if (!exists) {
return false;
}
return this.sketchService.isSketchFolder(uri);
}
protected onCurrentWidgetChange({
newValue,
}: FocusTracker.IChangedArgs<Widget>): void {
if (newValue instanceof EditorWidget) {
const { uri } = newValue.editor;
const currentWindow = remote.getCurrentWindow();
currentWindow.setRepresentedFilename(uri.path.toString());
if (Sketch.isSketchFile(uri.toString())) {
this.updateTitle();
} else {
const title = this.workspaceTitle;
const fileName = this.labelProvider.getName(uri);
document.title = this.formatTitle(
title ? `${title} - ${fileName}` : fileName
);
}
} else {
this.updateTitle();
}
}
protected formatTitle(title?: string): string {
const version = this.version ? ` ${this.version}` : '';
const name = `${this.applicationName} ${version}`;
return title ? `${title} | ${name}` : name;
}
protected get workspaceTitle(): string | undefined {
if (this.workspace) {
return this.labelProvider.getName(this.workspace.resource);
}
}
}