mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-12 13:56:34 +00:00
ATL-988: Aligned the hover size to the expression.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
parent
8a692d0ce5
commit
80bddc238d
@ -156,6 +156,8 @@ import { SearchInWorkspaceResultTreeWidget as TheiaSearchInWorkspaceResultTreeWi
|
|||||||
import { SearchInWorkspaceResultTreeWidget } from './theia/search-in-workspace/search-in-workspace-result-tree-widget';
|
import { SearchInWorkspaceResultTreeWidget } from './theia/search-in-workspace/search-in-workspace-result-tree-widget';
|
||||||
import { MonacoEditorProvider } from './theia/monaco/monaco-editor-provider';
|
import { MonacoEditorProvider } from './theia/monaco/monaco-editor-provider';
|
||||||
import { MonacoEditorProvider as TheiaMonacoEditorProvider } from '@theia/monaco/lib/browser/monaco-editor-provider';
|
import { MonacoEditorProvider as TheiaMonacoEditorProvider } from '@theia/monaco/lib/browser/monaco-editor-provider';
|
||||||
|
import { DebugEditorModel } from './theia/debug/debug-editor-model';
|
||||||
|
import { DebugEditorModelFactory } from '@theia/debug/lib/browser/editor/debug-editor-model';
|
||||||
|
|
||||||
const ElementQueries = require('css-element-queries/src/ElementQueries');
|
const ElementQueries = require('css-element-queries/src/ElementQueries');
|
||||||
|
|
||||||
@ -417,6 +419,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
bind(DebugConfigurationManager).toSelf().inSingletonScope();
|
bind(DebugConfigurationManager).toSelf().inSingletonScope();
|
||||||
rebind(TheiaDebugConfigurationManager).toService(DebugConfigurationManager);
|
rebind(TheiaDebugConfigurationManager).toService(DebugConfigurationManager);
|
||||||
|
|
||||||
|
// Patch for the debug hover: https://github.com/eclipse-theia/theia/pull/9256/
|
||||||
|
rebind(DebugEditorModelFactory).toDynamicValue(({ container }) => <DebugEditorModelFactory>(editor =>
|
||||||
|
DebugEditorModel.createModel(container, editor)
|
||||||
|
)).inSingletonScope();
|
||||||
|
|
||||||
// Preferences
|
// Preferences
|
||||||
bindArduinoPreferences(bind);
|
bindArduinoPreferences(bind);
|
||||||
|
|
||||||
|
36
arduino-ide-extension/src/browser/style/debug.css
Normal file
36
arduino-ide-extension/src/browser/style/debug.css
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/* TODO: remove after https://github.com/eclipse-theia/theia/pull/9256/ */
|
||||||
|
|
||||||
|
/* To fix colors in Theia. */
|
||||||
|
.theia-debug-hover-title.number,
|
||||||
|
.theia-debug-console-variable.number {
|
||||||
|
color: var(--theia-variable-number-variable-color);
|
||||||
|
}
|
||||||
|
.theia-debug-hover-title.boolean,
|
||||||
|
.theia-debug-console-variable.boolean {
|
||||||
|
color: var(--theia-variable-boolean-variable-color);
|
||||||
|
}
|
||||||
|
.theia-debug-hover-title.string,
|
||||||
|
.theia-debug-console-variable.string {
|
||||||
|
color: var(--theia-variable-string-variable-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To unset the default debug hover dimension. */
|
||||||
|
.theia-debug-hover {
|
||||||
|
min-width: unset;
|
||||||
|
min-height: unset;
|
||||||
|
width: unset;
|
||||||
|
height: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To adjust the left padding in the hover title. */
|
||||||
|
.theia-debug-hover-title {
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use the default Theia dimensions only iff the expression is complex (`!!expression.hasChildren~) */
|
||||||
|
.theia-debug-hover.complex-value {
|
||||||
|
min-width: 324px;
|
||||||
|
min-height: 324px;
|
||||||
|
width: 324px;
|
||||||
|
height: 324px;
|
||||||
|
}
|
@ -7,6 +7,7 @@
|
|||||||
@import './terminal.css';
|
@import './terminal.css';
|
||||||
@import './editor.css';
|
@import './editor.css';
|
||||||
@import './settings-dialog.css';
|
@import './settings-dialog.css';
|
||||||
|
@import './debug.css';
|
||||||
|
|
||||||
.theia-input.warning:focus {
|
.theia-input.warning:focus {
|
||||||
outline-width: 1px;
|
outline-width: 1px;
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
import debounce from 'p-debounce';
|
||||||
|
import { inject, injectable, postConstruct, interfaces, Container } from 'inversify';
|
||||||
|
import URI from '@theia/core/lib/common/uri';
|
||||||
|
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||||
|
import { MonacoConfigurationService } from '@theia/monaco/lib/browser/monaco-frontend-module';
|
||||||
|
import { INLINE_VALUE_DECORATION_KEY } from '@theia/debug/lib/browser/editor//debug-inline-value-decorator';
|
||||||
|
import { DebugEditor } from '@theia/debug/lib/browser/editor/debug-editor';
|
||||||
|
import { DebugExceptionWidget } from '@theia/debug/lib/browser/editor/debug-exception-widget';
|
||||||
|
import { DebugBreakpointWidget } from '@theia/debug/lib/browser/editor/debug-breakpoint-widget';
|
||||||
|
import { DebugEditorModel as TheiaDebugEditorModel } from '@theia/debug/lib/browser/editor/debug-editor-model';
|
||||||
|
import { createDebugHoverWidgetContainer } from './debug-hover-widget'
|
||||||
|
|
||||||
|
// TODO: Remove after https://github.com/eclipse-theia/theia/pull/9256/
|
||||||
|
@injectable()
|
||||||
|
export class DebugEditorModel extends TheiaDebugEditorModel {
|
||||||
|
|
||||||
|
static createContainer(parent: interfaces.Container, editor: DebugEditor): Container {
|
||||||
|
const child = createDebugHoverWidgetContainer(parent, editor);
|
||||||
|
child.bind(DebugEditorModel).toSelf();
|
||||||
|
child.bind(DebugBreakpointWidget).toSelf();
|
||||||
|
child.bind(DebugExceptionWidget).toSelf();
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createModel(parent: interfaces.Container, editor: DebugEditor): DebugEditorModel {
|
||||||
|
return DebugEditorModel.createContainer(parent, editor).get(DebugEditorModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@inject(MonacoConfigurationService)
|
||||||
|
readonly configurationService: monaco.services.IConfigurationService;
|
||||||
|
|
||||||
|
protected readonly toDisposeOnRenderFrames = new DisposableCollection();
|
||||||
|
|
||||||
|
@postConstruct()
|
||||||
|
protected init(): void {
|
||||||
|
this.toDispose.push(this.toDisposeOnRenderFrames);
|
||||||
|
super.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async updateEditorHover(): Promise<void> {
|
||||||
|
if (this.isCurrentEditorFrame(this.uri)) {
|
||||||
|
const codeEditor = this.editor.getControl();
|
||||||
|
codeEditor.updateOptions({ hover: { enabled: false } });
|
||||||
|
this.toDisposeOnRenderFrames.push(Disposable.create(() => {
|
||||||
|
const model = codeEditor.getModel()!;
|
||||||
|
const overrides = {
|
||||||
|
resource: model.uri,
|
||||||
|
overrideIdentifier: (model as any).getLanguageIdentifier().language,
|
||||||
|
};
|
||||||
|
const { enabled, delay, sticky } = this.configurationService._configuration.getValue('editor.hover', overrides, undefined);
|
||||||
|
codeEditor.updateOptions({
|
||||||
|
hover: {
|
||||||
|
enabled,
|
||||||
|
delay,
|
||||||
|
sticky
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private isCurrentEditorFrame(uri: URI): boolean {
|
||||||
|
return this.sessions.currentFrame?.source?.uri.toString() === uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected readonly renderFrames = debounce(async () => {
|
||||||
|
if (this.toDispose.disposed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.toDisposeOnRenderFrames.dispose();
|
||||||
|
|
||||||
|
this.toggleExceptionWidget();
|
||||||
|
const [newFrameDecorations, inlineValueDecorations] = await Promise.all([
|
||||||
|
this.createFrameDecorations(),
|
||||||
|
this.createInlineValueDecorations()
|
||||||
|
]);
|
||||||
|
const codeEditor = this.editor.getControl();
|
||||||
|
codeEditor.removeDecorations(INLINE_VALUE_DECORATION_KEY);
|
||||||
|
codeEditor.setDecorations(INLINE_VALUE_DECORATION_KEY, inlineValueDecorations);
|
||||||
|
this.frameDecorations = this.deltaDecorations(this.frameDecorations, newFrameDecorations);
|
||||||
|
this.updateEditorHover();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
import { injectable } from 'inversify';
|
||||||
|
import { ExpressionItem, DebugVariable } from '@theia/debug/lib/browser/console/debug-console-items';
|
||||||
|
import { DebugHoverSource as TheiaDebugHoverSource } from '@theia/debug/lib/browser/editor/debug-hover-source';
|
||||||
|
|
||||||
|
// TODO: remove after https://github.com/eclipse-theia/theia/pull/9256/.
|
||||||
|
@injectable()
|
||||||
|
export class DebugHoverSource extends TheiaDebugHoverSource {
|
||||||
|
|
||||||
|
async evaluate2(expression: string): Promise<ExpressionItem | DebugVariable | undefined> {
|
||||||
|
const evaluated = await this.doEvaluate(expression);
|
||||||
|
const elements = evaluated && await evaluated.getElements();
|
||||||
|
this._expression = evaluated;
|
||||||
|
this.elements = elements ? [...elements] : [];
|
||||||
|
this.fireDidChange();
|
||||||
|
return evaluated;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
import { injectable, interfaces, Container } from 'inversify';
|
||||||
|
import { Widget } from '@phosphor/widgets';
|
||||||
|
import { SourceTreeWidget } from '@theia/core/lib/browser/source-tree';
|
||||||
|
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||||
|
import { DebugEditor } from '@theia/debug/lib/browser/editor/debug-editor';
|
||||||
|
import { DebugVariable } from '@theia/debug/lib/browser/console/debug-console-items';
|
||||||
|
import { DebugExpressionProvider } from '@theia/debug/lib/browser/editor/debug-expression-provider';
|
||||||
|
import { DebugHoverSource as TheiaDebugHoverSource } from '@theia/debug/lib/browser/editor/debug-hover-source';
|
||||||
|
import { DebugHoverWidget as TheiaDebugHoverWidget, ShowDebugHoverOptions } from '@theia/debug/lib/browser/editor/debug-hover-widget';
|
||||||
|
import { DebugHoverSource } from './debug-hover-source';
|
||||||
|
|
||||||
|
export function createDebugHoverWidgetContainer(parent: interfaces.Container, editor: DebugEditor): Container {
|
||||||
|
const child = SourceTreeWidget.createContainer(parent, {
|
||||||
|
virtualized: false
|
||||||
|
});
|
||||||
|
child.bind(DebugEditor).toConstantValue(editor);
|
||||||
|
child.bind(TheiaDebugHoverSource).toSelf();
|
||||||
|
child.bind(DebugHoverSource).toSelf();
|
||||||
|
child.rebind(TheiaDebugHoverSource).to(DebugHoverSource);
|
||||||
|
child.unbind(SourceTreeWidget);
|
||||||
|
child.bind(DebugExpressionProvider).toSelf();
|
||||||
|
child.bind(TheiaDebugHoverWidget).toSelf();
|
||||||
|
child.bind(DebugHoverWidget).toSelf();
|
||||||
|
child.rebind(TheiaDebugHoverWidget).to(DebugHoverWidget);
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove patch after https://github.com/eclipse-theia/theia/pull/9256/
|
||||||
|
@injectable()
|
||||||
|
export class DebugHoverWidget extends TheiaDebugHoverWidget {
|
||||||
|
|
||||||
|
protected async doShow(options: ShowDebugHoverOptions | undefined = this.options): Promise<void> {
|
||||||
|
if (!this.isEditorFrame()) {
|
||||||
|
this.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!options) {
|
||||||
|
this.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.options && this.options.selection.equalsRange(options.selection)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.isAttached) {
|
||||||
|
Widget.attach(this, this.contentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.options = options;
|
||||||
|
const matchingExpression = this.expressionProvider.get(this.editor.getControl().getModel()!, options.selection);
|
||||||
|
if (!matchingExpression) {
|
||||||
|
this.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const toFocus = new DisposableCollection();
|
||||||
|
if (this.options.focus === true) {
|
||||||
|
toFocus.push(this.model.onNodeRefreshed(() => {
|
||||||
|
toFocus.dispose();
|
||||||
|
this.activate();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
const expression = await (this.hoverSource as DebugHoverSource).evaluate2(matchingExpression);
|
||||||
|
if (!expression || !expression.value) {
|
||||||
|
toFocus.dispose();
|
||||||
|
this.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.contentNode.hidden = false;
|
||||||
|
['number', 'boolean', 'string'].forEach(token => this.titleNode.classList.remove(token));
|
||||||
|
this.domNode.classList.remove('complex-value');
|
||||||
|
if (expression.hasElements) {
|
||||||
|
this.domNode.classList.add('complex-value');
|
||||||
|
} else {
|
||||||
|
this.contentNode.hidden = true;
|
||||||
|
if (expression.type === 'number' || expression.type === 'boolean' || expression.type === 'string') {
|
||||||
|
this.titleNode.classList.add(expression.type);
|
||||||
|
} else if (!isNaN(+expression.value)) {
|
||||||
|
this.titleNode.classList.add('number');
|
||||||
|
} else if (DebugVariable.booleanRegex.test(expression.value)) {
|
||||||
|
this.titleNode.classList.add('boolean');
|
||||||
|
} else if (DebugVariable.stringRegex.test(expression.value)) {
|
||||||
|
this.titleNode.classList.add('string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// super.show(); // Here we cannot call `super.show()` but have to call `show` on the `Widget` prototype.
|
||||||
|
Widget.prototype.show.call(this);
|
||||||
|
await new Promise<void>(resolve => {
|
||||||
|
setTimeout(() => window.requestAnimationFrame(() => {
|
||||||
|
this.editor.getControl().layoutContentWidget(this);
|
||||||
|
resolve();
|
||||||
|
}), 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user