Merge branch 'master' into rebornix/bettermerge

This commit is contained in:
Peng Lyu 2019-05-24 11:29:41 -07:00
commit bbeeefd713
17 changed files with 408 additions and 37 deletions

View file

@ -74,7 +74,9 @@ class MyCompletionItem extends vscode.CompletionItem {
}
this.insertText = tsEntry.insertText;
this.filterText = tsEntry.insertText;
// Set filterText for intelliCode and bracket accessors , but not for `this.` completions since it results in
// them being overly prioritized. #74164
this.filterText = tsEntry.insertText && !/^this\./.test(tsEntry.insertText) ? tsEntry.insertText : undefined;
if (completionContext.isMemberCompletion && completionContext.dotAccessorContext) {
this.filterText = completionContext.dotAccessorContext.text + (this.insertText || this.label);

View file

@ -131,6 +131,9 @@ suite('TypeScript Completions', () => {
'const x = { "hello world2": 1 };',
`x["hello world2"]${insert}`
));
disposeAll(_disposables);
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
}
});
@ -160,7 +163,7 @@ suite('TypeScript Completions', () => {
`f('abc.abc$0')`
);
const document = await acceptFirstSuggestion(testDocumentUri, _disposables);
const document = await acceptFirstSuggestion(testDocumentUri, _disposables, { useLineRange: true });
assert.strictEqual(
document.getText(),
joinLines(
@ -264,15 +267,38 @@ suite('TypeScript Completions', () => {
`abcdef(1, 2, 3)`
));
});
test('should not de-prioritized this.member suggestion, #74164', async () => {
await createTestEditor(testDocumentUri,
`class A {`,
` private detail = '';`,
` foo() {`,
` det$0`,
` }`,
`}`,
);
const document = await acceptFirstSuggestion(testDocumentUri, _disposables);
assert.strictEqual(
document.getText(),
joinLines(
`class A {`,
` private detail = '';`,
` foo() {`,
` this.detail`,
` }`,
`}`,
));
});
});
const joinLines = (...args: string[]) => args.join('\n');
const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
async function acceptFirstSuggestion(uri: vscode.Uri, _disposables: vscode.Disposable[]) {
async function acceptFirstSuggestion(uri: vscode.Uri, _disposables: vscode.Disposable[], options?: { useLineRange?: boolean }) {
const didChangeDocument = onChangedDocument(uri, _disposables);
const didSuggest = onDidSuggest(_disposables);
const didSuggest = onDidSuggest(_disposables, options);
await vscode.commands.executeCommand('editor.action.triggerSuggest');
await didSuggest;
// TODO: depends on reverting fix for https://github.com/Microsoft/vscode/issues/64257
@ -310,12 +336,14 @@ async function createTestEditor(uri: vscode.Uri, ...lines: string[]) {
await activeEditor.insertSnippet(new vscode.SnippetString(joinLines(...lines)), new vscode.Range(0, 0, 1000, 0));
}
function onDidSuggest(disposables: vscode.Disposable[]) {
function onDidSuggest(disposables: vscode.Disposable[], options?: { useLineRange?: boolean }) {
return new Promise(resolve =>
disposables.push(vscode.languages.registerCompletionItemProvider('typescript', new class implements vscode.CompletionItemProvider {
provideCompletionItems(doc: vscode.TextDocument, position: vscode.Position): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList> {
// Return a fake item that will come first
const range = new vscode.Range(new vscode.Position(position.line, 0), position);
const range = options && options.useLineRange
? new vscode.Range(new vscode.Position(position.line, 0), position)
: doc.getWordRangeAtPosition(position);
return [{
label: '🦄',
insertText: doc.getText(range),

View file

@ -362,6 +362,31 @@ export function matchesFuzzy2(pattern: string, word: string): IMatch[] | null {
return score ? createMatches(score) : null;
}
export function anyScore(pattern: string, lowPattern: string, _patternPos: number, word: string, lowWord: string, _wordPos: number): FuzzyScore {
const result = fuzzyScore(pattern, lowPattern, 0, word, lowWord, 0, true);
if (result) {
return result;
}
let matches = 0;
let score = 0;
let idx = _wordPos;
for (let patternPos = 0; patternPos < lowPattern.length && patternPos < _maxLen; ++patternPos) {
const wordPos = lowWord.indexOf(lowPattern.charAt(patternPos), idx);
if (wordPos >= 0) {
score += 1;
matches += 2 ** wordPos;
idx = wordPos + 1;
} else if (matches !== 0) {
// once we have started matching things
// we need to match the remaining pattern
// characters
break;
}
}
return [score, matches, _wordPos];
}
//#region --- fuzzyScore ---
export function createMatches(score: undefined | FuzzyScore): IMatch[] {

View file

@ -42,7 +42,7 @@ import { Button } from 'vs/base/browser/ui/button/button';
import { withUndefinedAsNull } from 'vs/base/common/types';
import { SystemInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService';
const MAX_URL_LENGTH = platform.isWindows ? 2081 : 5400;
const MAX_URL_LENGTH = 2045;
interface SearchResult {
html_url: string;
@ -440,11 +440,11 @@ export class IssueReporter extends Disposable {
}
});
document.onkeydown = (e: KeyboardEvent) => {
document.onkeydown = async (e: KeyboardEvent) => {
const cmdOrCtrlKey = platform.isMacintosh ? e.metaKey : e.ctrlKey;
// Cmd/Ctrl+Enter previews issue and closes window
if (cmdOrCtrlKey && e.keyCode === 13) {
if (this.createIssue()) {
if (await this.createIssue()) {
ipcRenderer.send('vscode:closeIssueReporter');
}
}
@ -843,7 +843,7 @@ export class IssueReporter extends Disposable {
return isValid;
}
private createIssue(): boolean {
private async createIssue(): Promise<boolean> {
if (!this.validateInputs()) {
// If inputs are invalid, set focus to the first one and add listeners on them
// to detect further changes
@ -887,14 +887,32 @@ export class IssueReporter extends Disposable {
let url = baseUrl + `&body=${encodeURIComponent(issueBody)}`;
if (url.length > MAX_URL_LENGTH) {
clipboard.writeText(issueBody);
url = baseUrl + `&body=${encodeURIComponent(localize('pasteData', "We have written the needed data into your clipboard because it was too large to send. Please paste."))}`;
try {
url = await this.writeToClipboard(baseUrl, issueBody);
} catch (_) {
return false;
}
}
ipcRenderer.send('vscode:openExternal', url);
return true;
}
private async writeToClipboard(baseUrl: string, issueBody: string): Promise<string> {
return new Promise((resolve, reject) => {
ipcRenderer.once('vscode:issueReporterClipboardResponse', (_: unknown, shouldWrite: boolean) => {
if (shouldWrite) {
clipboard.writeText(issueBody);
resolve(baseUrl + `&body=${encodeURIComponent(localize('pasteData', "We have written the needed data into your clipboard because it was too large to send. Please paste."))}`);
} else {
reject();
}
});
ipcRenderer.send('vscode:issueReporterClipboard');
});
}
private getExtensionGitHubUrl(): string {
let repositoryUrl = '';
const bugsUrl = this.getExtensionBugsUrl();

View file

@ -152,17 +152,22 @@ export async function formatDocumentRangeWithProvider(
cts = new TextModelCancellationTokenSource(editorOrModel, token);
}
const rawEdits = await provider.provideDocumentRangeFormattingEdits(
model,
range,
model.getFormattingOptions(),
cts.token
);
let edits: TextEdit[] | undefined;
try {
const rawEdits = await provider.provideDocumentRangeFormattingEdits(
model,
range,
model.getFormattingOptions(),
cts.token
);
edits = await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
const edits = await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
if (cts.token.isCancellationRequested) {
return true;
}
if (cts.token.isCancellationRequested) {
return true;
} finally {
cts.dispose();
}
if (!edits || edits.length === 0) {
@ -235,16 +240,22 @@ export async function formatDocumentWithProvider(
cts = new TextModelCancellationTokenSource(editorOrModel, token);
}
const rawEdits = await provider.provideDocumentFormattingEdits(
model,
model.getFormattingOptions(),
cts.token
);
let edits: TextEdit[] | undefined;
try {
const rawEdits = await provider.provideDocumentFormattingEdits(
model,
model.getFormattingOptions(),
cts.token
);
const edits = await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
edits = await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
if (cts.token.isCancellationRequested) {
return true;
if (cts.token.isCancellationRequested) {
return true;
}
} finally {
cts.dispose();
}
if (!edits || edits.length === 0) {

View file

@ -29,6 +29,7 @@ import { IProgressService } from 'vs/platform/progress/common/progress';
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition, getDeclarationsAtPosition } from './goToDefinition';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { EditorStateCancellationTokenSource, CodeEditorStateFlag } from 'vs/editor/browser/core/editorState';
import { ISymbolNavigationService } from 'vs/editor/contrib/goToDefinition/goToDefinitionResultsNavigation';
export class DefinitionActionConfig {
@ -58,6 +59,7 @@ export class DefinitionAction extends EditorAction {
const notificationService = accessor.get(INotificationService);
const editorService = accessor.get(ICodeEditorService);
const progressService = accessor.get(IProgressService);
const symbolNavService = accessor.get(ISymbolNavigationService);
const model = editor.getModel();
const pos = editor.getPosition();
@ -102,7 +104,7 @@ export class DefinitionAction extends EditorAction {
} else {
// handle multile results
return this._onResult(editorService, editor, new ReferencesModel(result));
return this._onResult(editorService, symbolNavService, editor, new ReferencesModel(result));
}
}, (err) => {
@ -130,7 +132,7 @@ export class DefinitionAction extends EditorAction {
return model.references.length > 1 ? nls.localize('meta.title', " {0} definitions", model.references.length) : '';
}
private async _onResult(editorService: ICodeEditorService, editor: ICodeEditor, model: ReferencesModel): Promise<void> {
private async _onResult(editorService: ICodeEditorService, symbolNavService: ISymbolNavigationService, editor: ICodeEditor, model: ReferencesModel): Promise<void> {
const msg = model.getAriaMessage();
alert(msg);
@ -150,6 +152,12 @@ export class DefinitionAction extends EditorAction {
} else {
model.dispose();
}
// keep remaining locations around when using
// 'goto'-mode
if (gotoLocation.multiple === 'goto') {
symbolNavService.put(next);
}
}
}

View file

@ -0,0 +1,212 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ReferencesModel, OneReference } from 'vs/editor/contrib/referenceSearch/referencesModel';
import { RawContextKey, IContextKeyService, IContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { createDecorator, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { KeybindingWeight, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { KeyCode } from 'vs/base/common/keyCodes';
import { registerEditorCommand, EditorCommand } from 'vs/editor/browser/editorExtensions';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { Range } from 'vs/editor/common/core/range';
import { Disposable, dispose, combinedDisposable, IDisposable } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
import { localize } from 'vs/nls';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
export const ctxHasSymbols = new RawContextKey('hasSymbols', false);
export const ISymbolNavigationService = createDecorator<ISymbolNavigationService>('ISymbolNavigationService');
export interface ISymbolNavigationService {
_serviceBrand: any;
reset(): void;
put(anchor: OneReference): void;
revealNext(source: ICodeEditor): Promise<any>;
}
class SymbolNavigationService implements ISymbolNavigationService {
_serviceBrand: any;
private readonly _ctxHasSymbols: IContextKey<boolean>;
private _currentModel?: ReferencesModel = undefined;
private _currentIdx: number = -1;
private _currentDisposables: IDisposable[] = [];
private _currentMessage?: IDisposable = undefined;
private _ignoreEditorChange: boolean = false;
constructor(
@IContextKeyService contextKeyService: IContextKeyService,
@ICodeEditorService private readonly _editorService: ICodeEditorService,
@IStatusbarService private readonly _statusbarService: IStatusbarService,
@IKeybindingService private readonly _keybindingService: IKeybindingService,
) {
this._ctxHasSymbols = ctxHasSymbols.bindTo(contextKeyService);
}
reset(): void {
this._ctxHasSymbols.reset();
dispose(this._currentDisposables);
dispose(this._currentMessage);
this._currentModel = undefined;
this._currentIdx = -1;
}
put(anchor: OneReference): void {
const refModel = anchor.parent.parent;
if (refModel.references.length <= 1) {
this.reset();
return;
}
this._currentModel = refModel;
this._currentIdx = refModel.references.indexOf(anchor);
this._ctxHasSymbols.set(true);
this._showMessage();
const editorStatus = new EditorStatus(this._editorService);
const listener = editorStatus.onDidChange(_ => {
if (this._ignoreEditorChange) {
return;
}
const editor = this._editorService.getActiveCodeEditor();
if (!editor) {
return;
}
const model = editor.getModel();
const position = editor.getPosition();
if (!model || !position) {
return;
}
let seenUri: boolean = false;
let seenPosition: boolean = false;
for (const reference of refModel.references) {
if (reference.uri.toString() === model.uri.toString()) {
seenUri = true;
seenPosition = seenPosition || Range.containsPosition(reference.range, position);
} else if (seenUri) {
break;
}
}
if (!seenUri || !seenPosition) {
this.reset();
}
});
this._currentDisposables = [editorStatus, listener];
}
revealNext(source: ICodeEditor): Promise<any> {
if (!this._currentModel) {
return Promise.resolve();
}
// get next result and advance
this._currentIdx += 1;
this._currentIdx %= this._currentModel.references.length;
const reference = this._currentModel.references[this._currentIdx];
// status
this._showMessage();
// open editor, ignore events while that happens
this._ignoreEditorChange = true;
return this._editorService.openCodeEditor({
resource: reference.uri,
options: {
selection: Range.collapseToStart(reference.range),
revealInCenterIfOutsideViewport: true,
revealIfOpened: true
}
}, source).finally(() => {
this._ignoreEditorChange = false;
});
}
private _showMessage(): void {
dispose(this._currentMessage);
const kb = this._keybindingService.lookupKeybinding('editor.gotoNextSymbolFromResult');
const message = kb
? localize('location.kb', "Symbol {0} of {1}, press {2} to reveal next", this._currentIdx + 1, this._currentModel!.references.length, kb.getLabel())
: localize('location', "Symbol {0} of {1}", this._currentIdx + 1, this._currentModel!.references.length);
this._currentMessage = this._statusbarService.setStatusMessage(message);
}
}
registerSingleton(ISymbolNavigationService, SymbolNavigationService, true);
registerEditorCommand(new class extends EditorCommand {
constructor() {
super({
id: 'editor.gotoNextSymbolFromResult',
precondition: ContextKeyExpr.and(
ctxHasSymbols,
ContextKeyExpr.equals('config.editor.gotoLocation.multiple', 'goto')
),
kbOpts: {
weight: KeybindingWeight.EditorContrib,
primary: KeyCode.F12
}
});
}
runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor): void | Promise<void> {
return accessor.get(ISymbolNavigationService).revealNext(editor);
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'editor.gotoNextSymbolFromResult.cancel',
weight: KeybindingWeight.EditorContrib,
when: ctxHasSymbols,
primary: KeyCode.Escape,
handler(accessor) {
accessor.get(ISymbolNavigationService).reset();
}
});
//
class EditorStatus extends Disposable {
private readonly _listener = new Map<ICodeEditor, IDisposable>();
private readonly _onDidChange = new Emitter<{ editor: ICodeEditor }>();
readonly onDidChange: Event<{ editor: ICodeEditor }> = this._onDidChange.event;
constructor(@ICodeEditorService editorService: ICodeEditorService) {
super();
this._register(this._onDidChange);
this._register(editorService.onCodeEditorRemove(this._onDidRemoveEditor, this));
this._register(editorService.onCodeEditorAdd(this._onDidAddEditor, this));
editorService.listCodeEditors().forEach(this._onDidAddEditor, this);
}
private _onDidAddEditor(editor: ICodeEditor): void {
this._listener.set(editor, combinedDisposable([
editor.onDidChangeCursorPosition(_ => this._onDidChange.fire({ editor })),
editor.onDidChangeModelContent(_ => this._onDidChange.fire({ editor })),
]));
}
private _onDidRemoveEditor(editor: ICodeEditor): void {
dispose(this._listener.get(editor));
this._listener.delete(editor);
}
}

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { fuzzyScore, fuzzyScoreGracefulAggressive, FuzzyScorer, FuzzyScore } from 'vs/base/common/filters';
import { fuzzyScore, fuzzyScoreGracefulAggressive, FuzzyScorer, FuzzyScore, anyScore } from 'vs/base/common/filters';
import { isDisposable } from 'vs/base/common/lifecycle';
import { CompletionList, CompletionItemProvider, CompletionItemKind } from 'vs/editor/common/modes';
import { CompletionItem } from './suggest';
@ -222,7 +222,7 @@ export class CompletionModel {
} else {
// re-run the scorer on the label in the hope of a result BUT use the rank
// of the filterText-match
item.score = scoreFn(word, wordLow, wordPos, item.completion.label, item.labelLow, 0, false) || [-100, 0, 0];
item.score = anyScore(word, wordLow, wordPos, item.completion.label, item.labelLow, 0);
item.score[0] = match[0]; // use score from filterText
}

View file

@ -75,6 +75,23 @@ export class IssueService implements IIssueService {
event.sender.send('vscode:listProcessesResponse', processes);
});
ipcMain.on('vscode:issueReporterClipboard', (event: Event) => {
const messageOptions = {
message: localize('issueReporterWriteToClipboard', "There is too much data to send to GitHub. Would you like to write the information to the clipboard so that it can be pasted?"),
type: 'warning',
buttons: [
localize('yes', "Yes"),
localize('cancel', "Cancel")
]
};
if (this._issueWindow) {
dialog.showMessageBox(this._issueWindow, messageOptions, response => {
event.sender.send('vscode:issueReporterClipboardResponse', response === 0);
});
}
});
ipcMain.on('vscode:issuePerformanceInfoRequest', (event: Event) => {
this.getPerformanceInfo().then(msg => {
event.sender.send('vscode:issuePerformanceInfoResponse', msg);

5
src/vs/vscode.d.ts vendored
View file

@ -5763,8 +5763,11 @@ declare module 'vscode' {
* to allow using a static localhost port inside the webview that is resolved to random port that a service is
* running on.
*
* If a webview accesses localhost content, we recomend that you specify port mappings even if
* If a webview accesses localhost content, we recommend that you specify port mappings even if
* the `webviewPort` and `extensionHostPort` ports are the same.
*
* *Note* that port mappings only work for `http` or `https` urls. Websocket urls (e.g. `ws://localhost:3000`)
* cannot be mapped to another port.
*/
readonly portMapping?: ReadonlyArray<WebviewPortMapping>;
}

View file

@ -366,6 +366,14 @@ export class MainThreadCommentController {
thread.dispose();
}
deleteCommentThreadMain(commentThreadId: string) {
this._threads.forEach(thread => {
if (thread.threadId === commentThreadId) {
this._proxy.$deleteCommentThread(this._handle, thread.commentThreadHandle);
}
});
}
updateInput(input: string) {
let thread = this.activeCommentThread;

View file

@ -1210,6 +1210,7 @@ export interface ExtHostCommentsShape {
$createNewCommentThread(handle: number, document: UriComponents, range: IRange, text: string): Promise<modes.CommentThread | null>;
$createCommentThreadTemplate(commentControllerHandle: number, uriComponents: UriComponents, range: IRange): void;
$onCommentWidgetInputChange(commentControllerHandle: number, document: UriComponents, range: IRange, input: string | undefined): Promise<number | undefined>;
$deleteCommentThread(commentControllerHandle: number, commentThreadHandle: number): void;
$provideCommentingRanges(commentControllerHandle: number, uriComponents: UriComponents, token: CancellationToken): Promise<IRange[] | undefined>;
$checkStaticContribution(commentControllerHandle: number): Promise<boolean>;
$provideReactionGroup(commentControllerHandle: number): Promise<modes.CommentReaction[] | undefined>;

View file

@ -173,6 +173,14 @@ export class ExtHostComments implements ExtHostCommentsShape {
return Promise.resolve(commentControllerHandle);
}
$deleteCommentThread(commentControllerHandle: number, commentThreadHandle: number) {
const commentController = this._commentControllers.get(commentControllerHandle);
if (commentController) {
commentController.$deleteCommentThread(commentThreadHandle);
}
}
$provideCommentingRanges(commentControllerHandle: number, uriComponents: UriComponents, token: CancellationToken): Promise<IRange[] | undefined> {
const commentController = this._commentControllers.get(commentControllerHandle);
@ -764,6 +772,16 @@ class ExtHostCommentController implements vscode.CommentController {
return commentThread;
}
$deleteCommentThread(threadHandle: number) {
let thread = this._threads.get(threadHandle);
if (thread) {
thread.dispose();
}
this._threads.delete(threadHandle);
}
$onCommentWidgetInputChange(uriComponents: UriComponents, range: IRange, input: string) {
if (!this.inputBox) {
this.inputBox = new ExtHostCommentInputBox(this._proxy, this.handle, URI.revive(uriComponents), extHostTypeConverter.Range.to(range), input);

View file

@ -52,6 +52,7 @@ export interface ICommentService {
registerDataProvider(owner: string, commentProvider: DocumentCommentProvider): void;
unregisterDataProvider(owner: string): void;
updateComments(ownerId: string, event: CommentThreadChangedEvent): void;
disposeCommentThread(ownerId: string, threadId: string): void;
createNewCommentThread(owner: string, resource: URI, range: Range, text: string): Promise<CommentThread | null>;
replyToCommentThread(owner: string, resource: URI, range: Range, thread: CommentThread, text: string): Promise<CommentThread | null>;
editComment(owner: string, resource: URI, comment: Comment, text: string): Promise<void>;
@ -144,6 +145,13 @@ export class CommentService extends Disposable implements ICommentService {
commentController.createCommentThreadTemplate(resource, range);
}
disposeCommentThread(owner: string, threadId: string) {
let controller = this.getCommentController(owner);
if (controller) {
controller.deleteCommentThreadMain(threadId);
}
}
getCommentMenus(owner: string): CommentMenus {
if (this._commentMenus.get(owner)) {
return this._commentMenus.get(owner)!;

View file

@ -267,6 +267,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
if (deleteCommand) {
return this.commandService.executeCommand(deleteCommand.id, ...(deleteCommand.arguments || []));
} else if (this._commentEditor.getValue() === '') {
this.commentService.disposeCommentThread(this._owner, this._commentThread.threadId!);
this.dispose();
return Promise.resolve();
}

View file

@ -19,11 +19,12 @@ import { ReviewController } from 'vs/workbench/contrib/comments/browser/comments
import { CommentsDataFilter, CommentsDataSource, CommentsModelRenderer } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer';
import { ICommentService, IWorkspaceCommentThreadsEvent } from 'vs/workbench/contrib/comments/browser/commentService';
import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands';
import { textLinkForeground, textLinkActiveForeground, focusBorder, textPreformatForeground } from 'vs/platform/theme/common/colorRegistry';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ResourceLabels } from 'vs/workbench/browser/labels';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
export const COMMENTS_PANEL_ID = 'workbench.panel.comments';
export const COMMENTS_PANEL_TITLE = 'Comments';
@ -266,3 +267,14 @@ export class CommentsPanel extends Panel {
}
}
}
CommandsRegistry.registerCommand({
id: 'workbench.action.focusCommentsPanel',
handler: (accessor) => {
const panelService = accessor.get(IPanelService);
const panels = panelService.getPanels();
if (panels.some(panelIdentifier => panelIdentifier.id === COMMENTS_PANEL_ID)) {
panelService.openPanel(COMMENTS_PANEL_ID, true);
}
}
});

View file

@ -165,8 +165,7 @@ class WebviewPortMappingProvider extends Disposable {
session.onBeforeRequest(async (details) => {
const uri = URI.parse(details.url);
const allowedSchemes = ['http', 'https', 'ws', 'wss'];
if (allowedSchemes.indexOf(uri.scheme) === -1) {
if (uri.scheme !== 'http' && uri.scheme !== 'https') {
return undefined;
}