Skip to content

Commit d3f4b7e

Browse files
author
Eric Amodio
committed
Fixes clearing context on reload if no changes
Adds statusbar entry Reworks context storage a bit
1 parent 62939fb commit d3f4b7e

8 files changed

Lines changed: 222 additions & 92 deletions

File tree

extensions/github-browser/src/changeStore.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,31 +47,17 @@ function fromSerialized(operations: StoredOperation): Operation {
4747
return { ...operations, uri: Uri.parse(operations.uri) };
4848
}
4949

50-
interface CreatedFileChangeStoreEvent {
51-
type: 'created';
52-
rootUri: Uri;
53-
uri: Uri;
54-
}
55-
56-
interface ChangedFileChangeStoreEvent {
57-
type: 'changed';
58-
rootUri: Uri;
59-
uri: Uri;
60-
}
61-
62-
interface DeletedFileChangeStoreEvent {
63-
type: 'deleted';
50+
export interface ChangeStoreEvent {
51+
type: 'created' | 'changed' | 'deleted';
6452
rootUri: Uri;
6553
uri: Uri;
6654
}
6755

68-
type ChangeStoreEvent = CreatedFileChangeStoreEvent | ChangedFileChangeStoreEvent | DeletedFileChangeStoreEvent;
69-
7056
function toChangeStoreEvent(operation: Operation | StoredOperation, rootUri: Uri, uri?: Uri): ChangeStoreEvent {
7157
return {
7258
type: operation.type,
7359
rootUri: rootUri,
74-
uri: uri ?? (typeof operation.uri === 'string' ? Uri.parse(operation.uri) : operation.uri)
60+
uri: uri ?? (typeof operation.uri === 'string' ? Uri.parse(operation.uri) : operation.uri),
7561
};
7662
}
7763

@@ -82,6 +68,8 @@ export interface IChangeStore {
8268
discard(uri: Uri): Promise<void>;
8369
discardAll(rootUri: Uri): Promise<void>;
8470

71+
hasChanges(rootUri: Uri): boolean;
72+
8573
getChanges(rootUri: Uri): Operation[];
8674
getContent(uri: Uri): string | undefined;
8775

@@ -116,9 +104,15 @@ export class ChangeStore implements IChangeStore, IWritableChangeStore {
116104

117105
await this.saveWorkingOperations(rootUri, undefined);
118106

107+
const events: ChangeStoreEvent[] = [];
108+
119109
for (const operation of operations) {
120110
await this.discardWorkingContent(operation.uri);
121-
this._onDidChange.fire(toChangeStoreEvent(operation, rootUri));
111+
events.push(toChangeStoreEvent(operation, rootUri));
112+
}
113+
114+
for (const e of events) {
115+
this._onDidChange.fire(e);
122116
}
123117
}
124118

@@ -143,7 +137,7 @@ export class ChangeStore implements IChangeStore, IWritableChangeStore {
143137
this._onDidChange.fire({
144138
type: operation.type === 'created' ? 'deleted' : operation.type === 'deleted' ? 'created' : 'changed',
145139
rootUri: rootUri,
146-
uri: uri
140+
uri: uri,
147141
});
148142
}
149143

@@ -152,9 +146,15 @@ export class ChangeStore implements IChangeStore, IWritableChangeStore {
152146

153147
await this.saveWorkingOperations(rootUri, undefined);
154148

149+
const events: ChangeStoreEvent[] = [];
150+
155151
for (const operation of operations) {
156152
await this.discardWorkingContent(operation.uri);
157-
this._onDidChange.fire(toChangeStoreEvent(operation, rootUri));
153+
events.push(toChangeStoreEvent(operation, rootUri));
154+
}
155+
156+
for (const e of events) {
157+
this._onDidChange.fire(e);
158158
}
159159
}
160160

extensions/github-browser/src/contextStore.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,50 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
'use strict';
7-
import { Event, EventEmitter, Memento, Uri } from 'vscode';
7+
import { Event, EventEmitter, Memento, Uri, workspace } from 'vscode';
88

9-
export const contextKeyPrefix = 'github.context|';
9+
export interface WorkspaceFolderContext<T> {
10+
context: T;
11+
name: string;
12+
folderUri: Uri;
13+
}
1014

1115
export class ContextStore<T> {
1216
private _onDidChange = new EventEmitter<Uri>();
1317
get onDidChange(): Event<Uri> {
1418
return this._onDidChange.event;
1519
}
1620

17-
constructor(private readonly memento: Memento, private readonly scheme: string) { }
21+
constructor(
22+
private readonly scheme: string,
23+
private readonly originalScheme: string,
24+
private readonly memento: Memento,
25+
) { }
1826

1927
delete(uri: Uri) {
2028
return this.set(uri, undefined);
2129
}
2230

2331
get(uri: Uri): T | undefined {
24-
return this.memento.get<T>(`${contextKeyPrefix}${uri.toString()}`);
32+
return this.memento.get<T>(`${this.originalScheme}.context|${this.getOriginalResource(uri).toString()}`);
2533
}
2634

35+
getForWorkspace(): WorkspaceFolderContext<T>[] {
36+
const folders = workspace.workspaceFolders?.filter(f => f.uri.scheme === this.scheme || f.uri.scheme === this.originalScheme) ?? [];
37+
return folders.map(f => ({ context: this.get(f.uri)!, name: f.name, folderUri: f.uri })).filter(c => c.context !== undefined);
38+
}
2739

2840
async set(uri: Uri, context: T | undefined) {
29-
if (uri.scheme !== this.scheme) {
30-
throw new Error(`Invalid context scheme: ${uri.scheme}`);
31-
}
32-
33-
await this.memento.update(`${contextKeyPrefix}${uri.toString()}`, context);
41+
uri = this.getOriginalResource(uri);
42+
await this.memento.update(`${this.originalScheme}.context|${uri.toString()}`, context);
3443
this._onDidChange.fire(uri);
3544
}
45+
46+
getOriginalResource(uri: Uri): Uri {
47+
return uri.with({ scheme: this.originalScheme });
48+
}
49+
50+
getWorkspaceResource(uri: Uri): Uri {
51+
return uri.with({ scheme: this.scheme });
52+
}
3653
}

extensions/github-browser/src/extension.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,24 @@ import { VirtualFS } from './fs';
1010
import { GitHubApiContext, GitHubApi } from './github/api';
1111
import { GitHubFS } from './github/fs';
1212
import { VirtualSCM } from './scm';
13+
import { StatusBar } from './statusbar';
1314

1415
const repositoryRegex = /^(?:(?:https:\/\/)?github.com\/)?([^\/]+)\/([^\/]+?)(?:\/|.git|$)/i;
1516

16-
export function activate(context: ExtensionContext) {
17-
const contextStore = new ContextStore<GitHubApiContext>(context.workspaceState, GitHubFS.scheme);
17+
export async function activate(context: ExtensionContext) {
18+
const contextStore = new ContextStore<GitHubApiContext>('codespace', GitHubFS.scheme, context.workspaceState);
1819
const changeStore = new ChangeStore(context.workspaceState);
1920

2021
const githubApi = new GitHubApi(contextStore);
2122
const gitHubFS = new GitHubFS(githubApi);
22-
const virtualFS = new VirtualFS('codespace', GitHubFS.scheme, contextStore, changeStore, gitHubFS);
23+
const virtualFS = new VirtualFS('codespace', contextStore, changeStore, gitHubFS);
2324

2425
context.subscriptions.push(
2526
githubApi,
2627
gitHubFS,
2728
virtualFS,
28-
new VirtualSCM(GitHubFS.scheme, githubApi, changeStore)
29+
new VirtualSCM(GitHubFS.scheme, githubApi, changeStore),
30+
new StatusBar(contextStore, changeStore),
2931
);
3032

3133
commands.registerCommand('githubBrowser.openRepository', async () => {
@@ -63,6 +65,11 @@ export function isDescendent(folderPath: string, filePath: string) {
6365
return folderPath.length === 0 || filePath.startsWith(folderPath.endsWith('/') ? folderPath : `${folderPath}/`);
6466
}
6567

68+
const shaRegex = /^[0-9a-f]{40}$/;
69+
export function isSha(ref: string) {
70+
return shaRegex.test(ref);
71+
}
72+
6673
function openWorkspace(uri: Uri, name: string, location: 'currentWindow' | 'newWindow' | 'addToCurrentWorkspace') {
6774
if (location === 'addToCurrentWorkspace') {
6875
const count = (workspace.workspaceFolders && workspace.workspaceFolders.length) || 0;

extensions/github-browser/src/fs.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,22 @@ export class VirtualFS implements FileSystemProvider, FileSearchProvider, TextSe
4343

4444
constructor(
4545
readonly scheme: string,
46-
private readonly originalScheme: string,
47-
contextStore: ContextStore<GitHubApiContext>,
46+
private readonly contextStore: ContextStore<GitHubApiContext>,
4847
private readonly changeStore: IWritableChangeStore,
4948
private readonly fs: FileSystemProvider & FileSearchProvider & TextSearchProvider
5049
) {
5150
// TODO@eamodio listen for workspace folder changes
52-
for (const folder of workspace.workspaceFolders ?? []) {
53-
const uri = this.getOriginalResource(folder.uri);
54-
51+
for (const context of contextStore.getForWorkspace()) {
5552
// If we have a saved context, but no longer have any changes, reset the context
5653
// We only do this on startup/reload to keep things consistent
57-
if (contextStore.get(uri) !== undefined && !changeStore.hasChanges(folder.uri)) {
58-
contextStore.delete(uri);
54+
if (!changeStore.hasChanges(context.folderUri)) {
55+
console.log('Clear context', context.folderUri.toString());
56+
contextStore.delete(context.folderUri);
5957
}
6058
}
6159

6260
this.disposable = Disposable.from(
63-
workspace.registerFileSystemProvider(scheme, this, {
64-
isCaseSensitive: true,
65-
}),
61+
workspace.registerFileSystemProvider(scheme, this, { isCaseSensitive: true }),
6662
workspace.registerFileSearchProvider(scheme, this),
6763
workspace.registerTextSearchProvider(scheme, this),
6864
changeStore.onDidChange(e => {
@@ -86,11 +82,11 @@ export class VirtualFS implements FileSystemProvider, FileSearchProvider, TextSe
8682
}
8783

8884
private getOriginalResource(uri: Uri): Uri {
89-
return uri.with({ scheme: this.originalScheme });
85+
return this.contextStore.getOriginalResource(uri);
9086
}
9187

92-
private getVirtualResource(uri: Uri): Uri {
93-
return uri.with({ scheme: this.scheme });
88+
private getWorkspaceResource(uri: Uri): Uri {
89+
return this.contextStore.getWorkspaceResource(uri);
9490
}
9591

9692
//#region FileSystemProvider
@@ -211,7 +207,7 @@ export class VirtualFS implements FileSystemProvider, FileSearchProvider, TextSe
211207
return this.fs.provideTextSearchResults(
212208
query,
213209
{ ...options, folder: this.getOriginalResource(options.folder) },
214-
{ report: (result: TextSearchResult) => progress.report({ ...result, uri: this.getVirtualResource(result.uri) }) },
210+
{ report: (result: TextSearchResult) => progress.report({ ...result, uri: this.getWorkspaceResource(result.uri) }) },
215211
token
216212
);
217213
}

0 commit comments

Comments
 (0)