Merge from vscode ff915844119ce9485abfe8aa9076ec76b5300ddd (#10030)

This commit is contained in:
Anthony Dresser
2020-04-16 15:12:30 -07:00
committed by GitHub
parent 4fc9057025
commit f3d4a55bb1
14 changed files with 103 additions and 32 deletions

View File

@@ -186,6 +186,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
const checksums = computeChecksums(out, [ const checksums = computeChecksums(out, [
'vs/workbench/workbench.desktop.main.js', 'vs/workbench/workbench.desktop.main.js',
'vs/workbench/workbench.desktop.main.css', 'vs/workbench/workbench.desktop.main.css',
'vs/workbench/services/extensions/node/extensionHostProcess.js',
'vs/code/electron-browser/workbench/workbench.html', 'vs/code/electron-browser/workbench/workbench.html',
'vs/code/electron-browser/workbench/workbench.js' 'vs/code/electron-browser/workbench/workbench.js'
]); ]);

View File

@@ -1262,7 +1262,7 @@
"timeline/item/context": [ "timeline/item/context": [
{ {
"command": "git.timeline.openDiff", "command": "git.timeline.openDiff",
"group": "1_actions", "group": "1_timeline",
"when": "config.git.enabled && !git.missing && timelineItem =~ /git:file\\b/" "when": "config.git.enabled && !git.missing && timelineItem =~ /git:file\\b/"
}, },
{ {

View File

@@ -443,7 +443,10 @@ export class Git {
); );
if (networkPath !== undefined) { if (networkPath !== undefined) {
return path.normalize( return path.normalize(
repoUri.fsPath.replace(networkPath, `${letter.toLowerCase()}:`), repoUri.fsPath.replace(
networkPath,
`${letter.toLowerCase()}:${networkPath.endsWith('\\') ? '\\' : ''}`
),
); );
} }
} catch { } } catch { }

View File

@@ -268,10 +268,10 @@ export type FuzzyScore2 = [number /* score*/, IMatch[]];
const NO_SCORE2: FuzzyScore2 = [NO_MATCH, []]; const NO_SCORE2: FuzzyScore2 = [NO_MATCH, []];
export function scoreFuzzy2(target: string, query: IPreparedQuery, patternStart = 0, matchOffset = 0): FuzzyScore2 { export function scoreFuzzy2(target: string, query: IPreparedQuery, patternStart = 0, matchOffset = 0, skipMultiMatching = false): FuzzyScore2 {
// Score: multiple inputs // Score: multiple inputs (unless disabled)
if (query.values && query.values.length > 1) { if (!skipMultiMatching && query.values && query.values.length > 1) {
return doScoreFuzzy2Multiple(target, query.values, patternStart, matchOffset); return doScoreFuzzy2Multiple(target, query.values, patternStart, matchOffset);
} }

View File

@@ -662,7 +662,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.ui.list.clearFocus(); this.ui.list.clearFocus();
} }
})); }));
this.visibleDisposables.add(this.ui.inputBox.onKeyDown(event => { this.visibleDisposables.add((this._hideInput ? this.ui.list : this.ui.inputBox).onKeyDown((event: KeyboardEvent | StandardKeyboardEvent) => {
switch (event.keyCode) { switch (event.keyCode) {
case KeyCode.DownArrow: case KeyCode.DownArrow:
this.ui.list.focus(QuickInputListFocus.Next); this.ui.list.focus(QuickInputListFocus.Next);

View File

@@ -259,6 +259,8 @@ export class QuickInputList {
onChangedCheckedElements: Event<IQuickPickItem[]> = this._onChangedCheckedElements.event; onChangedCheckedElements: Event<IQuickPickItem[]> = this._onChangedCheckedElements.event;
private readonly _onButtonTriggered = new Emitter<IQuickPickItemButtonEvent<IQuickPickItem>>(); private readonly _onButtonTriggered = new Emitter<IQuickPickItemButtonEvent<IQuickPickItem>>();
onButtonTriggered = this._onButtonTriggered.event; onButtonTriggered = this._onButtonTriggered.event;
private readonly _onKeyDown = new Emitter<StandardKeyboardEvent>();
onKeyDown: Event<StandardKeyboardEvent> = this._onKeyDown.event;
private readonly _onLeave = new Emitter<void>(); private readonly _onLeave = new Emitter<void>();
onLeave: Event<void> = this._onLeave.event; onLeave: Event<void> = this._onLeave.event;
private _fireCheckedEvents = true; private _fireCheckedEvents = true;
@@ -314,6 +316,8 @@ export class QuickInputList {
} }
break; break;
} }
this._onKeyDown.fire(event);
})); }));
this.disposables.push(this.list.onMouseDown(e => { this.disposables.push(this.list.onMouseDown(e => {
if (e.browserEvent.button !== 2) { if (e.browserEvent.button !== 2) {

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { app, ipcMain as ipc, systemPreferences, shell, Event, contentTracing, protocol, powerMonitor, IpcMainEvent, BrowserWindow } from 'electron'; import { app, ipcMain as ipc, systemPreferences, shell, Event, contentTracing, protocol, powerMonitor, IpcMainEvent, BrowserWindow, dialog } from 'electron';
import { IProcessEnvironment, isWindows, isMacintosh } from 'vs/base/common/platform'; import { IProcessEnvironment, isWindows, isMacintosh } from 'vs/base/common/platform';
import { WindowsMainService } from 'vs/platform/windows/electron-main/windowsMainService'; import { WindowsMainService } from 'vs/platform/windows/electron-main/windowsMainService';
import { IWindowOpenable } from 'vs/platform/windows/common/windows'; import { IWindowOpenable } from 'vs/platform/windows/common/windows';
@@ -80,6 +80,7 @@ import { coalesce } from 'vs/base/common/arrays';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys'; import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { StorageKeysSyncRegistryChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc'; import { StorageKeysSyncRegistryChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc';
import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService'; import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels';
export class CodeApplication extends Disposable { export class CodeApplication extends Disposable {
private windowsMainService: IWindowsMainService | undefined; private windowsMainService: IWindowsMainService | undefined;
@@ -605,6 +606,11 @@ export class CodeApplication extends Disposable {
return undefined; return undefined;
} }
})).filter(pendingUriToHandle => { })).filter(pendingUriToHandle => {
// if URI should be blocked, filter it out
if (this.shouldBlockURI(pendingUriToHandle)) {
return false;
}
// filter out any protocol link that wants to open as window so that // filter out any protocol link that wants to open as window so that
// we open the right set of windows on startup and not restore the // we open the right set of windows on startup and not restore the
// previous workspace too. // previous workspace too.
@@ -623,6 +629,10 @@ export class CodeApplication extends Disposable {
const environmentService = this.environmentService; const environmentService = this.environmentService;
urlService.registerHandler({ urlService.registerHandler({
async handleURL(uri: URI): Promise<boolean> { async handleURL(uri: URI): Promise<boolean> {
// if URI should be blocked, behave as if it's handled
if (app.shouldBlockURI(uri)) {
return true;
}
// Check for URIs to open in window // Check for URIs to open in window
const windowOpenableFromProtocolLink = app.getWindowOpenableFromProtocolLink(uri); const windowOpenableFromProtocolLink = app.getWindowOpenableFromProtocolLink(uri);
@@ -727,6 +737,29 @@ export class CodeApplication extends Disposable {
}); });
} }
private shouldBlockURI(uri: URI): boolean {
if (uri.authority === Schemas.file && isWindows) {
const res = dialog.showMessageBoxSync({
title: product.nameLong,
type: 'question',
buttons: [
mnemonicButtonLabel(localize({ key: 'open', comment: ['&& denotes a mnemonic'] }, "&&Yes")),
mnemonicButtonLabel(localize({ key: 'cancel', comment: ['&& denotes a mnemonic'] }, "&&No")),
],
cancelId: 1,
message: localize('confirmOpenMessage', "An external application wants to open '{0}' in {1}. Do you want to open this file or folder?", getPathLabel(uri.fsPath), product.nameShort),
detail: localize('confirmOpenDetail', "If you did not initiate this request, it may represent an attempted attack on your system. Unless you took an explicit action to initiate this request, you should press 'No'"),
noLink: true
});
if (res === 1) {
return true;
}
}
return false;
}
private getWindowOpenableFromProtocolLink(uri: URI): IWindowOpenable | undefined { private getWindowOpenableFromProtocolLink(uri: URI): IWindowOpenable | undefined {
if (!uri.path) { if (!uri.path) {
return undefined; return undefined;

View File

@@ -220,6 +220,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
const symbolLabel = trim(symbol.name); const symbolLabel = trim(symbol.name);
const symbolLabelWithIcon = `$(symbol-${SymbolKinds.toString(symbol.kind) || 'property'}) ${symbolLabel}`; const symbolLabelWithIcon = `$(symbol-${SymbolKinds.toString(symbol.kind) || 'property'}) ${symbolLabel}`;
const symbolLabelIconOffset = symbolLabelWithIcon.length - symbolLabel.length;
let containerLabel = symbol.containerName; let containerLabel = symbol.containerName;
if (options?.extraContainerLabel) { if (options?.extraContainerLabel) {
@@ -238,14 +239,28 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
if (query.original.length > filterPos) { if (query.original.length > filterPos) {
// Score by symbol // First: try to score on the entire query, it is possible that
[symbolScore, symbolMatches] = scoreFuzzy2(symbolLabel, symbolQuery, filterPos, symbolLabelWithIcon.length - symbolLabel.length /* Readjust matches to account for codicons in label */); // the symbol matches perfectly (e.g. searching for "change log"
// can be a match on a markdown symbol "change log"). In that
// case we want to skip the container query altogether.
let skipContainerQuery = false;
if (symbolQuery !== query) {
[symbolScore, symbolMatches] = scoreFuzzy2(symbolLabel, query, filterPos, symbolLabelIconOffset, true /* skip multi matching */);
if (symbolScore) {
skipContainerQuery = true; // since we consumed the query, skip any container matching
}
}
// Otherwise: score on the symbol query and match on the container later
if (!symbolScore) { if (!symbolScore) {
continue; [symbolScore, symbolMatches] = scoreFuzzy2(symbolLabel, symbolQuery, filterPos, symbolLabelIconOffset);
if (!symbolScore) {
continue;
}
} }
// Score by container if specified // Score by container if specified
if (containerQuery) { if (!skipContainerQuery && containerQuery) {
if (containerLabel && containerQuery.original.length > 0) { if (containerLabel && containerQuery.original.length > 0) {
[containerScore, containerMatches] = scoreFuzzy2(containerLabel, containerQuery); [containerScore, containerMatches] = scoreFuzzy2(containerLabel, containerQuery);
} }

View File

@@ -18,7 +18,7 @@ import { DelayedDragHandler } from 'vs/base/browser/dnd';
import { IActivity } from 'vs/workbench/common/activity'; import { IActivity } from 'vs/workbench/common/activity';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { Emitter } from 'vs/base/common/event'; import { Emitter } from 'vs/base/common/event';
import { LocalSelectionTransfer, DraggedCompositeIdentifier, DraggedViewIdentifier, CompositeDragAndDropObserver, ICompositeDragAndDrop, Before2D } from 'vs/workbench/browser/dnd'; import { CompositeDragAndDropObserver, ICompositeDragAndDrop, Before2D } from 'vs/workbench/browser/dnd';
import { Color } from 'vs/base/common/color'; import { Color } from 'vs/base/common/color';
export interface ICompositeActivity { export interface ICompositeActivity {
@@ -452,7 +452,6 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
private static manageExtensionAction: ManageExtensionAction; private static manageExtensionAction: ManageExtensionAction;
private compositeActivity: IActivity | undefined; private compositeActivity: IActivity | undefined;
private compositeTransfer: LocalSelectionTransfer<DraggedCompositeIdentifier | DraggedViewIdentifier>;
constructor( constructor(
private compositeActivityAction: ActivityAction, private compositeActivityAction: ActivityAction,
@@ -470,8 +469,6 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
) { ) {
super(compositeActivityAction, { draggable: true, colors, icon }, themeService); super(compositeActivityAction, { draggable: true, colors, icon }, themeService);
this.compositeTransfer = LocalSelectionTransfer.getInstance<DraggedCompositeIdentifier | DraggedViewIdentifier>();
if (!CompositeActionViewItem.manageExtensionAction) { if (!CompositeActionViewItem.manageExtensionAction) {
CompositeActionViewItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction); CompositeActionViewItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction);
} }
@@ -670,9 +667,6 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
dispose(): void { dispose(): void {
super.dispose(); super.dispose();
this.compositeTransfer.clearData(DraggedCompositeIdentifier.prototype);
this.label.remove(); this.label.remove();
} }
} }

View File

@@ -816,7 +816,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return TriggerAction.CLOSE_PICKER; return TriggerAction.CLOSE_PICKER;
}, },
accept: (keyMods, event) => this.openAnything(activeGlobalResource, { keyMods, range: editorSymbolPick.range?.selection, preserveFocus: event.inBackground }) accept: (keyMods, event) => this.openAnything(activeGlobalResource, { keyMods, range: editorSymbolPick.range?.selection, preserveFocus: event.inBackground, forcePinned: event.inBackground })
}; };
}); });
} }
@@ -901,14 +901,14 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return TriggerAction.NO_ACTION; return TriggerAction.NO_ACTION;
}, },
accept: (keyMods, event) => this.openAnything(resourceOrEditor, { keyMods, range: this.pickState.lastRange, preserveFocus: event.inBackground }) accept: (keyMods, event) => this.openAnything(resourceOrEditor, { keyMods, range: this.pickState.lastRange, preserveFocus: event.inBackground, forcePinned: event.inBackground })
}; };
} }
private async openAnything(resourceOrEditor: URI | IEditorInput | IResourceEditorInput, options: { keyMods?: IKeyMods, preserveFocus?: boolean, range?: IRange, forceOpenSideBySide?: boolean }): Promise<void> { private async openAnything(resourceOrEditor: URI | IEditorInput | IResourceEditorInput, options: { keyMods?: IKeyMods, preserveFocus?: boolean, range?: IRange, forceOpenSideBySide?: boolean, forcePinned?: boolean }): Promise<void> {
const editorOptions: ITextEditorOptions = { const editorOptions: ITextEditorOptions = {
preserveFocus: options.preserveFocus, preserveFocus: options.preserveFocus,
pinned: options.keyMods?.alt || this.configuration.openEditorPinned, pinned: options.keyMods?.alt || options.forcePinned || this.configuration.openEditorPinned,
selection: options.range ? Range.collapseToStart(options.range) : undefined selection: options.range ? Range.collapseToStart(options.range) : undefined
}; };

View File

@@ -130,15 +130,31 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
const symbolLabel = symbol.name; const symbolLabel = symbol.name;
const symbolLabelWithIcon = `$(symbol-${SymbolKinds.toString(symbol.kind) || 'property'}) ${symbolLabel}`; const symbolLabelWithIcon = `$(symbol-${SymbolKinds.toString(symbol.kind) || 'property'}) ${symbolLabel}`;
const symbolLabelIconOffset = symbolLabelWithIcon.length - symbolLabel.length;
// Score by symbol label if searching // Score by symbol label if searching
let symbolScore: number | undefined = undefined; let symbolScore: number | undefined = undefined;
let symbolMatches: IMatch[] | undefined = undefined; let symbolMatches: IMatch[] | undefined = undefined;
let skipContainerQuery = false;
if (symbolQuery.original.length > 0) { if (symbolQuery.original.length > 0) {
[symbolScore, symbolMatches] = scoreFuzzy2(symbolLabel, symbolQuery, 0, symbolLabelWithIcon.length - symbolLabel.length /* Readjust matches to account for codicons in label */);
// First: try to score on the entire query, it is possible that
// the symbol matches perfectly (e.g. searching for "change log"
// can be a match on a markdown symbol "change log"). In that
// case we want to skip the container query altogether.
if (symbolQuery !== query) {
[symbolScore, symbolMatches] = scoreFuzzy2(symbolLabel, query, 0, symbolLabelIconOffset, true /* skip multi matching */);
if (symbolScore) {
skipContainerQuery = true; // since we consumed the query, skip any container matching
}
}
// Otherwise: score on the symbol query and match on the container later
if (!symbolScore) { if (!symbolScore) {
continue; [symbolScore, symbolMatches] = scoreFuzzy2(symbolLabel, symbolQuery, 0, symbolLabelIconOffset);
if (!symbolScore) {
continue;
}
} }
} }
@@ -156,7 +172,7 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
// Score by container if specified and searching // Score by container if specified and searching
let containerScore: number | undefined = undefined; let containerScore: number | undefined = undefined;
let containerMatches: IMatch[] | undefined = undefined; let containerMatches: IMatch[] | undefined = undefined;
if (containerQuery && containerQuery.original.length > 0) { if (!skipContainerQuery && containerQuery && containerQuery.original.length > 0) {
if (containerLabel) { if (containerLabel) {
[containerScore, containerMatches] = scoreFuzzy2(containerLabel, containerQuery); [containerScore, containerMatches] = scoreFuzzy2(containerLabel, containerQuery);
} }
@@ -195,7 +211,7 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
return TriggerAction.CLOSE_PICKER; return TriggerAction.CLOSE_PICKER;
}, },
accept: async (keyMods, event) => this.openSymbol(provider, symbol, token, { keyMods, preserveFocus: event.inBackground }), accept: async (keyMods, event) => this.openSymbol(provider, symbol, token, { keyMods, preserveFocus: event.inBackground, forcePinned: event.inBackground }),
}); });
} }
} }
@@ -208,7 +224,7 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
return symbolPicks; return symbolPicks;
} }
private async openSymbol(provider: IWorkspaceSymbolProvider, symbol: IWorkspaceSymbol, token: CancellationToken, options: { keyMods: IKeyMods, forceOpenSideBySide?: boolean, preserveFocus?: boolean }): Promise<void> { private async openSymbol(provider: IWorkspaceSymbolProvider, symbol: IWorkspaceSymbol, token: CancellationToken, options: { keyMods: IKeyMods, forceOpenSideBySide?: boolean, preserveFocus?: boolean, forcePinned?: boolean }): Promise<void> {
// Resolve actual symbol to open for providers that can resolve // Resolve actual symbol to open for providers that can resolve
let symbolToOpen = symbol; let symbolToOpen = symbol;
@@ -231,7 +247,7 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
resource: symbolToOpen.location.uri, resource: symbolToOpen.location.uri,
options: { options: {
preserveFocus: options?.preserveFocus, preserveFocus: options?.preserveFocus,
pinned: options.keyMods.alt || this.configuration.openEditorPinned, pinned: options.keyMods.alt || options.forcePinned || this.configuration.openEditorPinned,
selection: symbolToOpen.location.range ? Range.collapseToStart(symbolToOpen.location.range) : undefined selection: symbolToOpen.location.range ? Range.collapseToStart(symbolToOpen.location.range) : undefined
} }
}, options.keyMods.ctrlCmd || options?.forceOpenSideBySide ? SIDE_GROUP : ACTIVE_GROUP); }, options.keyMods.ctrlCmd || options?.forceOpenSideBySide ? SIDE_GROUP : ACTIVE_GROUP);

