提交 1ec127e6 编写于 作者: J João Moreno

Merge branch 'master' of https://github.com/microsoft/vscode

......@@ -34,7 +34,7 @@ The extension fetches data from https://registry.npmjs.org and https://registry.
- `npm.autoDetect` - Enable detecting scripts as tasks, the default is `on`.
- `npm.runSilent` - Run npm script with the `--silent` option, the default is `false`.
- `npm.packageManager` - The package manager used to run the scripts: `npm` or `yarn`, the default is `npm`.
- `npm.packageManager` - The package manager used to run the scripts: `npm`, `yarn` or `pnpm`, the default is `npm`.
- `npm.exclude` - Glob patterns for folders that should be excluded from automatic script detection. The pattern is matched against the **absolute path** of the package.json. For example, to exclude all test folders use '**/test/**'.
- `npm.enableScriptExplorer` - Enable an explorer view for npm scripts.
- `npm.scriptExplorerAction` - The default click action: `open` or `run`, the default is `open`.
......
......@@ -215,7 +215,8 @@
"type": "string",
"enum": [
"npm",
"yarn"
"yarn",
"pnpm"
],
"default": "npm",
"description": "%config.npm.packageManager%"
......
......@@ -8,7 +8,6 @@ import * as assert from 'assert';
import { Registry } from 'vs/platform/registry/common/platform';
import { ConfigurationService } from 'vs/platform/configuration/common/configurationService';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
import { testFile, ITestFileResult } from 'vs/base/test/node/utils';
import { URI } from 'vs/base/common/uri';
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { Event } from 'vs/base/common/event';
......@@ -20,27 +19,20 @@ import { IFileService } from 'vs/platform/files/common/files';
import { VSBuffer } from 'vs/base/common/buffer';
import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider';
suite('ConfigurationService - Node', () => {
suite('ConfigurationService', () => {
let fileService: IFileService;
let testFileResult: ITestFileResult;
let settingsResource: URI;
const disposables: DisposableStore = new DisposableStore();
setup(async () => {
fileService = new FileService(new NullLogService());
disposables.add(fileService);
const diskFileSystemProvider = new InMemoryFileSystemProvider();
disposables.add(diskFileSystemProvider);
fileService = disposables.add(new FileService(new NullLogService()));
const diskFileSystemProvider = disposables.add(new InMemoryFileSystemProvider());
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
testFileResult = await testFile('config', 'config.json');
settingsResource = URI.file(testFileResult.testFile);
settingsResource = URI.file('settings.json');
});
teardown(async () => {
disposables.clear();
await testFileResult.cleanUp();
});
teardown(() => disposables.clear());
test('simple', async () => {
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }'));
......
......@@ -1734,8 +1734,8 @@ declare module 'vscode' {
/**
* Dialog title.
*
* Depending on the underlying operating system this parameter might be ignored, since some
* systems do not present title on open dialogs.
* This parameter might be ignored, as not all operating systems display a title on open dialogs
* (for example, macOS).
*/
title?: string;
}
......@@ -1769,8 +1769,8 @@ declare module 'vscode' {
/**
* Dialog title.
*
* Depending on the underlying operating system this parameter might be ignored, since some
* systems do not present title on save dialogs.
* This parameter might be ignored, as not all operating systems display a title on save dialogs
* (for example, macOS).
*/
title?: string;
}
......
......@@ -38,7 +38,7 @@ import { ResourceLabel } from 'vs/workbench/browser/labels';
import { BreadcrumbsConfig, IBreadcrumbsService } from 'vs/workbench/browser/parts/editor/breadcrumbs';
import { BreadcrumbElement, EditorBreadcrumbsModel, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel';
import { BreadcrumbsPicker, createBreadcrumbsPicker } from 'vs/workbench/browser/parts/editor/breadcrumbsPicker';
import { IEditorPartOptions, toResource, SideBySideEditor } from 'vs/workbench/common/editor';
import { IEditorPartOptions, toResource, SideBySideEditor, SideBySideEditorInput, IEditorInputFactoryRegistry, Extensions } from 'vs/workbench/common/editor';
import { ACTIVE_GROUP, ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
......@@ -49,6 +49,7 @@ import { withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types';
import { ILabelService } from 'vs/platform/label/common/label';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
import { Registry } from 'vs/platform/registry/common/platform';
class Item extends BreadcrumbsItem {
......@@ -248,12 +249,23 @@ export class BreadcrumbsControl {
}
}
// display uri which can be derived from file input
let fileInfoUri = uri;
let input = this._editorGroup.activeEditor;
if (input instanceof SideBySideEditorInput) {
input = input.primary;
}
if (Registry.as<IEditorInputFactoryRegistry>(Extensions.EditorInputFactories).getFileEditorInputFactory().isFileEditorInput(input)) {
fileInfoUri = input.label;
}
this.domNode.classList.toggle('hidden', false);
this._ckBreadcrumbsVisible.set(true);
this._ckBreadcrumbsPossible.set(true);
const editor = this._getActiveCodeEditor();
const model = new EditorBreadcrumbsModel(
fileInfoUri,
uri, editor,
this._configurationService,
this._textResourceConfigurationService,
......
......@@ -52,6 +52,7 @@ export class EditorBreadcrumbsModel {
readonly onDidUpdate: Event<this> = this._onDidUpdate.event;
constructor(
fileInfoUri: URI,
private readonly _uri: URI,
private readonly _editor: ICodeEditor | undefined,
@IConfigurationService private readonly _configurationService: IConfigurationService,
......@@ -64,7 +65,7 @@ export class EditorBreadcrumbsModel {
this._disposables.add(this._cfgFilePath.onDidChange(_ => this._onDidUpdate.fire(this)));
this._disposables.add(this._cfgSymbolPath.onDidChange(_ => this._onDidUpdate.fire(this)));
this._fileInfo = EditorBreadcrumbsModel._initFilePathInfo(this._uri, workspaceService);
this._fileInfo = EditorBreadcrumbsModel._initFilePathInfo(fileInfoUri, workspaceService);
this._bindToEditor();
this._onDidUpdate.fire(this);
}
......
......@@ -275,6 +275,11 @@ export class ViewsService extends Disposable implements IViewsService {
return viewContainerId ? this.viewDescriptorService.getViewContainerById(viewContainerId) : null;
}
getActiveViewPaneContainerWithId(viewContainerId: string): IViewPaneContainer | null {
const viewContainer = this.viewDescriptorService.getViewContainerById(viewContainerId);
return viewContainer ? this.getActiveViewPaneContainer(viewContainer) : null;
}
async openViewContainer(id: string, focus?: boolean): Promise<IPaneComposite | null> {
const viewContainer = this.viewDescriptorService.getViewContainerById(id);
if (viewContainer) {
......
......@@ -484,6 +484,7 @@ export interface IViewsService {
openViewContainer(id: string, focus?: boolean): Promise<IPaneComposite | null>;
closeViewContainer(id: string): void;
getVisibleViewContainer(location: ViewContainerLocation): ViewContainer | null;
getActiveViewPaneContainerWithId(viewContainerId: string): IViewPaneContainer | null;
// View APIs
readonly onDidChangeViewVisibility: Event<{ id: string, visible: boolean }>;
......
......@@ -348,8 +348,8 @@ export class DebugService implements IDebugService {
}
if (configOrName && !config) {
const message = !!launch ? nls.localize('configMissing', "Configuration '{0}' is missing in 'launch.json'.", typeof configOrName === 'string' ? configOrName : JSON.stringify(configOrName)) :
nls.localize('launchJsonDoesNotExist', "'launch.json' does not exist.");
const message = !!launch ? nls.localize('configMissing', "Configuration '{0}' is missing in 'launch.json'.", typeof configOrName === 'string' ? configOrName : configOrName.name) :
nls.localize('launchJsonDoesNotExist', "'launch.json' does not exist for passed workspace folder.");
throw new Error(message);
}
......@@ -358,6 +358,7 @@ export class DebugService implements IDebugService {
return result;
} catch (err) {
// make sure to get out of initializing state, and propagate the result
this.notificationService.error(err);
this.endInitializingState();
return Promise.reject(err);
}
......
......@@ -19,7 +19,7 @@ import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/brow
import {
OpenExtensionsViewletAction, InstallExtensionsAction, ShowOutdatedExtensionsAction, ShowRecommendedExtensionsAction, ShowRecommendedKeymapExtensionsAction, ShowPopularExtensionsAction,
ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowDisabledExtensionsAction, ShowBuiltInExtensionsAction, UpdateAllAction,
EnableAllAction, EnableAllWorkspaceAction, DisableAllAction, DisableAllWorkspaceAction, CheckForUpdatesAction, ShowLanguageExtensionsAction, ShowAzureExtensionsAction, EnableAutoUpdateAction, DisableAutoUpdateAction, ConfigureRecommendedExtensionsCommandsContributor, InstallVSIXAction, ReinstallAction, InstallSpecificVersionOfExtensionAction
EnableAllAction, EnableAllWorkspaceAction, DisableAllAction, DisableAllWorkspaceAction, CheckForUpdatesAction, ShowLanguageExtensionsAction, ShowAzureExtensionsAction, EnableAutoUpdateAction, DisableAutoUpdateAction, ConfigureRecommendedExtensionsCommandsContributor, InstallVSIXAction, ReinstallAction, InstallSpecificVersionOfExtensionAction, ClearExtensionsSearchResultsAction
} from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput';
import { ExtensionEditor } from 'vs/workbench/contrib/extensions/browser/extensionEditor';
......@@ -148,6 +148,7 @@ actionRegistry.registerWorkbenchAction(enableAllWorkspaceAction, 'Extensions: En
const checkForUpdatesAction = SyncActionDescriptor.from(CheckForUpdatesAction);
actionRegistry.registerWorkbenchAction(checkForUpdatesAction, `Extensions: Check for Extension Updates`, ExtensionsLabel);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(ClearExtensionsSearchResultsAction), 'Extensions: Clear Extensions Search Results', ExtensionsLabel);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(EnableAutoUpdateAction), `Extensions: Enable Auto Updating Extensions`, ExtensionsLabel);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(DisableAutoUpdateAction), `Extensions: Disable Auto Updating Extensions`, ExtensionsLabel);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(InstallSpecificVersionOfExtensionAction), 'Install Specific Version of Extension...', ExtensionsLabel);
......
......@@ -60,6 +60,7 @@ import { IProductService } from 'vs/platform/product/common/productService';
import { IFileDialogService, IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
import { Codicon } from 'vs/base/common/codicons';
import { IViewsService } from 'vs/workbench/common/views';
export function toExtensionDescription(local: ILocalExtension): IExtensionDescription {
return {
......@@ -1641,19 +1642,39 @@ export class ShowDisabledExtensionsAction extends Action {
}
}
export class ClearExtensionsInputAction extends Action {
export class ClearExtensionsSearchResultsAction extends Action {
static readonly ID = 'workbench.extensions.action.clearExtensionsInput';
static readonly LABEL = localize('clearExtensionsInput', "Clear Extensions Search Results");
static readonly ID = 'workbench.extensions.action.clearExtensionsSearchResults';
static readonly LABEL = localize('clearExtensionsSearchResults', "Clear Extensions Search Results");
constructor(
id: string,
label: string,
@IViewsService private readonly viewsService: IViewsService
) {
super(id, label, 'codicon-clear-all', true);
}
async run(): Promise<void> {
const viewPaneContainer = this.viewsService.getActiveViewPaneContainerWithId(VIEWLET_ID);
if (viewPaneContainer) {
const extensionsViewPaneContainer = viewPaneContainer as IExtensionsViewPaneContainer;
extensionsViewPaneContainer.search('');
extensionsViewPaneContainer.focus();
}
}
}
export class ClearExtensionsInputAction extends ClearExtensionsSearchResultsAction {
constructor(
id: string,
label: string,
onSearchChange: Event<string>,
value: string,
@IViewletService private readonly viewletService: IViewletService
@IViewsService viewsService: IViewsService
) {
super(id, label, 'codicon-clear-all', true);
super(id, label, viewsService);
this.onSearchChange(value);
this._register(onSearchChange(this.onSearchChange, this));
}
......@@ -1662,14 +1683,6 @@ export class ClearExtensionsInputAction extends Action {
this.enabled = !!value;
}
run(): Promise<void> {
return this.viewletService.openViewlet(VIEWLET_ID, true)
.then(viewlet => viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer)
.then(viewlet => {
viewlet.search('');
viewlet.focus();
});
}
}
export class ShowBuiltInExtensionsAction extends Action {
......
......@@ -9,6 +9,7 @@ import { TerminalLink } from 'vs/workbench/contrib/terminal/browser/links/termin
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TerminalBaseLinkProvider } from 'vs/workbench/contrib/terminal/browser/links/terminalBaseLinkProvider';
import { ITerminalExternalLinkProvider, ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
import { XtermLinkMatcherHandler } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
/**
* An adapter to convert a simple external link provider into an internal link provider that
......@@ -20,6 +21,7 @@ export class TerminalExternalLinkProviderAdapter extends TerminalBaseLinkProvide
private readonly _xterm: Terminal,
private readonly _instance: ITerminalInstance,
private readonly _externalLinkProvider: ITerminalExternalLinkProvider,
private readonly _wrapLinkHandler: (handler: (event: MouseEvent | undefined, link: string) => void) => XtermLinkMatcherHandler,
private readonly _tooltipCallback: (link: TerminalLink, viewportRange: IViewportRange, modifierDownCallback?: () => void, modifierUpCallback?: () => void) => void,
@IInstantiationService private readonly _instantiationService: IInstantiationService
) {
......@@ -58,7 +60,8 @@ export class TerminalExternalLinkProviderAdapter extends TerminalBaseLinkProvide
endLineNumber: 1
}, startLine);
const matchingText = lineContent.substr(link.startIndex, link.length) || '';
return this._instantiationService.createInstance(TerminalLink, bufferRange, matchingText, this._xterm.buffer.active.viewportY, (_, text) => link.activate(text), this._tooltipCallback, true, link.label);
const activateLink = this._wrapLinkHandler((_, text) => link.activate(text));
return this._instantiationService.createInstance(TerminalLink, bufferRange, matchingText, this._xterm.buffer.active.viewportY, activateLink, this._tooltipCallback, true, link.label);
});
}
}
......@@ -156,7 +156,7 @@ export class TerminalLinkManager extends DisposableStore {
}
public registerExternalLinkProvider(instance: ITerminalInstance, linkProvider: ITerminalExternalLinkProvider): IDisposable {
const wrappedLinkProvider = this._instantiationService.createInstance(TerminalExternalLinkProviderAdapter, this._xterm, instance, linkProvider, this._tooltipCallback2.bind(this));
const wrappedLinkProvider = this._instantiationService.createInstance(TerminalExternalLinkProviderAdapter, this._xterm, instance, linkProvider, this._wrapLinkHandler.bind(this), this._tooltipCallback2.bind(this));
const newLinkProvider = this._xterm.registerLinkProvider(wrappedLinkProvider);
// Re-register the standard link providers so they are a lower priority that the new one
this._registerStandardLinkProviders();
......
......@@ -111,7 +111,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
try {
const result = await stat(slc.executable);
if (!result.isFile() && !result.isSymbolicLink()) {
return { message: localize('launchFail.executableIsNotFileOrSymlink', "Shell path \"{0}\" is not a file of a symlink", slc.executable) };
return { message: localize('launchFail.executableIsNotFileOrSymlink', "Path to shell executable \"{0}\" is not a file of a symlink", slc.executable) };
}
} catch (err) {
if (err?.code === 'ENOENT') {
......@@ -120,7 +120,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
const envPaths: string[] | undefined = (slc.env && slc.env.PATH) ? slc.env.PATH.split(path.delimiter) : undefined;
const executable = await findExecutable(slc.executable!, cwd, envPaths);
if (!executable) {
return { message: localize('launchFail.executableDoesNotExist', "Shell path \"{0}\" does not exist", slc.executable) };
return { message: localize('launchFail.executableDoesNotExist', "Path to shell executable \"{0}\" does not exist", slc.executable) };
}
}
}
......
......@@ -32,7 +32,7 @@ suite('Breadcrumb Model', function () {
test('only uri, inside workspace', function () {
let model = new EditorBreadcrumbsModel(URI.parse('foo:/bar/baz/ws/some/path/file.ts'), undefined, configService, configService, workspaceService);
let model = new EditorBreadcrumbsModel(URI.parse('foo:/bar/baz/ws/some/path/file.ts'), URI.parse('foo:/bar/baz/ws/some/path/file.ts'), undefined, configService, configService, workspaceService);
let elements = model.getElements();
assert.equal(elements.length, 3);
......@@ -45,9 +45,24 @@ suite('Breadcrumb Model', function () {
assert.equal(three.uri.toString(), 'foo:/bar/baz/ws/some/path/file.ts');
});
test('display uri matters for FileElement', function () {
let model = new EditorBreadcrumbsModel(URI.parse('foo:/bar/baz/ws/some/PATH/file.ts'), URI.parse('foo:/bar/baz/ws/some/path/file.ts'), undefined, configService, configService, workspaceService);
let elements = model.getElements();
assert.equal(elements.length, 3);
let [one, two, three] = elements as FileElement[];
assert.equal(one.kind, FileKind.FOLDER);
assert.equal(two.kind, FileKind.FOLDER);
assert.equal(three.kind, FileKind.FILE);
assert.equal(one.uri.toString(), 'foo:/bar/baz/ws/some');
assert.equal(two.uri.toString(), 'foo:/bar/baz/ws/some/PATH');
assert.equal(three.uri.toString(), 'foo:/bar/baz/ws/some/PATH/file.ts');
});
test('only uri, outside workspace', function () {
let model = new EditorBreadcrumbsModel(URI.parse('foo:/outside/file.ts'), undefined, configService, configService, workspaceService);
let model = new EditorBreadcrumbsModel(URI.parse('foo:/outside/file.ts'), URI.parse('foo:/outside/file.ts'), undefined, configService, configService, workspaceService);
let elements = model.getElements();
assert.equal(elements.length, 2);
......
......@@ -495,6 +495,7 @@ export class TestViewsService implements IViewsService {
openView<T extends IView>(id: string, focus?: boolean | undefined): Promise<T | null> { return Promise.resolve(null); }
closeView(id: string): void { }
getViewProgressIndicator(id: string) { return null!; }
getActiveViewPaneContainerWithId(id: string) { return null; }
}
export class TestEditorGroupsService implements IEditorGroupsService {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册