Merge branch 'main' into aiday/checkingEffectiveLineCount

This commit is contained in:
Aiday Marlen Kyzy
2023-12-06 13:05:11 +01:00
committed by GitHub
140 changed files with 1441 additions and 795 deletions
@@ -0,0 +1,38 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as eslint from 'eslint';
import { Node } from 'estree';
export = new class EnsureNoDisposablesAreLeakedInTestSuite implements eslint.Rule.RuleModule {
readonly meta: eslint.Rule.RuleMetaData = {
type: 'problem',
messages: {
ensure: 'Suites should include a call to `ensureNoDisposablesAreLeakedInTestSuite()` to ensure no disposables are leaked in tests.'
}
};
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
const config = <{ exclude: string[] }>context.options[0];
const needle = context.getFilename().replace(/\\/g, '/');
if (config.exclude.some((e) => needle.endsWith(e))) {
return {};
}
return {
[`Program > ExpressionStatement > CallExpression[callee.name='suite']`]: (node: Node) => {
const src = context.getSourceCode().getText(node)
if (!src.includes('ensureNoDisposablesAreLeakedInTestSuite(')) {
context.report({
node,
messageId: 'ensure',
});
}
},
};
}
};
+188
View File
@@ -136,6 +136,194 @@
]
}
},
{
"files": [
"src/vs/**/*.test.ts"
],
"rules": {
"local/code-ensure-no-disposables-leak-in-test": [
"warn",
{
// Files should (only) be removed from the list they adopt the leak detector
"exclude": [
"src/vs/base/parts/sandbox/test/electron-sandbox/globals.test.ts",
"src/vs/base/test/browser/browser.test.ts",
"src/vs/base/test/browser/comparers.test.ts",
"src/vs/base/test/browser/hash.test.ts",
"src/vs/base/test/browser/indexedDB.test.ts",
"src/vs/base/test/browser/ui/menu/menubar.test.ts",
"src/vs/base/test/browser/ui/scrollbar/scrollableElement.test.ts",
"src/vs/base/test/browser/ui/scrollbar/scrollbarState.test.ts",
"src/vs/base/test/common/arrays.test.ts",
"src/vs/base/test/common/arraysFind.test.ts",
"src/vs/base/test/common/cache.test.ts",
"src/vs/base/test/common/charCode.test.ts",
"src/vs/base/test/common/collections.test.ts",
"src/vs/base/test/common/color.test.ts",
"src/vs/base/test/common/console.test.ts",
"src/vs/base/test/common/decorators.test.ts",
"src/vs/base/test/common/diff/diff.test.ts",
"src/vs/base/test/common/errors.test.ts",
"src/vs/base/test/common/filters.perf.test.ts",
"src/vs/base/test/common/filters.test.ts",
"src/vs/base/test/common/iconLabels.test.ts",
"src/vs/base/test/common/iterator.test.ts",
"src/vs/base/test/common/json.test.ts",
"src/vs/base/test/common/jsonEdit.test.ts",
"src/vs/base/test/common/jsonFormatter.test.ts",
"src/vs/base/test/common/keybindings.test.ts",
"src/vs/base/test/common/keyCodes.test.ts",
"src/vs/base/test/common/linkedList.test.ts",
"src/vs/base/test/common/linkedText.test.ts",
"src/vs/base/test/common/map.test.ts",
"src/vs/base/test/common/markdownString.test.ts",
"src/vs/base/test/common/marshalling.test.ts",
"src/vs/base/test/common/naturalLanguage/korean.test.ts",
"src/vs/base/test/common/network.test.ts",
"src/vs/base/test/common/normalization.test.ts",
"src/vs/base/test/common/observable.test.ts",
"src/vs/base/test/common/path.test.ts",
"src/vs/base/test/common/prefixTree.test.ts",
"src/vs/base/test/common/resources.test.ts",
"src/vs/base/test/common/resourceTree.test.ts",
"src/vs/base/test/common/scrollable.test.ts",
"src/vs/base/test/common/skipList.test.ts",
"src/vs/base/test/common/stripComments.test.ts",
"src/vs/base/test/common/ternarySearchtree.test.ts",
"src/vs/base/test/common/types.test.ts",
"src/vs/base/test/common/uri.test.ts",
"src/vs/base/test/common/uuid.test.ts",
"src/vs/base/test/node/crypto.test.ts",
"src/vs/base/test/node/css.build.test.ts",
"src/vs/base/test/node/id.test.ts",
"src/vs/base/test/node/nodeStreams.test.ts",
"src/vs/base/test/node/snapshot.test.ts",
"src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts",
"src/vs/editor/contrib/codeAction/test/browser/codeActionKeybindingResolver.test.ts",
"src/vs/editor/contrib/codeAction/test/browser/codeActionModel.test.ts",
"src/vs/editor/contrib/dropOrPasteInto/test/browser/editSort.test.ts",
"src/vs/editor/contrib/folding/test/browser/foldingModel.test.ts",
"src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts",
"src/vs/editor/contrib/folding/test/browser/indentFold.test.ts",
"src/vs/editor/contrib/folding/test/browser/indentRangeProvider.test.ts",
"src/vs/editor/contrib/gotoSymbol/test/browser/referencesModel.test.ts",
"src/vs/editor/contrib/smartSelect/test/browser/smartSelect.test.ts",
"src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts",
"src/vs/editor/contrib/snippet/test/browser/snippetSession.test.ts",
"src/vs/editor/contrib/snippet/test/browser/snippetVariables.test.ts",
"src/vs/editor/contrib/suggest/test/browser/completionModel.test.ts",
"src/vs/editor/contrib/suggest/test/browser/suggestMemory.test.ts",
"src/vs/editor/test/common/services/languageService.test.ts",
"src/vs/editor/test/node/classification/typescript.test.ts",
"src/vs/editor/test/node/diffing/defaultLinesDiffComputer.test.ts",
"src/vs/editor/test/node/diffing/fixtures.test.ts",
"src/vs/platform/configuration/test/common/configuration.test.ts",
"src/vs/platform/configuration/test/common/configurationModels.test.ts",
"src/vs/platform/configuration/test/common/configurationRegistry.test.ts",
"src/vs/platform/contextkey/test/common/contextkey.test.ts",
"src/vs/platform/contextkey/test/common/parser.test.ts",
"src/vs/platform/contextkey/test/common/scanner.test.ts",
"src/vs/platform/extensionManagement/test/common/extensionManagement.test.ts",
"src/vs/platform/extensions/test/common/extensionValidator.test.ts",
"src/vs/platform/externalTerminal/electron-main/externalTerminalService.test.ts",
"src/vs/platform/instantiation/test/common/graph.test.ts",
"src/vs/platform/instantiation/test/common/instantiationService.test.ts",
"src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts",
"src/vs/platform/keybinding/test/common/keybindingLabels.test.ts",
"src/vs/platform/keybinding/test/common/keybindingResolver.test.ts",
"src/vs/platform/markers/test/common/markerService.test.ts",
"src/vs/platform/opener/test/common/opener.test.ts",
"src/vs/platform/progress/test/common/progress.test.ts",
"src/vs/platform/registry/test/common/platform.test.ts",
"src/vs/platform/remote/test/common/remoteHosts.test.ts",
"src/vs/platform/telemetry/test/browser/1dsAppender.test.ts",
"src/vs/platform/telemetry/test/common/telemetryLogAppender.test.ts",
"src/vs/platform/userDataSync/test/common/extensionsMerge.test.ts",
"src/vs/platform/userDataSync/test/common/globalStateMerge.test.ts",
"src/vs/platform/userDataSync/test/common/settingsMerge.test.ts",
"src/vs/platform/userDataSync/test/common/snippetsMerge.test.ts",
"src/vs/platform/userDataSync/test/common/userDataProfilesManifestMerge.test.ts",
"src/vs/platform/workspace/test/common/workspace.test.ts",
"src/vs/platform/workspaces/test/electron-main/workspaces.test.ts",
"src/vs/server/test/node/serverConnectionToken.test.ts",
"src/vs/workbench/api/test/browser/extHostApiCommands.test.ts",
"src/vs/workbench/api/test/browser/extHostBulkEdits.test.ts",
"src/vs/workbench/api/test/browser/extHostCommands.test.ts",
"src/vs/workbench/api/test/browser/extHostDocumentSaveParticipant.test.ts",
"src/vs/workbench/api/test/browser/extHostTelemetry.test.ts",
"src/vs/workbench/api/test/browser/extHostTextEditor.test.ts",
"src/vs/workbench/api/test/browser/extHostTypeConverter.test.ts",
"src/vs/workbench/api/test/browser/extHostTypes.test.ts",
"src/vs/workbench/api/test/browser/extHostWorkspace.test.ts",
"src/vs/workbench/api/test/browser/mainThreadConfiguration.test.ts",
"src/vs/workbench/api/test/browser/mainThreadDocuments.test.ts",
"src/vs/workbench/api/test/common/extensionHostMain.test.ts",
"src/vs/workbench/api/test/common/extHostExtensionActivator.test.ts",
"src/vs/workbench/api/test/node/extHostTunnelService.test.ts",
"src/vs/workbench/contrib/bulkEdit/test/browser/bulkCellEdits.test.ts",
"src/vs/workbench/contrib/chat/test/common/chatWordCounter.test.ts",
"src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts",
"src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts",
"src/vs/workbench/contrib/debug/test/browser/callStack.test.ts",
"src/vs/workbench/contrib/debug/test/browser/debugHover.test.ts",
"src/vs/workbench/contrib/debug/test/browser/repl.test.ts",
"src/vs/workbench/contrib/debug/test/common/debugModel.test.ts",
"src/vs/workbench/contrib/debug/test/node/debugger.test.ts",
"src/vs/workbench/contrib/debug/test/node/streamDebugAdapter.test.ts",
"src/vs/workbench/contrib/debug/test/node/terminals.test.ts",
"src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts",
"src/vs/workbench/contrib/extensions/test/common/extensionQuery.test.ts",
"src/vs/workbench/contrib/extensions/test/electron-sandbox/extension.test.ts",
"src/vs/workbench/contrib/files/test/browser/explorerFileNestingTrie.test.ts",
"src/vs/workbench/contrib/files/test/browser/explorerView.test.ts",
"src/vs/workbench/contrib/notebook/test/browser/cellDnd.test.ts",
"src/vs/workbench/contrib/notebook/test/browser/contrib/contributedStatusBarItemController.test.ts",
"src/vs/workbench/contrib/notebook/test/browser/contrib/executionStatusBarItem.test.ts",
"src/vs/workbench/contrib/notebook/test/browser/contrib/layoutActions.test.ts",
"src/vs/workbench/contrib/notebook/test/browser/contrib/outputCopyTests.test.ts",
"src/vs/workbench/contrib/notebook/test/browser/notebookBrowser.test.ts",
"src/vs/workbench/contrib/notebook/test/browser/notebookExecutionService.test.ts",
"src/vs/workbench/contrib/notebook/test/browser/notebookExecutionStateService.test.ts",
"src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts",
"src/vs/workbench/contrib/search/test/common/cacheState.test.ts",
"src/vs/workbench/contrib/search/test/common/extractRange.test.ts",
"src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts",
"src/vs/workbench/contrib/snippets/test/browser/snippetsRegistry.test.ts",
"src/vs/workbench/contrib/snippets/test/browser/snippetsRewrite.test.ts",
"src/vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts",
"src/vs/workbench/contrib/tasks/test/common/taskConfiguration.test.ts",
"src/vs/workbench/contrib/terminal/test/browser/terminalActions.test.ts",
"src/vs/workbench/contrib/welcomeGettingStarted/test/browser/gettingStartedMarkdownRenderer.test.ts",
"src/vs/workbench/services/commands/test/common/commandService.test.ts",
"src/vs/workbench/services/configuration/test/common/configurationModels.test.ts",
"src/vs/workbench/services/dialogs/test/electron-sandbox/fileDialogService.test.ts",
"src/vs/workbench/services/editor/test/browser/editorResolverService.test.ts",
"src/vs/workbench/services/extensions/test/common/extensionDescriptionRegistry.test.ts",
"src/vs/workbench/services/keybinding/test/browser/keybindingIO.test.ts",
"src/vs/workbench/services/keybinding/test/node/fallbackKeyboardMapper.test.ts",
"src/vs/workbench/services/keybinding/test/node/macLinuxKeyboardMapper.test.ts",
"src/vs/workbench/services/keybinding/test/node/windowsKeyboardMapper.test.ts",
"src/vs/workbench/services/preferences/test/browser/preferencesService.test.ts",
"src/vs/workbench/services/preferences/test/common/preferencesValidation.test.ts",
"src/vs/workbench/services/search/test/browser/queryBuilder.test.ts",
"src/vs/workbench/services/search/test/common/ignoreFile.test.ts",
"src/vs/workbench/services/search/test/common/queryBuilder.test.ts",
"src/vs/workbench/services/search/test/common/replace.test.ts",
"src/vs/workbench/services/search/test/common/search.test.ts",
"src/vs/workbench/services/search/test/common/searchHelpers.test.ts",
"src/vs/workbench/services/search/test/node/ripgrepFileSearch.test.ts",
"src/vs/workbench/services/search/test/node/ripgrepTextSearchEngineUtils.test.ts",
"src/vs/workbench/services/telemetry/test/browser/commonProperties.test.ts",
"src/vs/workbench/services/themes/test/node/tokenStyleResolving.test.ts",
"src/vs/workbench/services/userActivity/test/browser/domActivityTracker.test.ts",
"src/vs/workbench/services/workspaces/test/browser/workspaces.test.ts",
"src/vs/workbench/services/workspaces/test/common/workspaceTrust.test.ts",
"src/vs/workbench/test/browser/quickAccess.test.ts"
]
}
]
}
},
{
"files": [
"**/vscode.d.ts",
+2
View File
@@ -253,6 +253,7 @@
"tokenization": {"assign": ["alexdima"]},
"touch/pointer": {"assign": []},
"trackpad/scroll": {"assign": []},
"tree-sticky-scroll": {"assign": ["benibenj"]},
"tree-views": {"assign": ["alexr00"]},
"tree-widget": {"assign": ["joaomoreno"]},
"typehierarchy": {"assign": ["jrieken"]},
@@ -272,6 +273,7 @@
"webview": {"assign": ["mjbvz"]},
"webview-views": {"assign": ["mjbvz"]},
"workbench-actions": {"assign": ["bpasero"]},
"workbench-auxwindow": {"assign": ["bpasero"]},
"workbench-banner": {"assign": ["lszomoru", "sbatten"]},
"workbench-cli": {"assign": ["bpasero"]},
"workbench-diagnostics": {"assign": ["Tyriar"]},
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -167,5 +167,6 @@
],
"[github-issues]": {
"editor.wordWrap": "on"
}
},
"css.format.spaceAroundSelectorSeparator": true,
}
+1 -1
View File
@@ -223,7 +223,7 @@ pub struct CommandShellArgs {
#[clap(long, num_args = 0..=1, default_missing_value = "0")]
pub on_port: Option<u16>,
/// Require the given token string to be given in the handshake.
#[clap(long)]
#[clap(long, env = "VSCODE_CLI_REQUIRE_TOKEN")]
pub require_token: Option<String>,
/// Optional parent process id. If provided, the server will be stopped when the process of the given pid no longer exists
#[clap(long, hide = true)]
@@ -201,7 +201,7 @@ export class ActionBar extends Disposable implements IActionRunner {
}
// Recompute focused item
else if (event.equals(KeyCode.Tab) || event.equals(KeyMod.Shift | KeyCode.Tab)) {
else if (event.equals(KeyCode.Tab) || event.equals(KeyMod.Shift | KeyCode.Tab) || event.equals(KeyCode.UpArrow) || event.equals(KeyCode.DownArrow) || event.equals(KeyCode.LeftArrow) || event.equals(KeyCode.RightArrow)) {
this.updateFocusedItem();
}
}));
@@ -51,7 +51,7 @@
opacity: 0.5;
}
.monaco-icon-label>.monaco-icon-label-container>.monaco-icon-suffix-container>.label-suffix {
.monaco-icon-label > .monaco-icon-label-container > .monaco-icon-suffix-container > .label-suffix {
opacity: .7;
white-space: pre;
}
+2 -2
View File
@@ -40,7 +40,7 @@ export type ConfigurationSyncStore = {
url: string;
insidersUrl: string;
stableUrl: string;
canSwitch: boolean;
canSwitch?: boolean;
authenticationProviders: IStringDictionary<{ scopes: string[] }>;
};
@@ -203,7 +203,7 @@ export interface IExtensionRecommendations {
}
export interface ISettingsEditorOpenCondition {
readonly prerelease: boolean | string;
readonly prerelease?: boolean | string;
}
export interface IExtensionRecommendationCondition {
@@ -571,6 +571,8 @@ flakySuite('IPC, create handle', () => {
suite('WebSocketNodeSocket', () => {
const ds = ensureNoDisposablesAreLeakedInTestSuite();
function toUint8Array(data: number[]): Uint8Array {
const result = new Uint8Array(data.length);
for (let i = 0; i < data.length; i++) {
@@ -724,15 +726,15 @@ suite('WebSocketNodeSocket', () => {
server.close();
const webSocketNodeSocket = new WebSocketNodeSocket(new NodeSocket(socket), true, null, false);
webSocketNodeSocket.onData((data) => {
ds.add(webSocketNodeSocket.onData((data) => {
receivingSideOnDataCallCount++;
receivingSideTotalBytes += data.byteLength;
});
}));
webSocketNodeSocket.onClose(() => {
ds.add(webSocketNodeSocket.onClose(() => {
webSocketNodeSocket.dispose();
receivingSideSocketClosedBarrier.open();
});
}));
});
const socket = connect({
+3
View File
@@ -8,6 +8,7 @@ import { $, asCssValueWithDefault, h, multibyteAwareBtoa, trackAttributes, copyA
import { ensureCodeWindow, isAuxiliaryWindow, mainWindow } from 'vs/base/browser/window';
import { DeferredPromise, timeout } from 'vs/base/common/async';
import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('dom', () => {
test('hasClass', () => {
@@ -404,4 +405,6 @@ suite('dom', () => {
assert.strictEqual(count, 0);
});
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -6,6 +6,7 @@
import * as assert from 'assert';
import { renderFormattedText, renderText } from 'vs/base/browser/formattedTextRenderer';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('FormattedTextRenderer', () => {
const store = new DisposableStore();
@@ -127,4 +128,6 @@ suite('FormattedTextRenderer', () => {
assert.strictEqual(result.children.length, 0);
assert.strictEqual(result.innerHTML, '**bold**');
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -5,6 +5,7 @@
import * as assert from 'assert';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('renderLabelWithIcons', () => {
@@ -49,4 +50,6 @@ suite('renderLabelWithIcons', () => {
.map(elem => elem instanceof HTMLElement ? elem.outerHTML : elem)
.reduce((a, b) => a + b, '');
};
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -5,6 +5,7 @@
import * as assert from 'assert';
import { layout, LayoutAnchorPosition } from 'vs/base/browser/ui/contextview/contextview';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('Contextview', function () {
@@ -25,4 +26,6 @@ suite('Contextview', function () {
assert.strictEqual(layout(200, 20, { offset: 50, size: 50, position: LayoutAnchorPosition.After }), 30);
assert.strictEqual(layout(200, 20, { offset: 150, size: 50, position: LayoutAnchorPosition.After }), 130);
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -361,6 +361,8 @@ suite('RangeMap', () => {
suite('RangeMap with top padding', () => {
ensureNoDisposablesAreLeakedInTestSuite();
test('empty', () => {
const rangeMap = new RangeMap(10);
assert.strictEqual(rangeMap.size, 10);
@@ -250,12 +250,14 @@ suite('CompressibleObjectTree', function () {
disposeTemplate(): void { }
}
const ds = ensureNoDisposablesAreLeakedInTestSuite();
test('empty', function () {
const container = document.createElement('div');
container.style.width = '200px';
container.style.height = '200px';
const tree = new CompressibleObjectTree<number>('test', container, new Delegate(), [new Renderer()]);
const tree = ds.add(new CompressibleObjectTree<number>('test', container, new Delegate(), [new Renderer()]));
tree.layout(200);
assert.strictEqual(getRowsTextContent(container).length, 0);
@@ -266,7 +268,7 @@ suite('CompressibleObjectTree', function () {
container.style.width = '200px';
container.style.height = '200px';
const tree = new CompressibleObjectTree<number>('test', container, new Delegate(), [new Renderer()]);
const tree = ds.add(new CompressibleObjectTree<number>('test', container, new Delegate(), [new Renderer()]));
tree.layout(200);
tree.setChildren(null, [
@@ -289,7 +291,7 @@ suite('CompressibleObjectTree', function () {
container.style.width = '200px';
container.style.height = '200px';
const tree = new CompressibleObjectTree<number>('test', container, new Delegate(), [new Renderer()]);
const tree = ds.add(new CompressibleObjectTree<number>('test', container, new Delegate(), [new Renderer()]));
tree.layout(200);
tree.setChildren(null, [
@@ -341,7 +343,7 @@ suite('CompressibleObjectTree', function () {
container.style.width = '200px';
container.style.height = '200px';
const tree = new CompressibleObjectTree<number>('test', container, new Delegate(), [new Renderer()]);
const tree = ds.add(new CompressibleObjectTree<number>('test', container, new Delegate(), [new Renderer()]));
tree.layout(200);
tree.setChildren(null, [
+3
View File
@@ -5,6 +5,7 @@
import * as assert from 'assert';
import { ok } from 'vs/base/common/assert';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('Assert', () => {
test('ok', () => {
@@ -31,4 +32,6 @@ suite('Assert', () => {
ok({});
ok(5);
});
ensureNoDisposablesAreLeakedInTestSuite();
});
File diff suppressed because it is too large Load Diff
+5
View File
@@ -498,6 +498,11 @@ suite('Filters', () => {
assertTopScore(fuzzyScore, '_lineS', 0, '_lineS', '_lines');
});
test.skip('Bad completion ranking changes valid variable name to class name when pressing "." #187055', function () {
assertTopScore(fuzzyScore, 'a', 1, 'A', 'a');
assertTopScore(fuzzyScore, 'theme', 1, 'Theme', 'theme');
});
test('HTML closing tag proposal filtered out #38880', function () {
assertMatches('\t\t<', '\t\t</body>', '^\t^\t^</body>', fuzzyScore, { patternPos: 0 });
assertMatches('\t\t<', '\t\t</body>', '\t\t^</body>', fuzzyScore, { patternPos: 2 });
+2
View File
@@ -184,6 +184,8 @@ suite('History Navigator', () => {
suite('History Navigator 2', () => {
ensureNoDisposablesAreLeakedInTestSuite();
test('constructor', () => {
const testObject = new HistoryNavigator2(['1', '2', '3', '4']);
@@ -6,6 +6,7 @@
import * as assert from 'assert';
import { IMatch } from 'vs/base/common/filters';
import { escapeIcons, getCodiconAriaLabel, IParsedLabelWithIcons, markdownEscapeEscapedIcons, matchesFuzzyIconAware, parseLabelWithIcons, stripIcons } from 'vs/base/common/iconLabels';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
interface IIconFilter {
// Returns null if word doesn't match.
@@ -110,4 +111,6 @@ suite('Icon Labels', () => {
assert.strictEqual(markdownEscapeEscapedIcons('$(Hello) World'), '$(Hello) World');
assert.strictEqual(markdownEscapeEscapedIcons('\\$(Hello) World'), '\\\\$(Hello) World');
});
ensureNoDisposablesAreLeakedInTestSuite();
});
+3
View File
@@ -5,6 +5,7 @@
import * as assert from 'assert';
import { Lazy } from 'vs/base/common/lazy';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('Lazy', () => {
@@ -27,4 +28,6 @@ suite('Lazy', () => {
assert.strictEqual(value.hasValue, true);
assert.throws(() => value.value, /\b1\b/);
});
ensureNoDisposablesAreLeakedInTestSuite();
});
+6 -1
View File
@@ -13,8 +13,9 @@ class Disposable implements IDisposable {
dispose() { this.isDisposed = true; }
}
// Leaks are allowed here since we test lifecycle stuff:
// eslint-disable-next-line local/code-ensure-no-disposables-leak-in-test
suite('Lifecycle', () => {
test('dispose single disposable', () => {
const disposable = new Disposable();
@@ -129,6 +130,8 @@ suite('Lifecycle', () => {
});
suite('DisposableStore', () => {
ensureNoDisposablesAreLeakedInTestSuite();
test('dispose should call all child disposes even if a child throws on dispose', () => {
const disposedValues = new Set<number>();
@@ -221,6 +224,8 @@ suite('DisposableStore', () => {
});
suite('Reference Collection', () => {
ensureNoDisposablesAreLeakedInTestSuite();
class Collection extends ReferenceCollection<number> {
private _count = 0;
get count() { return this._count; }
+3
View File
@@ -5,6 +5,7 @@
import * as assert from 'assert';
import { normalizeMimeType } from 'vs/base/common/mime';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('Mime', () => {
@@ -16,4 +17,6 @@ suite('Mime', () => {
assert.strictEqual(normalizeMimeType('Text/plain;UPPER'), 'text/plain;UPPER');
assert.strictEqual(normalizeMimeType('Text/plain;lower'), 'text/plain;lower');
});
ensureNoDisposablesAreLeakedInTestSuite();
});
+3
View File
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as objects from 'vs/base/common/objects';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
const check = (one: any, other: any, msg: string) => {
assert(objects.equals(one, other), msg);
@@ -17,6 +18,8 @@ const checkNot = (one: any, other: any, msg: string) => {
suite('Objects', () => {
ensureNoDisposablesAreLeakedInTestSuite();
test('equals', () => {
check(null, null, 'null');
check(undefined, undefined, 'undefined');
+3
View File
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as strings from 'vs/base/common/strings';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('Strings', () => {
test('equalsIgnoreCase', () => {
@@ -510,4 +511,6 @@ suite('Strings', () => {
assert.strictEqual(strings.removeAnsiEscapeCodes(`hello${sequence}world`), 'helloworld', `expect to remove ${JSON.stringify(sequence)}`);
}
});
ensureNoDisposablesAreLeakedInTestSuite();
});
+2
View File
@@ -6,6 +6,7 @@
import * as assert from 'assert';
import { CancellationToken } from 'vs/base/common/cancellation';
import { TfIdfCalculator, TfIdfDocument, TfIdfScore } from 'vs/base/common/tfIdf';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
/**
* Generates all permutations of an array.
@@ -39,6 +40,7 @@ function assertScoreOrdersEqual(actualScores: TfIdfScore[], expectedScoreKeys: s
}
suite('TF-IDF Calculator', function () {
ensureNoDisposablesAreLeakedInTestSuite();
test('Should return no scores when no documents are given', () => {
const tfidf = new TfIdfCalculator();
const scores = tfidf.calculateScores('something', CancellationToken.None);
+3
View File
@@ -6,6 +6,7 @@
import * as assert from 'assert';
import * as net from 'net';
import * as ports from 'vs/base/node/ports';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { flakySuite } from 'vs/base/test/node/testUtils';
flakySuite('Ports', () => {
@@ -29,4 +30,6 @@ flakySuite('Ports', () => {
});
}, err => done(err));
});
ensureNoDisposablesAreLeakedInTestSuite();
});
+2 -1
View File
@@ -6,6 +6,7 @@ import * as assert from 'assert';
import * as fs from 'fs';
import * as platform from 'vs/base/common/platform';
import { enumeratePowerShellInstallations, getFirstAvailablePowerShellInstallation, IPowerShellExeDetails } from 'vs/base/node/powershell';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
function checkPath(exePath: string) {
// Check to see if the path exists
@@ -28,7 +29,7 @@ function checkPath(exePath: string) {
if (platform.isWindows) {
suite('PowerShell finder', () => {
ensureNoDisposablesAreLeakedInTestSuite();
test('Can find first available PowerShell', async () => {
const pwshExe = await getFirstAvailablePowerShellInstallation();
const exePath = pwshExe?.exePath;
+3
View File
@@ -5,6 +5,7 @@
import { strictEqual } from 'assert';
import { getUNCHost } from 'vs/base/node/unc';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('UNC', () => {
@@ -43,4 +44,6 @@ suite('UNC', () => {
strictEqual(getUNCHost('\\\\.\\UNC\\localhost\\a'), 'localhost');
strictEqual(getUNCHost('\\\\?\\UNC\\localhost\\a'), 'localhost');
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -280,17 +280,6 @@ export class AccessibleDiffViewerPrev extends Action2 {
export function findFocusedDiffEditor(accessor: ServicesAccessor): IDiffEditor | null {
const codeEditorService = accessor.get(ICodeEditorService);
const diffEditors = codeEditorService.listDiffEditors();
const activeCodeEditor = codeEditorService.getFocusedCodeEditor() ?? codeEditorService.getActiveCodeEditor();
if (!activeCodeEditor) {
return null;
}
for (let i = 0, len = diffEditors.length; i < len; i++) {
const diffEditor = <IDiffEditor>diffEditors[i];
if (diffEditor.getModifiedEditor().getId() === activeCodeEditor.getId() || diffEditor.getOriginalEditor().getId() === activeCodeEditor.getId()) {
return diffEditor;
}
}
const activeElement = getActiveElement();
if (activeElement) {
@@ -483,13 +483,13 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor {
return;
}
const model = this._diffModel.get()?.model;
if (!model) { return; }
const model = this._diffModel.get();
if (!model || !model.isDiffUpToDate.get()) { return; }
this._editors.modified.executeEdits('diffEditor', [
{
range: diff.modified.toExclusiveRange(),
text: model.original.getValueInRange(diff.original.toExclusiveRange())
text: model.model.original.getValueInRange(diff.original.toExclusiveRange())
}
]);
}
+6
View File
@@ -112,6 +112,12 @@ export class OffsetRange implements IOffsetRange {
return undefined;
}
public intersects(other: OffsetRange): boolean {
const start = Math.max(this.start, other.start);
const end = Math.min(this.endExclusive, other.endExclusive);
return start < end;
}
public intersectsOrTouches(other: OffsetRange): boolean {
const start = Math.max(this.start, other.start);
const end = Math.min(this.endExclusive, other.endExclusive);
@@ -125,6 +125,13 @@ export class OffsetPair {
public toString(): string {
return `${this.offset1} <-> ${this.offset2}`;
}
public delta(offset: number): OffsetPair {
if (offset === 0) {
return this;
}
return new OffsetPair(this.offset1 + offset, this.offset2 + offset);
}
}
export interface ISequence {
@@ -220,72 +220,74 @@ export function removeShortMatches(sequence1: ISequence, sequence2: ISequence, s
}
export function extendDiffsToEntireWordIfAppropriate(sequence1: LinesSliceCharSequence, sequence2: LinesSliceCharSequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] {
const equalMappings = SequenceDiff.invert(sequenceDiffs, sequence1.length);
const additional: SequenceDiff[] = [];
let lastModifiedWord: { added: number; deleted: number; count: number; s1Range: OffsetRange; s2Range: OffsetRange } | undefined = undefined;
let lastPoint = new OffsetPair(0, 0);
function maybePushWordToAdditional() {
if (!lastModifiedWord) {
function scanWord(pair: OffsetPair, equalMapping: SequenceDiff) {
if (pair.offset1 < lastPoint.offset1 || pair.offset2 < lastPoint.offset2) {
return;
}
const originalLength1 = lastModifiedWord.s1Range.length - lastModifiedWord.deleted;
const originalLength2 = lastModifiedWord.s2Range.length - lastModifiedWord.added;
if (originalLength1 !== originalLength2) {
// TODO figure out why this happens
const w1 = sequence1.findWordContaining(pair.offset1);
const w2 = sequence2.findWordContaining(pair.offset2);
if (!w1 || !w2) {
return;
}
let w = new SequenceDiff(w1, w2);
const equalPart = w.intersect(equalMapping)!;
let equalChars1 = equalPart.seq1Range.length;
let equalChars2 = equalPart.seq2Range.length;
// The words do not touch previous equals mappings, as we would have processed them already.
// But they might touch the next ones.
while (equalMappings.length > 0) {
const next = equalMappings[0];
const intersects = next.seq1Range.intersects(w1) || next.seq2Range.intersects(w2);
if (!intersects) {
break;
}
const v1 = sequence1.findWordContaining(next.seq1Range.start);
const v2 = sequence2.findWordContaining(next.seq2Range.start);
// Because there is an intersection, we know that the words are not empty.
const v = new SequenceDiff(v1!, v2!);
const equalPart = v.intersect(next)!;
equalChars1 += equalPart.seq1Range.length;
equalChars2 += equalPart.seq2Range.length;
w = w.join(v);
if (w.seq1Range.endExclusive >= next.seq1Range.endExclusive) {
// The word extends beyond the next equal mapping.
equalMappings.shift();
} else {
break;
}
}
if (Math.max(lastModifiedWord.deleted, lastModifiedWord.added) + (lastModifiedWord.count - 1) > originalLength1) {
additional.push(new SequenceDiff(lastModifiedWord.s1Range, lastModifiedWord.s2Range));
if (equalChars1 + equalChars2 < (w.seq1Range.length + w.seq2Range.length) * 2 / 3) {
additional.push(new SequenceDiff(w1, w2));
}
lastModifiedWord = undefined;
lastPoint = w.getEndExclusives();
}
for (const s of sequenceDiffs) {
function processWord(s1Range: OffsetRange, s2Range: OffsetRange) {
if (!lastModifiedWord || !lastModifiedWord.s1Range.containsRange(s1Range) || !lastModifiedWord.s2Range.containsRange(s2Range)) {
if (lastModifiedWord && !(lastModifiedWord.s1Range.endExclusive < s1Range.start && lastModifiedWord.s2Range.endExclusive < s2Range.start)) {
const s1Added = OffsetRange.tryCreate(lastModifiedWord.s1Range.endExclusive, s1Range.start);
const s2Added = OffsetRange.tryCreate(lastModifiedWord.s2Range.endExclusive, s2Range.start);
lastModifiedWord.deleted += s1Added?.length ?? 0;
lastModifiedWord.added += s2Added?.length ?? 0;
lastModifiedWord.s1Range = lastModifiedWord.s1Range.join(s1Range);
lastModifiedWord.s2Range = lastModifiedWord.s2Range.join(s2Range);
} else {
maybePushWordToAdditional();
lastModifiedWord = { added: 0, deleted: 0, count: 0, s1Range: s1Range, s2Range: s2Range };
}
}
const changedS1 = s1Range.intersect(s.seq1Range);
const changedS2 = s2Range.intersect(s.seq2Range);
lastModifiedWord.count++;
lastModifiedWord.deleted += changedS1?.length ?? 0;
lastModifiedWord.added += changedS2?.length ?? 0;
}
const w1Before = sequence1.findWordContaining(s.seq1Range.start - 1);
const w2Before = sequence2.findWordContaining(s.seq2Range.start - 1);
const w1After = sequence1.findWordContaining(s.seq1Range.endExclusive);
const w2After = sequence2.findWordContaining(s.seq2Range.endExclusive);
if (w1Before && w1After && w2Before && w2After && w1Before.equals(w1After) && w2Before.equals(w2After)) {
processWord(w1Before, w2Before);
} else {
if (w1Before && w2Before) {
processWord(w1Before, w2Before);
}
if (w1After && w2After) {
processWord(w1After, w2After);
}
while (equalMappings.length > 0) {
const next = equalMappings.shift()!;
if (next.seq1Range.isEmpty) {
continue;
}
scanWord(next.getStarts(), next);
// The equal parts are not empty, so -1 gives us a character that is equal in both parts.
scanWord(next.getEndExclusives().delta(-1), next);
}
maybePushWordToAdditional();
const merged = mergeSequenceDiffs(sequenceDiffs, additional);
return merged;
}
@@ -92,6 +92,10 @@ export class LinesSliceCharSequence implements ISequence {
// don't break between \r and \n
return 0;
}
if (prevCategory === CharBoundaryCategory.LineBreakLF) {
// prefer the linebreak before the change
return 150;
}
let score = 0;
if (prevCategory !== nextCategory) {
@@ -187,7 +191,7 @@ const score: Record<CharBoundaryCategory, number> = {
[CharBoundaryCategory.WordNumber]: 0,
[CharBoundaryCategory.End]: 10,
[CharBoundaryCategory.Other]: 2,
[CharBoundaryCategory.Separator]: 3,
[CharBoundaryCategory.Separator]: 30,
[CharBoundaryCategory.Space]: 3,
[CharBoundaryCategory.LineBreakCR]: 10,
[CharBoundaryCategory.LineBreakLF]: 10,
@@ -105,21 +105,21 @@ export class SemanticTokensProviderStyling {
public warnOverlappingSemanticTokens(lineNumber: number, startColumn: number): void {
if (!this._hasWarnedOverlappingTokens) {
this._hasWarnedOverlappingTokens = true;
console.warn(`Overlapping semantic tokens detected at lineNumber ${lineNumber}, column ${startColumn}`);
this._logService.warn(`Overlapping semantic tokens detected at lineNumber ${lineNumber}, column ${startColumn}`);
}
}
public warnInvalidLengthSemanticTokens(lineNumber: number, startColumn: number): void {
if (!this._hasWarnedInvalidLengthTokens) {
this._hasWarnedInvalidLengthTokens = true;
console.warn(`Semantic token with invalid length detected at lineNumber ${lineNumber}, column ${startColumn}`);
this._logService.warn(`Semantic token with invalid length detected at lineNumber ${lineNumber}, column ${startColumn}`);
}
}
public warnInvalidEditStart(previousResultId: string | undefined, resultId: string | undefined, editIndex: number, editStart: number, maxExpectedStart: number): void {
if (!this._hasWarnedInvalidEditStart) {
this._hasWarnedInvalidEditStart = true;
console.warn(`Invalid semantic tokens edit detected (previousResultId: ${previousResultId}, resultId: ${resultId}) at edit #${editIndex}: The provided start offset ${editStart} is outside the previous data (length ${maxExpectedStart}).`);
this._logService.warn(`Invalid semantic tokens edit detected (previousResultId: ${previousResultId}, resultId: ${resultId}) at edit #${editIndex}: The provided start offset ${editStart} is outside the previous data (length ${maxExpectedStart}).`);
}
}
@@ -127,11 +127,6 @@ export function filtersAction(filter: CodeActionFilter, action: languages.CodeAc
}
}
// On empty lines and selections, show only code AI code actions
if (rangeOrSelection.isEmpty() && model.getLineContent(rangeOrSelection.startLineNumber).length === 0) {
return !!action.isAI;
}
return true;
}
@@ -16,24 +16,24 @@
font-family: var(--vscode-editorCodeLens-fontFamily), var(--vscode-editorCodeLens-fontFamilyDefault);
}
.monaco-editor .codelens-decoration>span,
.monaco-editor .codelens-decoration>a {
.monaco-editor .codelens-decoration > span,
.monaco-editor .codelens-decoration > a {
user-select: none;
-webkit-user-select: none;
white-space: nowrap;
vertical-align: sub;
}
.monaco-editor .codelens-decoration>a {
.monaco-editor .codelens-decoration > a {
text-decoration: none;
}
.monaco-editor .codelens-decoration>a:hover {
.monaco-editor .codelens-decoration > a:hover {
cursor: pointer;
color: var(--vscode-editorLink-activeForeground) !important;
}
.monaco-editor .codelens-decoration>a:hover .codicon {
.monaco-editor .codelens-decoration > a:hover .codicon {
color: var(--vscode-editorLink-activeForeground) !important;
}
@@ -45,7 +45,7 @@
font-size: var(--vscode-editorCodeLens-fontSize);
}
.monaco-editor .codelens-decoration>a:hover .codicon::before {
.monaco-editor .codelens-decoration > a:hover .codicon::before {
cursor: pointer;
}
@@ -911,6 +911,10 @@ export class ContentHoverWidget extends ResizableContentWidget {
public goToBottom(): void {
this._hover.scrollbar.setScrollPosition({ scrollTop: this._hover.scrollbar.getScrollDimensions().scrollHeight });
}
public toggleLocked(locked: boolean): void {
this._hover.containerDomNode.classList.toggle('locked', locked);
}
}
export class EditorHoverStatusBar extends Disposable implements IEditorHoverStatusBar {
@@ -14,6 +14,10 @@
border-radius: 3px;
}
.monaco-editor .monaco-hover.locked {
outline: 1px solid var(--vscode-editorHoverWidget-border);
}
.monaco-editor .monaco-hover a {
color: var(--vscode-textLink-foreground);
}
@@ -58,6 +58,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut
private _hoverActivatedByColorDecoratorClick: boolean = false;
private _reactToEditorMouseMoveRunner: RunOnceScheduler;
private _mouseMoveEvent: IEditorMouseEvent | undefined;
private _isLocked: boolean = false;
static get(editor: ICodeEditor): ModesHoverController | null {
return editor.getContribution<ModesHoverController>(ModesHoverController.ID);
@@ -96,6 +97,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut
this._toUnhook.add(this._editor.onMouseUp((e: IEditorMouseEvent) => this._onEditorMouseUp(e)));
this._toUnhook.add(this._editor.onMouseMove((e: IEditorMouseEvent) => this._onEditorMouseMove(e)));
this._toUnhook.add(this._editor.onKeyDown((e: IKeyboardEvent) => this._onKeyDown(e)));
this._toUnhook.add(this._editor.onKeyUp((e: IKeyboardEvent) => this._onKeyUp(e)));
} else {
this._toUnhook.add(this._editor.onMouseMove((e: IEditorMouseEvent) => this._onEditorMouseMove(e)));
this._toUnhook.add(this._editor.onKeyDown((e: IKeyboardEvent) => this._onKeyDown(e)));
@@ -206,6 +208,10 @@ export class ModesHoverController extends Disposable implements IEditorContribut
private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void {
this._mouseMoveEvent = mouseEvent;
if (this._isLocked) {
// When the alt key is pressed, hover remains visible
return;
}
if (this._contentWidget?.isFocused || this._contentWidget?.isResizing) {
return;
}
@@ -281,6 +287,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut
if (!this._editor.hasModel()) {
return;
}
this._toggleLockedState(e.altKey);
const resolvedKeyboardEvent = this._keybindingService.softDispatch(e, this._editor.getDomNode());
// If the beginning of a multi-chord keybinding is pressed, or the command aims to focus the hover, set the variable to true, otherwise false
@@ -293,6 +300,17 @@ export class ModesHoverController extends Disposable implements IEditorContribut
}
}
private _onKeyUp(e: IKeyboardEvent): void {
this._toggleLockedState(!e.altKey);
}
private _toggleLockedState(locked: boolean) {
if (this._isLocked !== locked) {
this._isLocked = locked;
this._contentWidget?.widget.toggleLocked(this._isLocked);
}
}
private _hideWidgets(): void {
if (_sticky) {
return;
@@ -83,6 +83,8 @@ function fromRange(rng: Range): number[] {
}
suite('Multicursor selection', () => {
ensureNoDisposablesAreLeakedInTestSuite();
const serviceCollection = new ServiceCollection();
serviceCollection.set(IStorageService, new InMemoryStorageService());
@@ -71,24 +71,24 @@
margin-right: 0.3em;
}
.monaco-editor .suggest-widget.with-status-bar .monaco-list .monaco-list-row>.contents>.main>.right>.readMore,
.monaco-editor .suggest-widget.with-status-bar .monaco-list .monaco-list-row.focused.string-label>.contents>.main>.right>.readMore {
.monaco-editor .suggest-widget.with-status-bar .monaco-list .monaco-list-row > .contents > .main > .right > .readMore,
.monaco-editor .suggest-widget.with-status-bar .monaco-list .monaco-list-row.focused.string-label > .contents > .main > .right > .readMore {
display: none;
}
.monaco-editor .suggest-widget.with-status-bar:not(.docs-side) .monaco-list .monaco-list-row:hover>.contents>.main>.right.can-expand-details>.details-label {
.monaco-editor .suggest-widget.with-status-bar:not(.docs-side) .monaco-list .monaco-list-row:hover > .contents > .main > .right.can-expand-details > .details-label {
width: 100%;
}
/* Styles for Message element for when widget is loading or is empty */
.monaco-editor .suggest-widget>.message {
.monaco-editor .suggest-widget > .message {
padding-left: 22px;
}
/** Styles for the list element **/
.monaco-editor .suggest-widget>.tree {
.monaco-editor .suggest-widget > .tree {
height: 100%;
width: 100%;
}
@@ -120,14 +120,14 @@
color: var(--vscode-editorSuggestWidget-selectedIconForeground);
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents {
flex: 1;
height: 100%;
overflow: hidden;
padding-left: 2px;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main {
display: flex;
overflow: hidden;
text-overflow: ellipsis;
@@ -135,12 +135,12 @@
justify-content: space-between;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left,
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left,
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right {
display: flex;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.focused)>.contents>.main .monaco-icon-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.focused) > .contents > .main .monaco-icon-label {
color: var(--vscode-editorSuggestWidget-foreground);
}
@@ -148,48 +148,48 @@
font-weight: bold;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main .monaco-highlighted-label .highlight {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main .monaco-highlighted-label .highlight {
color: var(--vscode-editorSuggestWidget-highlightForeground);
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused>.contents>.main .monaco-highlighted-label .highlight {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused > .contents > .main .monaco-highlighted-label .highlight {
color: var(--vscode-editorSuggestWidget-focusHighlightForeground);
}
/** ReadMore Icon styles **/
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.codicon-close,
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.readMore::before {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .codicon-close,
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .readMore::before {
color: inherit;
opacity: 1;
font-size: 14px;
cursor: pointer;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.codicon-close {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .codicon-close {
position: absolute;
top: 6px;
right: 2px;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.codicon-close:hover,
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.readMore:hover {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .codicon-close:hover,
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .readMore:hover {
opacity: 1;
}
/** signature, qualifier, type/details opacity **/
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label {
opacity: 0.7;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left>.signature-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left > .signature-label {
overflow: hidden;
text-overflow: ellipsis;
opacity: 0.6;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left>.qualifier-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left > .qualifier-label {
margin-left: 12px;
opacity: 0.4;
font-size: 85%;
@@ -201,7 +201,7 @@
/** Type Info and icon next to the label in the focused completion item **/
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label {
font-size: 85%;
margin-left: 1.1em;
overflow: hidden;
@@ -209,58 +209,58 @@
white-space: nowrap;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label>.monaco-tokenized-source {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label > .monaco-tokenized-source {
display: inline;
}
/** Details: if using CompletionItem#details, show on focus **/
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label {
display: none;
}
.monaco-editor .suggest-widget:not(.shows-details) .monaco-list .monaco-list-row.focused>.contents>.main>.right>.details-label {
.monaco-editor .suggest-widget:not(.shows-details) .monaco-list .monaco-list-row.focused > .contents > .main > .right > .details-label {
display: inline;
}
/** Details: if using CompletionItemLabel#details, always show **/
.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.string-label)>.contents>.main>.right>.details-label,
.monaco-editor .suggest-widget.docs-side .monaco-list .monaco-list-row.focused:not(.string-label)>.contents>.main>.right>.details-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.string-label) > .contents > .main > .right > .details-label,
.monaco-editor .suggest-widget.docs-side .monaco-list .monaco-list-row.focused:not(.string-label) > .contents > .main > .right > .details-label {
display: inline;
}
/** Ellipsis on hover **/
.monaco-editor .suggest-widget:not(.docs-side) .monaco-list .monaco-list-row.focused:hover>.contents>.main>.right.can-expand-details>.details-label {
.monaco-editor .suggest-widget:not(.docs-side) .monaco-list .monaco-list-row.focused:hover > .contents > .main > .right.can-expand-details > .details-label {
width: calc(100% - 26px);
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left {
flex-shrink: 1;
flex-grow: 1;
overflow: hidden;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left>.monaco-icon-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left > .monaco-icon-label {
flex-shrink: 0;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.string-label)>.contents>.main>.left>.monaco-icon-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.string-label) > .contents > .main > .left > .monaco-icon-label {
max-width: 100%;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.string-label>.contents>.main>.left>.monaco-icon-label {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.string-label > .contents > .main > .left > .monaco-icon-label {
flex-shrink: 1;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right {
overflow: hidden;
flex-shrink: 4;
max-width: 70%;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.readMore {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .readMore {
display: inline-block;
position: absolute;
right: 10px;
@@ -271,23 +271,23 @@
/** Do NOT display ReadMore when docs is side/below **/
.monaco-editor .suggest-widget.docs-side .monaco-list .monaco-list-row>.contents>.main>.right>.readMore {
.monaco-editor .suggest-widget.docs-side .monaco-list .monaco-list-row > .contents > .main > .right > .readMore {
display: none !important;
}
/** Do NOT display ReadMore when using plain CompletionItemLabel (details/documentation might not be resolved) **/
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.string-label>.contents>.main>.right>.readMore {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.string-label > .contents > .main > .right > .readMore {
display: none;
}
/** Focused item can show ReadMore, but can't when docs is side/below **/
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused.string-label>.contents>.main>.right>.readMore {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused.string-label > .contents > .main > .right > .readMore {
display: inline-block;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused:hover>.contents>.main>.right>.readMore {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused:hover > .contents > .main > .right > .readMore {
visibility: visible;
}
@@ -298,7 +298,7 @@
text-decoration: unset;
}
.monaco-editor .suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated>.monaco-icon-label-container>.monaco-icon-name-container {
.monaco-editor .suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated > .monaco-icon-label-container > .monaco-icon-name-container {
text-decoration: line-through;
}
@@ -372,17 +372,17 @@
display: none;
}
.monaco-editor .suggest-details>.monaco-scrollable-element {
.monaco-editor .suggest-details > .monaco-scrollable-element {
flex: 1;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body {
box-sizing: border-box;
height: 100%;
width: 100%;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.type {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .type {
flex: 2;
overflow: hidden;
text-overflow: ellipsis;
@@ -392,55 +392,55 @@
padding: 4px 0 12px 5px;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.type.auto-wrap {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .type.auto-wrap {
white-space: normal;
word-break: break-all;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs {
margin: 0;
padding: 4px 5px;
white-space: pre-wrap;
}
.monaco-editor .suggest-details.no-type>.monaco-scrollable-element>.body>.docs {
.monaco-editor .suggest-details.no-type > .monaco-scrollable-element > .body > .docs {
margin-right: 24px;
overflow: hidden;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs {
padding: 0;
white-space: initial;
min-height: calc(1rem + 8px);
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs>div,
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs>span:not(:empty) {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs > div,
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs > span:not(:empty) {
padding: 4px 5px;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs>div>p:first-child {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs > div > p:first-child {
margin-top: 0;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs>div>p:last-child {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs > div > p:last-child {
margin-bottom: 0;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs .monaco-tokenized-source {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs .monaco-tokenized-source {
white-space: pre;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs .code {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs .code {
white-space: pre-wrap;
word-wrap: break-word;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs .codicon {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs .codicon {
vertical-align: sub;
}
.monaco-editor .suggest-details>.monaco-scrollable-element>.body>p:empty {
.monaco-editor .suggest-details > .monaco-scrollable-element > .body > p:empty {
display: none;
}
@@ -253,9 +253,10 @@ function computeOccurencesMultiModel(registry: LanguageFeatureRegistry<MultiDocu
return new TextualOccurenceRequest(model, selection, word, wordSeparators, otherModels);
}
registerModelAndPositionCommand('_executeDocumentHighlights', (accessor, model, position) => {
registerModelAndPositionCommand('_executeDocumentHighlights', async (accessor, model, position) => {
const languageFeaturesService = accessor.get(ILanguageFeaturesService);
return getOccurrencesAtPosition(languageFeaturesService.documentHighlightProvider, model, position, CancellationToken.None);
const map = await getOccurrencesAtPosition(languageFeaturesService.documentHighlightProvider, model, position, CancellationToken.None);
return map?.get(model.uri);
});
class WordHighlighter {
@@ -37,14 +37,19 @@
clip-path: inset(50%);
}
/*.monaco-editor.vs [tabindex="0"]:focus {
outline: 1px solid rgba(0, 122, 204, 0.4);
.monaco-editor, .monaco-diff-editor .synthetic-focus,
.monaco-editor, .monaco-diff-editor [tabindex="0"]:focus,
.monaco-editor, .monaco-diff-editor [tabindex="-1"]:focus,
.monaco-editor, .monaco-diff-editor button:focus,
.monaco-editor, .monaco-diff-editor input[type=button]:focus,
.monaco-editor, .monaco-diff-editor input[type=checkbox]:focus,
.monaco-editor, .monaco-diff-editor input[type=search]:focus,
.monaco-editor, .monaco-diff-editor input[type=text]:focus,
.monaco-editor, .monaco-diff-editor select:focus,
.monaco-editor, .monaco-diff-editor textarea:focus {
outline-width: 1px;
outline-style: solid;
outline-offset: -1px;
opacity: 1 !important;
outline-color: var(--vscode-focusBorder);
opacity: 1
}
.monaco-editor.vs-dark [tabindex="0"]:focus {
outline: 1px solid rgba(14, 99, 156, 0.6);
outline-offset: -1px;
opacity: 1 !important;
}*/
@@ -23,8 +23,8 @@
"modifiedRange": "[39,40)",
"innerChanges": [
{
"originalRange": "[63,9 -> 63,43]",
"modifiedRange": "[39,9 -> 39,38]"
"originalRange": "[63,9 -> 63,48]",
"modifiedRange": "[39,9 -> 39,43]"
},
{
"originalRange": "[64,1 -> 72,1]",
@@ -21,8 +21,12 @@
"modifiedRange": "[7,76 -> 7,80]"
},
{
"originalRange": "[12,153 -> 12,155 EOL]",
"modifiedRange": "[7,157 -> 8,1 EOL]"
"originalRange": "[12,153 -> 12,153]",
"modifiedRange": "[7,157 -> 7,181]"
},
{
"originalRange": "[13,1 -> 13,1]",
"modifiedRange": "[8,1 -> 9,1]"
},
{
"originalRange": "[13,31 -> 13,31]",
@@ -21,8 +21,8 @@
"modifiedRange": "[2,17 -> 2,17]"
},
{
"originalRange": "[1,72 -> 1,73]",
"modifiedRange": "[2,48 -> 2,59]"
"originalRange": "[1,72 -> 1,84]",
"modifiedRange": "[2,48 -> 2,70]"
}
]
}
@@ -0,0 +1 @@
function x(alignments: RangeMapping[]): x[] { }
@@ -0,0 +1 @@
function x(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[]): x[] { }
@@ -0,0 +1,22 @@
{
"original": {
"content": "function x(alignments: RangeMapping[]): x[] { }\n",
"fileName": "./1.tst"
},
"modified": {
"content": "function x(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[]): x[] { }\n",
"fileName": "./2.tst"
},
"diffs": [
{
"originalRange": "[1,2)",
"modifiedRange": "[1,2)",
"innerChanges": [
{
"originalRange": "[1,38 -> 1,38]",
"modifiedRange": "[1,38 -> 1,88]"
}
]
}
]
}
@@ -0,0 +1,22 @@
{
"original": {
"content": "function x(alignments: RangeMapping[]): x[] { }\n",
"fileName": "./1.tst"
},
"modified": {
"content": "function x(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[]): x[] { }\n",
"fileName": "./2.tst"
},
"diffs": [
{
"originalRange": "[1,2)",
"modifiedRange": "[1,2)",
"innerChanges": [
{
"originalRange": "[1,38 -> 1,38]",
"modifiedRange": "[1,38 -> 1,88]"
}
]
}
]
}
@@ -75,12 +75,12 @@
"modifiedRange": "[23,25)",
"innerChanges": [
{
"originalRange": "[25,9 -> 26,18]",
"originalRange": "[25,9 -> 26,13]",
"modifiedRange": "[23,9 -> 23,18]"
},
{
"originalRange": "[26,22 -> 26,27]",
"modifiedRange": "[23,22 -> 23,23]"
"originalRange": "[26,22 -> 26,32]",
"modifiedRange": "[23,22 -> 23,28]"
},
{
"originalRange": "[27,1 -> 27,1]",
@@ -31,8 +31,8 @@
"modifiedRange": "[11,17 -> 11,17]"
},
{
"originalRange": "[10,72 -> 10,73]",
"modifiedRange": "[11,48 -> 11,59]"
"originalRange": "[10,72 -> 10,84]",
"modifiedRange": "[11,48 -> 11,70]"
}
]
},
@@ -83,8 +83,12 @@
"modifiedRange": "[43,44)",
"innerChanges": [
{
"originalRange": "[43,5 -> 43,16 EOL]",
"modifiedRange": "[43,5 -> 43,11 EOL]"
"originalRange": "[43,8 -> 43,11]",
"modifiedRange": "[43,8 -> 43,8]"
},
{
"originalRange": "[43,14 -> 43,16 EOL]",
"modifiedRange": "[43,11 -> 43,11 EOL]"
}
]
},
@@ -108,7 +112,7 @@
"innerChanges": [
{
"originalRange": "[53,8 -> 53,17]",
"modifiedRange": "[53,8 -> 53,31]"
"modifiedRange": "[53,8 -> 53,28]"
}
]
}
@@ -5,6 +5,7 @@
import { deepEqual } from 'assert';
import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { IMassagedMessageBoxOptions, massageMessageBoxOptions } from 'vs/platform/dialogs/common/dialogs';
import product from 'vs/platform/product/common/product';
import { IProductService } from 'vs/platform/product/common/productService';
@@ -139,4 +140,6 @@ suite('Dialog', () => {
assertOptions(fourButtonNegativeCancel, ['4', '3', '2', '1'], 3, -1, [3, 2, 1, 0]);
}
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { formatOptions, Option, OptionDescriptions, Subcommand, parseArgs, ErrorReporter } from 'vs/platform/environment/node/argv';
import { addArg } from 'vs/platform/environment/node/argvHelper';
@@ -81,6 +82,8 @@ suite('formatOptions', () => {
' A test command'
]);
});
ensureNoDisposablesAreLeakedInTestSuite();
});
suite('parseArgs', () => {
@@ -156,4 +159,6 @@ suite('parseArgs', () => {
[]
);
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { OPTIONS, parseArgs } from 'vs/platform/environment/node/argv';
import { getUserDataPath } from 'vs/platform/environment/node/userDataPath';
import product from 'vs/platform/product/common/product';
@@ -57,4 +58,6 @@ suite('User data path', () => {
}
}
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { getDomainsOfRemotes, getRemotes } from 'vs/platform/extensionManagement/common/configRemotes';
suite('Config Remotes', () => {
@@ -127,4 +128,6 @@ suite('Config Remotes', () => {
fetch = +refs/heads/*:refs/remotes/origin/*
`;
}
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -348,6 +348,8 @@ suite('NativeExtensionsScanerService Test', () => {
suite('ExtensionScannerInput', () => {
ensureNoDisposablesAreLeakedInTestSuite();
test('compare inputs - location', () => {
const anInput = (location: URI, mtime: number | undefined) => new ExtensionScannerInput(location, mtime, undefined, undefined, false, undefined, ExtensionType.User, true, true, '1.1.1', undefined, undefined, true, undefined, {});
@@ -8,6 +8,7 @@ import * as sinonTest from 'sinon-test';
import { mainWindow } from 'vs/base/browser/window';
import * as Errors from 'vs/base/common/errors';
import { Emitter } from 'vs/base/common/event';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import product from 'vs/platform/product/common/product';
import { IProductService } from 'vs/platform/product/common/productService';
@@ -741,4 +742,6 @@ suite('TelemetryService', () => {
service.dispose();
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -88,9 +88,10 @@ export interface IColorRegistry {
* Register a color to the registry.
* @param id The color id as used in theme description files
* @param defaults The default values
* @param needsTransparency Whether the color requires transparency
* @description the description
*/
registerColor(id: string, defaults: ColorDefaults, description: string): ColorIdentifier;
registerColor(id: string, defaults: ColorDefaults, description: string, needsTransparency?: boolean): ColorIdentifier;
/**
* Register a color to the registry.
@@ -139,6 +140,10 @@ class ColorRegistry implements IColorRegistry {
if (deprecationMessage) {
propertySchema.deprecationMessage = deprecationMessage;
}
if (needsTransparency) {
propertySchema.pattern = '^#(?:(?<rgba>[0-9a-fA-f]{3}[0-9a-eA-E])|(?:[0-9a-fA-F]{6}(?:(?![fF]{2})(?:[0-9a-fA-F]{2}))))?$';
propertySchema.patternErrorMessage = 'This color must be transparent or it will obscure content';
}
this.colorSchema.properties[id] = propertySchema;
this.colorReferenceSchema.enum.push(id);
this.colorReferenceSchema.enumDescriptions.push(description);
@@ -6,6 +6,7 @@
import * as assert from 'assert';
import { URI } from 'vs/base/common/uri';
import { mock } from 'vs/base/test/common/mock';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { IDialogService, IPrompt } from 'vs/platform/dialogs/common/dialogs';
import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
@@ -226,4 +227,5 @@ suite('UndoRedoService', () => {
assert.strictEqual(UndoRedoGroup.None.nextOrder(), 0);
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -4,25 +4,25 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { IFileService, FileChangeType, IFileChange, IFileSystemProviderWithFileReadWriteCapability, IStat, FileType, FileSystemProviderCapabilities, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileOpenOptions, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions } from 'vs/platform/files/common/files';
import { FileService } from 'vs/platform/files/common/fileService';
import { NullLogService } from 'vs/platform/log/common/log';
import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider';
import { dirname, isEqual, joinPath } from 'vs/base/common/resources';
import { VSBuffer } from 'vs/base/common/buffer';
import { DisposableStore, IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider';
import { AbstractNativeEnvironmentService } from 'vs/platform/environment/common/environmentService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import product from 'vs/platform/product/common/product';
import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { Schemas } from 'vs/base/common/network';
import { dirname, isEqual, joinPath } from 'vs/base/common/resources';
import { ReadableStreamEvents } from 'vs/base/common/stream';
import { URI } from 'vs/base/common/uri';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { AbstractNativeEnvironmentService } from 'vs/platform/environment/common/environmentService';
import { FileService } from 'vs/platform/files/common/fileService';
import { FileChangeType, FileSystemProviderCapabilities, FileType, IFileChange, IFileOpenOptions, IFileReadStreamOptions, IFileService, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithOpenReadWriteCloseCapability, IStat } from 'vs/platform/files/common/files';
import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider';
import { NullLogService } from 'vs/platform/log/common/log';
import product from 'vs/platform/product/common/product';
import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService';
import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider';
import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' });
@@ -315,7 +315,7 @@ class TestFileSystemProvider implements IFileSystemProviderWithFileReadWriteCapa
suite('FileUserDataProvider - Watching', () => {
let testObject: FileUserDataProvider;
const disposables = new DisposableStore();
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
const rootFileResource = joinPath(ROOT, 'User');
const rootUserDataResource = rootFileResource.with({ scheme: Schemas.vscodeUserData });
@@ -332,8 +332,6 @@ suite('FileUserDataProvider - Watching', () => {
testObject = disposables.add(new FileUserDataProvider(rootFileResource.scheme, new TestFileSystemProvider(fileEventEmitter.event), Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, new NullLogService()));
});
teardown(() => disposables.clear());
test('file added change event', done => {
disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false }));
const expected = joinPath(rootUserDataResource, 'settings.json');
@@ -427,7 +425,7 @@ suite('FileUserDataProvider - Watching', () => {
test('event is not triggered if not watched', async () => {
const target = joinPath(rootFileResource, 'settings.json');
let triggered = false;
testObject.onDidChangeFile(() => triggered = true);
disposables.add(testObject.onDidChangeFile(() => triggered = true));
fileEventEmitter.fire([{
resource: target,
type: FileChangeType.DELETED
@@ -441,7 +439,7 @@ suite('FileUserDataProvider - Watching', () => {
disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false }));
const target = joinPath(dirname(rootFileResource), 'settings.json');
let triggered = false;
testObject.onDidChangeFile(() => triggered = true);
disposables.add(testObject.onDidChangeFile(() => triggered = true));
fileEventEmitter.fire([{
resource: target,
type: FileChangeType.DELETED
@@ -417,6 +417,9 @@ suite('UserDataSyncRequestsSession', () => {
async loadCertificates() { return []; }
};
ensureNoDisposablesAreLeakedInTestSuite();
test('too many requests are thrown when limit exceeded', async () => {
const testObject = new RequestsSession(1, 500, requestService, new NullLogService());
await testObject.request('url', {}, CancellationToken.None);
@@ -839,7 +839,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
private async destroyWindow(reopen: boolean, skipRestoreEditors: boolean): Promise<void> {
const workspace = this._config?.workspace;
// check to discard editor state first
// check to discard editor state first
if (skipRestoreEditors && workspace) {
try {
const workspaceStorage = this.storageMainService.workspaceStorage(workspace);
@@ -854,37 +854,41 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
// 'close' event will not be fired on destroy(), so signal crash via explicit event
this._onDidDestroy.fire();
// make sure to destroy the window as its renderer process is gone
this._win?.destroy();
try {
// ask the windows service to open a new fresh window if specified
if (reopen && this._config) {
// ask the windows service to open a new fresh window if specified
if (reopen && this._config) {
// We have to reconstruct a openable from the current workspace
let uriToOpen: IWorkspaceToOpen | IFolderToOpen | undefined = undefined;
let forceEmpty = undefined;
if (isSingleFolderWorkspaceIdentifier(workspace)) {
uriToOpen = { folderUri: workspace.uri };
} else if (isWorkspaceIdentifier(workspace)) {
uriToOpen = { workspaceUri: workspace.configPath };
} else {
forceEmpty = true;
}
// We have to reconstruct a openable from the current workspace
let uriToOpen: IWorkspaceToOpen | IFolderToOpen | undefined = undefined;
let forceEmpty = undefined;
if (isSingleFolderWorkspaceIdentifier(workspace)) {
uriToOpen = { folderUri: workspace.uri };
} else if (isWorkspaceIdentifier(workspace)) {
uriToOpen = { workspaceUri: workspace.configPath };
} else {
forceEmpty = true;
// Delegate to windows service
const window = firstOrDefault(await this.windowsMainService.open({
context: OpenContext.API,
userEnv: this._config.userEnv,
cli: {
...this.environmentMainService.args,
_: [] // we pass in the workspace to open explicitly via `urisToOpen`
},
urisToOpen: uriToOpen ? [uriToOpen] : undefined,
forceEmpty,
forceNewWindow: true,
remoteAuthority: this.remoteAuthority
}));
window?.focus();
}
// Delegate to windows service
const window = firstOrDefault(await this.windowsMainService.open({
context: OpenContext.API,
userEnv: this._config.userEnv,
cli: {
...this.environmentMainService.args,
_: [] // we pass in the workspace to open explicitly via `urisToOpen`
},
urisToOpen: uriToOpen ? [uriToOpen] : undefined,
forceEmpty,
forceNewWindow: true,
remoteAuthority: this.remoteAuthority
}));
window?.focus();
} finally {
// make sure to destroy the window as its renderer process is gone. do this
// after the code for reopening the window, to prevent the entire application
// from quitting when the last window closes as a result.
this._win?.destroy();
}
}
@@ -1495,7 +1495,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
const disposables = new DisposableStore();
disposables.add(createdWindow.onDidSignalReady(() => this._onDidSignalReadyWindow.fire(createdWindow)));
disposables.add(Event.once(createdWindow.onDidClose)(() => this.onWindowClosed(createdWindow, disposables)));
disposables.add(Event.once(createdWindow.onDidDestroy)(() => this._onDidDestroyWindow.fire(createdWindow)));
disposables.add(Event.once(createdWindow.onDidDestroy)(() => this.onWindowDestroyed(createdWindow)));
disposables.add(createdWindow.onDidMaximize(() => this._onDidMaximizeWindow.fire(createdWindow)));
disposables.add(createdWindow.onDidUnmaximize(() => this._onDidUnmaximizeWindow.fire(createdWindow)));
disposables.add(createdWindow.onDidTriggerSystemContextMenu(({ x, y }) => this._onDidTriggerSystemContextMenu.fire({ window: createdWindow, x, y })));
@@ -1627,6 +1627,15 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
disposables.dispose();
}
private onWindowDestroyed(window: ICodeWindow): void {
// Remove from our list so that Electron can clean it up
this.windows.delete(window.id);
// Emit
this._onDidDestroyWindow.fire(window);
}
getFocusedWindow(): ICodeWindow | undefined {
const window = BrowserWindow.getFocusedWindow();
if (window) {
@@ -5,6 +5,7 @@
import * as assert from 'assert';
import { URI } from 'vs/base/common/uri';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { ISerializedSingleFolderWorkspaceIdentifier, ISerializedWorkspaceIdentifier, reviveIdentifier, hasWorkspaceFileExtension, isWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IEmptyWorkspaceIdentifier, toWorkspaceIdentifier, isEmptyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
suite('Workspaces', () => {
@@ -46,4 +47,6 @@ suite('Workspaces', () => {
assert.ok(!isSingleFolderWorkspaceIdentifier(identifier));
assert.ok(isWorkspaceIdentifier(identifier));
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -10,6 +10,7 @@ import * as path from 'vs/base/common/path';
import { isWindows } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
import * as pfs from 'vs/base/node/pfs';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils';
import { getSingleFolderWorkspaceIdentifier, getWorkspaceIdentifier } from 'vs/platform/workspaces/node/workspaces';
@@ -64,4 +65,6 @@ flakySuite('Workspaces', () => {
// single folder identifier (remote)
assert.strictEqual(getSingleFolderWorkspaceIdentifier(URI.parse('vscode-remote:/hello/test'))?.id, '786de4f224d57691f218dc7f31ee2ee3');
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -168,7 +168,7 @@ export class MainThreadFileSystemEventService implements MainThreadFileSystemEve
label: localize('cancel', "Skip Changes"),
run: () => Choice.Cancel
},
checkbox: { label: localize('again', "Don't ask again") }
checkbox: { label: localize('again', "Do not ask me again") }
});
if (result === Choice.Cancel) {
// no changes wanted, don't persist cancel option
@@ -7,6 +7,7 @@ import * as assert from 'assert';
import { URI } from 'vs/base/common/uri';
import { originalFSPath } from 'vs/base/common/resources';
import { isWindows } from 'vs/base/common/platform';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
suite('ExtHost API', function () {
test('issue #51387: originalFSPath', function () {
@@ -18,4 +19,6 @@ suite('ExtHost API', function () {
assert.strictEqual(originalFSPath(URI.revive(JSON.parse(JSON.stringify(URI.file('c:\\test'))))).charAt(0), 'c');
}
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -681,6 +681,33 @@ suite('ExtHostLanguageFeatureCommands', function () {
});
});
// --- document highlights
test('"vscode.executeDocumentHighlights" API has stopped returning DocumentHighlight[]#200056', async function () {
disposables.push(extHost.registerDocumentHighlightProvider(nullExtensionDescription, defaultSelector, <vscode.DocumentHighlightProvider>{
provideDocumentHighlights() {
return [
new types.DocumentHighlight(new types.Range(0, 17, 0, 25), types.DocumentHighlightKind.Read)
];
}
}));
await rpcProtocol.sync();
return commands.executeCommand<vscode.DocumentHighlight[]>('vscode.executeDocumentHighlights', model.uri, new types.Position(0, 0)).then(values => {
assert.ok(Array.isArray(values));
assert.strictEqual(values.length, 1);
const [first] = values;
assert.strictEqual(first.range.start.line, 0);
assert.strictEqual(first.range.start.character, 17);
assert.strictEqual(first.range.end.line, 0);
assert.strictEqual(first.range.end.character, 25);
});
});
// --- outline
test('Outline, back and forth', function () {
@@ -441,6 +441,8 @@ suite('ExtHostDocumentData updates line mapping', () => {
testLineMappingDirectionAfterEvents(lines, '\r\n', AssertDocumentLineMappingDirection.OffsetToPosition, e);
}
ensureNoDisposablesAreLeakedInTestSuite();
test('line mapping', () => {
testLineMappingAfterEvents([
'This is line one',
@@ -12,6 +12,7 @@ import { mock } from 'vs/base/test/common/mock';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { Event } from 'vs/base/common/event';
import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
const emptyCommandService: ICommandService = {
_serviceBrand: undefined,
@@ -132,4 +133,6 @@ suite('ExtHostMessageService', function () {
assert.strictEqual(handle, 42);
});
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -234,7 +234,7 @@
/* Right aligned */
.monaco-workbench .activitybar.right>.content :not(.monaco-menu)>.monaco-action-bar .profile-badge,
.monaco-workbench .activitybar.right > .content :not(.monaco-menu) > .monaco-action-bar .profile-badge,
.monaco-workbench .activitybar.right > .content :not(.monaco-menu) > .monaco-action-bar .badge {
left: auto;
right: 0;
@@ -19,7 +19,7 @@ import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
import { IAuxiliaryTitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart';
import { WindowTitle } from 'vs/workbench/browser/parts/titlebar/windowTitle';
import { IAuxiliaryWindowOpenOptions, IAuxiliaryWindowService } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService';
import { GroupsOrder, IAuxiliaryEditorPart } from 'vs/workbench/services/editor/common/editorGroupsService';
import { GroupDirection, GroupsOrder, IAuxiliaryEditorPart } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
@@ -220,10 +220,32 @@ class AuxiliaryEditorPartImpl extends EditorPart implements IAuxiliaryEditorPart
}
private doClose(mergeGroupsToMainPart: boolean): void {
if (mergeGroupsToMainPart && this.groups.some(group => group.count > 0)) {
this.mergeAllGroups(this.editorPartsView.mainPart.activeGroup);
if (mergeGroupsToMainPart) {
this.mergeGroupsToMainPart();
}
this._onWillClose.fire();
}
private mergeGroupsToMainPart(): void {
if (!this.groups.some(group => group.count > 0)) {
return; // skip if we have no editors opened
}
// Find the most recent group that is not locked
let targetGroup: IEditorGroupView | undefined = undefined;
for (const group of this.editorPartsView.mainPart.getGroups(GroupsOrder.MOST_RECENTLY_ACTIVE)) {
if (!group.isLocked) {
targetGroup = group;
break;
}
}
if (!targetGroup) {
targetGroup = this.editorPartsView.mainPart.addGroup(this.editorPartsView.mainPart.activeGroup, this.partOptions.openSideBySideDirection === 'right' ? GroupDirection.RIGHT : GroupDirection.DOWN);
}
this.mergeAllGroups(targetGroup);
targetGroup.focus();
}
}
@@ -1900,11 +1900,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
}
private canLock(): boolean {
if (this.groupsView.isAuxiliary) {
return true; // always allow locking in auxiliary parts, even single groups
}
return this.groupsView.groups.length > 1; // only allow locking if more than 1 group is opened
return this.editorPartsView.groups.length > 1; // only allow locking if more than 1 group is opened
}
//#endregion
@@ -13,7 +13,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IView, orthogonal, LayoutPriority, IViewSize, Direction, SerializableGrid, Sizing, ISerializedGrid, ISerializedNode, Orientation, GridBranchNode, isGridBranchNode, GridNode, createSerializedGrid, Grid } from 'vs/base/browser/ui/grid/grid';
import { GroupIdentifier, EditorInputWithOptions, IEditorPartOptions, IEditorPartOptionsChangeEvent, GroupModelChangeKind } from 'vs/workbench/common/editor';
import { EDITOR_GROUP_BORDER, EDITOR_PANE_BACKGROUND } from 'vs/workbench/common/theme';
import { distinct, coalesce, firstOrDefault } from 'vs/base/common/arrays';
import { distinct, coalesce } from 'vs/base/common/arrays';
import { IEditorGroupView, getEditorPartOptions, impactsEditorPartOptions, IEditorPartCreationOptions, IEditorPartsView, IEditorGroupsView } from 'vs/workbench/browser/parts/editor/editor';
import { EditorGroupView } from 'vs/workbench/browser/parts/editor/editorGroupView';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
@@ -811,12 +811,6 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupsView {
// Update container
this.updateContainer();
// Update locked state: clear when we are at just 1 group
// in case we are in the main editor part
if (this.count === 1 && !this.isAuxiliary) {
firstOrDefault(this.groups)?.lock(false);
}
// Event
this._onDidRemoveGroup.fire(groupView);
}
@@ -13,7 +13,7 @@ import { IEditorGroupView, IEditorPartsView } from 'vs/workbench/browser/parts/e
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IAuxiliaryWindowOpenOptions } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService';
import { distinct } from 'vs/base/common/arrays';
import { distinct, firstOrDefault } from 'vs/base/common/arrays';
import { AuxiliaryEditorPart } from 'vs/workbench/browser/parts/editor/auxiliaryEditorPart';
import { MultiWindowParts } from 'vs/workbench/browser/part';
@@ -94,7 +94,7 @@ export class EditorParts extends MultiWindowParts<EditorPart> implements IEditor
disposables.add(part.onDidChangeActiveGroup(group => this._onDidActiveGroupChange.fire(group)));
disposables.add(part.onDidAddGroup(group => this._onDidAddGroup.fire(group)));
disposables.add(part.onDidRemoveGroup(group => this._onDidRemoveGroup.fire(group)));
disposables.add(part.onDidRemoveGroup(group => this.handleOnDidRemoveGroup(group)));
disposables.add(part.onDidMoveGroup(group => this._onDidMoveGroup.fire(group)));
disposables.add(part.onDidActivateGroup(group => this._onDidActivateGroup.fire(group)));
disposables.add(part.onDidChangeGroupMaximized(maximized => this._onDidChangeGroupMaximized.fire(maximized)));
@@ -103,6 +103,17 @@ export class EditorParts extends MultiWindowParts<EditorPart> implements IEditor
disposables.add(part.onDidChangeGroupLocked(group => this._onDidChangeGroupLocked.fire(group)));
}
private handleOnDidRemoveGroup(group: IEditorGroupView): void {
// Reset locked state when only one group is remaining
if (this.count === 1) {
firstOrDefault(this.mainPart.groups)?.lock(false);
}
// Events
this._onDidRemoveGroup.fire(group);
}
private doUpdateMostRecentActive(part: EditorPart, makeMostRecentlyActive?: boolean): void {
const index = this.mostRecentActiveParts.indexOf(part);
@@ -3,17 +3,17 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control.hidden {
.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control.hidden {
display: none;
}
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .monaco-icon-label,
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .monaco-icon-label {
.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .monaco-icon-label,
.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .monaco-icon-label {
text-decoration-line: underline;
}
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .hint-more,
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .hint-more {
.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .hint-more,
.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .hint-more {
text-decoration-line: underline;
}
@@ -41,22 +41,22 @@
flex-direction: column;
}
.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree>.input {
.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree > .input {
padding: 5px 9px;
position: relative;
box-sizing: border-box;
height: 36px;
}
.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree>.tree {
.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree > .tree {
height: calc(100% - 36px);
}
.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree.inactive>.input {
.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree.inactive > .input {
display: none;
}
.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree.inactive>.tree {
.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree.inactive > .tree {
height: 100%;
}
+3 -1
View File
@@ -928,7 +928,7 @@ export interface IFileEditorInput extends EditorInput, IEncodingSupport, ILangua
isResolved(): boolean;
}
export interface IFileEditorInputOptions extends ITextEditorOptions {
export interface IFileLimitedEditorInputOptions extends IEditorOptions {
/**
* If provided, the size of the file will be checked against the limits
@@ -937,6 +937,8 @@ export interface IFileEditorInputOptions extends ITextEditorOptions {
readonly limits?: IFileReadLimits;
}
export interface IFileEditorInputOptions extends ITextEditorOptions, IFileLimitedEditorInputOptions { }
export function createTooLargeFileError(group: IEditorGroup, input: EditorInput, options: IEditorOptions | undefined, message: string, preferencesService: IPreferencesService): Error {
return createEditorOpenError(message, [
toAction({
@@ -3,14 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Verbosity, EditorInputWithPreferredResource, EditorInputCapabilities } from 'vs/workbench/common/editor';
import { Verbosity, EditorInputWithPreferredResource, EditorInputCapabilities, IFileLimitedEditorInputOptions } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { URI } from 'vs/base/common/uri';
import { IFileService } from 'vs/platform/files/common/files';
import { ByteSize, IFileReadLimits, IFileService, getLargeFileConfirmationLimit } from 'vs/platform/files/common/files';
import { ILabelService } from 'vs/platform/label/common/label';
import { dirname, isEqual } from 'vs/base/common/resources';
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { isConfigured } from 'vs/platform/configuration/common/configuration';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration';
/**
* The base class for all editor inputs that open resources.
@@ -43,7 +45,8 @@ export abstract class AbstractResourceEditorInput extends EditorInput implements
preferredResource: URI | undefined,
@ILabelService protected readonly labelService: ILabelService,
@IFileService protected readonly fileService: IFileService,
@IFilesConfigurationService protected readonly filesConfigurationService: IFilesConfigurationService
@IFilesConfigurationService protected readonly filesConfigurationService: IFilesConfigurationService,
@ITextResourceConfigurationService protected readonly textResourceConfigurationService: ITextResourceConfigurationService
) {
super();
@@ -179,4 +182,27 @@ export abstract class AbstractResourceEditorInput extends EditorInput implements
override isReadonly(): boolean | IMarkdownString {
return this.filesConfigurationService.isReadonly(this.resource);
}
protected ensureLimits(options?: IFileLimitedEditorInputOptions): IFileReadLimits | undefined {
if (options?.limits) {
return options.limits; // respect passed in limits if any
}
// We want to determine the large file configuration based on the best defaults
// for the resource but also respecting user settings. We only apply user settings
// if explicitly configured by the user. Otherwise we pick the best limit for the
// resource scheme.
const defaultSizeLimit = getLargeFileConfirmationLimit(this.resource);
let configuredSizeLimit: number | undefined = undefined;
const configuredSizeLimitMb = this.textResourceConfigurationService.inspect<number>(this.resource, null, 'workbench.editorLargeFileConfirmation');
if (isConfigured(configuredSizeLimitMb)) {
configuredSizeLimit = configuredSizeLimitMb.value * ByteSize.MB; // normalize to MB
}
return {
size: configuredSizeLimit ?? defaultSizeLimit
};
}
}
@@ -18,6 +18,7 @@ import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResource
import { IReference } from 'vs/base/common/lifecycle';
import { createTextBufferFactory } from 'vs/editor/common/model/textModel';
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration';
/**
* The base class for all editor inputs that open in text editors.
@@ -31,9 +32,10 @@ export abstract class AbstractTextResourceEditorInput extends AbstractResourceEd
@ITextFileService protected readonly textFileService: ITextFileService,
@ILabelService labelService: ILabelService,
@IFileService fileService: IFileService,
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService
) {
super(resource, preferredResource, labelService, fileService, filesConfigurationService);
super(resource, preferredResource, labelService, fileService, filesConfigurationService, textResourceConfigurationService);
}
override save(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise<IUntypedEditorInput | undefined> {
@@ -104,9 +106,10 @@ export class TextResourceEditorInput extends AbstractTextResourceEditorInput imp
@IEditorService editorService: IEditorService,
@IFileService fileService: IFileService,
@ILabelService labelService: ILabelService,
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService
) {
super(resource, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService);
super(resource, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService, textResourceConfigurationService);
}
override getName(): string {
@@ -122,6 +122,8 @@ suite('ChatModel', () => {
});
suite('Response', () => {
ensureNoDisposablesAreLeakedInTestSuite();
test('content, markdown', async () => {
const response = new Response([]);
response.updateContent({ content: 'text', kind: 'content' });
@@ -298,8 +298,8 @@
width: auto;
}
.review-widget .body .comment-additional-actions .button-bar>.monaco-text-button,
.review-widget .body .comment-additional-actions .button-bar>.monaco-button-dropdown {
.review-widget .body .comment-additional-actions .button-bar > .monaco-text-button,
.review-widget .body .comment-additional-actions .button-bar > .monaco-button-dropdown {
margin: 0 10px 0 0;
}
@@ -493,7 +493,7 @@ export class DebugService implements IDebugService {
return false;
}
const cfg = await this.configurationManager.resolveDebugConfigurationWithSubstitutedVariables(launch && launch.workspace ? launch.workspace.uri : undefined, type, resolvedConfig, initCancellationToken.token);
const cfg = await this.configurationManager.resolveDebugConfigurationWithSubstitutedVariables(launch && launch.workspace ? launch.workspace.uri : undefined, resolvedConfig.type, resolvedConfig, initCancellationToken.token);
if (!cfg) {
if (launch && type && cfg === null && !initCancellationToken.token.isCancellationRequested) { // show launch.json only for "config" being "null".
await launch.openConfigFile({ preserveFocus: true, type }, initCancellationToken.token);
@@ -281,7 +281,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
private get yRange(): [number, number] {
if (!this._yRange) {
const isTitleBarVisible = this.layoutService.isVisible(Parts.TITLEBAR_PART, dom.getWindow(this.layoutService.activeContainer));
const yMin = isTitleBarVisible ? 0 : this.layoutService.mainContainerOffset.top;
const yMin = isTitleBarVisible ? this.layoutService.mainContainerOffset.top : 0;
let yMax = 0;
if (isTitleBarVisible) {
@@ -339,7 +339,7 @@ export class DisassemblyView extends EditorPane {
async goToInstructionAndOffset(instructionReference: string, offset: number, focus?: boolean) {
let addr = this._referenceToMemoryAddress.get(instructionReference);
if (addr === undefined) {
await this.loadDisassembledInstructions(instructionReference, 0, -DisassemblyView.NUM_INSTRUCTIONS_TO_LOAD, DisassemblyView.NUM_INSTRUCTIONS_TO_LOAD);
await this.loadDisassembledInstructions(instructionReference, 0, -DisassemblyView.NUM_INSTRUCTIONS_TO_LOAD, DisassemblyView.NUM_INSTRUCTIONS_TO_LOAD * 2);
addr = this._referenceToMemoryAddress.get(instructionReference);
}
@@ -10,12 +10,12 @@
text-overflow: ellipsis;
}
.monaco-action-bar .action-item>.action-label.extension-action.label,
.monaco-action-bar .action-dropdown-item>.action-label.extension-action.label {
.monaco-action-bar .action-item > .action-label.extension-action.label,
.monaco-action-bar .action-dropdown-item > .action-label.extension-action.label {
padding: 0 5px;
}
.monaco-action-bar .action-dropdown-item>.monaco-dropdown .action-label {
.monaco-action-bar .action-dropdown-item > .monaco-dropdown .action-label {
padding: 0;
}
@@ -36,7 +36,7 @@
}
.monaco-action-bar .action-item .action-label.extension-action.label,
.monaco-action-bar .action-item.action-dropdown-item>.action-dropdown-item-separator {
.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator {
background-color: var(--vscode-extensionButton-background) !important;
}
@@ -48,12 +48,12 @@
background-color: var(--vscode-extensionButton-hoverBackground) !important;
}
.monaco-action-bar .action-item.action-dropdown-item>.action-dropdown-item-separator>div {
.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator > div {
background-color: var(--vscode-extensionButton-separator);
}
.monaco-action-bar .action-item .action-label.extension-action.label.prominent,
.monaco-action-bar .action-item.action-dropdown-item>.action-dropdown-item-separator.prominent {
.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator.prominent {
background-color: var(--vscode-extensionButton-prominentBackground);
}
@@ -69,7 +69,7 @@
border: 1px solid var(--vscode-contrastBorder);
}
.monaco-action-bar .action-item.action-dropdown-item>.action-dropdown-item-separator {
.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator {
border-top: 1px solid var(--vscode-contrastBorder);
border-bottom: 1px solid var(--vscode-contrastBorder);
}
@@ -31,7 +31,7 @@
text-align: right;
}
.runtime-extensions-editor .extension .desc>.msg>span:not(:last-child)::after {
.runtime-extensions-editor .extension .desc > .msg > span:not(:last-child)::after {
content: '\2022';
padding: 0 4px;
opacity: .8;
@@ -9,7 +9,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
import { ByteSize, IFileReadLimits, IFileService, getLargeFileConfirmationLimit } from 'vs/platform/files/common/files';
import { IFileService } from 'vs/platform/files/common/files';
import { ITextFileService, TextFileEditorModelState, TextFileResolveReason, TextFileOperationError, TextFileOperationResult, ITextFileEditorModel, EncodingMode } from 'vs/workbench/services/textfile/common/textfiles';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IReference, dispose, DisposableStore } from 'vs/base/common/lifecycle';
@@ -24,7 +24,6 @@ import { Schemas } from 'vs/base/common/network';
import { createTextBufferFactory } from 'vs/editor/common/model/textModel';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration';
import { isConfigured } from 'vs/platform/configuration/common/configuration';
import { IMarkdownString } from 'vs/base/common/htmlContent';
const enum ForceOpenAs {
@@ -99,9 +98,9 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
@IEditorService editorService: IEditorService,
@IPathService private readonly pathService: IPathService,
@ITextResourceConfigurationService private readonly textResourceConfigurationService: ITextResourceConfigurationService
@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService
) {
super(resource, preferredResource, editorService, textFileService, labelService, fileService, filesConfigurationService);
super(resource, preferredResource, editorService, textFileService, labelService, fileService, filesConfigurationService, textResourceConfigurationService);
this.model = this.textFileService.files.get(resource);
@@ -396,29 +395,6 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements
}
}
private ensureLimits(options?: IFileEditorInputOptions): IFileReadLimits | undefined {
if (options?.limits) {
return options.limits; // respect passed in limits if any
}
// We want to determine the large file configuration based on the best defaults
// for the resource but also respecting user settings. We only apply user settings
// if explicitly configured by the user. Otherwise we pick the best limit for the
// resource scheme.
const defaultSizeLimit = getLargeFileConfirmationLimit(this.resource);
let configuredSizeLimit: number | undefined = undefined;
const configuredSizeLimitMb = this.textResourceConfigurationService.inspect<number>(this.resource, null, 'workbench.editorLargeFileConfirmation');
if (isConfigured(configuredSizeLimitMb)) {
configuredSizeLimit = configuredSizeLimitMb.value * ByteSize.MB; // normalize to MB
}
return {
size: configuredSizeLimit ?? defaultSizeLimit
};
}
private async doResolveAsBinary(): Promise<BinaryEditorModel> {
const model = this.instantiationService.createInstance(BinaryEditorModel, this.preferredResource, this.getName());
await model.resolve();
@@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri';
import { join } from 'vs/base/common/path';
import { validateFileName } from 'vs/workbench/contrib/files/browser/fileActions';
import { ExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel';
import { toResource } from 'vs/base/test/common/utils';
import { ensureNoDisposablesAreLeakedInTestSuite, toResource } from 'vs/base/test/common/utils';
import { TestFileService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { NullFilesConfigurationService } from 'vs/workbench/test/common/workbenchTestServices';
@@ -277,4 +277,6 @@ suite('Files - View Model', function () {
ExplorerItem.mergeLocalWithDisk(merge2, merge1);
assert.ok(existingChild === merge1.getChild(existingChild!.name));
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { incrementFileName } from 'vs/workbench/contrib/files/browser/fileActions';
suite('Files - Increment file name simple', () => {
@@ -134,6 +135,7 @@ suite('Files - Increment file name simple', () => {
assert.strictEqual(result, 'test copy 2');
});
ensureNoDisposablesAreLeakedInTestSuite();
});
suite('Files - Increment file name smart', () => {
@@ -324,4 +326,5 @@ suite('Files - Increment file name smart', () => {
assert.strictEqual(result, '2-test');
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -93,7 +93,7 @@
}
/* UGLY - fighting against workbench styles */
.monaco-workbench .part.editor>.content .monaco-editor .inline-chat .progress .monaco-progress-container {
.monaco-workbench .part.editor > .content .monaco-editor .inline-chat .progress .monaco-progress-container {
top: 0;
}
@@ -900,6 +900,10 @@ export class LiveStrategy3 extends EditModeStrategy {
}
: undefined;
this._sessionStore.add(this._session.textModelN.onDidChangeContent(e => {
this._showDiff(true, true);
}));
const zoneLineNumber = this._zone.position!.lineNumber;
const myDistance = zoneLineNumber <= modifiedRange.startLineNumber
? modifiedRange.startLineNumber - zoneLineNumber
@@ -25,7 +25,7 @@
}
}
.monaco-workbench .statusbar DIV#status\.languageStatus A>SPAN.codicon.wiggle {
.monaco-workbench .statusbar DIV#status\.languageStatus A > SPAN.codicon.wiggle {
animation-duration: .8s;
animation-iteration-count: 1;
animation-name: wiggle;
@@ -62,60 +62,60 @@
border-bottom: 1px solid var(--vscode-notifications-border);
}
.monaco-workbench .hover-language-status>.severity {
.monaco-workbench .hover-language-status > .severity {
padding-right: 8px;
flex: 1;
margin: auto;
display: none;
}
.monaco-workbench .hover-language-status>.severity.sev3 {
.monaco-workbench .hover-language-status > .severity.sev3 {
color: var(--vscode-notificationsErrorIcon-foreground)
}
.monaco-workbench .hover-language-status>.severity.sev2 {
.monaco-workbench .hover-language-status > .severity.sev2 {
color: var(--vscode-notificationsInfoIcon-foreground)
}
.monaco-workbench .hover-language-status>.severity.show {
.monaco-workbench .hover-language-status > .severity.show {
display: inherit;
}
.monaco-workbench .hover-language-status>.element {
.monaco-workbench .hover-language-status > .element {
display: flex;
justify-content: space-between;
vertical-align: middle;
flex-grow: 100;
}
.monaco-workbench .hover-language-status>.element>.left>.detail:not(:empty)::before {
.monaco-workbench .hover-language-status > .element > .left > .detail:not(:empty)::before {
content: '\2013';
padding: 0 4px;
opacity: 0.6;
}
.monaco-workbench .hover-language-status>.element>.left>.label:empty {
.monaco-workbench .hover-language-status > .element > .left > .label:empty {
display: none;
}
.monaco-workbench .hover-language-status>.element .left {
.monaco-workbench .hover-language-status > .element .left {
margin: auto 0;
}
.monaco-workbench .hover-language-status>.element .right {
.monaco-workbench .hover-language-status > .element .right {
margin: auto 0;
display: flex;
}
.monaco-workbench .hover-language-status>.element .right:not(:empty) {
.monaco-workbench .hover-language-status > .element .right:not(:empty) {
padding-left: 16px;
}
.monaco-workbench .hover-language-status>.element .right .monaco-link {
.monaco-workbench .hover-language-status > .element .right .monaco-link {
margin: auto 0;
white-space: nowrap;
}
.monaco-workbench .hover-language-status>.element .right .monaco-action-bar:not(:first-child) {
.monaco-workbench .hover-language-status > .element .right .monaco-action-bar:not(:first-child) {
padding-left: 8px;
}
@@ -8,6 +8,7 @@ import { autorun } from 'vs/base/common/observable';
import { isEqual } from 'vs/base/common/resources';
import { isDefined } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration';
import { localize } from 'vs/nls';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IFileService } from 'vs/platform/files/common/files';
@@ -60,9 +61,10 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements
@ILabelService labelService: ILabelService,
@IFileService fileService: IFileService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService
) {
super(result, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService);
super(result, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService, textResourceConfigurationService);
}
override dispose(): void {
@@ -473,7 +473,7 @@ class WorkspaceMergeEditorInputModel extends EditorModel implements IMergeEditor
primaryButton: someUnhandledConflicts
? localize({ key: 'workspace.closeWithConflicts', comment: ['&& denotes a mnemonic'] }, '&&Close with Conflicts')
: localize({ key: 'workspace.close', comment: ['&& denotes a mnemonic'] }, '&&Close'),
checkbox: { label: localize('noMoreWarn', "Don't ask again") }
checkbox: { label: localize('noMoreWarn', "Do not ask me again") }
});
if (checkboxChecked) {
@@ -258,7 +258,7 @@
text-align: center;
}
.monaco-workbench .notebookOverlay>.cell-list-container>.monaco-list>.monaco-scrollable-element>.monaco-list-rows>.monaco-list-row .cell-statusbar-hidden .execution-count-label {
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-statusbar-hidden .execution-count-label {
line-height: 15px;
}

Some files were not shown because too many files have changed in this diff Show More