mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-20 20:10:11 -04:00
Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)
* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 * disable strict null check
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user