or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

extension-points.mdindex.mdworkspace-commands.mdworkspace-file-handling.mdworkspace-preferences.mdworkspace-server.mdworkspace-service.md

workspace-file-handling.mddocs/

0

# Workspace File Handling

1

2

The workspace file handling module provides services for managing workspace file formats, validation, and untitled workspace creation. It supports both Theia and Visual Studio Code workspace file formats and handles the lifecycle of temporary workspace files.

3

4

## Capabilities

5

6

### Workspace File Type Management

7

8

Service for managing supported workspace file formats and validation.

9

10

```typescript { .api }

11

interface WorkspaceFileType {

12

/** File extension without dot (e.g., 'theia-workspace') */

13

extension: string;

14

/** Display name for the file type (e.g., 'Theia') */

15

name: string;

16

}

17

18

class WorkspaceFileService {

19

/**

20

* Index of the default workspace file type (currently 0 for Theia format)

21

*/

22

readonly defaultFileTypeIndex: number;

23

24

/**

25

* Check if the file should be considered as a workspace file

26

* @param candidate - FileStat object or URI to check

27

*/

28

isWorkspaceFile(candidate: FileStat | URI): boolean;

29

30

/**

31

* Get all supported workspace file types

32

*/

33

getWorkspaceFileTypes(): WorkspaceFileType[];

34

35

/**

36

* Get workspace file extensions, optionally with dot prefix

37

* @param dot - Whether to include dot prefix (e.g., '.theia-workspace')

38

*/

39

getWorkspaceFileExtensions(dot?: boolean): string[];

40

}

41

```

42

43

**Usage Example:**

44

45

```typescript

46

import { injectable, inject } from "@theia/core/shared/inversify";

47

import { WorkspaceFileService, WorkspaceFileType } from "@theia/workspace/lib/common";

48

import URI from "@theia/core/lib/common/uri";

49

50

@injectable()

51

export class MyWorkspaceValidator {

52

53

@inject(WorkspaceFileService)

54

protected readonly workspaceFileService: WorkspaceFileService;

55

56

validateWorkspaceFile(uri: URI): boolean {

57

// Check if file is a valid workspace file

58

if (!this.workspaceFileService.isWorkspaceFile(uri)) {

59

console.log(`${uri} is not a valid workspace file`);

60

return false;

61

}

62

return true;

63

}

64

65

getSupportedFormats(): WorkspaceFileType[] {

66

// Get all supported workspace file types

67

const types = this.workspaceFileService.getWorkspaceFileTypes();

68

// Returns: [{ name: 'Theia', extension: 'theia-workspace' },

69

// { name: 'Visual Studio Code', extension: 'code-workspace' }]

70

return types;

71

}

72

73

createFileFilter(): string {

74

// Create file filter for file dialogs

75

const extensions = this.workspaceFileService.getWorkspaceFileExtensions(true);

76

return extensions.join(','); // '.theia-workspace,.code-workspace'

77

}

78

79

getDefaultExtension(): string {

80

const types = this.workspaceFileService.getWorkspaceFileTypes();

81

const defaultIndex = this.workspaceFileService.defaultFileTypeIndex;

82

return types[defaultIndex].extension; // 'theia-workspace'

83

}

84

}

85

```

86

87

### Untitled Workspace Management

88

89

Service for creating and managing temporary/untitled workspace files.

90

91

```typescript { .api }

92

class UntitledWorkspaceService {

93

/**

94

* Check if a URI represents an untitled workspace

95

* @param candidate - URI to check (optional, defaults to current workspace)

96

*/

97

isUntitledWorkspace(candidate?: URI): boolean;

98

99

/**

100

* Generate a unique URI for an untitled workspace

101

* @param configDirUri - Base configuration directory URI

102

* @param isAcceptable - Function to validate if generated URI is acceptable

103

* @param warnOnHits - Optional callback called after 10 generation attempts

104

*/

105

getUntitledWorkspaceUri(

106

configDirUri: URI,

107

isAcceptable: (candidate: URI) => MaybePromise<boolean>,

108

warnOnHits?: () => unknown

109

): Promise<URI>;

110

}

111

```

112

113

**Usage Example:**

114

115

