Merge from vscode 5b9869eb02fa4c96205a74d05cad9164dfd06d60 (#5607)

This commit is contained in:
Anthony Dresser
2019-05-24 12:20:30 -07:00
committed by GitHub
parent 361ada4963
commit bcc449b524
126 changed files with 3096 additions and 2255 deletions

View File

@@ -1288,6 +1288,7 @@ export interface CommentThread2 {
resource: string | null;
range: IRange;
label: string;
contextValue: string | undefined;
comments: Comment[] | undefined;
onDidChangeComments: Event<Comment[] | undefined>;
collapsibleState?: CommentThreadCollapsibleState;
@@ -1326,6 +1327,7 @@ export interface CommentThread {
collapsibleState?: CommentThreadCollapsibleState;
reply?: Command;
isDisposed?: boolean;
contextValue?: string;
}
/**
@@ -1347,14 +1349,24 @@ export interface CommentReaction {
readonly canEdit?: boolean;
}
/**
* @internal
*/
export enum CommentMode {
Editing = 0,
Preview = 1
}
/**
* @internal
*/
export interface Comment {
readonly commentId: string;
readonly uniqueIdInThread?: number;
readonly body: IMarkdownString;
readonly userName: string;
readonly userIconPath?: string;
readonly contextValue?: string;
readonly canEdit?: boolean;
readonly canDelete?: boolean;
readonly selectCommand?: Command;
@@ -1363,6 +1375,7 @@ export interface Comment {
readonly isDraft?: boolean;
readonly commentReactions?: CommentReaction[];
readonly label?: string;
readonly mode?: CommentMode;
}
/**

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 Source EULA. 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 Source EULA. 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) || FuzzyScore.Default;
item.score = anyScore(word, wordLow, wordPos, item.completion.label, item.labelLow, 0);
item.score[0] = match[0]; // use score from filterText
}