View File

@@ -85,7 +85,7 @@ import { InstallVSIXAction } from 'vs/workbench/contrib/extensions/browser/exten
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
command, command,
when: ContextKeyExpr.equals('config.window.nativeTabs', 'true') when: ContextKeyExpr.equals('config.window.nativeTabs', true)
}); });
}); });
} }

View File

@@ -144,7 +144,7 @@ export class IntegrityServiceImpl implements IIntegrityService {
return new Promise<ChecksumPair>((resolve, reject) => { return new Promise<ChecksumPair>((resolve, reject) => {
fs.readFile(fileUri.fsPath, (err, buff) => { fs.readFile(fileUri.fsPath, (err, buff) => {
if (err) { if (err) {
return reject(err); return resolve(IntegrityServiceImpl._createChecksumPair(fileUri, '', expected));
} }
resolve(IntegrityServiceImpl._createChecksumPair(fileUri, this._computeChecksum(buff), expected)); resolve(IntegrityServiceImpl._createChecksumPair(fileUri, this._computeChecksum(buff), expected));
}); });

View File

@@ -203,10 +203,15 @@ export class SearchService extends Disposable implements ISearchService {
this.fileSearchProviders.get(scheme) : this.fileSearchProviders.get(scheme) :
this.textSearchProviders.get(scheme); this.textSearchProviders.get(scheme);
if (!provider && scheme === 'file') { if (!provider && scheme === Schemas.file) {
diskSearchQueries.push(...schemeFQs); diskSearchQueries.push(...schemeFQs);
} else { } else {
if (!provider) { if (!provider) {
if (scheme !== Schemas.vscodeRemote) {
console.warn(`No search provider registered for scheme: ${scheme}`);
return;
}
console.warn(`No search provider registered for scheme: ${scheme}, waiting`); console.warn(`No search provider registered for scheme: ${scheme}, waiting`);
provider = await this.waitForProvider(query.type, scheme); provider = await this.waitForProvider(query.type, scheme);
} }