mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-21 12:20:29 -04:00
Vscode merge (#4582)
* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd * fix issues with merges * bump node version in azpipe * replace license headers * remove duplicate launch task * fix build errors * fix build errors * fix tslint issues * working through package and linux build issues * more work * wip * fix packaged builds * working through linux build errors * wip * wip * wip * fix mac and linux file limits * iterate linux pipeline * disable editor typing * revert series to parallel * remove optimize vscode from linux * fix linting issues * revert testing change * add work round for new node * readd packaging for extensions * fix issue with angular not resolving decorator dependencies
This commit is contained in:
@@ -8,7 +8,7 @@ import * as dom from 'vs/base/browser/dom';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Color, RGBA } from 'vs/base/common/color';
|
||||
import { IMarkdownString, MarkdownString, isEmptyMarkdownString, markedStringsEquals } from 'vs/base/common/htmlContent';
|
||||
import { Disposable, IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, IDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
@@ -24,11 +24,23 @@ import { ContentHoverWidget } from 'vs/editor/contrib/hover/hoverWidgets';
|
||||
import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { IMarker, IMarkerData } from 'vs/platform/markers/common/markers';
|
||||
import { basename } from 'vs/base/common/paths';
|
||||
import { IMarker, IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers';
|
||||
import { basename } from 'vs/base/common/resources';
|
||||
import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IOpenerService, NullOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { MarkerController, NextMarkerAction } from 'vs/editor/contrib/gotoError/gotoError';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
|
||||
import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction';
|
||||
import { applyCodeAction, QuickFixAction } from 'vs/editor/contrib/codeAction/codeActionCommands';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { CodeActionKind } from 'vs/editor/contrib/codeAction/codeActionTrigger';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -53,13 +65,13 @@ type HoverPart = MarkdownHover | ColorHover | MarkerHover;
|
||||
|
||||
class ModesContentComputer implements IHoverComputer<HoverPart[]> {
|
||||
|
||||
private _editor: ICodeEditor;
|
||||
private readonly _editor: ICodeEditor;
|
||||
private _result: HoverPart[];
|
||||
private _range: Range | null;
|
||||
|
||||
constructor(
|
||||
editor: ICodeEditor,
|
||||
private _markerDecorationsService: IMarkerDecorationsService
|
||||
private readonly _markerDecorationsService: IMarkerDecorationsService
|
||||
) {
|
||||
this._editor = editor;
|
||||
this._range = null;
|
||||
@@ -179,7 +191,7 @@ class ModesContentComputer implements IHoverComputer<HoverPart[]> {
|
||||
|
||||
private _getLoadingMessage(): HoverPart {
|
||||
return {
|
||||
range: this._range || undefined,
|
||||
range: withNullAsUndefined(this._range),
|
||||
contents: [new MarkdownString().appendText(nls.localize('modesContentHover.loading', "Loading..."))]
|
||||
};
|
||||
}
|
||||
@@ -191,11 +203,10 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
|
||||
private _messages: HoverPart[];
|
||||
private _lastRange: Range | null;
|
||||
private _computer: ModesContentComputer;
|
||||
private _hoverOperation: HoverOperation<HoverPart[]>;
|
||||
private readonly _computer: ModesContentComputer;
|
||||
private readonly _hoverOperation: HoverOperation<HoverPart[]>;
|
||||
private _highlightDecorations: string[];
|
||||
private _isChangingDecorations: boolean;
|
||||
private _markdownRenderer: MarkdownRenderer;
|
||||
private _shouldFocus: boolean;
|
||||
private _colorPicker: ColorPickerWidget | null;
|
||||
|
||||
@@ -203,9 +214,13 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
|
||||
constructor(
|
||||
editor: ICodeEditor,
|
||||
markdownRenderer: MarkdownRenderer,
|
||||
markerDecorationsService: IMarkerDecorationsService,
|
||||
private readonly _themeService: IThemeService,
|
||||
private readonly _keybindingService: IKeybindingService,
|
||||
private readonly _contextMenuService: IContextMenuService,
|
||||
private readonly _bulkEditService: IBulkEditService,
|
||||
private readonly _commandService: ICommandService,
|
||||
private readonly _modeService: IModeService,
|
||||
private readonly _openerService: IOpenerService | null = NullOpenerService,
|
||||
) {
|
||||
super(ModesContentHoverWidget.ID, editor);
|
||||
@@ -216,9 +231,6 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
this._highlightDecorations = [];
|
||||
this._isChangingDecorations = false;
|
||||
|
||||
this._markdownRenderer = markdownRenderer;
|
||||
this._register(markdownRenderer.onDidRenderCodeBlock(this.onContentsChange, this));
|
||||
|
||||
this._hoverOperation = new HoverOperation(
|
||||
this._computer,
|
||||
result => this._withResult(result, true),
|
||||
@@ -343,7 +355,8 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
let isEmptyHoverContent = true;
|
||||
|
||||
let containColorPicker = false;
|
||||
let markdownDisposeable: IDisposable;
|
||||
let markdownDisposeables: IDisposable[] = [];
|
||||
const markerMessages: MarkerHover[] = [];
|
||||
messages.forEach((msg) => {
|
||||
if (!msg.range) {
|
||||
return;
|
||||
@@ -433,25 +446,39 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
this.updateContents(fragment);
|
||||
this._colorPicker.layout();
|
||||
|
||||
this.renderDisposable = combinedDisposable([colorListener, colorChangeListener, widget, markdownDisposeable]);
|
||||
this.renderDisposable = combinedDisposable([colorListener, colorChangeListener, widget, ...markdownDisposeables]);
|
||||
});
|
||||
} else {
|
||||
if (msg instanceof MarkerHover) {
|
||||
markerMessages.push(msg);
|
||||
isEmptyHoverContent = false;
|
||||
fragment.appendChild($('div.hover-row', undefined, this.renderMarkerHover(msg)));
|
||||
} else {
|
||||
msg.contents
|
||||
.filter(contents => !isEmptyMarkdownString(contents))
|
||||
.forEach(contents => {
|
||||
const renderedContents = this._markdownRenderer.render(contents);
|
||||
markdownDisposeable = renderedContents;
|
||||
fragment.appendChild($('div.hover-row', undefined, renderedContents.element));
|
||||
const markdownHoverElement = $('div.hover-row.markdown-hover');
|
||||
const hoverContentsElement = dom.append(markdownHoverElement, $('div.hover-contents'));
|
||||
const renderer = new MarkdownRenderer(this._editor, this._modeService, this._openerService);
|
||||
markdownDisposeables.push(renderer.onDidRenderCodeBlock(() => {
|
||||
hoverContentsElement.className = 'hover-contents code-hover-contents';
|
||||
this.onContentsChange();
|
||||
}));
|
||||
const renderedContents = renderer.render(contents);
|
||||
hoverContentsElement.appendChild(renderedContents.element);
|
||||
fragment.appendChild(markdownHoverElement);
|
||||
markdownDisposeables.push(renderedContents);
|
||||
isEmptyHoverContent = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (markerMessages.length) {
|
||||
markerMessages.forEach(msg => fragment.appendChild(this.renderMarkerHover(msg)));
|
||||
const markerHoverForStatusbar = markerMessages.length === 1 ? markerMessages[0] : markerMessages.sort((a, b) => MarkerSeverity.compare(a.marker.severity, b.marker.severity))[0];
|
||||
fragment.appendChild(this.renderMarkerStatusbar(markerHoverForStatusbar));
|
||||
}
|
||||
|
||||
// show
|
||||
|
||||
if (!containColorPicker && !isEmptyHoverContent) {
|
||||
@@ -468,27 +495,28 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
}
|
||||
|
||||
private renderMarkerHover(markerHover: MarkerHover): HTMLElement {
|
||||
const hoverElement = $('div');
|
||||
const hoverElement = $('div.hover-row');
|
||||
const markerElement = dom.append(hoverElement, $('div.marker.hover-contents'));
|
||||
const { source, message, code, relatedInformation } = markerHover.marker;
|
||||
|
||||
const messageElement = dom.append(hoverElement, $('span'));
|
||||
this._editor.applyFontInfo(markerElement);
|
||||
const messageElement = dom.append(markerElement, $('span'));
|
||||
messageElement.style.whiteSpace = 'pre-wrap';
|
||||
messageElement.innerText = message.trim();
|
||||
this._editor.applyFontInfo(messageElement);
|
||||
messageElement.innerText = message;
|
||||
|
||||
if (source || code) {
|
||||
const detailsElement = dom.append(hoverElement, $('span'));
|
||||
const detailsElement = dom.append(markerElement, $('span'));
|
||||
detailsElement.style.opacity = '0.6';
|
||||
detailsElement.style.paddingLeft = '6px';
|
||||
detailsElement.innerText = source && code ? `${source}(${code})` : `(${code})`;
|
||||
detailsElement.innerText = source && code ? `${source}(${code})` : source ? source : `(${code})`;
|
||||
}
|
||||
|
||||
if (isNonEmptyArray(relatedInformation)) {
|
||||
const listElement = dom.append(hoverElement, $('ul'));
|
||||
for (const { message, resource, startLineNumber, startColumn } of relatedInformation) {
|
||||
const item = dom.append(listElement, $('li'));
|
||||
const a = dom.append(item, $('a'));
|
||||
a.innerText = `${basename(resource.path)}(${startLineNumber}, ${startColumn})`;
|
||||
const relatedInfoContainer = dom.append(markerElement, $('div'));
|
||||
relatedInfoContainer.style.marginTop = '8px';
|
||||
const a = dom.append(relatedInfoContainer, $('a'));
|
||||
a.innerText = `${basename(resource)}(${startLineNumber}, ${startColumn}): `;
|
||||
a.style.cursor = 'pointer';
|
||||
a.onclick = e => {
|
||||
e.stopPropagation();
|
||||
@@ -497,13 +525,84 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
this._openerService.open(resource.with({ fragment: `${startLineNumber},${startColumn}` })).catch(onUnexpectedError);
|
||||
}
|
||||
};
|
||||
const messageElement = dom.append<HTMLAnchorElement>(item, $('span'));
|
||||
messageElement.innerText = `: ${message}`;
|
||||
const messageElement = dom.append<HTMLAnchorElement>(relatedInfoContainer, $('span'));
|
||||
messageElement.innerText = message;
|
||||
this._editor.applyFontInfo(messageElement);
|
||||
}
|
||||
}
|
||||
|
||||
return hoverElement;
|
||||
}
|
||||
|
||||
private renderMarkerStatusbar(markerHover: MarkerHover): HTMLElement {
|
||||
const hoverElement = $('div.hover-row.status-bar');
|
||||
const disposables: IDisposable[] = [];
|
||||
const actionsElement = dom.append(hoverElement, $('div.actions'));
|
||||
disposables.push(this.renderAction(actionsElement, {
|
||||
label: nls.localize('quick fixes', "Quick Fix..."),
|
||||
commandId: QuickFixAction.Id,
|
||||
run: async (target) => {
|
||||
const codeActionsPromise = this.getCodeActions(markerHover.marker);
|
||||
disposables.push(toDisposable(() => codeActionsPromise.cancel()));
|
||||
const actions = await codeActionsPromise;
|
||||
const elementPosition = dom.getDomNodePagePosition(target);
|
||||
this._contextMenuService.showContextMenu({
|
||||
getAnchor: () => ({ x: elementPosition.left + 6, y: elementPosition.top + elementPosition.height + 6 }),
|
||||
getActions: () => actions
|
||||
});
|
||||
}
|
||||
}));
|
||||
if (markerHover.marker.severity === MarkerSeverity.Error || markerHover.marker.severity === MarkerSeverity.Warning || markerHover.marker.severity === MarkerSeverity.Info) {
|
||||
disposables.push(this.renderAction(actionsElement, {
|
||||
label: nls.localize('peek problem', "Peek Problem"),
|
||||
commandId: NextMarkerAction.ID,
|
||||
run: () => {
|
||||
this.hide();
|
||||
MarkerController.get(this._editor).show(markerHover.marker);
|
||||
this._editor.focus();
|
||||
}
|
||||
}));
|
||||
}
|
||||
this.renderDisposable = combinedDisposable(disposables);
|
||||
return hoverElement;
|
||||
}
|
||||
|
||||
private getCodeActions(marker: IMarker): CancelablePromise<Action[]> {
|
||||
return createCancelablePromise(async cancellationToken => {
|
||||
const codeActions = await getCodeActions(this._editor.getModel()!, new Range(marker.startLineNumber, marker.startColumn, marker.endLineNumber, marker.endColumn), { type: 'manual', filter: { kind: CodeActionKind.QuickFix } }, cancellationToken);
|
||||
if (codeActions.actions.length) {
|
||||
return codeActions.actions.map(codeAction => new Action(
|
||||
codeAction.command ? codeAction.command.id : codeAction.title,
|
||||
codeAction.title,
|
||||
undefined,
|
||||
true,
|
||||
() => applyCodeAction(codeAction, this._bulkEditService, this._commandService)));
|
||||
}
|
||||
return [
|
||||
new Action('', nls.localize('editor.action.quickFix.noneMessage', "No code actions available"))
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
private renderAction(parent: HTMLElement, actionOptions: { label: string, iconClass?: string, run: (target: HTMLElement) => void, commandId: string }): IDisposable {
|
||||
const actionContainer = dom.append(parent, $('div.action-container'));
|
||||
const action = dom.append(actionContainer, $('a.action'));
|
||||
if (actionOptions.iconClass) {
|
||||
dom.append(action, $(`span.icon.${actionOptions.iconClass}`));
|
||||
}
|
||||
const label = dom.append(action, $('span'));
|
||||
label.textContent = actionOptions.label;
|
||||
const keybinding = this._keybindingService.lookupKeybinding(actionOptions.commandId);
|
||||
if (keybinding) {
|
||||
label.title = `${actionOptions.label} (${keybinding.getLabel()})`;
|
||||
}
|
||||
return dom.addDisposableListener(actionContainer, dom.EventType.CLICK, e => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
actionOptions.run(actionContainer);
|
||||
});
|
||||
}
|
||||
|
||||
private static readonly _DECORATION_OPTIONS = ModelDecorationOptions.register({
|
||||
className: 'hoverHighlight'
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user