diff --git a/build/azure-pipelines/upload-sourcemaps.js b/build/azure-pipelines/upload-sourcemaps.js index 190023f40dc..b70335efe5b 100644 --- a/build/azure-pipelines/upload-sourcemaps.js +++ b/build/azure-pipelines/upload-sourcemaps.js @@ -14,9 +14,7 @@ const root = path.dirname(path.dirname(__dirname)); const commit = util.getVersion(root); // optionally allow to pass in explicit base/maps to upload -const args = process.argv.slice(2); -const base = args[0]; -const maps = args[1]; +const [, , base, maps] = process.argv; const fetch = function (base, maps = `${base}/**/*.map`) { return vfs.src(maps, { base }) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index a3483f451e2..3ae1ace01c1 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.35.3", + "version": "1.38.2", "repo": "https://github.com/Microsoft/vscode-node-debug", "metadata": { "id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6", diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index 32b0e6fb4c7..570d97669c7 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -269,6 +269,10 @@ { "name": "vs/workbench/services/preferences", "project": "vscode-preferences" + }, + { + "name": "vs/workbench/services/notification", + "project": "vscode-workbench" } ] } diff --git a/extensions/git/package.json b/extensions/git/package.json index 90064509397..ffa34ca6efb 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1148,6 +1148,20 @@ "description": "%config.enableSmartCommit%", "default": false }, + "git.smartCommitChanges": { + "type": "string", + "enum": [ + "all", + "tracked" + ], + "enumDescriptions": [ + "%config.smartCommitChanges.all%", + "%config.smartCommitChanges.tracked%" + ], + "scope": "resource", + "description": "%config.smartCommitChanges%", + "default": "all" + }, "git.suggestSmartCommit": { "type": "boolean", "scope": "resource", @@ -1171,10 +1185,26 @@ "default": true, "description": "%config.decorations.enabled%" }, - "git.promptToSaveFilesBeforeCommit": { + "git.enableStatusBarSync": { "type": "boolean", - "scope": "resource", "default": true, + "description": "%config.enableStatusBarSync%", + "scope": "resource" + }, + "git.promptToSaveFilesBeforeCommit": { + "type": "string", + "enum": [ + "always", + "staged", + "never" + ], + "enumDescriptions": [ + "%config.promptToSaveFilesBeforeCommit.always%", + "%config.promptToSaveFilesBeforeCommit.staged%", + "%config.promptToSaveFilesBeforeCommit.never%" + ], + "scope": "resource", + "default": "always", "description": "%config.promptToSaveFilesBeforeCommit%" }, "git.postCommitCommand": { diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 4d8bccf4e0b..367544c6cc3 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -89,11 +89,18 @@ "config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository.", "config.defaultCloneDirectory": "The default location to clone a git repository.", "config.enableSmartCommit": "Commit all changes when there are no staged changes.", + "config.smartCommitChanges": "Control which changes are automatically staged by Smart Commit.", + "config.smartCommitChanges.all": "Automatically stage all changes.", + "config.smartCommitChanges.tracked": "Automatically staged tracked changes only.", "config.suggestSmartCommit": "Suggests to enable smart commit (commit all changes when there are no staged changes).", "config.enableCommitSigning": "Enables commit signing with GPG.", "config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.", "config.decorations.enabled": "Controls whether Git contributes colors and badges to the explorer and the open editors view.", + "config.enableStatusBarSync": "Controls whether the Git Sync command appears in the status bar.", "config.promptToSaveFilesBeforeCommit": "Controls whether Git should check for unsaved files before committing.", + "config.promptToSaveFilesBeforeCommit.always": "Check for any unsaved files.", + "config.promptToSaveFilesBeforeCommit.staged": "Check only for unsaved staged files.", + "config.promptToSaveFilesBeforeCommit.never": "Disable this check.", "config.postCommitCommand": "Runs a git command after a successful commit.", "config.postCommitCommand.none": "Don't run any command after a commit.", "config.postCommitCommand.push": "Run 'Git Push' after a successful commit.", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 0977442e527..c8575ab880e 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1233,24 +1233,35 @@ export class CommandCenter { opts?: CommitOptions ): Promise { const config = workspace.getConfiguration('git', Uri.file(repository.root)); - const promptToSaveFilesBeforeCommit = config.get('promptToSaveFilesBeforeCommit') === true; + let promptToSaveFilesBeforeCommit = config.get<'always' | 'staged' | 'never'>('promptToSaveFilesBeforeCommit'); - if (promptToSaveFilesBeforeCommit) { - const unsavedTextDocuments = workspace.textDocuments + // migration + if (promptToSaveFilesBeforeCommit as any === true) { + promptToSaveFilesBeforeCommit = 'always'; + } else if (promptToSaveFilesBeforeCommit as any === false) { + promptToSaveFilesBeforeCommit = 'never'; + } + + if (promptToSaveFilesBeforeCommit !== 'never') { + let documents = workspace.textDocuments .filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath)); - if (unsavedTextDocuments.length > 0) { - const message = unsavedTextDocuments.length === 1 - ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(unsavedTextDocuments[0].uri.fsPath)) - : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", unsavedTextDocuments.length); + if (promptToSaveFilesBeforeCommit === 'staged') { + documents = documents + .filter(d => repository.indexGroup.resourceStates.some(s => s.resourceUri.path === d.uri.fsPath)); + } + + if (documents.length > 0) { + const message = documents.length === 1 + ? localize('unsaved files single', "The following file is unsaved and will not be included in the commit if you proceed: {0}.\n\nWould you like to save it before committing?", path.basename(documents[0].uri.fsPath)) + : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", documents.length); const saveAndCommit = localize('save and commit', "Save All & Commit"); const commit = localize('commit', "Commit Anyway"); const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit); if (pick === saveAndCommit) { - await Promise.all(unsavedTextDocuments.map(d => d.save())); - await repository.add(unsavedTextDocuments.map(d => d.uri)); - await repository.status(); + await Promise.all(documents.map(d => d.save())); + await repository.add(documents.map(d => d.uri)); } else if (pick !== commit) { return false; // do not commit on cancel } @@ -1264,8 +1275,8 @@ export class CommandCenter { // no changes, and the user has not configured to commit all in this case if (!noUnstagedChanges && noStagedChanges && !enableSmartCommit) { - const suggestSmartCommit = config.get('suggestSmartCommit') === true; + if (!suggestSmartCommit) { return false; } @@ -1319,6 +1330,10 @@ export class CommandCenter { return false; } + if (opts.all && config.get<'all' | 'tracked'>('smartCommitChanges') === 'tracked') { + opts.all = 'tracked'; + } + await repository.commit(message, opts); const postCommitCommand = config.get<'none' | 'push' | 'sync'>('postCommitCommand'); diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index b306cab1255..701ceded1c9 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -601,13 +601,13 @@ export function parseGitmodules(raw: string): Submodule[] { } export function parseGitCommit(raw: string): Commit | null { - const match = /^([0-9a-f]{40})\n(.*)\n(.*)\n([^]*)$/m.exec(raw.trim()); + const match = /^([0-9a-f]{40})\n(.*)\n(.*)(\n([^]*))?$/m.exec(raw.trim()); if (!match) { return null; } const parents = match[3] ? match[3].split(' ') : []; - return { hash: match[1], message: match[4], parents, authorEmail: match[2] }; + return { hash: match[1], message: match[5], parents, authorEmail: match[2] }; } interface LsTreeElement { @@ -642,7 +642,7 @@ export function parseLsFiles(raw: string): LsFilesElement[] { } export interface CommitOptions { - all?: boolean; + all?: boolean | 'tracked'; amend?: boolean; signoff?: boolean; signCommit?: boolean; @@ -1081,8 +1081,16 @@ export class Repository { return result.stdout.trim(); } - async add(paths: string[]): Promise { - const args = ['add', '-A', '--']; + async add(paths: string[], opts?: { update?: boolean }): Promise { + const args = ['add']; + + if (opts && opts.update) { + args.push('-u'); + } else { + args.push('-A'); + } + + args.push('--'); if (paths && paths.length) { args.push.apply(args, paths); @@ -1746,7 +1754,7 @@ export class Repository { } const raw = await readfile(templatePath, 'utf8'); - return raw.replace(/^\s*#.*$\n?/gm, '').trim(); + return raw.replace(/\n?#.*/g, ''); } catch (err) { return ''; diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index a4b37bebd5e..40b31dff923 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -679,12 +679,15 @@ export class Repository implements Disposable { const root = Uri.file(repository.root); this._sourceControl = scm.createSourceControl('git', 'Git', root); - this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message (press {0} to commit)"); + this._sourceControl.acceptInputCommand = { command: 'git.commit', title: localize('commit', "Commit"), arguments: [this._sourceControl] }; this._sourceControl.quickDiffProvider = this; this._sourceControl.inputBox.validateInput = this.validateInput.bind(this); this.disposables.push(this._sourceControl); + this.updateInputBoxPlaceholder(); + this.disposables.push(this.onDidRunGitStatus(() => this.updateInputBoxPlaceholder())); + this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "MERGE CHANGES")); this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "STAGED CHANGES")); this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "CHANGES")); @@ -910,7 +913,8 @@ export class Repository implements Disposable { if (this.rebaseCommit) { await this.run(Operation.RebaseContinue, async () => { if (opts.all) { - await this.repository.add([]); + const addOpts = opts.all === 'tracked' ? { update: true } : {}; + await this.repository.add([], addOpts); } await this.repository.rebaseContinue(); @@ -918,9 +922,11 @@ export class Repository implements Disposable { } else { await this.run(Operation.Commit, async () => { if (opts.all) { - await this.repository.add([]); + const addOpts = opts.all === 'tracked' ? { update: true } : {}; + await this.repository.add([], addOpts); } + delete opts.all; await this.repository.commit(message, opts); }); } @@ -1646,6 +1652,21 @@ export class Repository implements Disposable { return `${this.HEAD.behind}↓ ${this.HEAD.ahead}↑`; } + private updateInputBoxPlaceholder(): void { + const HEAD = this.HEAD; + + if (HEAD) { + const tag = this.refs.filter(iref => iref.type === RefType.Tag && iref.commit === HEAD.commit)[0]; + const tagName = tag && tag.name; + const head = HEAD.name || tagName || (HEAD.commit || '').substr(0, 8); + + // '{0}' will be replaced by the corresponding key-command later in the process, which is why it needs to stay. + this._sourceControl.inputBox.placeholder = localize('commitMessageWithHeadLabel', "Message ({0} to commit on '{1}')", "{0}", head); + } else { + this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message ({0} to commit)"); + } + } + dispose(): void { this.disposables = dispose(this.disposables); } diff --git a/extensions/git/src/statusbar.ts b/extensions/git/src/statusbar.ts index cc007172d5f..fb89aca7264 100644 --- a/extensions/git/src/statusbar.ts +++ b/extensions/git/src/statusbar.ts @@ -5,7 +5,7 @@ import { Disposable, Command, EventEmitter, Event, workspace, Uri } from 'vscode'; import { Repository, Operation } from './repository'; -import { anyEvent, dispose } from './util'; +import { anyEvent, dispose, filterEvent } from './util'; import * as nls from 'vscode-nls'; import { Branch } from './api/git'; @@ -27,7 +27,7 @@ class CheckoutStatusBar { return { command: 'git.checkout', - tooltip: localize('checkout', 'Checkout...'), + tooltip: `${this.repository.headLabel}`, title, arguments: [this.repository.sourceControl] }; @@ -39,6 +39,7 @@ class CheckoutStatusBar { } interface SyncStatusBarState { + enabled: boolean; isSyncRunning: boolean; hasRemotes: boolean; HEAD: Branch | undefined; @@ -47,6 +48,7 @@ interface SyncStatusBarState { class SyncStatusBar { private static StartState: SyncStatusBarState = { + enabled: true, isSyncRunning: false, hasRemotes: false, HEAD: undefined @@ -66,9 +68,20 @@ class SyncStatusBar { constructor(private repository: Repository) { repository.onDidRunGitStatus(this.onModelChange, this, this.disposables); repository.onDidChangeOperations(this.onOperationsChange, this, this.disposables); + + const onEnablementChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.enableStatusBarSync')); + onEnablementChange(this.updateEnablement, this, this.disposables); + this._onDidChange.fire(); } + private updateEnablement(): void { + const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); + const enabled = config.get('enableStatusBarSync', true); + + this.state = { ... this.state, enabled }; + } + private onOperationsChange(): void { const isSyncRunning = this.repository.operations.isRunning(Operation.Sync) || this.repository.operations.isRunning(Operation.Push) || @@ -86,7 +99,7 @@ class SyncStatusBar { } get command(): Command | undefined { - if (!this.state.hasRemotes) { + if (!this.state.enabled || !this.state.hasRemotes) { return undefined; } diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index 5291e7ab716..0905e90acb1 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -337,14 +337,15 @@ suite('window namespace tests', () => { }); terminal.dispose(); }); - overrideDimensionsEmitter.fire({ columns: 10, rows: 5 }); }); const writeEmitter = new EventEmitter(); const overrideDimensionsEmitter = new EventEmitter(); const pty: Pseudoterminal = { onDidWrite: writeEmitter.event, onDidOverrideDimensions: overrideDimensionsEmitter.event, - open: () => {}, + open: () => { + overrideDimensionsEmitter.fire({ columns: 10, rows: 5 }); + }, close: () => {} }; const terminal = window.createTerminal({ name: 'foo', pty }); diff --git a/src/vs/base/browser/ui/inputbox/inputBox.css b/src/vs/base/browser/ui/inputbox/inputBox.css index 294ca475662..dc1240dfbc5 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.css +++ b/src/vs/base/browser/ui/inputbox/inputBox.css @@ -58,7 +58,12 @@ .monaco-inputbox > .wrapper > textarea.input { display: block; - overflow: hidden; + -ms-overflow-style: none; /* IE 10+ */ + overflow: -moz-scrollbars-none; /* Firefox */ +} + +.monaco-inputbox > .wrapper > textarea.input::-webkit-scrollbar { + display: none; } .monaco-inputbox > .wrapper > .mirror { @@ -116,4 +121,4 @@ background-repeat: no-repeat; width: 16px; height: 16px; -} \ No newline at end of file +} diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index d92ae6e2dae..59d0c9900b9 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -19,6 +19,9 @@ import { Color } from 'vs/base/common/color'; import { mixin } from 'vs/base/common/objects'; import { HistoryNavigator } from 'vs/base/common/history'; import { IHistoryNavigationWidget } from 'vs/base/browser/history'; +import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; +import { ScrollbarVisibility } from 'vs/base/common/scrollable'; +import { domEvent } from 'vs/base/browser/event'; const $ = dom.$; @@ -28,6 +31,7 @@ export interface IInputOptions extends IInputBoxStyles { readonly type?: string; readonly validationOptions?: IInputValidationOptions; readonly flexibleHeight?: boolean; + readonly flexibleMaxHeight?: number; readonly actions?: ReadonlyArray; } @@ -86,7 +90,6 @@ export class InputBox extends Widget { private contextViewProvider?: IContextViewProvider; element: HTMLElement; private input: HTMLInputElement; - private mirror: HTMLElement | undefined; private actionbar?: ActionBar; private options: IInputOptions; private message: IMessage | null; @@ -94,7 +97,12 @@ export class InputBox extends Widget { private ariaLabel: string; private validation?: IInputValidator; private state: 'idle' | 'open' | 'closed' = 'idle'; - private cachedHeight: number | null; + + private mirror: HTMLElement | undefined; + private cachedHeight: number | undefined; + private cachedContentHeight: number | undefined; + private maxHeight: number = Number.POSITIVE_INFINITY; + private scrollableElement: ScrollableElement | undefined; private inputBackground?: Color; private inputForeground?: Color; @@ -123,7 +131,6 @@ export class InputBox extends Widget { this.options = options || Object.create(null); mixin(this.options, defaultOpts, false); this.message = null; - this.cachedHeight = null; this.placeholder = this.options.placeholder || ''; this.ariaLabel = this.options.ariaLabel || ''; @@ -159,8 +166,26 @@ export class InputBox extends Widget { this.onblur(this.input, () => dom.removeClass(this.element, 'synthetic-focus')); if (this.options.flexibleHeight) { + this.maxHeight = typeof this.options.flexibleMaxHeight === 'number' ? this.options.flexibleMaxHeight : Number.POSITIVE_INFINITY; + this.mirror = dom.append(wrapper, $('div.mirror')); this.mirror.innerHTML = ' '; + + this.scrollableElement = new ScrollableElement(this.element, { vertical: ScrollbarVisibility.Auto }); + dom.append(container, this.scrollableElement.getDomNode()); + this._register(this.scrollableElement); + + // from ScrollableElement to DOM + this._register(this.scrollableElement.onScroll(e => this.input.scrollTop = e.scrollTop)); + + const onSelectionChange = Event.filter(domEvent(document, 'selectionchange'), () => { + const selection = document.getSelection(); + return !!selection && selection.anchorNode === wrapper; + }); + + // from DOM to ScrollableElement + this._register(onSelectionChange(this.updateScrollDimensions, this)); + this._register(this.onDidHeightChange(this.updateScrollDimensions, this)); } else { this.input.type = this.options.type || 'text'; this.input.setAttribute('wrap', 'off'); @@ -250,7 +275,7 @@ export class InputBox extends Widget { } public get height(): number { - return this.cachedHeight === null ? dom.getTotalHeight(this.element) : this.cachedHeight; + return typeof this.cachedHeight === 'number' ? this.cachedHeight : dom.getTotalHeight(this.element); } public focus(): void { @@ -301,6 +326,19 @@ export class InputBox extends Widget { } } + private updateScrollDimensions(): void { + if (typeof this.cachedContentHeight !== 'number' || typeof this.cachedHeight !== 'number') { + return; + } + + const scrollHeight = this.cachedContentHeight; + const height = this.cachedHeight; + const scrollTop = this.input.scrollTop; + + this.scrollableElement!.setScrollDimensions({ scrollHeight, height }); + this.scrollableElement!.setScrollPosition({ scrollTop }); + } + public showMessage(message: IMessage, force?: boolean): void { this.message = message; @@ -510,12 +548,13 @@ export class InputBox extends Widget { return; } - const previousHeight = this.cachedHeight; - this.cachedHeight = dom.getTotalHeight(this.mirror); + const previousHeight = this.cachedContentHeight; + this.cachedContentHeight = dom.getTotalHeight(this.mirror); - if (previousHeight !== this.cachedHeight) { + if (previousHeight !== this.cachedContentHeight) { + this.cachedHeight = Math.min(this.cachedContentHeight, this.maxHeight); this.input.style.height = this.cachedHeight + 'px'; - this._onDidHeightChange.fire(this.cachedHeight); + this._onDidHeightChange.fire(this.cachedContentHeight); } } diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 7ff1b4a5d31..38d27f4d44b 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -2200,7 +2200,7 @@ export class InternalEditorOptionsFactory { stopRenderingLineAfter: opts.viewInfo.stopRenderingLineAfter, renderWhitespace: (accessibilityIsOn ? 'none' : opts.viewInfo.renderWhitespace), // DISABLED WHEN SCREEN READER IS ATTACHED renderControlCharacters: (accessibilityIsOn ? false : opts.viewInfo.renderControlCharacters), // DISABLED WHEN SCREEN READER IS ATTACHED - fontLigatures: (accessibilityIsOn ? false : opts.viewInfo.fontLigatures), // DISABLED WHEN SCREEN READER IS ATTACHED + fontLigatures: opts.viewInfo.fontLigatures, renderIndentGuides: (accessibilityIsOn ? false : opts.viewInfo.renderIndentGuides), // DISABLED WHEN SCREEN READER IS ATTACHED highlightActiveIndentGuide: opts.viewInfo.highlightActiveIndentGuide, renderLineHighlight: opts.viewInfo.renderLineHighlight, diff --git a/src/vs/editor/contrib/suggest/media/suggest.css b/src/vs/editor/contrib/suggest/media/suggest.css index 09594abb493..1fc61b27488 100644 --- a/src/vs/editor/contrib/suggest/media/suggest.css +++ b/src/vs/editor/contrib/suggest/media/suggest.css @@ -110,7 +110,9 @@ .monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .header > .close { background-image: url('./close-light.svg'); - float: right; + position: absolute; + top: 0px; + right: 0px; margin-right: 5px; } @@ -251,7 +253,7 @@ text-overflow: ellipsis; opacity: 0.7; word-break: break-all; - margin: 0; + margin: 0px 24px 0 0; padding: 4px 0 12px 5px; } diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 6817d5c8f51..e0ac791724b 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -440,7 +440,6 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate; private readonly suggestWidgetMultipleSuggestions: IContextKey; - private readonly editorBlurTimeout = new TimeoutTimer(); private readonly showTimeout = new TimeoutTimer(); private readonly toDispose = new DisposableStore(); @@ -962,12 +961,14 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate this.logService.error(err)); + if (updateMode === 'start') { + this.logService.info('update#ctor - startup checks only; automatic updates are disabled by user preference'); + + // Check for updates only once after 30 seconds + setTimeout(() => this.checkForUpdates(null), 30 * 1000); + } else { + // Start checking for updates after 30 seconds + this.scheduleCheckForUpdates(30 * 1000).then(undefined, err => this.logService.error(err)); + } } private getProductQuality(updateMode: string): string | undefined { diff --git a/src/vs/platform/update/node/update.config.contribution.ts b/src/vs/platform/update/node/update.config.contribution.ts index b6ef43b29fa..fe7b3cba8b2 100644 --- a/src/vs/platform/update/node/update.config.contribution.ts +++ b/src/vs/platform/update/node/update.config.contribution.ts @@ -17,7 +17,7 @@ configurationRegistry.registerConfiguration({ properties: { 'update.mode': { type: 'string', - enum: ['none', 'manual', 'default'], + enum: ['none', 'manual', 'start', 'default'], default: 'default', scope: ConfigurationScope.APPLICATION, description: localize('updateMode', "Configure whether you receive automatic updates. Requires a restart after change. The updates are fetched from a Microsoft online service."), @@ -25,6 +25,7 @@ configurationRegistry.registerConfiguration({ enumDescriptions: [ localize('none', "Disable updates."), localize('manual', "Disable automatic background update checks. Updates will be available if you manually check for updates."), + localize('start', "Check for updates only on startup. Disable automatic background update checks."), localize('default', "Enable automatic update checks. Code will check for updates automatically and periodically.") ] }, diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index f1d27d99781..e32decd5177 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -22,7 +22,6 @@ import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDeb import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; -import { IDisposable } from 'vs/base/common/lifecycle'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; @@ -692,9 +691,6 @@ class ApiRequest { } class ExtHostPseudoterminal implements ITerminalChildProcess { - private _queuedEvents: (IQueuedEvent | IQueuedEvent | IQueuedEvent<{ pid: number, cwd: string }> | IQueuedEvent)[] = []; - private _queueDisposables: IDisposable[] | undefined; - private readonly _onProcessData = new Emitter(); public readonly onProcessData: Event = this._onProcessData.event; private readonly _onProcessExit = new Emitter(); @@ -706,18 +702,7 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { private readonly _onProcessOverrideDimensions = new Emitter(); public get onProcessOverrideDimensions(): Event { return this._onProcessOverrideDimensions.event; } - constructor( - private readonly _pty: vscode.Pseudoterminal - ) { - this._queueDisposables = []; - this._queueDisposables.push(this._pty.onDidWrite(e => this._queuedEvents.push({ emitter: this._onProcessData, data: e }))); - if (this._pty.onDidClose) { - this._queueDisposables.push(this._pty.onDidClose(e => this._queuedEvents.push({ emitter: this._onProcessExit, data: 0 }))); - } - if (this._pty.onDidOverrideDimensions) { - this._queueDisposables.push(this._pty.onDidOverrideDimensions(e => this._queuedEvents.push({ emitter: this._onProcessOverrideDimensions, data: e ? { cols: e.columns, rows: e.rows } : undefined }))); - } - } + constructor(private readonly _pty: vscode.Pseudoterminal) { } shutdown(): void { this._pty.close(); @@ -748,12 +733,7 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { } startSendingEvents(initialDimensions: ITerminalDimensionsDto | undefined): void { - // Flush all buffered events - this._queuedEvents.forEach(e => (e.emitter.fire)(e.data)); - this._queuedEvents = []; - this._queueDisposables = undefined; - - // Attach the real listeners + // Attach the listeners this._pty.onDidWrite(e => this._onProcessData.fire(e)); if (this._pty.onDidClose) { this._pty.onDidClose(e => this._onProcessExit.fire(0)); @@ -766,7 +746,3 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { } } -interface IQueuedEvent { - emitter: Emitter; - data: T; -} diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 08fbdd94d74..d928b4a6c6c 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -35,6 +35,7 @@ import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService'; import { IFileService } from 'vs/platform/files/common/files'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { coalesce } from 'vs/base/common/arrays'; enum Settings { MENUBAR_VISIBLE = 'window.menuBarVisibility', @@ -45,7 +46,6 @@ enum Settings { PANEL_POSITION = 'workbench.panel.defaultLocation', ZEN_MODE_RESTORE = 'zenMode.restore', - } enum Storage { @@ -65,6 +65,14 @@ enum Storage { GRID_HEIGHT = 'workbench.grid.height' } +enum Classes { + SIDEBAR_HIDDEN = 'nosidebar', + EDITOR_HIDDEN = 'noeditorarea', + PANEL_HIDDEN = 'nopanel', + STATUSBAR_HIDDEN = 'nostatusbar', + FULLSCREEN = 'fullscreen' +} + export abstract class Layout extends Disposable implements IWorkbenchLayoutService { _serviceBrand!: ServiceIdentifier; @@ -252,9 +260,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Apply as CSS class if (this.state.fullscreen) { - addClass(this.container, 'fullscreen'); + addClass(this.container, Classes.FULLSCREEN); } else { - removeClass(this.container, 'fullscreen'); + removeClass(this.container, Classes.FULLSCREEN); if (this.state.zenMode.transitionedToFullScreen && this.state.zenMode.active) { this.toggleZenMode(); @@ -703,9 +711,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Adjust CSS if (hidden) { - addClass(this.container, 'nostatusbar'); + addClass(this.container, Classes.STATUSBAR_HIDDEN); } else { - removeClass(this.container, 'nostatusbar'); + removeClass(this.container, Classes.STATUSBAR_HIDDEN); } // Propagate to grid @@ -935,6 +943,13 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.state.editor.hidden = hidden; + // Adjust CSS + if (hidden) { + addClass(this.container, Classes.EDITOR_HIDDEN); + } else { + removeClass(this.container, Classes.EDITOR_HIDDEN); + } + // Propagate to grid this.workbenchGrid.setViewVisible(this.editorPartView, !hidden); @@ -944,14 +959,24 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } } + getLayoutClasses(): string[] { + return coalesce([ + this.state.sideBar.hidden ? Classes.SIDEBAR_HIDDEN : undefined, + this.state.editor.hidden ? Classes.EDITOR_HIDDEN : undefined, + this.state.panel.hidden ? Classes.PANEL_HIDDEN : undefined, + this.state.statusBar.hidden ? Classes.STATUSBAR_HIDDEN : undefined, + this.state.fullscreen ? Classes.FULLSCREEN : undefined + ]); + } + setSideBarHidden(hidden: boolean, skipLayout?: boolean): void { this.state.sideBar.hidden = hidden; // Adjust CSS if (hidden) { - addClass(this.container, 'nosidebar'); + addClass(this.container, Classes.SIDEBAR_HIDDEN); } else { - removeClass(this.container, 'nosidebar'); + removeClass(this.container, Classes.SIDEBAR_HIDDEN); } // If sidebar becomes hidden, also hide the current active Viewlet if any @@ -1004,9 +1029,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Adjust CSS if (hidden) { - addClass(this.container, 'nopanel'); + addClass(this.container, Classes.PANEL_HIDDEN); } else { - removeClass(this.container, 'nopanel'); + removeClass(this.container, Classes.PANEL_HIDDEN); } // If panel part becomes hidden, also hide the current active panel if any diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 1408ae24e0e..f36234ec441 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -118,7 +118,9 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito isEmpty(): boolean; setActive(isActive: boolean): void; - setLabel(label: string): void; + + notifyIndexChanged(newIndex: number): void; + relayout(): void; } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 54be65b6f03..6f575845305 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -54,16 +54,16 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#region factory - static createNew(accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView { - return instantiationService.createInstance(EditorGroupView, accessor, null, label); + static createNew(accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView { + return instantiationService.createInstance(EditorGroupView, accessor, null, index); } - static createFromSerialized(serialized: ISerializedEditorGroup, accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView { - return instantiationService.createInstance(EditorGroupView, accessor, serialized, label); + static createFromSerialized(serialized: ISerializedEditorGroup, accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView { + return instantiationService.createInstance(EditorGroupView, accessor, serialized, index); } - static createCopy(copyFrom: IEditorGroupView, accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView { - return instantiationService.createInstance(EditorGroupView, accessor, copyFrom, label); + static createCopy(copyFrom: IEditorGroupView, accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView { + return instantiationService.createInstance(EditorGroupView, accessor, copyFrom, index); } //#endregion @@ -119,7 +119,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { constructor( private accessor: IEditorGroupsAccessor, from: IEditorGroupView | ISerializedEditorGroup, - private _label: string, + private _index: number, @IInstantiationService private readonly instantiationService: IInstantiationService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService, @@ -656,8 +656,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this._group; } + get index(): number { + return this._index; + } + get label(): string { - return this._label; + return localize('groupLabel', "Group {0}", this._index + 1); } get disposed(): boolean { @@ -668,10 +672,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this._whenRestored; } - setLabel(label: string): void { - if (this._label !== label) { - this._label = label; - this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_LABEL }); + notifyIndexChanged(newIndex: number): void { + if (this._index !== newIndex) { + this._index = newIndex; + this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_INDEX }); } } diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 0d0ac0c7231..f4b7ce43846 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -24,7 +24,6 @@ import { assign } from 'vs/base/common/objects'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup'; import { EditorDropTarget } from 'vs/workbench/browser/parts/editor/editorDropTarget'; -import { localize } from 'vs/nls'; import { Color } from 'vs/base/common/color'; import { CenteredViewLayout } from 'vs/base/browser/ui/centered/centeredViewLayout'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -424,8 +423,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } }); - // Update labels - this.updateGroupLabels(); + // Notify group index change given layout has changed + this.notifyGroupIndexChange(); // Restore focus as needed if (restoreFocus) { @@ -484,25 +483,22 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro // Event this._onDidAddGroup.fire(newGroupView); - // Update labels - this.updateGroupLabels(); + // Notify group index change given a new group was added + this.notifyGroupIndexChange(); return newGroupView; } private doCreateGroupView(from?: IEditorGroupView | ISerializedEditorGroup | null): IEditorGroupView { - // Label: just use the number of existing groups as label - const label = this.getGroupLabel(this.count + 1); - // Create group view let groupView: IEditorGroupView; if (from instanceof EditorGroupView) { - groupView = EditorGroupView.createCopy(from, this, label, this.instantiationService); + groupView = EditorGroupView.createCopy(from, this, this.count, this.instantiationService); } else if (isSerializedEditorGroup(from)) { - groupView = EditorGroupView.createFromSerialized(from, this, label, this.instantiationService); + groupView = EditorGroupView.createFromSerialized(from, this, this.count, this.instantiationService); } else { - groupView = EditorGroupView.createNew(this, label, this.instantiationService); + groupView = EditorGroupView.createNew(this, this.count, this.instantiationService); } // Keep in map @@ -643,8 +639,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro this._activeGroup.focus(); } - // Update labels - this.updateGroupLabels(); + // Notify group index change given a group was removed + this.notifyGroupIndexChange(); // Update container this.updateContainer(); @@ -675,6 +671,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro // Event this._onDidMoveGroup.fire(sourceView); + // Notify group index change given a group was moved + this.notifyGroupIndexChange(); + return sourceView; } @@ -784,6 +783,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro centerLayout(active: boolean): void { this.centeredLayoutWidget.activate(active); + this._activeGroup.focus(); } @@ -909,19 +909,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro toggleClass(this.container, 'empty', this.isEmpty()); } - private updateGroupLabels(): void { - - // Since our labels are created using the index of the - // group, adding/removing a group might produce gaps. - // So we iterate over all groups and reassign the label - // based on the index. - this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => { - group.setLabel(this.getGroupLabel(index + 1)); - }); - } - - private getGroupLabel(index: number): string { - return localize('groupLabel', "Group {0}", index); + private notifyGroupIndexChange(): void { + this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => group.notifyIndexChanged(index)); } private isEmpty(): boolean { diff --git a/src/vs/workbench/browser/parts/panel/media/panelpart.css b/src/vs/workbench/browser/parts/panel/media/panelpart.css index 4839f8b0831..fb9a8f4bf2f 100644 --- a/src/vs/workbench/browser/parts/panel/media/panelpart.css +++ b/src/vs/workbench/browser/parts/panel/media/panelpart.css @@ -25,11 +25,19 @@ border-top-style: solid; } +.monaco-workbench.noeditorarea .part.panel.bottom .title { + border-top-width: 0; /* no border when editor area is hiden */ +} + .monaco-workbench .part.panel.right { border-left-width: 1px; border-left-style: solid; } +.monaco-workbench.noeditorarea .part.panel.right { + border-left-width: 0; /* no border when editor area is hiden */ +} + .monaco-workbench .part.panel > .title > .title-actions .monaco-action-bar .action-item .action-label { outline-offset: -2px; } @@ -181,4 +189,4 @@ .hc-black .monaco-workbench .panel.right .minimize-panel-action { background-image: url('chevron-right-hc.svg'); -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 61974d274ad..f60961dbdff 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -22,7 +22,6 @@ import { IRecentlyOpened, IRecent, isRecentFile, isRecentFolder } from 'vs/platf import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { ITunnelService } from 'vs/platform/remote/common/tunnel'; -import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug'; // tslint:disable-next-line: import-patterns import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; @@ -30,13 +29,11 @@ import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/co import { pathsToEditors } from 'vs/workbench/common/editor'; import { IFileService } from 'vs/platform/files/common/files'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ParsedArgs, IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { toStoreData, restoreRecentlyOpened } from 'vs/platform/history/common/historyStorage'; -import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; // tslint:disable-next-line: import-patterns import { IExperimentService, IExperiment, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; -import { ExtensionHostDebugChannelClient, ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; //#region Extension Tips @@ -504,41 +501,6 @@ registerSingleton(IWindowService, SimpleWindowService); //#endregion -//#region ExtensionHostDebugService - -export class SimpleExtensionHostDebugService extends ExtensionHostDebugChannelClient { - - constructor( - @IRemoteAgentService remoteAgentService: IRemoteAgentService, - //@IWindowService windowService: IWindowService, - @IEnvironmentService environmentService: IEnvironmentService - ) { - const connection = remoteAgentService.getConnection(); - - if (!connection) { - throw new Error('Missing agent connection'); - } - - super(connection.getChannel(ExtensionHostDebugBroadcastChannel.ChannelName)); - - this._register(this.onReload(event => { - if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { - //windowService.reloadWindow(); - window.location.reload(); - } - })); - this._register(this.onClose(event => { - if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { - //this._windowService.closeWindow(); - window.close(); - } - })); - } -} -registerSingleton(IExtensionHostDebugService, SimpleExtensionHostDebugService); - -//#endregion - //#region Window export class SimpleWindowsService implements IWindowsService { diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 336f7d97e97..014e2cb0686 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -298,10 +298,7 @@ export class Workbench extends Layout { 'monaco-workbench', platformClass, isWeb ? 'web' : undefined, - this.state.sideBar.hidden ? 'nosidebar' : undefined, - this.state.panel.hidden ? 'nopanel' : undefined, - this.state.statusBar.hidden ? 'nostatusbar' : undefined, - this.state.fullscreen ? 'fullscreen' : undefined + ...this.getLayoutClasses() ]); addClasses(this.container, ...workbenchClasses); diff --git a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts index 17369ff0b6c..551c3e4b86a 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts @@ -11,7 +11,6 @@ import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; /** * Shows a message when opening a large file which has been memory optimized (and features disabled). @@ -20,26 +19,19 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC private static readonly ID = 'editor.contrib.largeFileOptimizationsWarner'; - private _isDisabled: boolean; - constructor( private readonly _editor: ICodeEditor, @INotificationService private readonly _notificationService: INotificationService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IStorageService private readonly _storageService: IStorageService, ) { super(); - this._isDisabled = Boolean(this._storageService.getBoolean('editor.neverPromptForLargeFiles', StorageScope.GLOBAL, false)); this._register(this._editor.onDidChangeModel((e) => { const model = this._editor.getModel(); if (!model) { return; } - if (this._isDisabled) { - return; - } if (model.isTooLargeForTokenization()) { const message = nls.localize( @@ -54,13 +46,6 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC ); this._notificationService.prompt(Severity.Info, message, [ - { - label: nls.localize('dontShowAgain', "Don't Show Again"), - run: () => { - this._isDisabled = true; - this._storageService.store('editor.neverPromptForLargeFiles', true, StorageScope.GLOBAL); - } - }, { label: nls.localize('removeOptimizations', "Forcefully enable features"), run: () => { @@ -71,7 +56,7 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC }); } } - ]); + ], { neverShowAgain: { id: 'editor.contrib.largeFileOptimizationsWarner' } }); } })); } diff --git a/src/vs/workbench/contrib/debug/browser/debugHelperService.ts b/src/vs/workbench/contrib/debug/browser/debugHelperService.ts deleted file mode 100644 index a0616866a48..00000000000 --- a/src/vs/workbench/contrib/debug/browser/debugHelperService.ts +++ /dev/null @@ -1,21 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; -import { IDebugHelperService } from 'vs/workbench/contrib/debug/common/debug'; -import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; - -export class BrowserDebugHelperService implements IDebugHelperService { - - _serviceBrand!: ServiceIdentifier; - - createTelemetryService(configurationService: IConfigurationService, args: string[]): TelemetryService | undefined { - return undefined; - } -} - -registerSingleton(IDebugHelperService, BrowserDebugHelperService); diff --git a/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts b/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts new file mode 100644 index 00000000000..3f5b703c4ce --- /dev/null +++ b/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts @@ -0,0 +1,57 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ExtensionHostDebugChannelClient, ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc'; +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug'; +import { IDebugHelperService } from 'vs/workbench/contrib/debug/common/debug'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; + +class BrowserExtensionHostDebugService extends ExtensionHostDebugChannelClient { + + constructor( + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + //@IWindowService windowService: IWindowService, + @IEnvironmentService environmentService: IEnvironmentService + ) { + const connection = remoteAgentService.getConnection(); + + if (!connection) { + throw new Error('Missing agent connection'); + } + + super(connection.getChannel(ExtensionHostDebugBroadcastChannel.ChannelName)); + + this._register(this.onReload(event => { + if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { + //windowService.reloadWindow(); + window.location.reload(); + } + })); + this._register(this.onClose(event => { + if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { + //this._windowService.closeWindow(); + window.close(); + } + })); + } +} + +registerSingleton(IExtensionHostDebugService, BrowserExtensionHostDebugService); + +class BrowserDebugHelperService implements IDebugHelperService { + + _serviceBrand!: ServiceIdentifier; + + createTelemetryService(configurationService: IConfigurationService, args: string[]): TelemetryService | undefined { + return undefined; + } +} + +registerSingleton(IDebugHelperService, BrowserDebugHelperService); diff --git a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts index 8b29304e715..40a0ec28bf2 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts @@ -5,7 +5,7 @@ import * as nls from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; -import { ToggleAutoSaveAction, GlobalNewUntitledFileAction, ShowOpenedFileInNewWindow, FocusFilesExplorer, GlobalCompareResourcesAction, SaveAllAction, ShowActiveFileInExplorer, CollapseExplorerView, RefreshExplorerView, CompareWithClipboardAction, NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, TRIGGER_RENAME_LABEL, MOVE_FILE_TO_TRASH_LABEL, COPY_FILE_LABEL, PASTE_FILE_LABEL, FileCopiedContext, renameHandler, moveFileToTrashHandler, copyFileHandler, pasteFileHandler, deleteFileHandler, cutFileHandler, DOWNLOAD_COMMAND_ID } from 'vs/workbench/contrib/files/browser/fileActions'; +import { ToggleAutoSaveAction, GlobalNewUntitledFileAction, ShowOpenedFileInNewWindow, FocusFilesExplorer, GlobalCompareResourcesAction, SaveAllAction, ShowActiveFileInExplorer, CollapseExplorerView, RefreshExplorerView, CompareWithClipboardAction, NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, TRIGGER_RENAME_LABEL, MOVE_FILE_TO_TRASH_LABEL, COPY_FILE_LABEL, PASTE_FILE_LABEL, FileCopiedContext, renameHandler, moveFileToTrashHandler, copyFileHandler, pasteFileHandler, deleteFileHandler, cutFileHandler, DOWNLOAD_COMMAND_ID, openFilePreserveFocusHandler } from 'vs/workbench/contrib/files/browser/fileActions'; import { revertLocalChangesCommand, acceptLocalChangesCommand, CONFLICT_RESOLUTION_CONTEXT } from 'vs/workbench/contrib/files/browser/saveErrorHandler'; import { SyncActionDescriptor, MenuId, MenuRegistry, ILocalizedString } from 'vs/platform/actions/common/actions'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; @@ -186,6 +186,14 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'filesExplorer.openFilePreserveFocus', + weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus, + when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerFolderContext.toNegated()), + primary: KeyCode.Space, + handler: openFilePreserveFocusHandler +}); + const copyPathCommand = { id: COPY_PATH_COMMAND_ID, title: nls.localize('copyPath', "Copy Path") diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 4bde241c886..cb9ac033e43 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -1059,3 +1059,19 @@ export const pasteFileHandler = async (accessor: ServicesAccessor) => { } } }; + +export const openFilePreserveFocusHandler = async (accessor: ServicesAccessor) => { + const listService = accessor.get(IListService); + const editorService = accessor.get(IEditorService); + + if (listService.lastFocusedList) { + const explorerContext = getContext(listService.lastFocusedList); + if (explorerContext.stat) { + const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat]; + await editorService.openEditors(stats.filter(s => !s.isDirectory).map(s => ({ + resource: s.resource, + options: { preserveFocus: true } + }))); + } + } +}; diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index e94990d2390..38835200d54 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -578,7 +578,7 @@ CommandsRegistry.registerCommand({ CommandsRegistry.registerCommand({ id: SAVE_ALL_IN_GROUP_COMMAND_ID, - handler: (accessor, resource: URI | object, editorContext: IEditorCommandsContext) => { + handler: (accessor, _: URI | object, editorContext: IEditorCommandsContext) => { const contexts = getMultiSelectedEditorContexts(editorContext, accessor.get(IListService), accessor.get(IEditorGroupsService)); const editorGroupService = accessor.get(IEditorGroupsService); let saveAllArg: any; diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index bffa827671f..a069bee3bf9 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -141,7 +141,7 @@ export class FilesRenderer implements ITreeRenderer validationDelayer.trigger(validate); - this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, { flexibleHeight: true }); + this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, { flexibleHeight: true, flexibleMaxHeight: 134 }); this.inputBox.setEnabled(this.isBodyVisible()); this._register(attachInputBoxStyler(this.inputBox, this.themeService)); this._register(this.inputBox); @@ -896,11 +896,8 @@ export class RepositoryPanel extends ViewletPanel { const listHeight = height - (editorHeight + 12 /* margin */); this.listContainer.style.height = `${listHeight}px`; this.list.layout(listHeight, width); - - toggleClass(this.inputBoxContainer, 'scroll', editorHeight >= 134); } else { addClass(this.inputBoxContainer, 'hidden'); - removeClass(this.inputBoxContainer, 'scroll'); this.listContainer.style.height = `${height}px`; this.list.layout(height, width); diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index be59e276ec8..5451b8eb6f4 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -306,7 +306,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); CommandsRegistry.registerCommand('workbench.action.tasks.reRunTask', (accessor, arg) => { - this.reRunTaskCommand(arg); + this.reRunTaskCommand(); }); CommandsRegistry.registerCommand('workbench.action.tasks.restartTask', (accessor, arg) => { @@ -1810,7 +1810,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } - private reRunTaskCommand(arg?: any): void { + private reRunTaskCommand(): void { if (!this.canRunCommand()) { return; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 48edebe7c19..9d6decb1a34 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1130,6 +1130,12 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } } + // HACK: Force initialText to be non-falsy for reused terminals such that the + // conptyInheritCursor flag is passed to the node-pty, this flag can cause a Window to hang + // in Windows 10 1903 so we only want to use it when something is definitely written to the + // terminal. + shell.initialText = ' '; + // Set the new shell launch config this._shellLaunchConfig = shell; // Must be done before calling _createProcess() diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index b8ad7fd4c28..2fbc8a25e74 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -66,7 +66,8 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess cols, rows, experimentalUseConpty: useConpty, - conptyInheritCursor: true + // This option will force conpty to not redraw the whole viewport on launch + conptyInheritCursor: useConpty && !!shellLaunchConfig.initialText }; const cwdVerification = stat(cwd).then(async stat => { diff --git a/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts b/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts index a56cff41c02..2cfebd34775 100644 --- a/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts +++ b/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts @@ -9,7 +9,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ShowAllCommandsAction } from 'vs/workbench/contrib/quickopen/browser/commandsHandler'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { localize } from 'vs/nls'; import { Action } from 'vs/base/common/actions'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; @@ -168,10 +168,8 @@ class WelcomeOverlay extends Disposable { } private create(): void { - const container = this.layoutService.getContainer(Parts.EDITOR_PART)!; - const offset = this.layoutService.getTitleBarOffset(); - this._overlay = dom.append(container.parentElement!, $('.welcomeOverlay')); + this._overlay = dom.append(this.layoutService.getWorkbenchElement(), $('.welcomeOverlay')); this._overlay.style.top = `${offset}px`; this._overlay.style.height = `calc(100% - ${offset}px)`; this._overlay.style.display = 'none'; diff --git a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts index fafa3c35e17..47281663ce9 100644 --- a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts @@ -60,4 +60,4 @@ export interface CommandInputInfo { args?: any; } -export type ConfiguredInput = PromptStringInputInfo | PickStringInputInfo | CommandInputInfo; \ No newline at end of file +export type ConfiguredInput = PromptStringInputInfo | PickStringInputInfo | CommandInputInfo; diff --git a/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts b/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts index fa0e030188e..1fa8a4ca589 100644 --- a/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts +++ b/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts @@ -102,8 +102,20 @@ export const inputsSchema: IJSONSchema = { description: nls.localize('JsonSchema.input.command.command', "The command to execute for this input variable.") }, args: { - type: 'object', - description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.") + oneOf: [ + { + type: 'object', + description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.") + }, + { + type: 'array', + description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.") + }, + { + type: 'string', + description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.") + } + ] } } } diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index a9ab498cc98..78e852dd29c 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -343,7 +343,7 @@ export const enum GroupChangeKind { /* Group Changes */ GROUP_ACTIVE, - GROUP_LABEL, + GROUP_INDEX, /* Editor Changes */ EDITOR_OPEN, @@ -374,6 +374,14 @@ export interface IEditorGroup { */ readonly id: GroupIdentifier; + /** + * A number that indicates the position of this group in the visual + * order of groups from left to right and top to bottom. The lowest + * index will likely be top-left while the largest index in most + * cases should be bottom-right, but that depends on the grid. + */ + readonly index: number; + /** * A human readable label for the group. This label can change depending * on the layout of all editor groups. Clients should listen on the diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index 477fdfc5bc7..35584c57600 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -254,28 +254,49 @@ suite('EditorGroupsService', () => { part.dispose(); }); - test('groups labels', function () { + test('groups index / labels', function () { const part = createPart(); const rootGroup = part.groups[0]; const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT); const downGroup = part.addGroup(rightGroup, GroupDirection.DOWN); - let labelChangeCounter = 0; + let indexChangeCounter = 0; const labelChangeListener = downGroup.onDidGroupChange(e => { - if (e.kind === GroupChangeKind.GROUP_LABEL) { - labelChangeCounter++; + if (e.kind === GroupChangeKind.GROUP_INDEX) { + indexChangeCounter++; } }); + assert.equal(rootGroup.index, 0); + assert.equal(rightGroup.index, 1); + assert.equal(downGroup.index, 2); assert.equal(rootGroup.label, 'Group 1'); assert.equal(rightGroup.label, 'Group 2'); assert.equal(downGroup.label, 'Group 3'); part.removeGroup(rightGroup); + assert.equal(rootGroup.index, 0); + assert.equal(downGroup.index, 1); assert.equal(rootGroup.label, 'Group 1'); assert.equal(downGroup.label, 'Group 2'); - assert.equal(labelChangeCounter, 1); + assert.equal(indexChangeCounter, 1); + + part.moveGroup(downGroup, rootGroup, GroupDirection.UP); + assert.equal(downGroup.index, 0); + assert.equal(rootGroup.index, 1); + assert.equal(downGroup.label, 'Group 1'); + assert.equal(rootGroup.label, 'Group 2'); + assert.equal(indexChangeCounter, 2); + + const newFirstGroup = part.addGroup(downGroup, GroupDirection.UP); + assert.equal(newFirstGroup.index, 0); + assert.equal(downGroup.index, 1); + assert.equal(rootGroup.index, 2); + assert.equal(newFirstGroup.label, 'Group 1'); + assert.equal(downGroup.label, 'Group 2'); + assert.equal(rootGroup.label, 'Group 3'); + assert.equal(indexChangeCounter, 3); labelChangeListener.dispose(); diff --git a/src/vs/workbench/services/notification/common/notificationService.ts b/src/vs/workbench/services/notification/common/notificationService.ts index 5db9ec24347..81ba282a7c3 100644 --- a/src/vs/workbench/services/notification/common/notificationService.ts +++ b/src/vs/workbench/services/notification/common/notificationService.ts @@ -3,13 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions } from 'vs/platform/notification/common/notification'; +import * as nls from 'vs/nls'; +import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification } from 'vs/platform/notification/common/notification'; import { INotificationsModel, NotificationsModel, ChoiceAction } from 'vs/workbench/common/notifications'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; -import { IAction } from 'vs/base/common/actions'; +import { IAction, Action } from 'vs/base/common/actions'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; export class NotificationService extends Disposable implements INotificationService { @@ -21,6 +23,10 @@ export class NotificationService extends Disposable implements INotificationServ return this._model; } + constructor(@IStorageService private readonly storageService: IStorageService) { + super(); + } + info(message: NotificationMessage | NotificationMessage[]): void { if (Array.isArray(message)) { message.forEach(m => this.info(m)); @@ -52,12 +58,80 @@ export class NotificationService extends Disposable implements INotificationServ } notify(notification: INotification): INotificationHandle { - return this.model.addNotification(notification); + const toDispose = new DisposableStore(); + + // Handle neverShowAgain option accordingly + let handle: INotificationHandle; + if (notification.neverShowAgain) { + + // If the user already picked to not show the notification + // again, we return with a no-op notification here + const id = notification.neverShowAgain.id; + if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) { + return new NoOpNotification(); + } + + const neverShowAgainAction = toDispose.add(new Action( + 'workbench.notification.neverShowAgain', + nls.localize('neverShowAgain', "Don't Show Again"), + undefined, true, () => { + + // Close notification + handle.close(); + + // Remember choice + this.storageService.store(id, true, StorageScope.GLOBAL); + + return Promise.resolve(); + })); + + // Insert as primary or secondary action + const actions = notification.actions || { primary: [], secondary: [] }; + if (!notification.neverShowAgain.isSecondary) { + actions.primary = [neverShowAgainAction, ...(actions.primary || [])]; // action comes first + } else { + actions.secondary = [...(actions.secondary || []), neverShowAgainAction]; // actions comes last + } + + notification.actions = actions; + } + + // Show notification + handle = this.model.addNotification(notification); + + // Cleanup when notification gets disposed + Event.once(handle.onDidClose)(() => toDispose.dispose()); + + return handle; } prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle { const toDispose = new DisposableStore(); + // Handle neverShowAgain option accordingly + if (options && options.neverShowAgain) { + + // If the user already picked to not show the notification + // again, we return with a no-op notification here + const id = options.neverShowAgain.id; + if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) { + return new NoOpNotification(); + } + + const neverShowAgainChoice = { + label: nls.localize('neverShowAgain', "Don't Show Again"), + run: () => this.storageService.store(id, true, StorageScope.GLOBAL), + isSecondary: options.neverShowAgain.isSecondary + }; + + // Insert as primary or secondary action + if (!options.neverShowAgain.isSecondary) { + choices = [neverShowAgainChoice, ...choices]; // action comes first + } else { + choices = [...choices, neverShowAgainChoice]; // actions comes last + } + } + let choiceClicked = false; let handle: INotificationHandle; diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 48ebaf8e296..3895ed64e2a 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -761,6 +761,7 @@ export class TestEditorGroup implements IEditorGroupView { disposed: boolean; editors: ReadonlyArray = []; label: string; + index: number; whenRestored: Promise = Promise.resolve(undefined); element: HTMLElement; minimumWidth: number; @@ -839,7 +840,7 @@ export class TestEditorGroup implements IEditorGroupView { isEmpty(): boolean { return true; } setActive(_isActive: boolean): void { } - setLabel(_label: string): void { } + notifyIndexChanged(_index: number): void { } dispose(): void { } toJSON(): object { return Object.create(null); } layout(_width: number, _height: number): void { } diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index ca799d9789a..1a11ef19d75 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -99,7 +99,6 @@ import 'vs/workbench/services/decorations/browser/decorationsService'; import 'vs/workbench/services/search/common/searchService'; import 'vs/workbench/services/progress/browser/progressService'; import 'vs/workbench/services/editor/browser/codeEditorService'; -// import 'vs/workbench/services/extensions/electron-browser/extensionHostDebugService'; import 'vs/workbench/services/preferences/browser/preferencesService'; import 'vs/workbench/services/output/common/outputChannelModelService'; import 'vs/workbench/services/configuration/common/jsonEditingService'; @@ -240,7 +239,7 @@ import 'vs/workbench/contrib/debug/browser/debugQuickOpen'; import 'vs/workbench/contrib/debug/browser/debugEditorContribution'; import 'vs/workbench/contrib/debug/browser/repl'; import 'vs/workbench/contrib/debug/browser/debugViewlet'; -import 'vs/workbench/contrib/debug/browser/debugHelperService'; +import 'vs/workbench/contrib/debug/browser/extensionHostDebugService'; // Markers import 'vs/workbench/contrib/markers/browser/markers.contribution';