Skip to content

Commit

Permalink
Implement workspace.workspaceFile extension API
Browse files Browse the repository at this point in the history
This first implementation returns the Uri location of the workspace
file even if it is untitled (i.e. saved on a temporary default
location).

Issue: eclipse-theia#8994

Signed-off-by: Alvaro Sanchez-Leon <alvaro.sanchez-leon@ericsson.com>
  • Loading branch information
alvsan09 authored and vince-fugnitto committed Mar 3, 2021
1 parent 1110f99 commit 308a6f7
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/plugin-ext/src/common/plugin-api-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,12 @@ export interface WorkspaceMain {
$unregisterTextDocumentContentProvider(scheme: string): void;
$onTextDocumentContentChange(uri: string, content: string): void;
$updateWorkspaceFolders(start: number, deleteCount?: number, ...rootsToAdd: string[]): Promise<void>;
$getWorkspace(): Promise<files.FileStat | undefined>;
}

export interface WorkspaceExt {
$onWorkspaceFoldersChanged(event: WorkspaceRootsChangeEvent): void;
$onWorkspaceLocationChanged(event: files.FileStat | undefined): void;
$provideTextDocumentContent(uri: string): Promise<string | undefined>;
$onTextSearchResult(searchRequestId: number, done: boolean, result?: SearchInWorkspaceResult): void;
}
Expand Down
8 changes: 8 additions & 0 deletions packages/plugin-ext/src/main/browser/workspace-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { Emitter, Event, ResourceResolver, CancellationToken } from '@theia/core
import { PluginServer } from '../../common/plugin-protocol';
import { FileSystemPreferences } from '@theia/filesystem/lib/browser';
import { SearchInWorkspaceService } from '@theia/search-in-workspace/lib/browser/search-in-workspace-service';
import { FileStat } from '@theia/filesystem/lib/common/files';

export class WorkspaceMainImpl implements WorkspaceMain, Disposable {

Expand Down Expand Up @@ -73,6 +74,9 @@ export class WorkspaceMainImpl implements WorkspaceMain, Disposable {
this.toDispose.push(this.workspaceService.onWorkspaceChanged(roots => {
this.processWorkspaceFoldersChanged(roots.map(root => root.resource.toString()));
}));
this.toDispose.push(this.workspaceService.onWorkspaceLocationChanged(stat => {
this.proxy.$onWorkspaceLocationChanged(stat);
}));
}

dispose(): void {
Expand Down Expand Up @@ -102,6 +106,10 @@ export class WorkspaceMainImpl implements WorkspaceMain, Disposable {
return this.roots.some((root, index) => root !== roots[index]);
}

async $getWorkspace(): Promise<FileStat | undefined> {
return this.workspaceService.workspace;
}

$pickWorkspaceFolder(options: WorkspaceFolderPickOptionsMain): Promise<theia.WorkspaceFolder | undefined> {
return new Promise((resolve, reject) => {
// Return undefined if workspace root is not set
Expand Down
3 changes: 3 additions & 0 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@ export function createAPIFactory(
get workspaceFolders(): theia.WorkspaceFolder[] | undefined {
return workspaceExt.workspaceFolders;
},
get workspaceFile(): Uri | undefined {
return workspaceExt.workspaceFile;
},
get name(): string | undefined {
return workspaceExt.name;
},
Expand Down
23 changes: 23 additions & 0 deletions packages/plugin-ext/src/plugin/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { Schemes } from '../common/uri-components';
import { toWorkspaceFolder } from './type-converters';
import { MessageRegistryExt } from './message-registry';
import * as Converter from './type-converters';
import { FileStat } from '@theia/filesystem/lib/common/files';

export class WorkspaceExtImpl implements WorkspaceExt {

Expand All @@ -50,6 +51,7 @@ export class WorkspaceExtImpl implements WorkspaceExt {
public readonly onDidChangeWorkspaceFolders: Event<theia.WorkspaceFoldersChangeEvent> = this.workspaceFoldersChangedEmitter.event;

private folders: theia.WorkspaceFolder[] | undefined;
private workspaceFileUri: theia.Uri | undefined;
private documentContentProviders = new Map<string, theia.TextDocumentContentProvider>();
private searchInWorkspaceEmitter: Emitter<{ result?: theia.TextSearchResult, searchId: number }> = new Emitter<{ result?: theia.TextSearchResult, searchId: number }>();
protected workspaceSearchSequence: number = 0;
Expand All @@ -72,6 +74,10 @@ export class WorkspaceExtImpl implements WorkspaceExt {
return this.folders;
}

get workspaceFile(): theia.Uri | undefined {
return this.workspaceFileUri;
}

get name(): string | undefined {
if (this.workspaceFolders && this.workspaceFolders.length > 0) {
return new Path(this.workspaceFolders[0].uri.path).base;
Expand All @@ -87,9 +93,15 @@ export class WorkspaceExtImpl implements WorkspaceExt {

this.folders = newFolders;

this.refreshWorkspaceFile();

this.workspaceFoldersChangedEmitter.fire(delta);
}

$onWorkspaceLocationChanged(stat: FileStat | undefined): void {
this.updateWorkSpace(stat);
}

$onTextSearchResult(searchRequestId: number, done: boolean, result?: SearchInWorkspaceResult): void {
if (result) {
result.matches.map(next => {
Expand Down Expand Up @@ -395,4 +407,15 @@ export class WorkspaceExtImpl implements WorkspaceExt {
return true;
}

private async refreshWorkspaceFile(): Promise<void> {
const workspace = await this.proxy.$getWorkspace();
this.updateWorkSpace(workspace);
}

private updateWorkSpace(workspace: FileStat | undefined): void {
// A workspace directory implies an undefined workspace file
if (workspace && !workspace.isDirectory) {
this.workspaceFileUri = URI.parse(workspace.resource.toString());
}
}
}
16 changes: 16 additions & 0 deletions packages/plugin/src/theia.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5145,6 +5145,22 @@ declare module '@theia/plugin' {
*/
export let workspaceFolders: WorkspaceFolder[] | undefined;

/**
* The location of the workspace file, for example:
*
* `file:///Users/name/Development/myProject.code-workspace`
*
* Depending on the workspace that is opened, the value will be:
* * `undefined` when no workspace or a single folder is opened
* * the path of the workspace file as `Uri` otherwise.
*
* **Note:** it is not advised to use `workspace.workspaceFile` to write
* configuration data into the file.
*
* @readonly
*/
export const workspaceFile: Uri | undefined;

/**
* The name of the workspace. `undefined` when no folder
* has been opened.
Expand Down

0 comments on commit 308a6f7

Please sign in to comment.