Path: blob/main/src/vs/editor/contrib/hover/browser/hoverActions.ts
4779 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, GO_TO_BOTTOM_HOVER_ACTION_ID, GO_TO_TOP_HOVER_ACTION_ID, HIDE_HOVER_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL, PAGE_DOWN_HOVER_ACTION_ID, PAGE_UP_HOVER_ACTION_ID, SCROLL_DOWN_HOVER_ACTION_ID, SCROLL_LEFT_HOVER_ACTION_ID, SCROLL_RIGHT_HOVER_ACTION_ID, SCROLL_UP_HOVER_ACTION_ID, SHOW_DEFINITION_PREVIEW_HOVER_ACTION_ID, SHOW_OR_FOCUS_HOVER_ACTION_ID } from './hoverActionIds.js';6import { KeyChord, KeyCode, KeyMod } from '../../../../base/common/keyCodes.js';7import { ICodeEditor } from '../../../browser/editorBrowser.js';8import { EditorAction, ServicesAccessor } from '../../../browser/editorExtensions.js';9import { EditorOption } from '../../../common/config/editorOptions.js';10import { Range } from '../../../common/core/range.js';11import { EditorContextKeys } from '../../../common/editorContextKeys.js';12import { GotoDefinitionAtPositionEditorContribution } from '../../gotoSymbol/browser/link/goToDefinitionAtPosition.js';13import { HoverStartMode, HoverStartSource } from './hoverOperation.js';14import { AccessibilitySupport } from '../../../../platform/accessibility/common/accessibility.js';15import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';16import { ContentHoverController } from './contentHoverController.js';17import { HoverVerbosityAction } from '../../../common/languages.js';18import * as nls from '../../../../nls.js';19import './hover.css';2021enum HoverFocusBehavior {22NoAutoFocus = 'noAutoFocus',23FocusIfVisible = 'focusIfVisible',24AutoFocusImmediately = 'autoFocusImmediately'25}2627export class ShowOrFocusHoverAction extends EditorAction {2829constructor() {30super({31id: SHOW_OR_FOCUS_HOVER_ACTION_ID,32label: nls.localize2({33key: 'showOrFocusHover',34comment: [35'Label for action that will trigger the showing/focusing of a hover in the editor.',36'If the hover is not visible, it will show the hover.',37'This allows for users to show the hover without using the mouse.'38]39}, "Show or Focus Hover"),40metadata: {41description: nls.localize2('showOrFocusHoverDescription', 'Show or focus the editor hover which shows documentation, references, and other content for a symbol at the current cursor position.'),42args: [{43name: 'args',44schema: {45type: 'object',46properties: {47'focus': {48description: 'Controls if and when the hover should take focus upon being triggered by this action.',49enum: [HoverFocusBehavior.NoAutoFocus, HoverFocusBehavior.FocusIfVisible, HoverFocusBehavior.AutoFocusImmediately],50enumDescriptions: [51nls.localize('showOrFocusHover.focus.noAutoFocus', 'The hover will not automatically take focus.'),52nls.localize('showOrFocusHover.focus.focusIfVisible', 'The hover will take focus only if it is already visible.'),53nls.localize('showOrFocusHover.focus.autoFocusImmediately', 'The hover will automatically take focus when it appears.'),54],55default: HoverFocusBehavior.FocusIfVisible,56}57},58}59}]60},61precondition: undefined,62kbOpts: {63kbExpr: EditorContextKeys.editorTextFocus,64primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyI),65weight: KeybindingWeight.EditorContrib66}67});68}6970public run(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {71if (!editor.hasModel()) {72return;73}7475const controller = ContentHoverController.get(editor);76if (!controller) {77return;78}7980const focusArgument = args?.focus;81let focusOption = HoverFocusBehavior.FocusIfVisible;82if (Object.values(HoverFocusBehavior).includes(focusArgument)) {83focusOption = focusArgument;84} else if (typeof focusArgument === 'boolean' && focusArgument) {85focusOption = HoverFocusBehavior.AutoFocusImmediately;86}8788const showContentHover = (focus: boolean) => {89const position = editor.getPosition();90const range = new Range(position.lineNumber, position.column, position.lineNumber, position.column);91controller.showContentHover(range, HoverStartMode.Immediate, HoverStartSource.Keyboard, focus);92};9394const accessibilitySupportEnabled = editor.getOption(EditorOption.accessibilitySupport) === AccessibilitySupport.Enabled;9596if (controller.isHoverVisible) {97if (focusOption !== HoverFocusBehavior.NoAutoFocus) {98controller.focus();99} else {100showContentHover(accessibilitySupportEnabled);101}102} else {103showContentHover(accessibilitySupportEnabled || focusOption === HoverFocusBehavior.AutoFocusImmediately);104}105}106}107108export class ShowDefinitionPreviewHoverAction extends EditorAction {109110constructor() {111super({112id: SHOW_DEFINITION_PREVIEW_HOVER_ACTION_ID,113label: nls.localize2({114key: 'showDefinitionPreviewHover',115comment: [116'Label for action that will trigger the showing of definition preview hover in the editor.',117'This allows for users to show the definition preview hover without using the mouse.'118]119}, "Show Definition Preview Hover"),120precondition: undefined,121metadata: {122description: nls.localize2('showDefinitionPreviewHoverDescription', 'Show the definition preview hover in the editor.'),123},124});125}126127public run(accessor: ServicesAccessor, editor: ICodeEditor): void {128const controller = ContentHoverController.get(editor);129if (!controller) {130return;131}132const position = editor.getPosition();133134if (!position) {135return;136}137138const range = new Range(position.lineNumber, position.column, position.lineNumber, position.column);139const goto = GotoDefinitionAtPositionEditorContribution.get(editor);140if (!goto) {141return;142}143144const promise = goto.startFindDefinitionFromCursor(position);145promise.then(() => {146controller.showContentHover(range, HoverStartMode.Immediate, HoverStartSource.Keyboard, true);147});148}149}150151export class HideContentHoverAction extends EditorAction {152153constructor() {154super({155id: HIDE_HOVER_ACTION_ID,156label: nls.localize2({157key: 'hideHover',158comment: ['Label for action that will hide the hover in the editor.']159}, "Hide Hover"),160alias: 'Hide Content Hover',161precondition: undefined162});163}164165public run(accessor: ServicesAccessor, editor: ICodeEditor): void {166ContentHoverController.get(editor)?.hideContentHover();167}168}169170export class ScrollUpHoverAction extends EditorAction {171172constructor() {173super({174id: SCROLL_UP_HOVER_ACTION_ID,175label: nls.localize2({176key: 'scrollUpHover',177comment: [178'Action that allows to scroll up in the hover widget with the up arrow when the hover widget is focused.'179]180}, "Scroll Up Hover"),181precondition: EditorContextKeys.hoverFocused,182kbOpts: {183kbExpr: EditorContextKeys.hoverFocused,184primary: KeyCode.UpArrow,185weight: KeybindingWeight.EditorContrib186},187metadata: {188description: nls.localize2('scrollUpHoverDescription', 'Scroll up the editor hover.')189},190});191}192193public run(accessor: ServicesAccessor, editor: ICodeEditor): void {194const controller = ContentHoverController.get(editor);195if (!controller) {196return;197}198controller.scrollUp();199}200}201202export class ScrollDownHoverAction extends EditorAction {203204constructor() {205super({206id: SCROLL_DOWN_HOVER_ACTION_ID,207label: nls.localize2({208key: 'scrollDownHover',209comment: [210'Action that allows to scroll down in the hover widget with the up arrow when the hover widget is focused.'211]212}, "Scroll Down Hover"),213precondition: EditorContextKeys.hoverFocused,214kbOpts: {215kbExpr: EditorContextKeys.hoverFocused,216primary: KeyCode.DownArrow,217weight: KeybindingWeight.EditorContrib218},219metadata: {220description: nls.localize2('scrollDownHoverDescription', 'Scroll down the editor hover.'),221},222});223}224225public run(accessor: ServicesAccessor, editor: ICodeEditor): void {226const controller = ContentHoverController.get(editor);227if (!controller) {228return;229}230controller.scrollDown();231}232}233234export class ScrollLeftHoverAction extends EditorAction {235236constructor() {237super({238id: SCROLL_LEFT_HOVER_ACTION_ID,239label: nls.localize2({240key: 'scrollLeftHover',241comment: [242'Action that allows to scroll left in the hover widget with the left arrow when the hover widget is focused.'243]244}, "Scroll Left Hover"),245precondition: EditorContextKeys.hoverFocused,246kbOpts: {247kbExpr: EditorContextKeys.hoverFocused,248primary: KeyCode.LeftArrow,249weight: KeybindingWeight.EditorContrib250},251metadata: {252description: nls.localize2('scrollLeftHoverDescription', 'Scroll left the editor hover.'),253},254});255}256257public run(accessor: ServicesAccessor, editor: ICodeEditor): void {258const controller = ContentHoverController.get(editor);259if (!controller) {260return;261}262controller.scrollLeft();263}264}265266export class ScrollRightHoverAction extends EditorAction {267268constructor() {269super({270id: SCROLL_RIGHT_HOVER_ACTION_ID,271label: nls.localize2({272key: 'scrollRightHover',273comment: [274'Action that allows to scroll right in the hover widget with the right arrow when the hover widget is focused.'275]276}, "Scroll Right Hover"),277precondition: EditorContextKeys.hoverFocused,278kbOpts: {279kbExpr: EditorContextKeys.hoverFocused,280primary: KeyCode.RightArrow,281weight: KeybindingWeight.EditorContrib282},283metadata: {284description: nls.localize2('scrollRightHoverDescription', 'Scroll right the editor hover.')285},286});287}288289public run(accessor: ServicesAccessor, editor: ICodeEditor): void {290const controller = ContentHoverController.get(editor);291if (!controller) {292return;293}294controller.scrollRight();295}296}297298export class PageUpHoverAction extends EditorAction {299300constructor() {301super({302id: PAGE_UP_HOVER_ACTION_ID,303label: nls.localize2({304key: 'pageUpHover',305comment: [306'Action that allows to page up in the hover widget with the page up command when the hover widget is focused.'307]308}, "Page Up Hover"),309precondition: EditorContextKeys.hoverFocused,310kbOpts: {311kbExpr: EditorContextKeys.hoverFocused,312primary: KeyCode.PageUp,313secondary: [KeyMod.Alt | KeyCode.UpArrow],314weight: KeybindingWeight.EditorContrib315},316metadata: {317description: nls.localize2('pageUpHoverDescription', 'Page up the editor hover.'),318},319});320}321322public run(accessor: ServicesAccessor, editor: ICodeEditor): void {323const controller = ContentHoverController.get(editor);324if (!controller) {325return;326}327controller.pageUp();328}329}330331export class PageDownHoverAction extends EditorAction {332333constructor() {334super({335id: PAGE_DOWN_HOVER_ACTION_ID,336label: nls.localize2({337key: 'pageDownHover',338comment: [339'Action that allows to page down in the hover widget with the page down command when the hover widget is focused.'340]341}, "Page Down Hover"),342precondition: EditorContextKeys.hoverFocused,343kbOpts: {344kbExpr: EditorContextKeys.hoverFocused,345primary: KeyCode.PageDown,346secondary: [KeyMod.Alt | KeyCode.DownArrow],347weight: KeybindingWeight.EditorContrib348},349metadata: {350description: nls.localize2('pageDownHoverDescription', 'Page down the editor hover.'),351},352});353}354355public run(accessor: ServicesAccessor, editor: ICodeEditor): void {356const controller = ContentHoverController.get(editor);357if (!controller) {358return;359}360controller.pageDown();361}362}363364export class GoToTopHoverAction extends EditorAction {365366constructor() {367super({368id: GO_TO_TOP_HOVER_ACTION_ID,369label: nls.localize2({370key: 'goToTopHover',371comment: [372'Action that allows to go to the top of the hover widget with the home command when the hover widget is focused.'373]374}, "Go To Top Hover"),375precondition: EditorContextKeys.hoverFocused,376kbOpts: {377kbExpr: EditorContextKeys.hoverFocused,378primary: KeyCode.Home,379secondary: [KeyMod.CtrlCmd | KeyCode.UpArrow],380weight: KeybindingWeight.EditorContrib381},382metadata: {383description: nls.localize2('goToTopHoverDescription', 'Go to the top of the editor hover.'),384},385});386}387388public run(accessor: ServicesAccessor, editor: ICodeEditor): void {389const controller = ContentHoverController.get(editor);390if (!controller) {391return;392}393controller.goToTop();394}395}396397398export class GoToBottomHoverAction extends EditorAction {399400constructor() {401super({402id: GO_TO_BOTTOM_HOVER_ACTION_ID,403label: nls.localize2({404key: 'goToBottomHover',405comment: [406'Action that allows to go to the bottom in the hover widget with the end command when the hover widget is focused.'407]408}, "Go To Bottom Hover"),409precondition: EditorContextKeys.hoverFocused,410kbOpts: {411kbExpr: EditorContextKeys.hoverFocused,412primary: KeyCode.End,413secondary: [KeyMod.CtrlCmd | KeyCode.DownArrow],414weight: KeybindingWeight.EditorContrib415},416metadata: {417description: nls.localize2('goToBottomHoverDescription', 'Go to the bottom of the editor hover.')418},419});420}421422public run(accessor: ServicesAccessor, editor: ICodeEditor): void {423const controller = ContentHoverController.get(editor);424if (!controller) {425return;426}427controller.goToBottom();428}429}430431export class IncreaseHoverVerbosityLevel extends EditorAction {432433constructor() {434super({435id: INCREASE_HOVER_VERBOSITY_ACTION_ID,436label: INCREASE_HOVER_VERBOSITY_ACTION_LABEL,437alias: 'Increase Hover Verbosity Level',438precondition: EditorContextKeys.hoverVisible439});440}441442public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { index: number; focus: boolean }): void {443const hoverController = ContentHoverController.get(editor);444if (!hoverController) {445return;446}447const index = args?.index !== undefined ? args.index : hoverController.focusedHoverPartIndex();448hoverController.updateHoverVerbosityLevel(HoverVerbosityAction.Increase, index, args?.focus);449}450}451452export class DecreaseHoverVerbosityLevel extends EditorAction {453454constructor() {455super({456id: DECREASE_HOVER_VERBOSITY_ACTION_ID,457label: DECREASE_HOVER_VERBOSITY_ACTION_LABEL,458alias: 'Decrease Hover Verbosity Level',459precondition: EditorContextKeys.hoverVisible460});461}462463public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { index: number; focus: boolean }): void {464const hoverController = ContentHoverController.get(editor);465if (!hoverController) {466return;467}468const index = args?.index !== undefined ? args.index : hoverController.focusedHoverPartIndex();469ContentHoverController.get(editor)?.updateHoverVerbosityLevel(HoverVerbosityAction.Decrease, index, args?.focus);470}471}472473474