Merge branch 'master' into rebornix/bettermerge
This commit is contained in:
commit
bbeeefd713
|
@ -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);
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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[] {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
5
src/vs/vscode.d.ts
vendored
|
@ -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>;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)!;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue