packages/vscode-extension-web-ide/src/scm/index.ts (81 lines of code) (raw):
import * as vscode from 'vscode';
import { debounce } from 'lodash';
import type { SourceControlFileSystem, SourceControlSystem } from '@gitlab/web-ide-fs';
import type { GitLabProject, GitLabRef } from '@gitlab/vscode-mediator-commands';
import { COMMIT_COMMAND_ID, SCM_SCHEME } from '../constants';
import { anyEvent } from '../utils';
import { SourceControlFileSystemProvider } from '../vscode/SourceControlFileSystemProvider';
import * as commitCommand from './commit/command';
import { createSourceControlViewModel } from './create';
import { preventUnload } from '../mediator';
import type { LocalStorage } from '../types';
const initializeScmFileSystemProvider = (
disposables: vscode.Disposable[],
sourceControlFs: SourceControlFileSystem,
) => {
disposables.push(
vscode.workspace.registerFileSystemProvider(
SCM_SCHEME,
new SourceControlFileSystemProvider(sourceControlFs),
{
isReadonly: true,
},
),
);
};
const createVSCodeFSWatcher = (disposables: vscode.Disposable[]) => {
// FileSystemWatcher Example https://sourcegraph.com/github.com/microsoft/vscode@3bdea7784d6ef67722967a4cd51179b30e9a1013/-/blob/extensions/git/src/model.ts?L120
const fsWatcher = vscode.workspace.createFileSystemWatcher('**');
disposables.push(fsWatcher);
return anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete);
};
const onFilesChanged = (disposables: vscode.Disposable[], callback: () => void) => {
const watcher = createVSCodeFSWatcher(disposables);
watcher(debounce(callback, 200), null, disposables);
};
export interface ScmSetupOptions {
sourceControl: SourceControlSystem;
sourceControlFs: SourceControlFileSystem;
localStorage: LocalStorage;
repoRoot: string;
ref: GitLabRef;
branchMergeRequestUrl: string;
project: GitLabProject;
}
export const initializeSourceControl = async (
disposables: vscode.Disposable[],
{
sourceControl,
localStorage,
sourceControlFs,
repoRoot,
ref,
project,
branchMergeRequestUrl,
}: ScmSetupOptions,
) => {
initializeScmFileSystemProvider(disposables, sourceControlFs);
const viewModel = createSourceControlViewModel(disposables, repoRoot, ref, project);
let hasStatus = false;
// On initialization there are no changes, so we should reset `preventUnload`
await preventUnload({ shouldPrevent: false });
onFilesChanged(disposables, async () => {
const status = await sourceControl.status();
viewModel.update(status);
const newHasStatus = Boolean(status.length);
if (newHasStatus !== hasStatus) {
hasStatus = newHasStatus;
await preventUnload({ shouldPrevent: hasStatus });
}
});
disposables.push(
vscode.commands.registerCommand(
COMMIT_COMMAND_ID,
commitCommand.factory({
viewModel,
localStorage,
ref,
branchMergeRequestUrl,
project,
}),
),
);
};