Merge VS Code 1.21 source code (#1067)

* Initial VS Code 1.21 file copy with patches

* A few more merges

* Post npm install

* Fix batch of build breaks

* Fix more build breaks

* Fix more build errors

* Fix more build breaks

* Runtime fixes 1

* Get connection dialog working with some todos

* Fix a few packaging issues

* Copy several node_modules to package build to fix loader issues

* Fix breaks from master

* A few more fixes

* Make tests pass

* First pass of license header updates

* Second pass of license header updates

* Fix restore dialog issues

* Remove add additional themes menu items

* fix select box issues where the list doesn't show up

* formatting

* Fix editor dispose issue

* Copy over node modules to correct location on all platforms
This commit is contained in:
Karl Burtram
2018-04-04 15:27:51 -07:00
committed by GitHub
parent 5fba3e31b4
commit dafb780987
9412 changed files with 141255 additions and 98813 deletions

View File

@@ -5,10 +5,10 @@
'use strict';
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, ConfigurationChangeEvent } from 'vscode';
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, OutputChannel } from 'vscode';
import { Repository, RepositoryState } from './repository';
import { memoize, sequentialize, debounce } from './decorators';
import { dispose, anyEvent, filterEvent, IDisposable, isDescendant } from './util';
import { dispose, anyEvent, filterEvent, isDescendant, firstIndex } from './util';
import { Git, GitErrorCodes } from './git';
import * as path from 'path';
import * as fs from 'fs';
@@ -28,7 +28,7 @@ class RepositoryPick implements QuickPickItem {
.join(' ');
}
constructor(public readonly repository: Repository) { }
constructor(public readonly repository: Repository, public readonly index: number) { }
}
export interface ModelChangeEvent {
@@ -66,7 +66,7 @@ export class Model {
private disposables: Disposable[] = [];
constructor(private git: Git, private globalState: Memento) {
constructor(private git: Git, private globalState: Memento, private outputChannel: OutputChannel) {
workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables);
this.onDidChangeWorkspaceFolders({ added: workspace.workspaceFolders || [], removed: [] });
@@ -93,17 +93,25 @@ export class Model {
private async scanWorkspaceFolders(): Promise<void> {
for (const folder of workspace.workspaceFolders || []) {
const root = folder.uri.fsPath;
const children = await new Promise<string[]>((c, e) => fs.readdir(root, (err, r) => err ? e(err) : c(r)));
children
.filter(child => child !== '.git')
.forEach(child => this.tryOpenRepository(path.join(root, child)));
try {
const children = await new Promise<string[]>((c, e) => fs.readdir(root, (err, r) => err ? e(err) : c(r)));
children
.filter(child => child !== '.git')
.forEach(child => this.tryOpenRepository(path.join(root, child)));
} catch (err) {
// noop
}
}
}
private onPossibleGitRepositoryChange(uri: Uri): void {
const possibleGitRepositoryPath = uri.fsPath.replace(/\.git.*$/, '');
this.possibleGitRepositoryPaths.add(possibleGitRepositoryPath);
this.eventuallyScanPossibleGitRepository(uri.fsPath.replace(/\.git.*$/, ''));
}
private eventuallyScanPossibleGitRepository(path: string) {
this.possibleGitRepositoryPaths.add(path);
this.eventuallyScanPossibleGitRepositories();
}
@@ -150,6 +158,13 @@ export class Model {
}
private onDidChangeVisibleTextEditors(editors: TextEditor[]): void {
const config = workspace.getConfiguration('git');
const enabled = config.get<boolean>('autoRepositoryDetection') === true;
if (!enabled) {
return;
}
editors.forEach(editor => {
const uri = editor.document.uri;
@@ -181,11 +196,13 @@ export class Model {
}
try {
const repositoryRoot = await this.git.getRepositoryRoot(path);
const rawRoot = await this.git.getRepositoryRoot(path);
// This can happen whenever `path` has the wrong case sensitivity in
// case insensitive file systems
// https://github.com/Microsoft/vscode/issues/33498
const repositoryRoot = Uri.file(rawRoot).fsPath;
if (this.getRepository(repositoryRoot)) {
return;
}
@@ -203,15 +220,31 @@ export class Model {
}
private open(repository: Repository): void {
this.outputChannel.appendLine(`Open repository: ${repository.root}`);
const onDidDisappearRepository = filterEvent(repository.onDidChangeState, state => state === RepositoryState.Disposed);
const disappearListener = onDidDisappearRepository(() => dispose());
const changeListener = repository.onDidChangeRepository(uri => this._onDidChangeRepository.fire({ repository, uri }));
const originalResourceChangeListener = repository.onDidChangeOriginalResource(uri => this._onDidChangeOriginalResource.fire({ repository, uri }));
const checkForSubmodules = () => {
if (repository.submodules.length > 10) {
window.showWarningMessage(localize('too many submodules', "The '{0}' repository has {1} submodules which won't be opened automatically. You can still open each one individually by opening a file within.", path.basename(repository.root), repository.submodules.length));
statusListener.dispose();
return;
}
this.scanSubmodules(repository);
};
const statusListener = repository.onDidRunGitStatus(checkForSubmodules);
checkForSubmodules();
const dispose = () => {
disappearListener.dispose();
changeListener.dispose();
originalResourceChangeListener.dispose();
statusListener.dispose();
repository.dispose();
this.openRepositories = this.openRepositories.filter(e => e !== openRepository);
@@ -223,6 +256,20 @@ export class Model {
this._onDidOpenRepository.fire(repository);
}
private scanSubmodules(repository: Repository): void {
const shouldScanSubmodules = workspace
.getConfiguration('git', Uri.file(repository.root))
.get<boolean>('detectSubmodules') === true;
if (!shouldScanSubmodules) {
return;
}
repository.submodules
.map(r => path.join(repository.root, r.path))
.forEach(p => this.eventuallyScanPossibleGitRepository(p));
}
close(repository: Repository): void {
const openRepository = this.getOpenRepository(repository);
@@ -230,6 +277,7 @@ export class Model {
return;
}
this.outputChannel.appendLine(`Close repository: ${repository.root}`);
openRepository.dispose();
}
@@ -238,7 +286,16 @@ export class Model {
throw new Error(localize('no repositories', "There are no available repositories"));
}
const picks = this.openRepositories.map(e => new RepositoryPick(e.repository));
const picks = this.openRepositories.map((e, index) => new RepositoryPick(e.repository, index));
const active = window.activeTextEditor;
const repository = active && this.getRepository(active.document.fileName);
const index = firstIndex(picks, pick => pick.repository === repository);
// Move repository pick containing the active text editor to appear first
if (index > -1) {
picks.unshift(...picks.splice(index, 1));
}
const placeHolder = localize('pick repo', "Choose a repository");
const pick = await window.showQuickPick(picks, { placeHolder });
@@ -281,12 +338,21 @@ export class Model {
resourcePath = hint.fsPath;
}
for (const liveRepository of this.openRepositories) {
const relativePath = path.relative(liveRepository.repository.root, resourcePath);
if (isDescendant(liveRepository.repository.root, resourcePath)) {
return liveRepository;
outer:
for (const liveRepository of this.openRepositories.sort((a, b) => b.repository.root.length - a.repository.root.length)) {
if (!isDescendant(liveRepository.repository.root, resourcePath)) {
continue;
}
for (const submodule of liveRepository.repository.submodules) {
const submoduleRoot = path.join(liveRepository.repository.root, submodule.path);
if (isDescendant(submoduleRoot, resourcePath)) {
continue outer;
}
}
return liveRepository;
}
return undefined;
@@ -307,6 +373,20 @@ export class Model {
return undefined;
}
getRepositoryForSubmodule(submoduleUri: Uri): Repository | undefined {
for (const repository of this.repositories) {
for (const submodule of repository.submodules) {
const submodulePath = path.join(repository.root, submodule.path);
if (submodulePath === submoduleUri.fsPath) {
return repository;
}
}
}
return undefined;
}
dispose(): void {
const openRepositories = [...this.openRepositories];
openRepositories.forEach(r => r.dispose());