mirror of
https://github.com/Microsoft/vscode
synced 2024-09-29 07:51:27 +00:00
Extracting HoverController code into Content Hover Controller and Margin Hover Controller (#225239)
* adding code * renaming to 2 * polishing the code * adding code
This commit is contained in:
parent
7f71c79c95
commit
e4843ae75e
|
@ -11,7 +11,7 @@ import { Range } from 'vs/editor/common/core/range';
|
|||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { ColorDecorationInjectedTextMarker } from 'vs/editor/contrib/colorPicker/browser/colorDetector';
|
||||
import { ColorHoverParticipant } from 'vs/editor/contrib/colorPicker/browser/colorHoverParticipant';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { HoverStartMode, HoverStartSource } from 'vs/editor/contrib/hover/browser/hoverOperation';
|
||||
import { HoverParticipantRegistry } from 'vs/editor/contrib/hover/browser/hoverTypes';
|
||||
|
||||
|
@ -56,7 +56,7 @@ export class ColorContribution extends Disposable implements IEditorContribution
|
|||
return;
|
||||
}
|
||||
|
||||
const hoverController = this._editor.getContribution<HoverController>(HoverController.ID);
|
||||
const hoverController = this._editor.getContribution<ContentHoverController>(ContentHoverController.ID);
|
||||
if (!hoverController) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,8 @@ import { ResultKind } from 'vs/platform/keybinding/common/keybindingResolver';
|
|||
import { HoverVerbosityAction } from 'vs/editor/common/languages';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { isMousePositionWithinElement } from 'vs/editor/contrib/hover/browser/hoverUtils';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController';
|
||||
import { ContentHoverWidgetWrapper } from 'vs/editor/contrib/hover/browser/contentHoverWidgetWrapper';
|
||||
import 'vs/css!./hover';
|
||||
import { MarginHoverWidget } from 'vs/editor/contrib/hover/browser/marginHoverWidget';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
|
||||
// sticky hover widget which doesn't disappear on focus out and such
|
||||
|
@ -41,24 +40,18 @@ interface IHoverState {
|
|||
activatedByDecoratorClick: boolean;
|
||||
}
|
||||
|
||||
const enum HoverWidgetType {
|
||||
Content,
|
||||
Glyph,
|
||||
}
|
||||
|
||||
export class HoverController extends Disposable implements IEditorContribution {
|
||||
export class ContentHoverController extends Disposable implements IEditorContribution {
|
||||
|
||||
private readonly _onHoverContentsChanged = this._register(new Emitter<void>());
|
||||
public readonly onHoverContentsChanged = this._onHoverContentsChanged.event;
|
||||
|
||||
public static readonly ID = 'editor.contrib.hover';
|
||||
public static readonly ID = 'editor.contrib.contentHover';
|
||||
|
||||
public shouldKeepOpenOnEditorMouseMoveOrLeave: boolean = false;
|
||||
|
||||
private readonly _listenersStore = new DisposableStore();
|
||||
|
||||
private _glyphWidget: MarginHoverWidget | undefined;
|
||||
private _contentWidget: ContentHoverController | undefined;
|
||||
private _contentWidget: ContentHoverWidgetWrapper | undefined;
|
||||
|
||||
private _mouseMoveEvent: IEditorMouseEvent | undefined;
|
||||
private _reactToEditorMouseMoveRunner: RunOnceScheduler;
|
||||
|
@ -89,8 +82,8 @@ export class HoverController extends Disposable implements IEditorContribution {
|
|||
}));
|
||||
}
|
||||
|
||||
static get(editor: ICodeEditor): HoverController | null {
|
||||
return editor.getContribution<HoverController>(HoverController.ID);
|
||||
static get(editor: ICodeEditor): ContentHoverController | null {
|
||||
return editor.getContribution<ContentHoverController>(ContentHoverController.ID);
|
||||
}
|
||||
|
||||
private _hookListeners(): void {
|
||||
|
@ -149,17 +142,7 @@ export class HoverController extends Disposable implements IEditorContribution {
|
|||
}
|
||||
|
||||
private _shouldNotHideCurrentHoverWidget(mouseEvent: IPartialEditorMouseEvent): boolean {
|
||||
return this._isMouseOnContentHoverWidget(mouseEvent)
|
||||
|| this._isMouseOnMarginHoverWidget(mouseEvent)
|
||||
|| this._isContentWidgetResizing();
|
||||
}
|
||||
|
||||
private _isMouseOnMarginHoverWidget(mouseEvent: IPartialEditorMouseEvent): boolean {
|
||||
const marginHoverWidgetNode = this._glyphWidget?.getDomNode();
|
||||
if (marginHoverWidgetNode) {
|
||||
return isMousePositionWithinElement(marginHoverWidgetNode, mouseEvent.event.posx, mouseEvent.event.posy);
|
||||
}
|
||||
return false;
|
||||
return this._isMouseOnContentHoverWidget(mouseEvent) || this._isContentWidgetResizing();
|
||||
}
|
||||
|
||||
private _isMouseOnContentHoverWidget(mouseEvent: IPartialEditorMouseEvent): boolean {
|
||||
|
@ -195,10 +178,6 @@ export class HoverController extends Disposable implements IEditorContribution {
|
|||
|
||||
const isHoverSticky = this._hoverSettings.sticky;
|
||||
|
||||
const isMouseOnStickyMarginHoverWidget = (mouseEvent: IEditorMouseEvent, isHoverSticky: boolean): boolean => {
|
||||
const isMouseOnMarginHoverWidget = this._isMouseOnMarginHoverWidget(mouseEvent);
|
||||
return isHoverSticky && isMouseOnMarginHoverWidget;
|
||||
};
|
||||
const isMouseOnStickyContentHoverWidget = (mouseEvent: IEditorMouseEvent, isHoverSticky: boolean): boolean => {
|
||||
const isMouseOnContentHoverWidget = this._isMouseOnContentHoverWidget(mouseEvent);
|
||||
return isHoverSticky && isMouseOnContentHoverWidget;
|
||||
|
@ -215,8 +194,7 @@ export class HoverController extends Disposable implements IEditorContribution {
|
|||
&& !mouseEvent.event.browserEvent.view?.getSelection()?.isCollapsed) ?? false;
|
||||
};
|
||||
|
||||
return isMouseOnStickyMarginHoverWidget(mouseEvent, isHoverSticky)
|
||||
|| isMouseOnStickyContentHoverWidget(mouseEvent, isHoverSticky)
|
||||
return isMouseOnStickyContentHoverWidget(mouseEvent, isHoverSticky)
|
||||
|| isMouseOnColorPicker(mouseEvent)
|
||||
|| isTextSelectedWithinContentHoverWidget(mouseEvent, isHoverSticky);
|
||||
}
|
||||
|
@ -284,44 +262,20 @@ export class HoverController extends Disposable implements IEditorContribution {
|
|||
return;
|
||||
}
|
||||
|
||||
const contentHoverShowsOrWillShow = this._tryShowHoverWidget(mouseEvent, HoverWidgetType.Content);
|
||||
const contentHoverShowsOrWillShow = this._tryShowHoverWidget(mouseEvent);
|
||||
if (contentHoverShowsOrWillShow) {
|
||||
return;
|
||||
}
|
||||
|
||||
const glyphWidgetShowsOrWillShow = this._tryShowHoverWidget(mouseEvent, HoverWidgetType.Glyph);
|
||||
if (glyphWidgetShowsOrWillShow) {
|
||||
return;
|
||||
}
|
||||
if (_sticky) {
|
||||
return;
|
||||
}
|
||||
this._hideWidgets();
|
||||
}
|
||||
|
||||
private _tryShowHoverWidget(mouseEvent: IEditorMouseEvent, hoverWidgetType: HoverWidgetType): boolean {
|
||||
private _tryShowHoverWidget(mouseEvent: IEditorMouseEvent): boolean {
|
||||
const contentWidget: IHoverWidget = this._getOrCreateContentWidget();
|
||||
const glyphWidget: IHoverWidget = this._getOrCreateGlyphWidget();
|
||||
let currentWidget: IHoverWidget;
|
||||
let otherWidget: IHoverWidget;
|
||||
switch (hoverWidgetType) {
|
||||
case HoverWidgetType.Content:
|
||||
currentWidget = contentWidget;
|
||||
otherWidget = glyphWidget;
|
||||
break;
|
||||
case HoverWidgetType.Glyph:
|
||||
currentWidget = glyphWidget;
|
||||
otherWidget = contentWidget;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`HoverWidgetType ${hoverWidgetType} is unrecognized`);
|
||||
}
|
||||
|
||||
const showsOrWillShow = currentWidget.showsOrWillShow(mouseEvent);
|
||||
if (showsOrWillShow) {
|
||||
otherWidget.hide();
|
||||
}
|
||||
return showsOrWillShow;
|
||||
return contentWidget.showsOrWillShow(mouseEvent);
|
||||
}
|
||||
|
||||
private _onKeyDown(e: IKeyboardEvent): void {
|
||||
|
@ -369,25 +323,17 @@ export class HoverController extends Disposable implements IEditorContribution {
|
|||
return;
|
||||
}
|
||||
this._hoverState.activatedByDecoratorClick = false;
|
||||
this._glyphWidget?.hide();
|
||||
this._contentWidget?.hide();
|
||||
}
|
||||
|
||||
private _getOrCreateContentWidget(): ContentHoverController {
|
||||
private _getOrCreateContentWidget(): ContentHoverWidgetWrapper {
|
||||
if (!this._contentWidget) {
|
||||
this._contentWidget = this._instantiationService.createInstance(ContentHoverController, this._editor);
|
||||
this._contentWidget = this._instantiationService.createInstance(ContentHoverWidgetWrapper, this._editor);
|
||||
this._listenersStore.add(this._contentWidget.onContentsChanged(() => this._onHoverContentsChanged.fire()));
|
||||
}
|
||||
return this._contentWidget;
|
||||
}
|
||||
|
||||
private _getOrCreateGlyphWidget(): MarginHoverWidget {
|
||||
if (!this._glyphWidget) {
|
||||
this._glyphWidget = this._instantiationService.createInstance(MarginHoverWidget, this._editor);
|
||||
}
|
||||
return this._glyphWidget;
|
||||
}
|
||||
|
||||
public hideContentHover(): void {
|
||||
this._hideWidgets();
|
||||
}
|
||||
|
@ -483,7 +429,6 @@ export class HoverController extends Disposable implements IEditorContribution {
|
|||
super.dispose();
|
||||
this._unhookListeners();
|
||||
this._listenersStore.dispose();
|
||||
this._glyphWidget?.dispose();
|
||||
this._contentWidget?.dispose();
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ import { Emitter } from 'vs/base/common/event';
|
|||
import { RenderedContentHover } from 'vs/editor/contrib/hover/browser/contentHoverRendered';
|
||||
import { isMousePositionWithinElement } from 'vs/editor/contrib/hover/browser/hoverUtils';
|
||||
|
||||
export class ContentHoverController extends Disposable implements IHoverWidget {
|
||||
export class ContentHoverWidgetWrapper extends Disposable implements IHoverWidget {
|
||||
|
||||
private _currentResult: HoverResult | null = null;
|
||||
private _renderedContentHover: RenderedContentHover | undefined;
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
import { localize } from 'vs/nls';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { AccessibleViewType, AccessibleViewProviderId, AccessibleContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions } from 'vs/platform/accessibility/browser/accessibleView';
|
||||
import { IAccessibleViewImplentation } from 'vs/platform/accessibility/browser/accessibleViewRegistry';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
|
@ -40,7 +40,7 @@ export class HoverAccessibleView implements IAccessibleViewImplentation {
|
|||
if (!codeEditor) {
|
||||
throw new Error('No active or focused code editor');
|
||||
}
|
||||
const hoverController = HoverController.get(codeEditor);
|
||||
const hoverController = ContentHoverController.get(codeEditor);
|
||||
if (!hoverController) {
|
||||
return;
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ export class HoverAccessibilityHelp implements IAccessibleViewImplentation {
|
|||
if (!codeEditor) {
|
||||
throw new Error('No active or focused code editor');
|
||||
}
|
||||
const hoverController = HoverController.get(codeEditor);
|
||||
const hoverController = ContentHoverController.get(codeEditor);
|
||||
if (!hoverController) {
|
||||
return;
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ abstract class BaseHoverAccessibleViewProvider extends Disposable implements IAc
|
|||
|
||||
protected _focusedHoverPartIndex: number = -1;
|
||||
|
||||
constructor(protected readonly _hoverController: HoverController) {
|
||||
constructor(protected readonly _hoverController: ContentHoverController) {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ export class HoverAccessibilityHelpProvider extends BaseHoverAccessibleViewProvi
|
|||
|
||||
public readonly options: IAccessibleViewOptions = { type: AccessibleViewType.Help };
|
||||
|
||||
constructor(hoverController: HoverController) {
|
||||
constructor(hoverController: ContentHoverController) {
|
||||
super(hoverController);
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider
|
|||
constructor(
|
||||
private readonly _keybindingService: IKeybindingService,
|
||||
private readonly _editor: ICodeEditor,
|
||||
hoverController: HoverController,
|
||||
hoverController: ContentHoverController,
|
||||
) {
|
||||
super(hoverController);
|
||||
this._initializeOptions(this._editor, hoverController);
|
||||
|
@ -221,7 +221,7 @@ export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider
|
|||
});
|
||||
}
|
||||
|
||||
private _initializeOptions(editor: ICodeEditor, hoverController: HoverController): void {
|
||||
private _initializeOptions(editor: ICodeEditor, hoverController: ContentHoverController): void {
|
||||
const helpProvider = this._register(new HoverAccessibilityHelpProvider(hoverController));
|
||||
this.options.language = editor.getModel()?.getLanguageId();
|
||||
this.options.customHelp = () => { return helpProvider.provideContentAtIndex(this._focusedHoverPartIndex, true); };
|
||||
|
|
|
@ -14,7 +14,7 @@ import { GotoDefinitionAtPositionEditorContribution } from 'vs/editor/contrib/go
|
|||
import { HoverStartMode, HoverStartSource } from 'vs/editor/contrib/hover/browser/hoverOperation';
|
||||
import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { HoverVerbosityAction } from 'vs/editor/common/languages';
|
||||
import * as nls from 'vs/nls';
|
||||
import 'vs/css!./hover';
|
||||
|
@ -74,7 +74,7 @@ export class ShowOrFocusHoverAction extends EditorAction {
|
|||
return;
|
||||
}
|
||||
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ export class ShowDefinitionPreviewHoverAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ export class ScrollUpHoverAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ export class ScrollDownHoverAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ export class ScrollLeftHoverAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ export class ScrollRightHoverAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ export class PageUpHoverAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ export class PageDownHoverAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ export class GoToTopHoverAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ export class GoToBottomHoverAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = HoverController.get(editor);
|
||||
const controller = ContentHoverController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ export class IncreaseHoverVerbosityLevel extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { index: number; focus: boolean }): void {
|
||||
const hoverController = HoverController.get(editor);
|
||||
const hoverController = ContentHoverController.get(editor);
|
||||
if (!hoverController) {
|
||||
return;
|
||||
}
|
||||
|
@ -453,11 +453,11 @@ export class DecreaseHoverVerbosityLevel extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { index: number; focus: boolean }): void {
|
||||
const hoverController = HoverController.get(editor);
|
||||
const hoverController = ContentHoverController.get(editor);
|
||||
if (!hoverController) {
|
||||
return;
|
||||
}
|
||||
const index = args?.index !== undefined ? args.index : hoverController.focusedHoverPartIndex();
|
||||
HoverController.get(editor)?.updateHoverVerbosityLevel(HoverVerbosityAction.Decrease, index, args?.focus);
|
||||
ContentHoverController.get(editor)?.updateHoverVerbosityLevel(HoverVerbosityAction.Decrease, index, args?.focus);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,14 @@ import { registerThemingParticipant } from 'vs/platform/theme/common/themeServic
|
|||
import { HoverParticipantRegistry } from 'vs/editor/contrib/hover/browser/hoverTypes';
|
||||
import { MarkdownHoverParticipant } from 'vs/editor/contrib/hover/browser/markdownHoverParticipant';
|
||||
import { MarkerHoverParticipant } from 'vs/editor/contrib/hover/browser/markerHoverParticipant';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { MarginHoverController } from 'vs/editor/contrib/hover/browser/marginHoverController';
|
||||
import 'vs/css!./hover';
|
||||
import { AccessibleViewRegistry } from 'vs/platform/accessibility/browser/accessibleViewRegistry';
|
||||
import { ExtHoverAccessibleView, HoverAccessibilityHelp, HoverAccessibleView } from 'vs/editor/contrib/hover/browser/hoverAccessibleViews';
|
||||
|
||||
registerEditorContribution(HoverController.ID, HoverController, EditorContributionInstantiation.BeforeFirstInteraction);
|
||||
registerEditorContribution(ContentHoverController.ID, ContentHoverController, EditorContributionInstantiation.BeforeFirstInteraction);
|
||||
registerEditorContribution(MarginHoverController.ID, MarginHoverController, EditorContributionInstantiation.BeforeFirstInteraction);
|
||||
registerEditorAction(ShowOrFocusHoverAction);
|
||||
registerEditorAction(ShowDefinitionPreviewHoverAction);
|
||||
registerEditorAction(ScrollUpHoverAction);
|
||||
|
|
232
src/vs/editor/contrib/hover/browser/marginHoverController.ts
Normal file
232
src/vs/editor/contrib/hover/browser/marginHoverController.ts
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ICodeEditor, IEditorMouseEvent, IPartialEditorMouseEvent } from 'vs/editor/browser/editorBrowser';
|
||||
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { IEditorContribution, IScrollEvent } from 'vs/editor/common/editorCommon';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IHoverWidget } from 'vs/editor/contrib/hover/browser/hoverTypes';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { isMousePositionWithinElement } from 'vs/editor/contrib/hover/browser/hoverUtils';
|
||||
import 'vs/css!./hover';
|
||||
import { MarginHoverWidget } from 'vs/editor/contrib/hover/browser/marginHoverWidget';
|
||||
|
||||
// sticky hover widget which doesn't disappear on focus out and such
|
||||
const _sticky = false
|
||||
// || Boolean("true") // done "weirdly" so that a lint warning prevents you from pushing this
|
||||
;
|
||||
|
||||
interface IHoverSettings {
|
||||
readonly enabled: boolean;
|
||||
readonly sticky: boolean;
|
||||
readonly hidingDelay: number;
|
||||
}
|
||||
|
||||
interface IHoverState {
|
||||
mouseDown: boolean;
|
||||
}
|
||||
|
||||
export class MarginHoverController extends Disposable implements IEditorContribution {
|
||||
|
||||
public static readonly ID = 'editor.contrib.marginHover';
|
||||
|
||||
public shouldKeepOpenOnEditorMouseMoveOrLeave: boolean = false;
|
||||
|
||||
private readonly _listenersStore = new DisposableStore();
|
||||
|
||||
private _glyphWidget: MarginHoverWidget | undefined;
|
||||
private _mouseMoveEvent: IEditorMouseEvent | undefined;
|
||||
private _reactToEditorMouseMoveRunner: RunOnceScheduler;
|
||||
|
||||
private _hoverSettings!: IHoverSettings;
|
||||
private _hoverState: IHoverState = {
|
||||
mouseDown: false
|
||||
};
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
this._reactToEditorMouseMoveRunner = this._register(
|
||||
new RunOnceScheduler(
|
||||
() => this._reactToEditorMouseMove(this._mouseMoveEvent), 0
|
||||
)
|
||||
);
|
||||
this._hookListeners();
|
||||
this._register(this._editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => {
|
||||
if (e.hasChanged(EditorOption.hover)) {
|
||||
this._unhookListeners();
|
||||
this._hookListeners();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
static get(editor: ICodeEditor): MarginHoverController | null {
|
||||
return editor.getContribution<MarginHoverController>(MarginHoverController.ID);
|
||||
}
|
||||
|
||||
private _hookListeners(): void {
|
||||
|
||||
const hoverOpts = this._editor.getOption(EditorOption.hover);
|
||||
this._hoverSettings = {
|
||||
enabled: hoverOpts.enabled,
|
||||
sticky: hoverOpts.sticky,
|
||||
hidingDelay: hoverOpts.delay
|
||||
};
|
||||
|
||||
if (hoverOpts.enabled) {
|
||||
this._listenersStore.add(this._editor.onMouseDown((e: IEditorMouseEvent) => this._onEditorMouseDown(e)));
|
||||
this._listenersStore.add(this._editor.onMouseUp(() => this._onEditorMouseUp()));
|
||||
this._listenersStore.add(this._editor.onMouseMove((e: IEditorMouseEvent) => this._onEditorMouseMove(e)));
|
||||
this._listenersStore.add(this._editor.onKeyDown((e: IKeyboardEvent) => this._onKeyDown(e)));
|
||||
} else {
|
||||
this._listenersStore.add(this._editor.onMouseMove((e: IEditorMouseEvent) => this._onEditorMouseMove(e)));
|
||||
this._listenersStore.add(this._editor.onKeyDown((e: IKeyboardEvent) => this._onKeyDown(e)));
|
||||
}
|
||||
|
||||
this._listenersStore.add(this._editor.onMouseLeave((e) => this._onEditorMouseLeave(e)));
|
||||
this._listenersStore.add(this._editor.onDidChangeModel(() => {
|
||||
this._cancelScheduler();
|
||||
this._hideWidgets();
|
||||
}));
|
||||
this._listenersStore.add(this._editor.onDidChangeModelContent(() => this._cancelScheduler()));
|
||||
this._listenersStore.add(this._editor.onDidScrollChange((e: IScrollEvent) => this._onEditorScrollChanged(e)));
|
||||
}
|
||||
|
||||
private _unhookListeners(): void {
|
||||
this._listenersStore.clear();
|
||||
}
|
||||
|
||||
private _cancelScheduler() {
|
||||
this._mouseMoveEvent = undefined;
|
||||
this._reactToEditorMouseMoveRunner.cancel();
|
||||
}
|
||||
|
||||
private _onEditorScrollChanged(e: IScrollEvent): void {
|
||||
if (e.scrollTopChanged || e.scrollLeftChanged) {
|
||||
this._hideWidgets();
|
||||
}
|
||||
}
|
||||
|
||||
private _onEditorMouseDown(mouseEvent: IEditorMouseEvent): void {
|
||||
this._hoverState.mouseDown = true;
|
||||
const shouldNotHideCurrentHoverWidget = this._isMouseOnMarginHoverWidget(mouseEvent);
|
||||
if (shouldNotHideCurrentHoverWidget) {
|
||||
return;
|
||||
}
|
||||
this._hideWidgets();
|
||||
}
|
||||
|
||||
private _isMouseOnMarginHoverWidget(mouseEvent: IPartialEditorMouseEvent): boolean {
|
||||
const marginHoverWidgetNode = this._glyphWidget?.getDomNode();
|
||||
if (marginHoverWidgetNode) {
|
||||
return isMousePositionWithinElement(marginHoverWidgetNode, mouseEvent.event.posx, mouseEvent.event.posy);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private _onEditorMouseUp(): void {
|
||||
this._hoverState.mouseDown = false;
|
||||
}
|
||||
|
||||
private _onEditorMouseLeave(mouseEvent: IPartialEditorMouseEvent): void {
|
||||
if (this.shouldKeepOpenOnEditorMouseMoveOrLeave) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._cancelScheduler();
|
||||
const shouldNotHideCurrentHoverWidget = this._isMouseOnMarginHoverWidget(mouseEvent);
|
||||
if (shouldNotHideCurrentHoverWidget) {
|
||||
return;
|
||||
}
|
||||
if (_sticky) {
|
||||
return;
|
||||
}
|
||||
this._hideWidgets();
|
||||
}
|
||||
|
||||
private _shouldNotRecomputeCurrentHoverWidget(mouseEvent: IEditorMouseEvent): boolean {
|
||||
const isHoverSticky = this._hoverSettings.sticky;
|
||||
const isMouseOnMarginHoverWidget = this._isMouseOnMarginHoverWidget(mouseEvent);
|
||||
return isHoverSticky && isMouseOnMarginHoverWidget;
|
||||
}
|
||||
|
||||
private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void {
|
||||
if (this.shouldKeepOpenOnEditorMouseMoveOrLeave) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._mouseMoveEvent = mouseEvent;
|
||||
const shouldNotRecomputeCurrentHoverWidget = this._shouldNotRecomputeCurrentHoverWidget(mouseEvent);
|
||||
if (shouldNotRecomputeCurrentHoverWidget) {
|
||||
this._reactToEditorMouseMoveRunner.cancel();
|
||||
return;
|
||||
}
|
||||
this._reactToEditorMouseMove(mouseEvent);
|
||||
}
|
||||
|
||||
private _reactToEditorMouseMove(mouseEvent: IEditorMouseEvent | undefined): void {
|
||||
|
||||
if (!mouseEvent) {
|
||||
return;
|
||||
}
|
||||
const glyphWidgetShowsOrWillShow = this._tryShowHoverWidget(mouseEvent);
|
||||
if (glyphWidgetShowsOrWillShow) {
|
||||
return;
|
||||
}
|
||||
if (_sticky) {
|
||||
return;
|
||||
}
|
||||
this._hideWidgets();
|
||||
}
|
||||
|
||||
private _tryShowHoverWidget(mouseEvent: IEditorMouseEvent): boolean {
|
||||
const glyphWidget: IHoverWidget = this._getOrCreateGlyphWidget();
|
||||
return glyphWidget.showsOrWillShow(mouseEvent);
|
||||
}
|
||||
|
||||
private _onKeyDown(e: IKeyboardEvent): void {
|
||||
if (!this._editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
if (e.keyCode === KeyCode.Ctrl
|
||||
|| e.keyCode === KeyCode.Alt
|
||||
|| e.keyCode === KeyCode.Meta
|
||||
|| e.keyCode === KeyCode.Shift) {
|
||||
// Do not hide hover when a modifier key is pressed
|
||||
return;
|
||||
}
|
||||
this._hideWidgets();
|
||||
}
|
||||
|
||||
private _hideWidgets(): void {
|
||||
if (_sticky) {
|
||||
return;
|
||||
}
|
||||
this._glyphWidget?.hide();
|
||||
}
|
||||
|
||||
private _getOrCreateGlyphWidget(): MarginHoverWidget {
|
||||
if (!this._glyphWidget) {
|
||||
this._glyphWidget = this._instantiationService.createInstance(MarginHoverWidget, this._editor);
|
||||
}
|
||||
return this._glyphWidget;
|
||||
}
|
||||
|
||||
public hideContentHover(): void {
|
||||
this._hideWidgets();
|
||||
}
|
||||
|
||||
public override dispose(): void {
|
||||
super.dispose();
|
||||
this._unhookListeners();
|
||||
this._listenersStore.dispose();
|
||||
this._glyphWidget?.dispose();
|
||||
}
|
||||
}
|
|
@ -26,7 +26,8 @@ import { IPosition } from 'vs/editor/common/core/position';
|
|||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IModelService } from 'vs/editor/common/services/model';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { MarginHoverController } from 'vs/editor/contrib/hover/browser/marginHoverController';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { DropdownWithPrimaryActionViewItem } from 'vs/platform/actions/browser/dropdownWithPrimaryActionViewItem';
|
||||
|
@ -407,7 +408,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
|
|||
|
||||
this._inputEditorElement = dom.append(inputContainer, $(chatInputEditorContainerSelector));
|
||||
const editorOptions = getSimpleCodeEditorWidgetOptions();
|
||||
editorOptions.contributions?.push(...EditorExtensionsRegistry.getSomeEditorContributions([HoverController.ID]));
|
||||
editorOptions.contributions?.push(...EditorExtensionsRegistry.getSomeEditorContributions([ContentHoverController.ID, MarginHoverController.ID]));
|
||||
this._inputEditor = this._register(scopedInstantiationService.createInstance(CodeEditorWidget, this._inputEditorElement, options, editorOptions));
|
||||
|
||||
this._register(this._inputEditor.onDidChangeModelContent(() => {
|
||||
|
|
|
@ -35,7 +35,8 @@ import { BracketMatchingController } from 'vs/editor/contrib/bracketMatching/bro
|
|||
import { ColorDetector } from 'vs/editor/contrib/colorPicker/browser/colorDetector';
|
||||
import { ContextMenuController } from 'vs/editor/contrib/contextmenu/browser/contextmenu';
|
||||
import { GotoDefinitionAtPositionEditorContribution } from 'vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { MarginHoverController } from 'vs/editor/contrib/hover/browser/marginHoverController';
|
||||
import { MessageController } from 'vs/editor/contrib/message/browser/messageController';
|
||||
import { ViewportSemanticTokensContribution } from 'vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens';
|
||||
import { SmartSelectController } from 'vs/editor/contrib/smartSelect/browser/smartSelect';
|
||||
|
@ -290,7 +291,8 @@ export class CodeBlockPart extends Disposable {
|
|||
ViewportSemanticTokensContribution.ID,
|
||||
BracketMatchingController.ID,
|
||||
SmartSelectController.ID,
|
||||
HoverController.ID,
|
||||
ContentHoverController.ID,
|
||||
MarginHoverController.ID,
|
||||
MessageController.ID,
|
||||
GotoDefinitionAtPositionEditorContribution.ID,
|
||||
ColorDetector.ID
|
||||
|
@ -400,7 +402,8 @@ export class CodeBlockPart extends Disposable {
|
|||
}
|
||||
|
||||
private clearWidgets() {
|
||||
HoverController.get(this.editor)?.hideContentHover();
|
||||
ContentHoverController.get(this.editor)?.hideContentHover();
|
||||
MarginHoverController.get(this.editor)?.hideContentHover();
|
||||
}
|
||||
|
||||
private async updateEditor(data: ICodeBlockData): Promise<void> {
|
||||
|
@ -607,7 +610,8 @@ export class CodeCompareBlockPart extends Disposable {
|
|||
ViewportSemanticTokensContribution.ID,
|
||||
BracketMatchingController.ID,
|
||||
SmartSelectController.ID,
|
||||
HoverController.ID,
|
||||
ContentHoverController.ID,
|
||||
MarginHoverController.ID,
|
||||
GotoDefinitionAtPositionEditorContribution.ID,
|
||||
])
|
||||
};
|
||||
|
@ -717,8 +721,10 @@ export class CodeCompareBlockPart extends Disposable {
|
|||
}
|
||||
|
||||
private clearWidgets() {
|
||||
HoverController.get(this.diffEditor.getOriginalEditor())?.hideContentHover();
|
||||
HoverController.get(this.diffEditor.getModifiedEditor())?.hideContentHover();
|
||||
ContentHoverController.get(this.diffEditor.getOriginalEditor())?.hideContentHover();
|
||||
ContentHoverController.get(this.diffEditor.getModifiedEditor())?.hideContentHover();
|
||||
MarginHoverController.get(this.diffEditor.getOriginalEditor())?.hideContentHover();
|
||||
MarginHoverController.get(this.diffEditor.getModifiedEditor())?.hideContentHover();
|
||||
}
|
||||
|
||||
private async updateEditor(data: ICodeCompareBlockData, token: CancellationToken): Promise<void> {
|
||||
|
|
|
@ -36,7 +36,8 @@ import { LinkDetector } from 'vs/editor/contrib/links/browser/links';
|
|||
import { MessageController } from 'vs/editor/contrib/message/browser/messageController';
|
||||
import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard';
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { MarginHoverController } from 'vs/editor/contrib/hover/browser/marginHoverController';
|
||||
|
||||
export const ctxCommentEditorFocused = new RawContextKey<boolean>('commentEditorFocused', false);
|
||||
export const MIN_EDITOR_HEIGHT = 5 * 18;
|
||||
|
@ -78,7 +79,8 @@ export class SimpleCommentEditor extends CodeEditorWidget {
|
|||
DropIntoEditorController.ID,
|
||||
LinkDetector.ID,
|
||||
MessageController.ID,
|
||||
HoverController.ID,
|
||||
ContentHoverController.ID,
|
||||
MarginHoverController.ID,
|
||||
SelectionClipboardContributionID,
|
||||
InlineCompletionsController.ID,
|
||||
CodeActionController.ID,
|
||||
|
|
|
@ -37,7 +37,7 @@ import { IModelDeltaDecoration, ITextModel, InjectedTextCursorStops } from 'vs/e
|
|||
import { IFeatureDebounceInformation, ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce';
|
||||
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
|
||||
import { IModelService } from 'vs/editor/common/services/model';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { HoverStartMode, HoverStartSource } from 'vs/editor/contrib/hover/browser/hoverOperation';
|
||||
import * as nls from 'vs/nls';
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
|
@ -375,7 +375,7 @@ export class DebugEditorContribution implements IDebugEditorContribution {
|
|||
return;
|
||||
}
|
||||
|
||||
const hoverController = this.editor.getContribution<HoverController>(HoverController.ID);
|
||||
const hoverController = this.editor.getContribution<ContentHoverController>(ContentHoverController.ID);
|
||||
hoverController?.hideContentHover();
|
||||
|
||||
this.editor.updateOptions({ hover: { enabled: false } });
|
||||
|
@ -389,7 +389,7 @@ export class DebugEditorContribution implements IDebugEditorContribution {
|
|||
}
|
||||
|
||||
private showEditorHover(position: Position, focus: boolean) {
|
||||
const hoverController = this.editor.getContribution<HoverController>(HoverController.ID);
|
||||
const hoverController = this.editor.getContribution<ContentHoverController>(ContentHoverController.ID);
|
||||
const range = new Range(position.lineNumber, position.column, position.lineNumber, position.column);
|
||||
// enable the editor hover, otherwise the content controller will see it
|
||||
// as disabled and hide it on the first mouse move (#193149)
|
||||
|
|
|
@ -60,7 +60,8 @@ import { INTERACTIVE_WINDOW_EDITOR_ID } from 'vs/workbench/contrib/notebook/comm
|
|||
import 'vs/css!./interactiveEditor';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { deepClone } from 'vs/base/common/objects';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { MarginHoverController } from 'vs/editor/contrib/hover/browser/marginHoverController';
|
||||
import { ReplInputHintContentWidget } from 'vs/workbench/contrib/interactive/browser/replInputHintContentWidget';
|
||||
|
||||
const DECORATION_KEY = 'interactiveInputDecoration';
|
||||
|
@ -382,7 +383,8 @@ export class InteractiveEditor extends EditorPane implements IEditorPaneWithScro
|
|||
cellEditorContributions: EditorExtensionsRegistry.getSomeEditorContributions([
|
||||
SelectionClipboardContributionID,
|
||||
ContextMenuController.ID,
|
||||
HoverController.ID,
|
||||
ContentHoverController.ID,
|
||||
MarginHoverController.ID,
|
||||
MarkerController.ID
|
||||
]),
|
||||
options: this._notebookOptions,
|
||||
|
@ -400,7 +402,8 @@ export class InteractiveEditor extends EditorPane implements IEditorPaneWithScro
|
|||
ParameterHintsController.ID,
|
||||
SnippetController2.ID,
|
||||
TabCompletionController.ID,
|
||||
HoverController.ID,
|
||||
ContentHoverController.ID,
|
||||
MarginHoverController.ID,
|
||||
MarkerController.ID
|
||||
])
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ import { EXECUTE_REPL_COMMAND_ID, REPL_EDITOR_ID } from 'vs/workbench/contrib/no
|
|||
import 'vs/css!./interactiveEditor';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { deepClone } from 'vs/base/common/objects';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { MarginHoverController } from 'vs/editor/contrib/hover/browser/marginHoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { ReplEditorInput } from 'vs/workbench/contrib/replNotebook/browser/replEditorInput';
|
||||
|
||||
const DECORATION_KEY = 'interactiveInputDecoration';
|
||||
|
@ -377,7 +378,8 @@ export class ReplEditor extends EditorPane implements IEditorPaneWithScrolling {
|
|||
cellEditorContributions: EditorExtensionsRegistry.getSomeEditorContributions([
|
||||
SelectionClipboardContributionID,
|
||||
ContextMenuController.ID,
|
||||
HoverController.ID,
|
||||
ContentHoverController.ID,
|
||||
MarginHoverController.ID,
|
||||
MarkerController.ID
|
||||
]),
|
||||
options: this._notebookOptions,
|
||||
|
@ -395,7 +397,8 @@ export class ReplEditor extends EditorPane implements IEditorPaneWithScrolling {
|
|||
ParameterHintsController.ID,
|
||||
SnippetController2.ID,
|
||||
TabCompletionController.ID,
|
||||
HoverController.ID,
|
||||
ContentHoverController.ID,
|
||||
MarginHoverController.ID,
|
||||
MarkerController.ID
|
||||
])
|
||||
}
|
||||
|
|
|
@ -104,7 +104,8 @@ import { MarkdownString } from 'vs/base/common/htmlContent';
|
|||
import type { IHoverOptions, IManagedHover, IManagedHoverTooltipMarkdownString } from 'vs/base/browser/ui/hover/hover';
|
||||
import { IHoverService, WorkbenchHoverDelegate } from 'vs/platform/hover/browser/hover';
|
||||
import { OpenScmGroupAction } from 'vs/workbench/contrib/multiDiffEditor/browser/scmMultiDiffSourceResolver';
|
||||
import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController';
|
||||
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController2';
|
||||
import { MarginHoverController } from 'vs/editor/contrib/hover/browser/marginHoverController';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { autorun } from 'vs/base/common/observable';
|
||||
import { createInstantHoverDelegate, getDefaultHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegateFactory';
|
||||
|
@ -2776,7 +2777,8 @@ class SCMInputWidget {
|
|||
DropIntoEditorController.ID,
|
||||
EditorDictation.ID,
|
||||
FormatOnType.ID,
|
||||
HoverController.ID,
|
||||
ContentHoverController.ID,
|
||||
MarginHoverController.ID,
|
||||
InlineCompletionsController.ID,
|
||||
LinkDetector.ID,
|
||||
MenuPreventer.ID,
|
||||
|
|
Loading…
Reference in a new issue