Merge branch 'master' into rebornix/integration-test-notebook

This commit is contained in:
Peng Lyu 2020-07-22 09:32:48 -07:00 committed by GitHub
commit bd70388d46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
78 changed files with 834 additions and 446 deletions

View file

@ -1801,7 +1801,7 @@
"Ignore",
"ignore"
],
"filenames": [
"extensions": [
".gitignore_global",
".gitignore"
],

View file

@ -74,7 +74,7 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
new GitTimelineProvider(model)
);
await checkGitVersion(info);
checkGitVersion(info);
return model;
}

View file

@ -40,13 +40,13 @@
"languages": [
{
"id": "ignore",
"filenames": [
"extensions": [
".npmignore"
]
},
{
"id": "properties",
"filenames": [
"extensions": [
".npmrc"
]
}

View file

@ -9,17 +9,17 @@ import { Lazy } from '../utils/lazy';
import { PluginManager } from '../utils/plugins';
import { ConfigurePluginCommand } from './configurePlugin';
import { JavaScriptGoToProjectConfigCommand, TypeScriptGoToProjectConfigCommand } from './goToProjectConfiguration';
import { LearnMoreAboutRefactoringsCommand } from './learnMoreAboutRefactorings';
import { OpenTsServerLogCommand } from './openTsServerLog';
import { ReloadJavaScriptProjectsCommand, ReloadTypeScriptProjectsCommand } from './reloadProject';
import { RestartTsServerCommand } from './restartTsServer';
import { SelectTypeScriptVersionCommand } from './selectTypeScriptVersion';
import { LearnMoreAboutRefactoringsCommand } from './learnMoreAboutRefactorings';
export function registerCommands(
export function registerBaseCommands(
commandManager: CommandManager,
lazyClientHost: Lazy<TypeScriptServiceClientHost>,
pluginManager: PluginManager
) {
): void {
commandManager.register(new ReloadTypeScriptProjectsCommand(lazyClientHost));
commandManager.register(new ReloadJavaScriptProjectsCommand(lazyClientHost));
commandManager.register(new SelectTypeScriptVersionCommand(lazyClientHost));

View file

@ -5,8 +5,8 @@
import * as vscode from 'vscode';
import { Api, getExtensionApi } from './api';
import { registerCommands } from './commands/index';
import { LanguageConfigurationManager } from './features/languageConfiguration';
import { registerBaseCommands } from './commands/index';
import { LanguageConfigurationManager } from './languageFeatures/languageConfiguration';
import { createLazyClientHost, lazilyActivateClient } from './lazyClientHost';
import { noopRequestCancellerFactory } from './tsServer/cancellation';
import { noopLogDirectoryProvider } from './tsServer/logDirectoryProvider';
@ -44,6 +44,8 @@ export function activate(
const commandManager = new CommandManager();
context.subscriptions.push(commandManager);
context.subscriptions.push(new LanguageConfigurationManager());
const onCompletionAccepted = new vscode.EventEmitter<vscode.CompletionItem>();
context.subscriptions.push(onCompletionAccepted);
@ -53,15 +55,22 @@ export function activate(
'/builtin-extension/typescript-language-features/dist/browser/typescript-web/tsserver.js',
API.v400));
const lazyClientHost = createLazyClientHost(context, false, pluginManager, commandManager, noopLogDirectoryProvider, noopRequestCancellerFactory, versionProvider, WorkerServerProcess, item => {
const lazyClientHost = createLazyClientHost(context, false, {
pluginManager,
commandManager,
logDirectoryProvider: noopLogDirectoryProvider,
cancellerFactory: noopRequestCancellerFactory,
versionProvider,
processFactory: WorkerServerProcess
}, item => {
onCompletionAccepted.fire(item);
});
registerCommands(commandManager, lazyClientHost, pluginManager);
// context.subscriptions.push(task.register(lazyClientHost.map(x => x.serviceClient)));
context.subscriptions.push(new LanguageConfigurationManager());
registerBaseCommands(commandManager, lazyClientHost, pluginManager);
import('./features/tsconfig').then(module => {
// context.subscriptions.push(task.register(lazyClientHost.map(x => x.serviceClient)));
import('./languageFeatures/tsconfig').then(module => {
context.subscriptions.push(module.register());
});

View file

@ -6,9 +6,8 @@
import * as rimraf from 'rimraf';
import * as vscode from 'vscode';
import { Api, getExtensionApi } from './api';
import { registerCommands } from './commands/index';
import { LanguageConfigurationManager } from './features/languageConfiguration';
import * as task from './features/task';
import { registerBaseCommands } from './commands/index';
import { LanguageConfigurationManager } from './languageFeatures/languageConfiguration';
import { createLazyClientHost, lazilyActivateClient } from './lazyClientHost';
import { nodeRequestCancellerFactory } from './tsServer/cancellation.electron';
import { NodeLogDirectoryProvider } from './tsServer/logDirectoryProvider.electron';
@ -32,18 +31,28 @@ export function activate(
context.subscriptions.push(onCompletionAccepted);
const logDirectoryProvider = new NodeLogDirectoryProvider(context);
const versionProvider = new DiskTypeScriptVersionProvider();
const lazyClientHost = createLazyClientHost(context, onCaseInsenitiveFileSystem(), pluginManager, commandManager, logDirectoryProvider, nodeRequestCancellerFactory, versionProvider, ChildServerProcess, item => {
context.subscriptions.push(new LanguageConfigurationManager());
const lazyClientHost = createLazyClientHost(context, onCaseInsenitiveFileSystem(), {
pluginManager,
commandManager,
logDirectoryProvider,
cancellerFactory: nodeRequestCancellerFactory,
versionProvider,
processFactory: ChildServerProcess,
}, item => {
onCompletionAccepted.fire(item);
});
registerCommands(commandManager, lazyClientHost, pluginManager);
context.subscriptions.push(task.register(lazyClientHost.map(x => x.serviceClient)));
context.subscriptions.push(new LanguageConfigurationManager());
registerBaseCommands(commandManager, lazyClientHost, pluginManager);
import('./features/tsconfig').then(module => {
import('./task/taskProvider').then(module => {
context.subscriptions.push(module.register(lazyClientHost.map(x => x.serviceClient)));
});
import('./languageFeatures/tsconfig').then(module => {
context.subscriptions.push(module.register());
});

View file

@ -5,11 +5,11 @@
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import type * as Proto from '../protocol';
import { ITypeScriptServiceClient } from '../typescriptService';
import { escapeRegExp } from '../utils/regexp';
import * as typeConverters from '../utils/typeConverters';
import { CachedResponse } from '../tsServer/cachedResponse';
import type * as Proto from '../../protocol';
import { CachedResponse } from '../../tsServer/cachedResponse';
import { ITypeScriptServiceClient } from '../../typescriptService';
import { escapeRegExp } from '../../utils/regexp';
import * as typeConverters from '../../utils/typeConverters';
const localize = nls.loadMessageBundle();

View file

@ -5,13 +5,13 @@
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import type * as Proto from '../protocol';
import * as PConst from '../protocol.const';
import { CachedResponse } from '../tsServer/cachedResponse';
import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService';
import { conditionalRegistration, requireSomeCapability, requireConfiguration } from '../utils/dependentRegistration';
import { DocumentSelector } from '../utils/documentSelector';
import * as typeConverters from '../utils/typeConverters';
import type * as Proto from '../../protocol';
import * as PConst from '../../protocol.const';
import { CachedResponse } from '../../tsServer/cachedResponse';
import { ClientCapability, ITypeScriptServiceClient } from '../../typescriptService';
import { conditionalRegistration, requireSomeCapability, requireConfiguration } from '../../utils/dependentRegistration';
import { DocumentSelector } from '../../utils/documentSelector';
import * as typeConverters from '../../utils/typeConverters';
import { getSymbolRange, ReferencesCodeLens, TypeScriptBaseCodeLensProvider } from './baseCodeLensProvider';
const localize = nls.loadMessageBundle();

View file

@ -5,14 +5,14 @@
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import type * as Proto from '../protocol';
import * as PConst from '../protocol.const';
import { CachedResponse } from '../tsServer/cachedResponse';
import { ExectuionTarget } from '../tsServer/server';
import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService';
import { conditionalRegistration, requireConfiguration, requireSomeCapability } from '../utils/dependentRegistration';
import { DocumentSelector } from '../utils/documentSelector';
import * as typeConverters from '../utils/typeConverters';
import type * as Proto from '../../protocol';
import * as PConst from '../../protocol.const';
import { CachedResponse } from '../../tsServer/cachedResponse';
import { ExectuionTarget } from '../../tsServer/server';
import { ClientCapability, ITypeScriptServiceClient } from '../../typescriptService';
import { conditionalRegistration, requireConfiguration, requireSomeCapability } from '../../utils/dependentRegistration';
import { DocumentSelector } from '../../utils/documentSelector';
import * as typeConverters from '../../utils/typeConverters';
import { getSymbolRange, ReferencesCodeLens, TypeScriptBaseCodeLensProvider } from './baseCodeLensProvider';
const localize = nls.loadMessageBundle();

View file

@ -5,8 +5,8 @@
import { basename } from 'path';
import * as vscode from 'vscode';
import { DiagnosticKind } from './features/diagnostics';
import FileConfigurationManager from './features/fileConfigurationManager';
import { DiagnosticKind } from './languageFeatures/diagnostics';
import FileConfigurationManager from './languageFeatures/fileConfigurationManager';
import { CachedResponse } from './tsServer/cachedResponse';
import TypeScriptServiceClient from './typescriptServiceClient';
import { CommandManager } from './utils/commandManager';
@ -58,30 +58,30 @@ export default class LanguageProvider extends Disposable {
const cachedResponse = new CachedResponse();
await Promise.all([
import('./features/completions').then(provider => this._register(provider.register(selector, this.description.id, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager, this.telemetryReporter, this.onCompletionAccepted))),
import('./features/definitions').then(provider => this._register(provider.register(selector, this.client))),
import('./features/directiveCommentCompletions').then(provider => this._register(provider.register(selector, this.client))),
import('./features/documentHighlight').then(provider => this._register(provider.register(selector, this.client))),
import('./features/documentSymbol').then(provider => this._register(provider.register(selector, this.client, cachedResponse))),
import('./features/folding').then(provider => this._register(provider.register(selector, this.client))),
import('./features/formatting').then(provider => this._register(provider.register(selector, this.description.id, this.client, this.fileConfigurationManager))),
import('./features/hover').then(provider => this._register(provider.register(selector, this.client))),
import('./features/implementations').then(provider => this._register(provider.register(selector, this.client))),
import('./features/implementationsCodeLens').then(provider => this._register(provider.register(selector, this.description.id, this.client, cachedResponse))),
import('./features/jsDocCompletions').then(provider => this._register(provider.register(selector, this.description.id, this.client))),
import('./features/organizeImports').then(provider => this._register(provider.register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter))),
import('./features/quickFix').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter))),
import('./features/fixAll').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.client.diagnosticsManager))),
import('./features/refactor').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter))),
import('./features/references').then(provider => this._register(provider.register(selector, this.client))),
import('./features/referencesCodeLens').then(provider => this._register(provider.register(selector, this.description.id, this.client, cachedResponse))),
import('./features/rename').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager))),
import('./features/smartSelect').then(provider => this._register(provider.register(selector, this.client))),
import('./features/signatureHelp').then(provider => this._register(provider.register(selector, this.client))),
import('./features/tagClosing').then(provider => this._register(provider.register(selector, this.description.id, this.client))),
import('./features/typeDefinitions').then(provider => this._register(provider.register(selector, this.client))),
import('./features/semanticTokens').then(provider => this._register(provider.register(selector, this.client))),
import('./features/callHierarchy').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/completions').then(provider => this._register(provider.register(selector, this.description.id, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager, this.telemetryReporter, this.onCompletionAccepted))),
import('./languageFeatures/definitions').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/directiveCommentCompletions').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/documentHighlight').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/documentSymbol').then(provider => this._register(provider.register(selector, this.client, cachedResponse))),
import('./languageFeatures/folding').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/formatting').then(provider => this._register(provider.register(selector, this.description.id, this.client, this.fileConfigurationManager))),
import('./languageFeatures/hover').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/implementations').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/codeLens/implementationsCodeLens').then(provider => this._register(provider.register(selector, this.description.id, this.client, cachedResponse))),
import('./languageFeatures/jsDocCompletions').then(provider => this._register(provider.register(selector, this.description.id, this.client))),
import('./languageFeatures/organizeImports').then(provider => this._register(provider.register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter))),
import('./languageFeatures/quickFix').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter))),
import('./languageFeatures/fixAll').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.client.diagnosticsManager))),
import('./languageFeatures/refactor').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter))),
import('./languageFeatures/references').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/codeLens/referencesCodeLens').then(provider => this._register(provider.register(selector, this.description.id, this.client, cachedResponse))),
import('./languageFeatures/rename').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager))),
import('./languageFeatures/smartSelect').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/signatureHelp').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/tagClosing').then(provider => this._register(provider.register(selector, this.description.id, this.client))),
import('./languageFeatures/typeDefinitions').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/semanticTokens').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/callHierarchy').then(provider => this._register(provider.register(selector, this.client))),
]);
}