```typescript

116

import { injectable, inject } from "@theia/core/shared/inversify";

117

import { UntitledWorkspaceService } from "@theia/workspace/lib/common";

118

import { FileService } from "@theia/filesystem/lib/browser/file-service";

119

import URI from "@theia/core/lib/common/uri";

120

121

@injectable()

122

export class MyWorkspaceCreator {

123

124

@inject(UntitledWorkspaceService)

125

protected readonly untitledWorkspaceService: UntitledWorkspaceService;

126

127

@inject(FileService)

128

protected readonly fileService: FileService;

129

130

async createNewUntitledWorkspace(): Promise<URI> {

131

const configDir = new URI("file:///home/user/.theia");

132

133

// Generate unique untitled workspace URI

134

const workspaceUri = await this.untitledWorkspaceService.getUntitledWorkspaceUri(

135

configDir,

136

async (candidate: URI) => {

137

// Check if file already exists

138

try {

139

await this.fileService.resolve(candidate);

140

return false; // File exists, try another name

141

} catch {

142

return true; // File doesn't exist, this name is acceptable

143

}

144

},

145

() => {

146

console.warn("Having trouble finding unique workspace name, trying harder...");

147

}

148

);

149

150

console.log(`Created untitled workspace: ${workspaceUri}`);

151

// Result might be: file:///home/user/.theia/workspaces/Untitled-742.theia-workspace

152

return workspaceUri;

153

}

154

155

checkIfUntitled(workspaceUri: URI): boolean {

156

// Check if a workspace is untitled

157

const isUntitled = this.untitledWorkspaceService.isUntitledWorkspace(workspaceUri);

158

if (isUntitled) {

159

console.log("This is an untitled workspace");

160

}

161

return isUntitled;

162

}

163

164

async createMultipleUntitledWorkspaces(count: number): Promise<URI[]> {

165

const configDir = new URI("file:///home/user/.theia");

166

const workspaces: URI[] = [];

167

168

for (let i = 0; i < count; i++) {

169

try {

170

const uri = await this.untitledWorkspaceService.getUntitledWorkspaceUri(

171

configDir,

172

async (candidate: URI) => {

173

// Ensure no duplicates in our current batch

174

const alreadyUsed = workspaces.some(existing => existing.isEqual(candidate));

175

if (alreadyUsed) return false;

176

177

// Check filesystem

178

try {

179

await this.fileService.resolve(candidate);

180

return false;

181

} catch {

182

return true;

183

}

184

}

185

);

186

workspaces.push(uri);

187

} catch (error) {

188

console.error(`Failed to create untitled workspace ${i + 1}:`, error);

189

break;

190

}

191

}

192

193

return workspaces;

194

}

195

}

196

```

197

198

### File Format Support

199

200

Built-in support for multiple workspace file formats with extensibility.

201

202

```typescript { .api }

203

// Deprecated constants (use WorkspaceFileService methods instead)

204

/** @deprecated Since 1.39.0. Use WorkspaceFileService#getWorkspaceFileTypes instead */

205

const THEIA_EXT = 'theia-workspace';

206

207

/** @deprecated Since 1.39.0. Use WorkspaceFileService#getWorkspaceFileTypes instead */

208

const VSCODE_EXT = 'code-workspace';

209

```

210

211

**Usage Example:**

212

213

```typescript

214

import { injectable, inject } from "@theia/core/shared/inversify";

215

import { WorkspaceFileService } from "@theia/workspace/lib/common";

216

217

@injectable()

218

export class WorkspaceFormatHandler {

219

220

@inject(WorkspaceFileService)

221

protected readonly workspaceFileService: WorkspaceFileService;

222

223

getSupportedFormats(): { [key: string]: string } {

224

const types = this.workspaceFileService.getWorkspaceFileTypes();

225

const formats: { [key: string]: string } = {};

226

227

types.forEach(type => {

228

formats[type.extension] = type.name;

229

});

230

231

return formats;

232

// Returns: { 'theia-workspace': 'Theia', 'code-workspace': 'Visual Studio Code' }

233

}

234

235

createFileFilterString(): string {

236

const types = this.workspaceFileService.getWorkspaceFileTypes();

237

const filters = types.map(type =>

238

`${type.name} Files (*.${type.extension})|*.${type.extension}`

239

);

240

return filters.join('|');

241

// Returns: "Theia Files (*.theia-workspace)|*.theia-workspace|Visual Studio Code Files (*.code-workspace)|*.code-workspace"

242

}

243

244

getPreferredExtension(): string {

245

const types = this.workspaceFileService.getWorkspaceFileTypes();

246

const defaultIndex = this.workspaceFileService.defaultFileTypeIndex;

247

return types[defaultIndex].extension; // 'theia-workspace'

248

}

249

250

isKnownWorkspaceFormat(filename: string): boolean {

251

const extensions = this.workspaceFileService.getWorkspaceFileExtensions();

252

return extensions.some(ext => filename.endsWith(`.${ext}`));

253

}

254

}

255

```

256

257

### Error Handling

258

259

The services include built-in error handling and validation.

260

261

**Example Error Scenarios:**

262

263

```typescript

264

// UntitledWorkspaceService error after too many attempts

265

try {

266

const uri = await this.untitledWorkspaceService.getUntitledWorkspaceUri(

267

configDir,

268

() => false // Always reject to trigger error

269

);

270

} catch (error) {

271

// Error: "Workspace Service: too many attempts to find unused filename."

272

console.error("Could not generate unique workspace name:", error.message);

273

}

274

275

// WorkspaceFileService validation

276

const invalidUri = new URI("file:///project/not-a-workspace.txt");

277

if (!this.workspaceFileService.isWorkspaceFile(invalidUri)) {

278

console.log("File is not a recognized workspace format");

279

}

280

```

281

282

## Types

283

284

```typescript { .api }

285

interface WorkspaceFileType {

286

/** File extension without dot prefix */

287

extension: string;

288

/** Human-readable name for the file type */

289

name: string;

290

}

291

292

type MaybePromise<T> = T | Promise<T>;

293

294

// Deprecated constants

295

/** @deprecated Use WorkspaceFileService methods instead */

296

const THEIA_EXT: string;

297

/** @deprecated Use WorkspaceFileService methods instead */

298

const VSCODE_EXT: string;

299

```