Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -9,8 +9,8 @@ import { createMatches } from 'vs/base/common/filters';
import * as strings from 'vs/base/common/strings';
import { Event, Emitter } from 'vs/base/common/event';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { addClass, append, $, hide, removeClass, show, toggleClass, getDomNodePagePosition, hasClass } from 'vs/base/browser/dom';
import { IDisposable, dispose, toDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
import { addClass, append, $, hide, removeClass, show, toggleClass, getDomNodePagePosition, hasClass, addDisposableListener } from 'vs/base/browser/dom';
import { IListVirtualDelegate, IListEvent, IListRenderer, IListMouseEvent } from 'vs/base/browser/ui/list/list';
import { List } from 'vs/base/browser/ui/list/listWidget';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
@@ -29,7 +29,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { TimeoutTimer, CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
import { TimeoutTimer, CancelablePromise, createCancelablePromise, disposableTimeout } from 'vs/base/common/async';
import { CompletionItemKind, completionKindToCssClass } from 'vs/editor/common/modes';
import { IconLabel, IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel';
import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
@@ -37,6 +37,9 @@ import { IModelService } from 'vs/editor/common/services/modelService';
import { URI } from 'vs/base/common/uri';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { FileKind } from 'vs/platform/files/common/files';
import { MarkdownString } from 'vs/base/common/htmlContent';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
const expandSuggestionDocsByDefault = false;
@@ -103,7 +106,9 @@ class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData>
renderTemplate(container: HTMLElement): ISuggestionTemplateData {
const data = <ISuggestionTemplateData>Object.create(null);
data.disposables = [];
const disposables = new DisposableStore();
data.disposables = [disposables];
data.root = container;
addClass(data.root, 'show-file-icons');
@@ -114,7 +119,7 @@ class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData>
const main = append(text, $('.main'));
data.iconLabel = new IconLabel(main, { supportHighlights: true });
data.disposables.push(data.iconLabel);
disposables.add(data.iconLabel);
data.typeLabel = append(main, $('span.type-label'));
@@ -142,9 +147,9 @@ class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData>
configureFont();
Event.chain<IConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
disposables.add(Event.chain<IConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
.filter(e => e.fontInfo || e.contribInfo)
.on(configureFont, null, data.disposables);
.on(configureFont, null));
return data;
}
@@ -226,6 +231,18 @@ const enum State {
Details
}
let _explainMode = false;
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'suggest.toggleExplainMode',
handler() {
_explainMode = !_explainMode;
},
when: SuggestContext.Visible,
weight: KeybindingWeight.EditorContrib,
primary: KeyMod.CtrlCmd | KeyCode.US_SLASH,
});
class SuggestionDetails {
private el: HTMLElement;
@@ -245,7 +262,7 @@ class SuggestionDetails {
private readonly widget: SuggestWidget,
private readonly editor: ICodeEditor,
private readonly markdownRenderer: MarkdownRenderer,
private readonly triggerKeybindingLabel: string
private readonly triggerKeybindingLabel: string,
) {
this.disposables = [];
@@ -279,10 +296,27 @@ class SuggestionDetails {
return this.el;
}
render(item: CompletionItem): void {
renderLoading(): void {
this.type.textContent = nls.localize('loading', "Loading...");
this.docs.textContent = '';
}
renderItem(item: CompletionItem): void {
this.renderDisposeable = dispose(this.renderDisposeable);
if (!item || !canExpandCompletionItem(item)) {
let { documentation, detail } = item.completion;
// --- documentation
if (_explainMode) {
let md = '';
md += `score: ${item.score[0]}${item.word ? `, compared '${item.completion.filterText && (item.completion.filterText + ' (filterText)') || item.completion.label}' with '${item.word}'` : ' (no prefix)'}\n`;
md += `distance: ${item.distance}, see localityBonus-setting\n`;
md += `index: ${item.idx}, based on ${item.completion.sortText && `sortText: "${item.completion.sortText}"` || 'label'}\n`;
documentation = new MarkdownString().appendCodeblock('empty', md);
detail = `Provider: ${item.provider._debugDisplayName}`;
}
if (!_explainMode && !canExpandCompletionItem(item)) {
this.type.textContent = '';
this.docs.textContent = '';
addClass(this.el, 'no-docs');
@@ -290,19 +324,20 @@ class SuggestionDetails {
return;
}
removeClass(this.el, 'no-docs');
if (typeof item.completion.documentation === 'string') {
if (typeof documentation === 'string') {
removeClass(this.docs, 'markdown-docs');
this.docs.textContent = item.completion.documentation;
this.docs.textContent = documentation;
} else {
addClass(this.docs, 'markdown-docs');
this.docs.innerHTML = '';
const renderedContents = this.markdownRenderer.render(item.completion.documentation);
const renderedContents = this.markdownRenderer.render(documentation);
this.renderDisposeable = renderedContents;
this.docs.appendChild(renderedContents.element);
}
if (item.completion.detail) {
this.type.innerText = item.completion.detail;
// --- details
if (detail) {
this.type.innerText = detail;
show(this.type);
} else {
this.type.innerText = '';
@@ -326,8 +361,8 @@ class SuggestionDetails {
this.ariaLabel = strings.format(
'{0}{1}',
item.completion.detail || '',
item.completion.documentation ? (typeof item.completion.documentation === 'string' ? item.completion.documentation : item.completion.documentation.value) : '');
detail || '',
documentation ? (typeof documentation === 'string' ? documentation : documentation.value) : '');
}
getAriaLabel() {
@@ -399,10 +434,11 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
// Editor.IContentWidget.allowEditorOverflow
readonly allowEditorOverflow = true;
readonly suppressMouseDown = true;
private state: State | null;
private isAuto: boolean;
private loadingTimeout: any;
private loadingTimeout: IDisposable = Disposable.None;
private currentSuggestionDetails: CancelablePromise<void> | null;
private focusedItem: CompletionItem | null;
private ignoreFocusEvents = false;
@@ -420,14 +456,13 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
private readonly editorBlurTimeout = new TimeoutTimer();
private readonly showTimeout = new TimeoutTimer();
private toDispose: IDisposable[];
private readonly toDispose = new DisposableStore();
private onDidSelectEmitter = new Emitter<ISelectedSuggestion>();
private onDidFocusEmitter = new Emitter<ISelectedSuggestion>();
private onDidHideEmitter = new Emitter<this>();
private onDidShowEmitter = new Emitter<this>();
readonly onDidSelect: Event<ISelectedSuggestion> = this.onDidSelectEmitter.event;
readonly onDidFocus: Event<ISelectedSuggestion> = this.onDidFocusEmitter.event;
readonly onDidHide: Event<this> = this.onDidHideEmitter.event;
@@ -457,17 +492,22 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
) {
const kb = keybindingService.lookupKeybinding('editor.action.triggerSuggest');
const triggerKeybindingLabel = !kb ? '' : ` (${kb.getLabel()})`;
const markdownRenderer = new MarkdownRenderer(editor, modeService, openerService);
const markdownRenderer = this.toDispose.add(new MarkdownRenderer(editor, modeService, openerService));
this.isAuto = false;
this.focusedItem = null;
this.storageService = storageService;
this.element = $('.editor-widget.suggest-widget');
this.toDispose.add(addDisposableListener(this.element, 'click', e => {
if (e.target === this.element) {
this.hideWidget();
}
}));
this.messageElement = append(this.element, $('.message'));
this.listElement = append(this.element, $('.tree'));
this.details = new SuggestionDetails(this.element, this, this.editor, markdownRenderer, triggerKeybindingLabel);
this.details = instantiationService.createInstance(SuggestionDetails, this.element, this, this.editor, markdownRenderer, triggerKeybindingLabel);
const applyIconStyle = () => toggleClass(this.element, 'no-icons', !this.editor.getConfiguration().contribInfo.suggest.showIcons);
applyIconStyle();
@@ -480,19 +520,18 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
mouseSupport: false
});
this.toDispose = [
attachListStyler(this.list, themeService, {
listInactiveFocusBackground: editorSuggestWidgetSelectedBackground,
listInactiveFocusOutline: activeContrastBorder
}),
themeService.onThemeChange(t => this.onThemeChange(t)),
editor.onDidLayoutChange(() => this.onEditorLayoutChange()),
this.list.onMouseDown(e => this.onListMouseDown(e)),
this.list.onSelectionChange(e => this.onListSelection(e)),
this.list.onFocusChange(e => this.onListFocus(e)),
this.editor.onDidChangeCursorSelection(() => this.onCursorSelectionChanged()),
this.editor.onDidChangeConfiguration(e => e.contribInfo && applyIconStyle())
];
this.toDispose.add(attachListStyler(this.list, themeService, {
listInactiveFocusBackground: editorSuggestWidgetSelectedBackground,
listInactiveFocusOutline: activeContrastBorder
}));
this.toDispose.add(themeService.onThemeChange(t => this.onThemeChange(t)));
this.toDispose.add(editor.onDidLayoutChange(() => this.onEditorLayoutChange()));
this.toDispose.add(this.list.onMouseDown(e => this.onListMouseDown(e)));
this.toDispose.add(this.list.onSelectionChange(e => this.onListSelection(e)));
this.toDispose.add(this.list.onFocusChange(e => this.onListFocus(e)));
this.toDispose.add(this.editor.onDidChangeCursorSelection(() => this.onCursorSelectionChanged()));
this.toDispose.add(this.editor.onDidChangeConfiguration(e => e.contribInfo && applyIconStyle()));
this.suggestWidgetVisible = SuggestContext.Visible.bindTo(contextKeyService);
this.suggestWidgetMultipleSuggestions = SuggestContext.MultipleSuggestions.bindTo(contextKeyService);
@@ -624,7 +663,13 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
this.list.reveal(index);
this.currentSuggestionDetails = createCancelablePromise(token => item.resolve(token));
this.currentSuggestionDetails = createCancelablePromise(async token => {
const loading = disposableTimeout(() => this.showDetails(true), 250);
token.onCancellationRequested(() => loading.dispose());
const result = await item.resolve(token);
loading.dispose();
return result;
});
this.currentSuggestionDetails.then(() => {
if (this.list.length < index) {
@@ -638,7 +683,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
this.ignoreFocusEvents = false;
if (this.expandDocsSettingFromStorage()) {
this.showDetails();
this.showDetails(false);
} else {
removeClass(this.element, 'docs-side');
}
@@ -718,10 +763,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
this.isAuto = !!auto;
if (!this.isAuto) {
this.loadingTimeout = setTimeout(() => {
this.loadingTimeout = null;
this.setState(State.Loading);
}, delay);
this.loadingTimeout = disposableTimeout(() => this.setState(State.Loading), delay);
}
}
@@ -729,10 +771,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
this.preferDocPositionTop = false;
this.docsPositionPreviousWidgetY = null;
if (this.loadingTimeout) {
clearTimeout(this.loadingTimeout);
this.loadingTimeout = null;
}
this.loadingTimeout.dispose();
if (this.currentSuggestionDetails) {
this.currentSuggestionDetails.cancel();
@@ -945,7 +984,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
}
this.updateExpandDocsSetting(true);
this.showDetails();
this.showDetails(false);
this._ariaAlert(this.details.getAriaLabel());
/* __GDPR__
"suggestWidget:expandDetails" : {
@@ -958,11 +997,15 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
}
}
showDetails(): void {
showDetails(loading: boolean): void {
this.expandSideOrBelow();
show(this.details.element);
this.details.render(this.list.getFocusedElements()[0]);
if (loading) {
this.details.renderLoading();
} else {
this.details.renderItem(this.list.getFocusedElements()[0]);
}
this.details.element.style.maxHeight = this.maxWidgetHeight + 'px';
// Reset margin-top that was set as Fix for #26416
@@ -998,7 +1041,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
}
hideWidget(): void {
clearTimeout(this.loadingTimeout);
this.loadingTimeout.dispose();
this.setState(State.Hidden);
this.onDidHideEmitter.fire(this);
}
@@ -1142,22 +1185,10 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
}
dispose(): void {
this.state = null;
this.currentSuggestionDetails = null;
this.focusedItem = null;
this.element = null!; // StrictNullOverride: nulling out ok in dispose
this.messageElement = null!; // StrictNullOverride: nulling out ok in dispose
this.listElement = null!; // StrictNullOverride: nulling out ok in dispose
this.details.dispose();
this.details = null!; // StrictNullOverride: nulling out ok in dispose
this.list.dispose();
this.list = null!; // StrictNullOverride: nulling out ok in dispose
this.toDispose = dispose(this.toDispose);
if (this.loadingTimeout) {
clearTimeout(this.loadingTimeout);
this.loadingTimeout = null;
}
this.toDispose.dispose();
this.loadingTimeout.dispose();
this.editorBlurTimeout.dispose();
this.showTimeout.dispose();
}