View file

@ -20,12 +20,14 @@ import { PluginManager } from './utils/plugins';
export function createLazyClientHost(
context: vscode.ExtensionContext,
onCaseInsenitiveFileSystem: boolean,
pluginManager: PluginManager,
commandManager: CommandManager,
logDirectoryProvider: ILogDirectoryProvider,
cancellerFactory: OngoingRequestCancellerFactory,
versionProvider: ITypeScriptVersionProvider,
processFactory: TsServerProcessFactory,
services: {
pluginManager: PluginManager,
commandManager: CommandManager,
logDirectoryProvider: ILogDirectoryProvider,
cancellerFactory: OngoingRequestCancellerFactory,
versionProvider: ITypeScriptVersionProvider,
processFactory: TsServerProcessFactory,
},
onCompletionAccepted: (item: vscode.CompletionItem) => void,
): Lazy<TypeScriptServiceClientHost> {
return lazy(() => {
@ -33,12 +35,7 @@ export function createLazyClientHost(
standardLanguageDescriptions,
context.workspaceState,
onCaseInsenitiveFileSystem,
pluginManager,
commandManager,
logDirectoryProvider,
cancellerFactory,
versionProvider,
processFactory,
services,
onCompletionAccepted);
context.subscriptions.push(clientHost);
@ -57,7 +54,7 @@ export function createLazyClientHost(
export function lazilyActivateClient(
lazyClientHost: Lazy<TypeScriptServiceClientHost>,
pluginManager: PluginManager,
) {
): vscode.Disposable {
const disposables: vscode.Disposable[] = [];
const supportedLanguage = flatten([

View file

@ -11,7 +11,7 @@ import { ITypeScriptServiceClient, ServerResponse } from '../typescriptService';
import { isTsConfigFileName } from '../utils/languageDescription';
import { Lazy } from '../utils/lazy';
import { isImplicitProjectConfigFile } from '../utils/tsconfig';
import TsConfigProvider, { TSConfig } from '../utils/tsconfigProvider';
import { TSConfig, TsConfigProvider } from './tsconfigProvider';
const localize = nls.loadMessageBundle();

View file

@ -12,7 +12,7 @@ export interface TSConfig {
readonly workspaceFolder?: vscode.WorkspaceFolder;
}
export default class TsConfigProvider {
export class TsConfigProvider {
public async getConfigsForWorkspace(): Promise<Iterable<TSConfig>> {
if (!vscode.workspace.workspaceFolders) {
return [];

View file

@ -5,7 +5,7 @@
import * as assert from 'assert';
import 'mocha';
import { templateToSnippet } from '../features/jsDocCompletions';
import { templateToSnippet } from '../languageFeatures/jsDocCompletions';
const joinLines = (...args: string[]) => args.join('\n');

View file

@ -10,7 +10,7 @@ import type * as Proto from '../protocol';
import { NodeRequestCanceller } from '../tsServer/cancellation.electron';
import { ProcessBasedTsServer, TsServerProcess } from '../tsServer/server';
import { nulToken } from '../utils/cancellation';
import Logger from '../utils/logger';
import { Logger } from '../utils/logger';
import { TelemetryReporter } from '../utils/telemetry';
import Tracer from '../utils/tracer';

View file

@ -9,7 +9,7 @@ import { OngoingRequestCancellerFactory } from '../tsServer/cancellation';
import { ClientCapabilities, ClientCapability } from '../typescriptService';
import API from '../utils/api';
import { SeparateSyntaxServerConfiguration, TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration';
import Logger from '../utils/logger';
import { Logger } from '../utils/logger';
import { TypeScriptPluginPathsProvider } from '../utils/pluginPathsProvider';
import { PluginManager } from '../utils/plugins';
import { TelemetryReporter } from '../utils/telemetry';

View file

@ -9,8 +9,8 @@
* ------------------------------------------------------------------------------------------ */
import * as vscode from 'vscode';
import { DiagnosticKind } from './features/diagnostics';
import FileConfigurationManager from './features/fileConfigurationManager';
import { DiagnosticKind } from './languageFeatures/diagnostics';
import FileConfigurationManager from './languageFeatures/fileConfigurationManager';
import LanguageProvider from './languageProvider';
import * as Proto from './protocol';
import * as PConst from './protocol.const';
@ -58,29 +58,31 @@ export default class TypeScriptServiceClientHost extends Disposable {
private reportStyleCheckAsWarnings: boolean = true;
private readonly commandManager: CommandManager;
constructor(
descriptions: LanguageDescription[],
workspaceState: vscode.Memento,
onCaseInsenitiveFileSystem: boolean,
pluginManager: PluginManager,
private readonly commandManager: CommandManager,
logDirectoryProvider: ILogDirectoryProvider,
cancellerFactory: OngoingRequestCancellerFactory,
versionProvider: ITypeScriptVersionProvider,
processFactory: TsServerProcessFactory,
services: {
pluginManager: PluginManager,
commandManager: CommandManager,
logDirectoryProvider: ILogDirectoryProvider,
cancellerFactory: OngoingRequestCancellerFactory,
versionProvider: ITypeScriptVersionProvider,
processFactory: TsServerProcessFactory,
},
onCompletionAccepted: (item: vscode.CompletionItem) => void,
) {
super();
const allModeIds = this.getAllModeIds(descriptions, pluginManager);
this.commandManager = services.commandManager;
const allModeIds = this.getAllModeIds(descriptions, services.pluginManager);
this.client = this._register(new TypeScriptServiceClient(
workspaceState,
onCaseInsenitiveFileSystem,
pluginManager,
logDirectoryProvider,
cancellerFactory,
versionProvider,
processFactory,
services,
allModeIds));
this.client.onDiagnosticsReceived(({ kind, resource, diagnostics }) => {
@ -90,7 +92,7 @@ export default class TypeScriptServiceClientHost extends Disposable {
this.client.onConfigDiagnosticsReceived(diag => this.configFileDiagnosticsReceived(diag), null, this._disposables);
this.client.onResendModelsRequested(() => this.populateService(), null, this._disposables);
this._register(new VersionStatus(this.client, commandManager));
this._register(new VersionStatus(this.client, services.commandManager));
this._register(new AtaProgressReporter(this.client));
this.typingsStatus = this._register(new TypingsStatus(this.client));
this.fileConfigurationManager = this._register(new FileConfigurationManager(this.client, onCaseInsenitiveFileSystem));
@ -102,16 +104,16 @@ export default class TypeScriptServiceClientHost extends Disposable {
this.languagePerId.set(description.id, manager);
}
import('./features/updatePathsOnRename').then(module =>
import('./languageFeatures/updatePathsOnRename').then(module =>
this._register(module.register(this.client, this.fileConfigurationManager, uri => this.handles(uri))));
import('./features/workspaceSymbols').then(module =>
import('./languageFeatures/workspaceSymbols').then(module =>
this._register(module.register(this.client, allModeIds)));
this.client.ensureServiceStarted();
this.client.onReady(() => {
const languages = new Set<string>();
for (const plugin of pluginManager.plugins) {
for (const plugin of services.pluginManager.plugins) {
if (plugin.configNamespace && plugin.languages.length) {
this.registerExtensionLanguageProvider({
id: plugin.configNamespace,

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import BufferSyncSupport from './features/bufferSyncSupport';
import BufferSyncSupport from './languageFeatures/bufferSyncSupport';
import * as Proto from './protocol';
import { ExectuionTarget } from './tsServer/server';
import { TypeScriptVersion } from './tsServer/versionProvider';

View file

@ -6,8 +6,8 @@
import * as path from 'path';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import BufferSyncSupport from './features/bufferSyncSupport';
import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics';
import BufferSyncSupport from './languageFeatures/bufferSyncSupport';
import { DiagnosticKind, DiagnosticsManager } from './languageFeatures/diagnostics';
import * as Proto from './protocol';
import { EventName } from './protocol.const';
import { OngoingRequestCancellerFactory } from './tsServer/cancellation';
@ -22,7 +22,7 @@ import API from './utils/api';
import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration';
import { Disposable } from './utils/dispose';
import * as fileSchemes from './utils/fileSchemes';
import Logger from './utils/logger';
import { Logger } from './utils/logger';
import { isWeb } from './utils/platform';
import { TypeScriptPluginPathsProvider } from './utils/pluginPathsProvider';
import { PluginManager } from './utils/plugins';
@ -119,17 +119,32 @@ export default class TypeScriptServiceClient extends Disposable implements IType
public readonly bufferSyncSupport: BufferSyncSupport;
public readonly diagnosticsManager: DiagnosticsManager;
public readonly pluginManager: PluginManager;
private readonly logDirectoryProvider: ILogDirectoryProvider;
private readonly cancellerFactory: OngoingRequestCancellerFactory;
private readonly versionProvider: ITypeScriptVersionProvider;
private readonly processFactory: TsServerProcessFactory;
constructor(
private readonly workspaceState: vscode.Memento,
onCaseInsenitiveFileSystem: boolean,
public readonly pluginManager: PluginManager,
private readonly logDirectoryProvider: ILogDirectoryProvider,
private readonly cancellerFactory: OngoingRequestCancellerFactory,
private readonly versionProvider: ITypeScriptVersionProvider,
private readonly processFactory: TsServerProcessFactory,
services: {
pluginManager: PluginManager,
logDirectoryProvider: ILogDirectoryProvider,
cancellerFactory: OngoingRequestCancellerFactory,
versionProvider: ITypeScriptVersionProvider,
processFactory: TsServerProcessFactory,
},
allModeIds: readonly string[]
) {
super();
this.pluginManager = services.pluginManager;
this.logDirectoryProvider = services.logDirectoryProvider;
this.cancellerFactory = services.cancellerFactory;
this.versionProvider = services.versionProvider;
this.processFactory = services.processFactory;
this.pathSeparator = path.sep;
this.lastStart = Date.now();

View file

@ -11,7 +11,7 @@ const localize = nls.loadMessageBundle();
type LogLevel = 'Trace' | 'Info' | 'Error';
export default class Logger {
export class Logger {
@memoize
private get output(): vscode.OutputChannel {

View file

@ -5,7 +5,7 @@
import * as vscode from 'vscode';
import type * as Proto from '../protocol';
import Logger from './logger';
import { Logger } from './logger';
enum Trace {
Off,

View file

@ -34,5 +34,5 @@ export interface IContextMenuDelegate {
actionRunner?: IActionRunner;
autoSelectFirstItem?: boolean;
anchorAlignment?: AnchorAlignment;
anchorAsContainer?: boolean;
domForShadowRoot?: HTMLElement;
}

View file

@ -5,7 +5,6 @@
.monaco-action-bar {
text-align: right;
overflow: hidden;
white-space: nowrap;
}

View file

@ -28,7 +28,7 @@ function initialize() {
delayer.schedule();
}
function formatRule(c: Codicon) {
export function formatRule(c: Codicon) {
let def = c.definition;
while (def instanceof Codicon) {
def = def.definition;

View file

@ -10,6 +10,12 @@ import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/
import { Range } from 'vs/base/common/range';
import { BrowserFeatures } from 'vs/base/browser/canIUse';
export const enum ContextViewDOMPosition {
ABSOLUTE = 1,
FIXED,
FIXED_SHADOW
}
export interface IAnchor {
x: number;
y: number;
@ -105,32 +111,62 @@ export class ContextView extends Disposable {
private container: HTMLElement | null = null;
private view: HTMLElement;
private useFixedPosition: boolean;
private useShadowDOM: boolean;
private delegate: IDelegate | null = null;
private toDisposeOnClean: IDisposable = Disposable.None;
private toDisposeOnSetContainer: IDisposable = Disposable.None;
private shadowRoot: ShadowRoot | null = null;
private shadowRootHostElement: HTMLElement | null = null;
constructor(container: HTMLElement, useFixedPosition: boolean) {
constructor(container: HTMLElement, domPosition: ContextViewDOMPosition) {
super();
this.view = DOM.$('.context-view');
this.useFixedPosition = false;
this.useShadowDOM = false;
DOM.hide(this.view);
this.setContainer(container, useFixedPosition);
this.setContainer(container, domPosition);
this._register(toDisposable(() => this.setContainer(null, false)));
this._register(toDisposable(() => this.setContainer(null, ContextViewDOMPosition.ABSOLUTE)));
}
setContainer(container: HTMLElement | null, useFixedPosition: boolean): void {
setContainer(container: HTMLElement | null, domPosition: ContextViewDOMPosition): void {
if (this.container) {
this.toDisposeOnSetContainer.dispose();
this.container.removeChild(this.view);
if (this.shadowRoot) {
this.shadowRoot.removeChild(this.view);
this.shadowRoot = null;
DOM.removeNode(this.shadowRootHostElement!);
this.shadowRootHostElement = null;
} else {
this.container.removeChild(this.view);
}
this.container = null;
}
if (container) {
this.container = container;
this.container.appendChild(this.view);
this.useFixedPosition = domPosition !== ContextViewDOMPosition.ABSOLUTE;
this.useShadowDOM = domPosition === ContextViewDOMPosition.FIXED_SHADOW;
if (this.useShadowDOM) {
this.shadowRootHostElement = DOM.$('.shadow-root-host');
this.container.appendChild(this.shadowRootHostElement);
this.shadowRoot = this.shadowRootHostElement.attachShadow({ mode: 'closed' });
this.shadowRoot.innerHTML = `
<style>
${SHADOW_ROOT_CSS}
</style>
`;
this.shadowRoot.appendChild(this.view);
this.shadowRoot.appendChild(DOM.$('slot'));
} else {
this.container.appendChild(this.view);
}
const toDisposeOnSetContainer = new DisposableStore();
@ -148,8 +184,6 @@ export class ContextView extends Disposable {
this.toDisposeOnSetContainer = toDisposeOnSetContainer;
}
this.useFixedPosition = useFixedPosition;
}
show(delegate: IDelegate): void {
@ -162,6 +196,7 @@ export class ContextView extends Disposable {
this.view.className = 'context-view';
this.view.style.top = '0px';
this.view.style.left = '0px';
this.view.style.zIndex = '2500';
this.view.style.position = this.useFixedPosition ? 'fixed' : 'absolute';
DOM.show(this.view);
@ -300,3 +335,45 @@ export class ContextView extends Disposable {
super.dispose();
}
}
let SHADOW_ROOT_CSS = /* css */ `
:host {
all: initial; /* 1st rule so subsequent properties are reset. */
}
@font-face {
font-family: "codicon";
src: url("./codicon.ttf?5d4d76ab2ce5108968ad644d591a16a6") format("truetype");
}
.codicon[class*='codicon-'] {
font: normal normal normal 16px/1 codicon;
display: inline-block;
text-decoration: none;
text-rendering: auto;
text-align: center;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
:host-context(.mac) { font-family: -apple-system, BlinkMacSystemFont, sans-serif; }
:host-context(.mac:lang(zh-Hans)) { font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", sans-serif; }
:host-context(.mac:lang(zh-Hant)) { font-family: -apple-system, BlinkMacSystemFont, "PingFang TC", sans-serif; }
:host-context(.mac:lang(ja)) { font-family: -apple-system, BlinkMacSystemFont, "Hiragino Kaku Gothic Pro", sans-serif; }
:host-context(.mac:lang(ko)) { font-family: -apple-system, BlinkMacSystemFont, "Nanum Gothic", "Apple SD Gothic Neo", "AppleGothic", sans-serif; }
:host-context(.windows) { font-family: "Segoe WPC", "Segoe UI", sans-serif; }
:host-context(.windows:lang(zh-Hans)) { font-family: "Segoe WPC", "Segoe UI", "Microsoft YaHei", sans-serif; }
:host-context(.windows:lang(zh-Hant)) { font-family: "Segoe WPC", "Segoe UI", "Microsoft Jhenghei", sans-serif; }
:host-context(.windows:lang(ja)) { font-family: "Segoe WPC", "Segoe UI", "Yu Gothic UI", "Meiryo UI", sans-serif; }
:host-context(.windows:lang(ko)) { font-family: "Segoe WPC", "Segoe UI", "Malgun Gothic", "Dotom", sans-serif; }
:host-context(.mac).linux) { font-family: system-ui, "Ubuntu", "Droid Sans", sans-serif; }
:host-context(.mac).linux:lang(zh-Hans)) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans", sans-serif; }
:host-context(.mac).linux:lang(zh-Hant)) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans TC", "Source Han Sans TW", "Source Han Sans", sans-serif; }
:host-context(.mac).linux:lang(ja)) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans J", "Source Han Sans JP", "Source Han Sans", sans-serif; }
:host-context(.mac).linux:lang(ko)) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans K", "Source Han Sans JR", "Source Han Sans", "UnDotum", "FBaekmuk Gulim", sans-serif; }
`;

View file

@ -270,7 +270,7 @@ export class DropdownMenu extends BaseDropdown {
onHide: () => this.onHide(),
actionRunner: this.menuOptions ? this.menuOptions.actionRunner : undefined,
anchorAlignment: this.menuOptions ? this.menuOptions.anchorAlignment : AnchorAlignment.LEFT,
anchorAsContainer: this.menuAsChild
domForShadowRoot: this.menuAsChild ? this.element : undefined
});
}

View file

@ -1,225 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-menu .monaco-action-bar.vertical {
margin-left: 0;
overflow: visible;
}
.monaco-menu .monaco-action-bar.vertical .actions-container {
display: block;
}
.monaco-menu .monaco-action-bar.vertical .action-item {
padding: 0;
transform: none;
display: flex;
}
.monaco-menu .monaco-action-bar.vertical .action-item.active {
transform: none;
}
.monaco-menu .monaco-action-bar.vertical .action-menu-item {
flex: 1 1 auto;
display: flex;
height: 2em;
align-items: center;
position: relative;
}
.monaco-menu .monaco-action-bar.vertical .action-label {
flex: 1 1 auto;
text-decoration: none;
padding: 0 1em;
background: none;
font-size: 12px;
line-height: 1;
}
.monaco-menu .monaco-action-bar.vertical .keybinding,
.monaco-menu .monaco-action-bar.vertical .submenu-indicator {
display: inline-block;
flex: 2 1 auto;
padding: 0 1em;
text-align: right;
font-size: 12px;
line-height: 1;
}
.monaco-menu .monaco-action-bar.vertical .submenu-indicator {
height: 100%;
}
.monaco-menu .monaco-action-bar.vertical .submenu-indicator.codicon {
font-size: 16px !important;
display: flex;
align-items: center;
}
.monaco-menu .monaco-action-bar.vertical .submenu-indicator.codicon::before {
margin-left: auto;
margin-right: -20px;
}
.monaco-menu .monaco-action-bar.vertical .action-item.disabled .keybinding,
.monaco-menu .monaco-action-bar.vertical .action-item.disabled .submenu-indicator {
opacity: 0.4;
}
.monaco-menu .monaco-action-bar.vertical .action-label:not(.separator) {
display: inline-block;
box-sizing: border-box;
margin: 0;
}
.monaco-menu .monaco-action-bar.vertical .action-item {
position: static;
overflow: visible;
}
.monaco-menu .monaco-action-bar.vertical .action-item .monaco-submenu {
position: absolute;
}
.monaco-menu .monaco-action-bar.vertical .action-label.separator {
padding: 0.5em 0 0 0;
margin-bottom: 0.5em;
width: 100%;
height: 0px !important;
margin-left: .8em !important;
margin-right: .8em !important;
}
.monaco-menu .monaco-action-bar.vertical .action-label.separator.text {
padding: 0.7em 1em 0.1em 1em;
font-weight: bold;
opacity: 1;
}
.monaco-menu .monaco-action-bar.vertical .action-label:hover {
color: inherit;
}
.monaco-menu .monaco-action-bar.vertical .menu-item-check {
position: absolute;
visibility: hidden;
width: 1em;
height: 100%;
}
.monaco-menu .monaco-action-bar.vertical .action-menu-item.checked .menu-item-check {
visibility: visible;
display: flex;
align-items: center;
justify-content: center;
}
/* Context Menu */
.context-view.monaco-menu-container {
outline: 0;
border: none;
animation: fadeIn 0.083s linear;
}
.context-view.monaco-menu-container :focus,
.context-view.monaco-menu-container .monaco-action-bar.vertical:focus,
.context-view.monaco-menu-container .monaco-action-bar.vertical :focus {
outline: 0;
}
.monaco-menu .monaco-action-bar.vertical .action-item {
border: thin solid transparent; /* prevents jumping behaviour on hover or focus */
}
/* High Contrast Theming */
.hc-black .context-view.monaco-menu-container {
box-shadow: none;
}
.hc-black .monaco-menu .monaco-action-bar.vertical .action-item.focused {
background: none;
}
/* Menubar styles */
.menubar {
display: flex;
flex-shrink: 1;
box-sizing: border-box;
height: 30px;
overflow: hidden;
flex-wrap: wrap;
}
.fullscreen .menubar:not(.compact) {
margin: 0px;
padding: 0px 5px;
}
.menubar > .menubar-menu-button {
align-items: center;
box-sizing: border-box;
padding: 0px 8px;
cursor: default;
-webkit-app-region: no-drag;
zoom: 1;
white-space: nowrap;
outline: 0;
}
.menubar.compact {
flex-shrink: 0;
overflow: visible; /* to avoid the compact menu to be repositioned when clicking */
}
.menubar.compact > .menubar-menu-button {
width: 100%;
height: 100%;
padding: 0px;
}
.menubar .menubar-menu-items-holder {
position: absolute;
left: 0px;
opacity: 1;
z-index: 2000;
}
.menubar .menubar-menu-items-holder.monaco-menu-container {
outline: 0;
border: none;
}
.menubar .menubar-menu-items-holder.monaco-menu-container :focus {
outline: 0;
}
.menubar .toolbar-toggle-more {
width: 20px;
height: 100%;
}
.menubar.compact .toolbar-toggle-more {
position: relative;
left: 0px;
top: 0px;
cursor: pointer;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.menubar .toolbar-toggle-more {
padding: 0;
vertical-align: sub;
}
.menubar.compact .toolbar-toggle-more::before {
content: "\eb94" !important;
}

View file

@ -3,13 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./menu';
import * as nls from 'vs/nls';
import * as strings from 'vs/base/common/strings';
import { IActionRunner, IAction, Action } from 'vs/base/common/actions';
import { ActionBar, IActionViewItemProvider, ActionsOrientation, Separator, ActionViewItem, IActionViewItemOptions, BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ResolvedKeybinding, KeyCode } from 'vs/base/common/keyCodes';
import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor, hasClass, addDisposableListener, removeClass, append, $, addClasses, removeClasses, clearNode } from 'vs/base/browser/dom';
import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor, hasClass, addDisposableListener, removeClass, append, $, addClasses, removeClasses, clearNode, createStyleSheet, isInShadowDOM } from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { RunOnceScheduler } from 'vs/base/common/async';
import { DisposableStore } from 'vs/base/common/lifecycle';
@ -20,6 +19,7 @@ import { Event } from 'vs/base/common/event';
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { isLinux, isMacintosh } from 'vs/base/common/platform';
import { Codicon, registerIcon, stripCodicons } from 'vs/base/common/codicons';
import { formatRule } from 'vs/base/browser/ui/codicons/codiconStyles';
export const MENU_MNEMONIC_REGEX = /\(&([^\s&])\)|(^|[^&])&([^\s&])/;
export const MENU_ESCAPED_MNEMONIC_REGEX = /(&amp;)?(&amp;)([^\s&])/g;
@ -71,6 +71,8 @@ export class Menu extends ActionBar {
private readonly menuDisposables: DisposableStore;
private scrollableElement: DomScrollableElement;
private menuElement: HTMLElement;
static globalStyleSheet: HTMLStyleElement;
protected styleSheet: HTMLStyleElement | undefined;
constructor(container: HTMLElement, actions: ReadonlyArray<IAction>, options: IMenuOptions = {}) {
addClass(container, 'monaco-menu-container');
@ -96,6 +98,8 @@ export class Menu extends ActionBar {
this.menuDisposables = this._register(new DisposableStore());
this.initializeStyleSheet(container);
addDisposableListener(menuElement, EventType.KEY_DOWN, (e) => {
const event = new StandardKeyboardEvent(e);
@ -215,6 +219,20 @@ export class Menu extends ActionBar {
});
}
private initializeStyleSheet(container: HTMLElement): void {
if (isInShadowDOM(container)) {
this.styleSheet = createStyleSheet(container);
this.styleSheet.innerHTML = MENU_WIDGET_CSS;
} else {
if (!Menu.globalStyleSheet) {
Menu.globalStyleSheet = createStyleSheet();
Menu.globalStyleSheet.innerHTML = MENU_WIDGET_CSS;
}
this.styleSheet = Menu.globalStyleSheet;
}
}
style(style: IMenuStyles): void {
const container = this.getContainer();
@ -877,3 +895,298 @@ export function cleanMnemonic(label: string): string {
return label.replace(regex, mnemonicInText ? '$2$3' : '').trim();
}
let MENU_WIDGET_CSS: string = /* css */`
.monaco-menu {
font-size: 13px;
}
${formatRule(menuSelectionIcon)}
${formatRule(menuSubmenuIcon)}
.monaco-action-bar {
text-align: right;
overflow: hidden;
white-space: nowrap;
}
.monaco-action-bar .actions-container {
display: flex;
margin: 0 auto;
padding: 0;
width: 100%;
justify-content: flex-end;
}
.monaco-action-bar.vertical .actions-container {
display: inline-block;
}
.monaco-action-bar.reverse .actions-container {
flex-direction: row-reverse;
}
.monaco-action-bar .action-item {
cursor: pointer;
display: inline-block;
transition: transform 50ms ease;
position: relative; /* DO NOT REMOVE - this is the key to preventing the ghosting icon bug in Chrome 42 */
}
.monaco-action-bar .action-item.disabled {
cursor: default;
}
.monaco-action-bar.animated .action-item.active {
transform: scale(1.272019649, 1.272019649); /* 1.272019649 = √φ */
}
.monaco-action-bar .action-item .icon,
.monaco-action-bar .action-item .codicon {
display: inline-block;
}
.monaco-action-bar .action-item .codicon {
display: flex;
align-items: center;
}
.monaco-action-bar .action-label {
font-size: 11px;
margin-right: 4px;
}
.monaco-action-bar .action-item.disabled .action-label,
.monaco-action-bar .action-item.disabled .action-label:hover {
opacity: 0.4;
}
/* Vertical actions */
.monaco-action-bar.vertical {
text-align: left;
}
.monaco-action-bar.vertical .action-item {
display: block;
}
.monaco-action-bar.vertical .action-label.separator {
display: block;
border-bottom: 1px solid #bbb;
padding-top: 1px;
margin-left: .8em;
margin-right: .8em;
}
.monaco-action-bar.animated.vertical .action-item.active {
transform: translate(5px, 0);
}
.secondary-actions .monaco-action-bar .action-label {
margin-left: 6px;
}
/* Action Items */
.monaco-action-bar .action-item.select-container {
overflow: hidden; /* somehow the dropdown overflows its container, we prevent it here to not push */
flex: 1;
max-width: 170px;
min-width: 60px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
.monaco-menu .monaco-action-bar.vertical {
margin-left: 0;
overflow: visible;
}
.monaco-menu .monaco-action-bar.vertical .actions-container {
display: block;
}
.monaco-menu .monaco-action-bar.vertical .action-item {
padding: 0;
transform: none;
display: flex;
}
.monaco-menu .monaco-action-bar.vertical .action-item.active {
transform: none;
}
.monaco-menu .monaco-action-bar.vertical .action-menu-item {
flex: 1 1 auto;
display: flex;
height: 2em;
align-items: center;
position: relative;
}
.monaco-menu .monaco-action-bar.vertical .action-label {
flex: 1 1 auto;
text-decoration: none;
padding: 0 1em;
background: none;
font-size: 12px;
line-height: 1;
}
.monaco-menu .monaco-action-bar.vertical .keybinding,
.monaco-menu .monaco-action-bar.vertical .submenu-indicator {
display: inline-block;
flex: 2 1 auto;
padding: 0 1em;
text-align: right;
font-size: 12px;
line-height: 1;
}
.monaco-menu .monaco-action-bar.vertical .submenu-indicator {
height: 100%;
}
.monaco-menu .monaco-action-bar.vertical .submenu-indicator.codicon {
font-size: 16px !important;
display: flex;
align-items: center;
}
.monaco-menu .monaco-action-bar.vertical .submenu-indicator.codicon::before {
margin-left: auto;
margin-right: -20px;
}
.monaco-menu .monaco-action-bar.vertical .action-item.disabled .keybinding,
.monaco-menu .monaco-action-bar.vertical .action-item.disabled .submenu-indicator {
opacity: 0.4;
}
.monaco-menu .monaco-action-bar.vertical .action-label:not(.separator) {
display: inline-block;
box-sizing: border-box;
margin: 0;
}
.monaco-menu .monaco-action-bar.vertical .action-item {
position: static;
overflow: visible;
}
.monaco-menu .monaco-action-bar.vertical .action-item .monaco-submenu {
position: absolute;
}
.monaco-menu .monaco-action-bar.vertical .action-label.separator {
padding: 0.5em 0 0 0;
margin-bottom: 0.5em;
width: 100%;
height: 0px !important;
margin-left: .8em !important;
margin-right: .8em !important;
}
.monaco-menu .monaco-action-bar.vertical .action-label.separator.text {
padding: 0.7em 1em 0.1em 1em;
font-weight: bold;
opacity: 1;
}
.monaco-menu .monaco-action-bar.vertical .action-label:hover {
color: inherit;
}
.monaco-menu .monaco-action-bar.vertical .menu-item-check {
position: absolute;
visibility: hidden;
width: 1em;
height: 100%;
}
.monaco-menu .monaco-action-bar.vertical .action-menu-item.checked .menu-item-check {
visibility: visible;
display: flex;
align-items: center;
justify-content: center;
}
/* Context Menu */
.context-view.monaco-menu-container {
outline: 0;
border: none;
animation: fadeIn 0.083s linear;
}
.context-view.monaco-menu-container :focus,
.context-view.monaco-menu-container .monaco-action-bar.vertical:focus,
.context-view.monaco-menu-container .monaco-action-bar.vertical :focus {
outline: 0;
}
.monaco-menu .monaco-action-bar.vertical .action-item {
border: thin solid transparent; /* prevents jumping behaviour on hover or focus */
}
/* High Contrast Theming */
.hc-black .context-view.monaco-menu-container {
box-shadow: none;
}
.hc-black .monaco-menu .monaco-action-bar.vertical .action-item.focused {
background: none;
}
/* Vertical Action Bar Styles */
.monaco-menu .monaco-action-bar.vertical {
padding: .5em 0;
}
.monaco-menu .monaco-action-bar.vertical .action-menu-item {
height: 1.8em;
}
.monaco-menu .monaco-action-bar.vertical .action-label:not(.separator),
.monaco-menu .monaco-action-bar.vertical .keybinding {
font-size: inherit;
padding: 0 2em;
}
.monaco-menu .monaco-action-bar.vertical .menu-item-check {
font-size: inherit;
width: 2em;
}
.monaco-menu .monaco-action-bar.vertical .action-label.separator {
font-size: inherit;
padding: 0.2em 0 0 0;
margin-bottom: 0.2em;
}
linux .monaco-menu .monaco-action-bar.vertical .action-label.separator {
margin-left: 0;
margin-right: 0;
}
.monaco-menu .monaco-action-bar.vertical .submenu-indicator {
font-size: 60%;
padding: 0 1.8em;
}
:host-context(.linux) .monaco-menu .monaco-action-bar.vertical .submenu-indicator {
height: 100%;
mask-size: 10px 10px;
-webkit-mask-size: 10px 10px;
}
.monaco-menu .action-item {
cursor: default;
}
`;

View file

@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/* Menubar styles */
.menubar {
display: flex;
flex-shrink: 1;
box-sizing: border-box;
height: 30px;
overflow: hidden;
flex-wrap: wrap;
}
.fullscreen .menubar:not(.compact) {
margin: 0px;
padding: 0px 5px;
}
.menubar > .menubar-menu-button {
align-items: center;
box-sizing: border-box;
padding: 0px 8px;
cursor: default;
-webkit-app-region: no-drag;
zoom: 1;
white-space: nowrap;
outline: 0;
}
.menubar.compact {
flex-shrink: 0;
overflow: visible; /* to avoid the compact menu to be repositioned when clicking */
}
.menubar.compact > .menubar-menu-button {
width: 100%;
height: 100%;
padding: 0px;
}
.menubar .menubar-menu-items-holder {
position: absolute;
left: 0px;
opacity: 1;
z-index: 2000;
}
.menubar .menubar-menu-items-holder.monaco-menu-container {
outline: 0;
border: none;
}
.menubar .menubar-menu-items-holder.monaco-menu-container :focus {
outline: 0;
}
.menubar .toolbar-toggle-more {
width: 20px;
height: 100%;
}
.menubar.compact .toolbar-toggle-more {
position: relative;
left: 0px;
top: 0px;
cursor: pointer;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.menubar .toolbar-toggle-more {
padding: 0;
vertical-align: sub;
}
.menubar.compact .toolbar-toggle-more::before {
content: "\eb94" !important;
}

View file

@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./menubar';
import * as browser from 'vs/base/browser/browser';
import * as DOM from 'vs/base/browser/dom';
import * as strings from 'vs/base/common/strings';

View file

@ -12,6 +12,7 @@ import { generateUuid } from 'vs/base/common/uuid';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { VSBuffer } from 'vs/base/common/buffer';
import { ISocket, Protocol, Client, ChunkStream } from 'vs/base/parts/ipc/common/ipc.net';
import { onUnexpectedError } from 'vs/base/common/errors';
export class NodeSocket implements ISocket {
public readonly socket: Socket;
@ -57,7 +58,20 @@ export class NodeSocket implements ISocket {
// > https://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback
// > However, the false return value is only advisory and the writable stream will unconditionally
// > accept and buffer chunk even if it has not been allowed to drain.
this.socket.write(<Buffer>buffer.buffer);
try {
this.socket.write(<Buffer>buffer.buffer);
} catch (err) {
if (err.code === 'EPIPE') {
// An EPIPE exception at the wrong time can lead to a renderer process crash
// so ignore the error since the socket will fire the close event soon anyways:
// > https://nodejs.org/api/errors.html#errors_common_system_errors
// > EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is no
// > process to read the data. Commonly encountered at the net and http layers,
// > indicative that the remote side of the stream being written to has been closed.
return;
}
onUnexpectedError(err);
}
}
public end(): void {

View file

@ -90,6 +90,7 @@ export class CodeActionMenu extends Disposable {
const resolver = this._keybindingResolver.getResolver();
this._contextMenuService.showContextMenu({
domForShadowRoot: this._editor.getDomNode()!,
getAnchor: () => anchor,
getActions: () => menuActions,
onHide: () => {

View file

@ -205,6 +205,8 @@ export class ContextMenuController implements IEditorContribution {
// Show menu
this._contextMenuIsBeingShownCount++;
this._contextMenuService.showContextMenu({
domForShadowRoot: this._editor.getDomNode(),
getAnchor: () => anchor!,
getActions: () => actions,

View file

@ -50,7 +50,7 @@ export class ContextMenuHandler {
let menu: Menu | undefined;
const anchor = delegate.getAnchor();
let shadowRootElement = isHTMLElement(delegate.domForShadowRoot) ? delegate.domForShadowRoot : undefined;
this.contextViewService.showContextView({
getAnchor: () => delegate.getAnchor(),
canRelayout: false,
@ -133,7 +133,7 @@ export class ContextMenuHandler {
this.focusToReturn.focus();
}
}
}, !!delegate.anchorAsContainer && isHTMLElement(anchor) ? anchor : undefined);
}, shadowRootElement, !!shadowRootElement);
}
private onActionRun(e: IRunEvent): void {

View file

@ -15,7 +15,7 @@ export interface IContextViewService extends IContextViewProvider {
readonly _serviceBrand: undefined;
showContextView(delegate: IContextViewDelegate, container?: HTMLElement): IDisposable;
showContextView(delegate: IContextViewDelegate, container?: HTMLElement, shadowRoot?: boolean): IDisposable;
hideContextView(data?: any): void;
layout(): void;
anchorAlignment?: AnchorAlignment;

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IContextViewService, IContextViewDelegate } from './contextView';
import { ContextView } from 'vs/base/browser/ui/contextview/contextview';
import { ContextView, ContextViewDOMPosition } from 'vs/base/browser/ui/contextview/contextview';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
@ -21,7 +21,7 @@ export class ContextViewService extends Disposable implements IContextViewServic
super();
this.container = layoutService.container;
this.contextView = this._register(new ContextView(this.container, false));
this.contextView = this._register(new ContextView(this.container, ContextViewDOMPosition.ABSOLUTE));
this.layout();
this._register(layoutService.onLayout(() => this.layout()));
@ -29,20 +29,20 @@ export class ContextViewService extends Disposable implements IContextViewServic
// ContextView
setContainer(container: HTMLElement, useFixedPosition?: boolean): void {
this.contextView.setContainer(container, !!useFixedPosition);
setContainer(container: HTMLElement, domPosition?: ContextViewDOMPosition): void {
this.contextView.setContainer(container, domPosition || ContextViewDOMPosition.ABSOLUTE);
}
showContextView(delegate: IContextViewDelegate, container?: HTMLElement): IDisposable {
showContextView(delegate: IContextViewDelegate, container?: HTMLElement, shadowRoot?: boolean): IDisposable {
if (container) {
if (container !== this.container) {
this.container = container;
this.setContainer(container, true);
this.setContainer(container, shadowRoot ? ContextViewDOMPosition.FIXED_SHADOW : ContextViewDOMPosition.FIXED);
}
} else {
if (this.container !== this.layoutService.container) {
this.container = this.layoutService.container;
this.setContainer(this.container, false);
this.setContainer(this.container, ContextViewDOMPosition.ABSOLUTE);
}
}

View file

@ -82,10 +82,19 @@ class RemovedResources {
let messages: string[] = [];
if (externalRemoval.length > 0) {
messages.push(nls.localize('externalRemoval', "The following files have been closed and modified on disk: {0}.", externalRemoval.join(', ')));
messages.push(
nls.localize(
{ key: 'externalRemoval', comment: ['{0} is a list of filenames'] },
"The following files have been closed and modified on disk: {0}.", externalRemoval.join(', ')
)
);
}
if (noParallelUniverses.length > 0) {
messages.push(nls.localize('noParallelUniverses', "The following files have been modified in an incompatible way: {0}.", noParallelUniverses.join(', ')));
messages.push(
nls.localize(
{ key: 'noParallelUniverses', comment: ['{0} is a list of filenames'] },
"The following files have been modified in an incompatible way: {0}.", noParallelUniverses.join(', ')
));
}
return messages.join('\n');
}
@ -771,10 +780,26 @@ export class UndoRedoService implements IUndoRedoService {
private _checkWorkspaceUndo(strResource: string, element: WorkspaceStackElement, editStackSnapshot: EditStackSnapshot, checkInvalidatedResources: boolean): WorkspaceVerificationError | null {
if (element.removedResources) {
return this._tryToSplitAndUndo(strResource, element, element.removedResources, nls.localize('cannotWorkspaceUndo', "Could not undo '{0}' across all files. {1}", element.label, element.removedResources.createMessage()));
return this._tryToSplitAndUndo(
strResource,
element,
element.removedResources,
nls.localize(
{ key: 'cannotWorkspaceUndo', comment: ['{0} is a label for an operation. {1} is another message.'] },
"Could not undo '{0}' across all files. {1}", element.label, element.removedResources.createMessage()
)
);
}
if (checkInvalidatedResources && element.invalidatedResources) {
return this._tryToSplitAndUndo(strResource, element, element.invalidatedResources, nls.localize('cannotWorkspaceUndo', "Could not undo '{0}' across all files. {1}", element.label, element.invalidatedResources.createMessage()));
return this._tryToSplitAndUndo(
strResource,
element,
element.invalidatedResources,
nls.localize(
{ key: 'cannotWorkspaceUndo', comment: ['{0} is a label for an operation. {1} is another message.'] },
"Could not undo '{0}' across all files. {1}", element.label, element.invalidatedResources.createMessage()
)
);
}
// this must be the last past element in all the impacted resources!
@ -785,7 +810,15 @@ export class UndoRedoService implements IUndoRedoService {
}
}
if (cannotUndoDueToResources.length > 0) {
return this._tryToSplitAndUndo(strResource, element, null, nls.localize('cannotWorkspaceUndoDueToChanges', "Could not undo '{0}' across all files because changes were made to {1}", element.label, cannotUndoDueToResources.join(', ')));
return this._tryToSplitAndUndo(
strResource,
element,
null,
nls.localize(
{ key: 'cannotWorkspaceUndoDueToChanges', comment: ['{0} is a label for an operation. {1} is a list of filenames.'] },
"Could not undo '{0}' across all files because changes were made to {1}", element.label, cannotUndoDueToResources.join(', ')
)
);
}
const cannotLockDueToResources: string[] = [];
@ -795,12 +828,28 @@ export class UndoRedoService implements IUndoRedoService {
}
}
if (cannotLockDueToResources.length > 0) {
return this._tryToSplitAndUndo(strResource, element, null, nls.localize('cannotWorkspaceUndoDueToInProgressUndoRedo', "Could not undo '{0}' across all files because there is already an undo or redo operation running on {1}", element.label, cannotLockDueToResources.join(', ')));
return this._tryToSplitAndUndo(
strResource,
element,
null,
nls.localize(
{ key: 'cannotWorkspaceUndoDueToInProgressUndoRedo', comment: ['{0} is a label for an operation. {1} is a list of filenames.'] },
"Could not undo '{0}' across all files because there is already an undo or redo operation running on {1}", element.label, cannotLockDueToResources.join(', ')
)
);
}
// check if new stack elements were added in the meantime...
if (!editStackSnapshot.isValid()) {
return this._tryToSplitAndUndo(strResource, element, null, nls.localize('cannotWorkspaceUndoDueToInMeantimeUndoRedo', "Could not undo '{0}' across all files because an undo or redo operation occurred in the meantime", element.label));
return this._tryToSplitAndUndo(
strResource,
element,
null,
nls.localize(
{ key: 'cannotWorkspaceUndoDueToInMeantimeUndoRedo', comment: ['{0} is a label for an operation. {1} is a list of filenames.'] },
"Could not undo '{0}' across all files because an undo or redo operation occurred in the meantime", element.label
)
);
}
return null;
@ -881,7 +930,10 @@ export class UndoRedoService implements IUndoRedoService {
return;
}
if (editStack.locked) {
const message = nls.localize('cannotResourceUndoDueToInProgressUndoRedo', "Could not undo '{0}' because there is already an undo or redo operation running.", element.label);
const message = nls.localize(
{ key: 'cannotResourceUndoDueToInProgressUndoRedo', comment: ['{0} is a label for an operation.'] },
"Could not undo '{0}' because there is already an undo or redo operation running.", element.label
);
this._notificationService.info(message);
return;
}
@ -942,10 +994,26 @@ export class UndoRedoService implements IUndoRedoService {
private _checkWorkspaceRedo(strResource: string, element: WorkspaceStackElement, editStackSnapshot: EditStackSnapshot, checkInvalidatedResources: boolean): WorkspaceVerificationError | null {
if (element.removedResources) {
return this._tryToSplitAndRedo(strResource, element, element.removedResources, nls.localize('cannotWorkspaceRedo', "Could not redo '{0}' across all files. {1}", element.label, element.removedResources.createMessage()));
return this._tryToSplitAndRedo(
strResource,
element,
element.removedResources,
nls.localize(
{ key: 'cannotWorkspaceRedo', comment: ['{0} is a label for an operation. {1} is another message.'] },
"Could not redo '{0}' across all files. {1}", element.label, element.removedResources.createMessage()
)
);
}
if (checkInvalidatedResources && element.invalidatedResources) {
return this._tryToSplitAndRedo(strResource, element, element.invalidatedResources, nls.localize('cannotWorkspaceRedo', "Could not redo '{0}' across all files. {1}", element.label, element.invalidatedResources.createMessage()));
return this._tryToSplitAndRedo(
strResource,
element,
element.invalidatedResources,
nls.localize(
{ key: 'cannotWorkspaceRedo', comment: ['{0} is a label for an operation. {1} is another message.'] },
"Could not redo '{0}' across all files. {1}", element.label, element.invalidatedResources.createMessage()
)
);
}
// this must be the last future element in all the impacted resources!
@ -956,7 +1024,15 @@ export class UndoRedoService implements IUndoRedoService {
}
}
if (cannotRedoDueToResources.length > 0) {
return this._tryToSplitAndRedo(strResource, element, null, nls.localize('cannotWorkspaceRedoDueToChanges', "Could not redo '{0}' across all files because changes were made to {1}", element.label, cannotRedoDueToResources.join(', ')));
return this._tryToSplitAndRedo(
strResource,
element,
null,
nls.localize(
{ key: 'cannotWorkspaceRedoDueToChanges', comment: ['{0} is a label for an operation. {1} is a list of filenames.'] },
"Could not redo '{0}' across all files because changes were made to {1}", element.label, cannotRedoDueToResources.join(', ')
)
);
}
const cannotLockDueToResources: string[] = [];
@ -966,12 +1042,28 @@ export class UndoRedoService implements IUndoRedoService {
}
}
if (cannotLockDueToResources.length > 0) {
return this._tryToSplitAndRedo(strResource, element, null, nls.localize('cannotWorkspaceRedoDueToInProgressUndoRedo', "Could not redo '{0}' across all files because there is already an undo or redo operation running on {1}", element.label, cannotLockDueToResources.join(', ')));
return this._tryToSplitAndRedo(
strResource,
element,
null,
nls.localize(
{ key: 'cannotWorkspaceRedoDueToInProgressUndoRedo', comment: ['{0} is a label for an operation. {1} is a list of filenames.'] },
"Could not redo '{0}' across all files because there is already an undo or redo operation running on {1}", element.label, cannotLockDueToResources.join(', ')
)
);
}
// check if new stack elements were added in the meantime...
if (!editStackSnapshot.isValid()) {
return this._tryToSplitAndRedo(strResource, element, null, nls.localize('cannotWorkspaceRedoDueToInMeantimeUndoRedo', "Could not redo '{0}' across all files because an undo or redo operation occurred in the meantime", element.label));
return this._tryToSplitAndRedo(
strResource,
element,
null,
nls.localize(
{ key: 'cannotWorkspaceRedoDueToInMeantimeUndoRedo', comment: ['{0} is a label for an operation. {1} is a list of filenames.'] },
"Could not redo '{0}' across all files because an undo or redo operation occurred in the meantime", element.label
)
);
}
return null;
@ -1015,7 +1107,10 @@ export class UndoRedoService implements IUndoRedoService {
return;
}
if (editStack.locked) {
const message = nls.localize('cannotResourceRedoDueToInProgressUndoRedo', "Could not redo '{0}' because there is already an undo or redo operation running.", element.label);
const message = nls.localize(
{ key: 'cannotResourceRedoDueToInProgressUndoRedo', comment: ['{0} is a label for an operation.'] },
"Could not redo '{0}' because there is already an undo or redo operation running.", element.label
);
this._notificationService.info(message);
return;
}

View file

@ -868,22 +868,6 @@ declare module 'vscode' {
debugAdapterExecutable?(folder: WorkspaceFolder | undefined, token?: CancellationToken): ProviderResult<DebugAdapterExecutable>;
}
export interface DebugSession {
/**
* Terminates the session.
*/
terminate(): Thenable<void>;
}
export interface DebugSession {
/**
* Terminates the session.
*/
terminate(): Thenable<void>;
}
export namespace debug {
/**

View file

@ -262,14 +262,6 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
return Promise.reject(new Error('debug session not found'));
}
public $terminateDebugSession(sessionId: DebugSessionUUID): Promise<void> {
const session = this.debugService.getModel().getSession(sessionId, true);
if (session) {
return session.terminate();
}
return Promise.reject(new Error('debug session not found'));
}
public $stopDebugging(sessionId: DebugSessionUUID | undefined): Promise<void> {
if (sessionId) {
const session = this.debugService.getModel().getSession(sessionId, true);

View file

@ -269,6 +269,14 @@ export class MainThreadTextEditor {
}
}));
const isValidCodeEditor = () => {
// Due to event timings, it is possible that there is a model change event not yet delivered to us.
// > e.g. a model change event is emitted to a listener which then decides to update editor options
// > In this case the editor configuration change event reaches us first.
// So simply check that the model is still attached to this code editor
return (this._codeEditor && this._codeEditor.getModel() === this._model);
};
const updateProperties = (selectionChangeSource: string | null) => {
// Some editor events get delivered faster than model content changes. This is
// problematic, as this leads to editor properties reaching the extension host
@ -287,18 +295,30 @@ export class MainThreadTextEditor {
this._codeEditorListeners.add(this._codeEditor.onDidChangeCursorSelection((e) => {
// selection
if (!isValidCodeEditor()) {
return;
}
updateProperties(e.source);
}));
this._codeEditorListeners.add(this._codeEditor.onDidChangeConfiguration(() => {
this._codeEditorListeners.add(this._codeEditor.onDidChangeConfiguration((e) => {
// options
if (!isValidCodeEditor()) {
return;
}
updateProperties(null);
}));
this._codeEditorListeners.add(this._codeEditor.onDidLayoutChange(() => {
// visibleRanges
if (!isValidCodeEditor()) {
return;
}
updateProperties(null);
}));
this._codeEditorListeners.add(this._codeEditor.onDidScrollChange(() => {
// visibleRanges
if (!isValidCodeEditor()) {
return;
}
updateProperties(null);
}));
this._updatePropertiesNow(null);

View file

@ -878,7 +878,6 @@ export interface MainThreadDebugServiceShape extends IDisposable {
$stopDebugging(sessionId: DebugSessionUUID | undefined): Promise<void>;
$setDebugSessionName(id: DebugSessionUUID, name: string): void;
$customDebugAdapterRequest(id: DebugSessionUUID, command: string, args: any): Promise<any>;
$terminateDebugSession(id: DebugSessionUUID): Promise<void>;
$appendDebugConsole(value: string): void;
$startBreakpointEvents(): void;
$registerBreakpoints(breakpoints: Array<ISourceMultiBreakpointDto | IFunctionBreakpointDto | IDataBreakpointDto>): Promise<void>;

View file

@ -957,10 +957,6 @@ export class ExtHostDebugSession implements vscode.DebugSession {
public customRequest(command: string, args: any): Promise<any> {
return this._debugServiceProxy.$customDebugAdapterRequest(this._id, command, args);
}
public terminate(): Promise<void> {
return this._debugServiceProxy.$terminateDebugSession(this._id);
}
}
export class ExtHostDebugConsole implements vscode.DebugConsole {

View file

@ -51,7 +51,10 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService {
// fetch JS sources as text and create a new function around it
const source = await response.text();
const initFn = new Function('module', 'exports', 'require', `${source}\n//# sourceURL=${module.toString(true)}`);
// Here we append #vscode-extension to serve as a marker, such that source maps
// can be adjusted for the extra wrapping function.
const sourceURL = `${module.toString(true)}#vscode-extension`;
const initFn = new Function('module', 'exports', 'require', `${source}\n//# sourceURL=${sourceURL}`);
// define commonjs globals: `module`, `exports`, and `require`
const _exports = {};

View file

@ -883,7 +883,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
resolve(undefined);
}
} else {
resolve(this.executeTask(task, resolver));
resolve(this.executeTask(task, resolver, runSource));
}
}).then((value) => {
if (runSource === TaskRunSource.User) {
@ -1452,7 +1452,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
};
}
private executeTask(task: Task, resolver: ITaskResolver): Promise<ITaskSummary> {
private executeTask(task: Task, resolver: ITaskResolver, runSource?: TaskRunSource): Promise<ITaskSummary> {
enum SaveBeforeRunConfigOptions {
Always = 'always',
Never = 'never',
@ -1464,7 +1464,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
const execTask = async (task: Task, resolver: ITaskResolver): Promise<ITaskSummary> => {
return ProblemMatcherRegistry.onReady().then(() => {
let executeResult = this.getTaskSystem().run(task, resolver);
return this.handleExecuteResult(executeResult);
return this.handleExecuteResult(executeResult, runSource);
});
};
@ -1501,7 +1501,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
}
private async handleExecuteResult(executeResult: ITaskExecuteResult): Promise<ITaskSummary> {
private async handleExecuteResult(executeResult: ITaskExecuteResult, runSource?: TaskRunSource): Promise<ITaskSummary> {
if (executeResult.task.taskLoadMessages && executeResult.task.taskLoadMessages.length > 0) {
executeResult.task.taskLoadMessages.forEach(loadMessage => {
this._outputChannel.append(loadMessage + '\n');
@ -1509,7 +1509,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
this.showOutput();
}
await this.setRecentlyUsedTask(executeResult.task);
if (runSource === TaskRunSource.User) {
await this.setRecentlyUsedTask(executeResult.task);
}
if (executeResult.kind === TaskExecuteKind.Active) {
let active = executeResult.active;
if (active && active.same) {

View file

@ -16,7 +16,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, dispose } from 'vs/base/common/lifecycle';
import { Codicon } from 'vs/base/common/codicons';
import { IUserDataSyncWorkbenchService, getSyncAreaLabel, IUserDataSyncPreview, IUserDataSyncResource, MANUAL_SYNC_VIEW_ID } from 'vs/workbench/services/userDataSync/common/userDataSync';
import { IUserDataSyncWorkbenchService, getSyncAreaLabel, IUserDataSyncPreview, IUserDataSyncResource, SYNC_MERGES_VIEW_ID } from 'vs/workbench/services/userDataSync/common/userDataSync';
import { isEqual, basename } from 'vs/base/common/resources';
import { IDecorationsProvider, IDecorationData, IDecorationsService } from 'vs/workbench/services/decorations/browser/decorations';
import { IProgressService } from 'vs/platform/progress/common/progress';
@ -39,7 +39,7 @@ import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { Severity } from 'vs/platform/notification/common/notification';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
export class UserDataManualSyncViewPane extends TreeViewPane {
export class UserDataSyncMergesViewPane extends TreeViewPane {
private userDataSyncPreview: IUserDataSyncPreview;
@ -83,7 +83,7 @@ export class UserDataManualSyncViewPane extends TreeViewPane {
this.createButtons(container);
const that = this;
this.treeView.message = localize('explanation', "Please go through each entry and accept the change to enable sync.");
this.treeView.message = localize('explanation', "Please go through each entry and merge to enable sync.");
this.treeView.dataProvider = { getChildren() { return that.getTreeItems(); } };
}
@ -164,7 +164,7 @@ export class UserDataManualSyncViewPane extends TreeViewPane {
icon: Codicon.cloudDownload,
menu: {
id: MenuId.ViewItemContext,
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', MANUAL_SYNC_VIEW_ID), ContextKeyExpr.equals('viewItem', 'sync-resource-preview')),
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', SYNC_MERGES_VIEW_ID), ContextKeyExpr.equals('viewItem', 'sync-resource-preview')),
group: 'inline',
order: 1,
},
@ -184,7 +184,7 @@ export class UserDataManualSyncViewPane extends TreeViewPane {
icon: Codicon.cloudUpload,
menu: {
id: MenuId.ViewItemContext,
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', MANUAL_SYNC_VIEW_ID), ContextKeyExpr.equals('viewItem', 'sync-resource-preview')),
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', SYNC_MERGES_VIEW_ID), ContextKeyExpr.equals('viewItem', 'sync-resource-preview')),
group: 'inline',
order: 2,
},
@ -204,7 +204,7 @@ export class UserDataManualSyncViewPane extends TreeViewPane {
icon: Codicon.merge,
menu: {
id: MenuId.ViewItemContext,
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', MANUAL_SYNC_VIEW_ID), ContextKeyExpr.equals('viewItem', 'sync-resource-preview')),
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', SYNC_MERGES_VIEW_ID), ContextKeyExpr.equals('viewItem', 'sync-resource-preview')),
group: 'inline',
order: 3,
},
@ -224,7 +224,7 @@ export class UserDataManualSyncViewPane extends TreeViewPane {
icon: Codicon.discard,
menu: {
id: MenuId.ViewItemContext,
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', MANUAL_SYNC_VIEW_ID), ContextKeyExpr.or(ContextKeyExpr.equals('viewItem', 'sync-resource-accepted'), ContextKeyExpr.equals('viewItem', 'sync-resource-conflict'))),
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', SYNC_MERGES_VIEW_ID), ContextKeyExpr.or(ContextKeyExpr.equals('viewItem', 'sync-resource-accepted'), ContextKeyExpr.equals('viewItem', 'sync-resource-conflict'))),
group: 'inline',
order: 3,
},
@ -270,7 +270,7 @@ export class UserDataManualSyncViewPane extends TreeViewPane {
previewResource = this.userDataSyncPreview.resources.find(({ local }) => isEqual(local, previewResource.local))!;
await this.reopen(previewResource);
if (previewResource.mergeState === MergeState.Conflict) {
await this.dialogService.show(Severity.Warning, localize('conflicts detected', "Conflicts Detected."), [], {
await this.dialogService.show(Severity.Warning, localize('conflicts detected', "Conflicts Detected"), [], {
detail: localize('resolve', "Unable to merge due to conflicts. Please resolve them to continue.")
});
}
@ -373,7 +373,7 @@ export class UserDataManualSyncViewPane extends TreeViewPane {
}
private withProgress(task: () => Promise<void>): Promise<void> {
return this.progressService.withProgress({ location: MANUAL_SYNC_VIEW_ID, delay: 500 }, task);
return this.progressService.withProgress({ location: SYNC_MERGES_VIEW_ID, delay: 500 }, task);
}
}

View file

@ -30,13 +30,13 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IAction, Action } from 'vs/base/common/actions';
import { IUserDataSyncWorkbenchService, CONTEXT_SYNC_STATE, getSyncAreaLabel, CONTEXT_ACCOUNT_STATE, AccountStatus, CONTEXT_ENABLE_ACTIVITY_VIEWS, SHOW_SYNC_LOG_COMMAND_ID, CONFIGURE_SYNC_COMMAND_ID, MANUAL_SYNC_VIEW_ID, CONTEXT_ENABLE_MANUAL_SYNC_VIEW } from 'vs/workbench/services/userDataSync/common/userDataSync';
import { IUserDataSyncWorkbenchService, CONTEXT_SYNC_STATE, getSyncAreaLabel, CONTEXT_ACCOUNT_STATE, AccountStatus, CONTEXT_ENABLE_ACTIVITY_VIEWS, SHOW_SYNC_LOG_COMMAND_ID, CONFIGURE_SYNC_COMMAND_ID, SYNC_MERGES_VIEW_ID, CONTEXT_ENABLE_SYNC_MERGES_VIEW } from 'vs/workbench/services/userDataSync/common/userDataSync';
import { IUserDataSyncMachinesService, IUserDataSyncMachine } from 'vs/platform/userDataSync/common/userDataSyncMachines';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { TreeView } from 'vs/workbench/contrib/views/browser/treeView';
import { flatten } from 'vs/base/common/arrays';
import { UserDataManualSyncViewPane } from 'vs/workbench/contrib/userDataSync/browser/userDataManualSyncView';
import { UserDataSyncMergesViewPane } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncMergesView';
export class UserDataSyncViewPaneContainer extends ViewPaneContainer {
@ -86,7 +86,7 @@ export class UserDataSyncDataViews extends Disposable {
}
private registerViews(container: ViewContainer): void {
this.registerManualSyncView(container);
this.registerMergesView(container);
this.registerActivityView(container, true);
this.registerMachinesView(container);
@ -94,17 +94,17 @@ export class UserDataSyncDataViews extends Disposable {
this.registerActivityView(container, false);
}
private registerManualSyncView(container: ViewContainer): void {
private registerMergesView(container: ViewContainer): void {
const viewsRegistry = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry);
const viewName = localize('manual sync', "Manual Sync");
const viewName = localize('merges', "Merges");
viewsRegistry.registerViews([<ITreeViewDescriptor>{
id: MANUAL_SYNC_VIEW_ID,
id: SYNC_MERGES_VIEW_ID,
name: viewName,
ctorDescriptor: new SyncDescriptor(UserDataManualSyncViewPane),
when: CONTEXT_ENABLE_MANUAL_SYNC_VIEW,
ctorDescriptor: new SyncDescriptor(UserDataSyncMergesViewPane),
when: CONTEXT_ENABLE_SYNC_MERGES_VIEW,
canToggleVisibility: false,
canMoveView: false,
treeView: this.instantiationService.createInstance(TreeView, MANUAL_SYNC_VIEW_ID, viewName),
treeView: this.instantiationService.createInstance(TreeView, SYNC_MERGES_VIEW_ID, viewName),
collapsed: false,
order: 100,
}], container);

View file

@ -6,7 +6,7 @@
import { IUserDataSyncService, IAuthenticationProvider, getUserDataSyncStore, isAuthenticationProvider, IUserDataAutoSyncService, SyncResource, IResourcePreview, ISyncResourcePreview, Change, IManualSyncTask } from 'vs/platform/userDataSync/common/userDataSync';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IUserDataSyncWorkbenchService, IUserDataSyncAccount, AccountStatus, CONTEXT_SYNC_ENABLEMENT, CONTEXT_SYNC_STATE, CONTEXT_ACCOUNT_STATE, SHOW_SYNC_LOG_COMMAND_ID, getSyncAreaLabel, IUserDataSyncPreview, IUserDataSyncResource, CONTEXT_ENABLE_MANUAL_SYNC_VIEW, MANUAL_SYNC_VIEW_ID, CONTEXT_ENABLE_ACTIVITY_VIEWS, SYNC_VIEW_CONTAINER_ID } from 'vs/workbench/services/userDataSync/common/userDataSync';
import { IUserDataSyncWorkbenchService, IUserDataSyncAccount, AccountStatus, CONTEXT_SYNC_ENABLEMENT, CONTEXT_SYNC_STATE, CONTEXT_ACCOUNT_STATE, SHOW_SYNC_LOG_COMMAND_ID, getSyncAreaLabel, IUserDataSyncPreview, IUserDataSyncResource, CONTEXT_ENABLE_SYNC_MERGES_VIEW, SYNC_MERGES_VIEW_ID, CONTEXT_ENABLE_ACTIVITY_VIEWS, SYNC_VIEW_CONTAINER_ID } from 'vs/workbench/services/userDataSync/common/userDataSync';
import { AuthenticationSession, AuthenticationSessionsChangeEvent } from 'vs/editor/common/modes';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
@ -79,7 +79,7 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
private readonly syncEnablementContext: IContextKey<boolean>;
private readonly syncStatusContext: IContextKey<string>;
private readonly accountStatusContext: IContextKey<string>;
private readonly manualSyncViewEnablementContext: IContextKey<boolean>;
private readonly mergesViewEnablementContext: IContextKey<boolean>;
private readonly activityViewsEnablementContext: IContextKey<boolean>;
readonly userDataSyncPreview: UserDataSyncPreview = this._register(new UserDataSyncPreview(this.userDataSyncService));
@ -110,7 +110,7 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
this.syncStatusContext = CONTEXT_SYNC_STATE.bindTo(contextKeyService);
this.accountStatusContext = CONTEXT_ACCOUNT_STATE.bindTo(contextKeyService);
this.activityViewsEnablementContext = CONTEXT_ENABLE_ACTIVITY_VIEWS.bindTo(contextKeyService);
this.manualSyncViewEnablementContext = CONTEXT_ENABLE_MANUAL_SYNC_VIEW.bindTo(contextKeyService);
this.mergesViewEnablementContext = CONTEXT_ENABLE_SYNC_MERGES_VIEW.bindTo(contextKeyService);
if (this.authenticationProviders.length) {
@ -302,16 +302,16 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
const result = await this.dialogService.show(
Severity.Info,
localize('preferences sync', "Preferences Sync"),
localize('merge or replace', "Merge or Replace"),
[
localize('merge', "Merge"),
localize('replace local', "Replace Local"),
localize('sync manually', "Sync Manually..."),
localize('merge Manually', "Merge Manually..."),
localize('cancel', "Cancel"),
],
{
cancelId: 3,
detail: localize('first time sync detail', "It looks like you last synced from another machine.\nWould you like to replace or merge with your data in the cloud or sync manually?"),
detail: localize('first time sync detail', "It looks like you last synced from another machine.\nWould you like to merge or replace with your data in the cloud?"),
}
);
switch (result.choice) {
@ -333,18 +333,18 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
const visibleViewContainer = this.viewsService.getVisibleViewContainer(ViewContainerLocation.Sidebar);
this.userDataSyncPreview.setManualSyncPreview(task, preview);
this.manualSyncViewEnablementContext.set(true);
this.mergesViewEnablementContext.set(true);
await this.waitForActiveSyncViews();
await this.viewsService.openView(MANUAL_SYNC_VIEW_ID);
await this.viewsService.openView(SYNC_MERGES_VIEW_ID);
const error = await Event.toPromise(this.userDataSyncPreview.onDidCompleteManualSync);
this.userDataSyncPreview.unsetManualSyncPreview();
this.manualSyncViewEnablementContext.set(false);
this.mergesViewEnablementContext.set(false);
if (visibleViewContainer) {
this.viewsService.openViewContainer(visibleViewContainer.id);
} else {
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(MANUAL_SYNC_VIEW_ID);
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(SYNC_MERGES_VIEW_ID);
this.viewsService.closeViewContainer(viewContainer!.id);
}

View file

@ -82,7 +82,7 @@ export const CONTEXT_SYNC_STATE = new RawContextKey<string>('syncStatus', SyncSt
export const CONTEXT_SYNC_ENABLEMENT = new RawContextKey<boolean>('syncEnabled', false);
export const CONTEXT_ACCOUNT_STATE = new RawContextKey<string>('userDataSyncAccountStatus', AccountStatus.Uninitialized);
export const CONTEXT_ENABLE_ACTIVITY_VIEWS = new RawContextKey<boolean>(`enableSyncActivityViews`, false);
export const CONTEXT_ENABLE_MANUAL_SYNC_VIEW = new RawContextKey<boolean>(`enableManualSyncView`, false);
export const CONTEXT_ENABLE_SYNC_MERGES_VIEW = new RawContextKey<boolean>(`enableSyncMergesView`, false);
// Commands
export const CONFIGURE_SYNC_COMMAND_ID = 'workbench.userDataSync.actions.configure';
@ -90,4 +90,4 @@ export const SHOW_SYNC_LOG_COMMAND_ID = 'workbench.userDataSync.actions.showLog'
// VIEWS
export const SYNC_VIEW_CONTAINER_ID = 'workbench.view.sync';
export const MANUAL_SYNC_VIEW_ID = 'workbench.views.manualSyncView';
export const SYNC_MERGES_VIEW_ID = 'workbench.views.sync.merges';