Path: blob/main/src/vs/workbench/browser/actions/helpActions.ts
3296 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 { localize, localize2 } from '../../../nls.js';6import product from '../../../platform/product/common/product.js';7import { isMacintosh, isLinux, language, isWeb } from '../../../base/common/platform.js';8import { ITelemetryService } from '../../../platform/telemetry/common/telemetry.js';9import { IOpenerService } from '../../../platform/opener/common/opener.js';10import { URI } from '../../../base/common/uri.js';11import { MenuId, Action2, registerAction2, MenuRegistry } from '../../../platform/actions/common/actions.js';12import { KeyChord, KeyMod, KeyCode } from '../../../base/common/keyCodes.js';13import { IProductService } from '../../../platform/product/common/productService.js';14import { ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js';15import { KeybindingWeight } from '../../../platform/keybinding/common/keybindingsRegistry.js';16import { Categories } from '../../../platform/action/common/actionCommonCategories.js';17import { ICommandService } from '../../../platform/commands/common/commands.js';18import { ContextKeyExpr } from '../../../platform/contextkey/common/contextkey.js';1920class KeybindingsReferenceAction extends Action2 {2122static readonly ID = 'workbench.action.keybindingsReference';23static readonly AVAILABLE = !!(isLinux ? product.keyboardShortcutsUrlLinux : isMacintosh ? product.keyboardShortcutsUrlMac : product.keyboardShortcutsUrlWin);2425constructor() {26super({27id: KeybindingsReferenceAction.ID,28title: {29...localize2('keybindingsReference', "Keyboard Shortcuts Reference"),30mnemonicTitle: localize({ key: 'miKeyboardShortcuts', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts Reference"),31},32category: Categories.Help,33f1: true,34keybinding: {35weight: KeybindingWeight.WorkbenchContrib,36when: null,37primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyR)38},39menu: {40id: MenuId.MenubarHelpMenu,41group: '2_reference',42order: 143}44});45}4647run(accessor: ServicesAccessor): void {48const productService = accessor.get(IProductService);49const openerService = accessor.get(IOpenerService);5051const url = isLinux ? productService.keyboardShortcutsUrlLinux : isMacintosh ? productService.keyboardShortcutsUrlMac : productService.keyboardShortcutsUrlWin;52if (url) {53openerService.open(URI.parse(url));54}55}56}5758class OpenIntroductoryVideosUrlAction extends Action2 {5960static readonly ID = 'workbench.action.openVideoTutorialsUrl';61static readonly AVAILABLE = !!product.introductoryVideosUrl;6263constructor() {64super({65id: OpenIntroductoryVideosUrlAction.ID,66title: {67...localize2('openVideoTutorialsUrl', "Video Tutorials"),68mnemonicTitle: localize({ key: 'miVideoTutorials', comment: ['&& denotes a mnemonic'] }, "&&Video Tutorials"),69},70category: Categories.Help,71f1: true,72menu: {73id: MenuId.MenubarHelpMenu,74group: '2_reference',75order: 276}77});78}7980run(accessor: ServicesAccessor): void {81const productService = accessor.get(IProductService);82const openerService = accessor.get(IOpenerService);8384if (productService.introductoryVideosUrl) {85openerService.open(URI.parse(productService.introductoryVideosUrl));86}87}88}8990class OpenTipsAndTricksUrlAction extends Action2 {9192static readonly ID = 'workbench.action.openTipsAndTricksUrl';93static readonly AVAILABLE = !!product.tipsAndTricksUrl;9495constructor() {96super({97id: OpenTipsAndTricksUrlAction.ID,98title: {99...localize2('openTipsAndTricksUrl', "Tips and Tricks"),100mnemonicTitle: localize({ key: 'miTipsAndTricks', comment: ['&& denotes a mnemonic'] }, "Tips and Tri&&cks"),101},102category: Categories.Help,103f1: true,104menu: {105id: MenuId.MenubarHelpMenu,106group: '2_reference',107order: 3108}109});110}111112run(accessor: ServicesAccessor): void {113const productService = accessor.get(IProductService);114const openerService = accessor.get(IOpenerService);115116if (productService.tipsAndTricksUrl) {117openerService.open(URI.parse(productService.tipsAndTricksUrl));118}119}120}121122class OpenDocumentationUrlAction extends Action2 {123124static readonly ID = 'workbench.action.openDocumentationUrl';125static readonly AVAILABLE = !!(isWeb ? product.serverDocumentationUrl : product.documentationUrl);126127constructor() {128super({129id: OpenDocumentationUrlAction.ID,130title: {131...localize2('openDocumentationUrl', "Documentation"),132mnemonicTitle: localize({ key: 'miDocumentation', comment: ['&& denotes a mnemonic'] }, "&&Documentation"),133},134category: Categories.Help,135f1: true,136menu: {137id: MenuId.MenubarHelpMenu,138group: '1_welcome',139order: 3140}141});142}143144run(accessor: ServicesAccessor): void {145const productService = accessor.get(IProductService);146const openerService = accessor.get(IOpenerService);147const url = isWeb ? productService.serverDocumentationUrl : productService.documentationUrl;148149if (url) {150openerService.open(URI.parse(url));151}152}153}154155class OpenNewsletterSignupUrlAction extends Action2 {156157static readonly ID = 'workbench.action.openNewsletterSignupUrl';158static readonly AVAILABLE = !!product.newsletterSignupUrl;159160constructor() {161super({162id: OpenNewsletterSignupUrlAction.ID,163title: localize2('newsletterSignup', 'Signup for the VS Code Newsletter'),164category: Categories.Help,165f1: true166});167}168169run(accessor: ServicesAccessor) {170const productService = accessor.get(IProductService);171const openerService = accessor.get(IOpenerService);172const telemetryService = accessor.get(ITelemetryService);173openerService.open(URI.parse(`${productService.newsletterSignupUrl}?machineId=${encodeURIComponent(telemetryService.machineId)}`));174}175}176177class OpenYouTubeUrlAction extends Action2 {178179static readonly ID = 'workbench.action.openYouTubeUrl';180static readonly AVAILABLE = !!product.youTubeUrl;181182constructor() {183super({184id: OpenYouTubeUrlAction.ID,185title: {186...localize2('openYouTubeUrl', "Join Us on YouTube"),187mnemonicTitle: localize({ key: 'miYouTube', comment: ['&& denotes a mnemonic'] }, "&&Join Us on YouTube"),188},189category: Categories.Help,190f1: true,191menu: {192id: MenuId.MenubarHelpMenu,193group: '3_feedback',194order: 1195}196});197}198199run(accessor: ServicesAccessor): void {200const productService = accessor.get(IProductService);201const openerService = accessor.get(IOpenerService);202203if (productService.youTubeUrl) {204openerService.open(URI.parse(productService.youTubeUrl));205}206}207}208209class OpenRequestFeatureUrlAction extends Action2 {210211static readonly ID = 'workbench.action.openRequestFeatureUrl';212static readonly AVAILABLE = !!product.requestFeatureUrl;213214constructor() {215super({216id: OpenRequestFeatureUrlAction.ID,217title: {218...localize2('openUserVoiceUrl', "Search Feature Requests"),219mnemonicTitle: localize({ key: 'miUserVoice', comment: ['&& denotes a mnemonic'] }, "&&Search Feature Requests"),220},221category: Categories.Help,222f1: true,223menu: {224id: MenuId.MenubarHelpMenu,225group: '3_feedback',226order: 2227}228});229}230231run(accessor: ServicesAccessor): void {232const productService = accessor.get(IProductService);233const openerService = accessor.get(IOpenerService);234235if (productService.requestFeatureUrl) {236openerService.open(URI.parse(productService.requestFeatureUrl));237}238}239}240241class OpenLicenseUrlAction extends Action2 {242243static readonly ID = 'workbench.action.openLicenseUrl';244static readonly AVAILABLE = !!(isWeb ? product.serverLicense : product.licenseUrl);245246constructor() {247super({248id: OpenLicenseUrlAction.ID,249title: {250...localize2('openLicenseUrl', "View License"),251mnemonicTitle: localize({ key: 'miLicense', comment: ['&& denotes a mnemonic'] }, "View &&License"),252},253category: Categories.Help,254f1: true,255menu: {256id: MenuId.MenubarHelpMenu,257group: '4_legal',258order: 1259}260});261}262263run(accessor: ServicesAccessor): void {264const productService = accessor.get(IProductService);265const openerService = accessor.get(IOpenerService);266const url = isWeb ? productService.serverLicenseUrl : productService.licenseUrl;267268if (url) {269if (language) {270const queryArgChar = url.indexOf('?') > 0 ? '&' : '?';271openerService.open(URI.parse(`${url}${queryArgChar}lang=${language}`));272} else {273openerService.open(URI.parse(url));274}275}276}277}278279class OpenPrivacyStatementUrlAction extends Action2 {280281static readonly ID = 'workbench.action.openPrivacyStatementUrl';282static readonly AVAILABLE = !!product.privacyStatementUrl;283284constructor() {285super({286id: OpenPrivacyStatementUrlAction.ID,287title: {288...localize2('openPrivacyStatement', "Privacy Statement"),289mnemonicTitle: localize({ key: 'miPrivacyStatement', comment: ['&& denotes a mnemonic'] }, "Privac&&y Statement"),290},291category: Categories.Help,292f1: true,293menu: {294id: MenuId.MenubarHelpMenu,295group: '4_legal',296order: 2297}298});299}300301run(accessor: ServicesAccessor): void {302const productService = accessor.get(IProductService);303const openerService = accessor.get(IOpenerService);304305if (productService.privacyStatementUrl) {306openerService.open(URI.parse(productService.privacyStatementUrl));307}308}309}310311class GetStartedWithAccessibilityFeatures extends Action2 {312313static readonly ID = 'workbench.action.getStartedWithAccessibilityFeatures';314315constructor() {316super({317id: GetStartedWithAccessibilityFeatures.ID,318title: localize2('getStartedWithAccessibilityFeatures', 'Get Started with Accessibility Features'),319category: Categories.Help,320f1: true,321menu: {322id: MenuId.MenubarHelpMenu,323group: '1_welcome',324order: 6325}326});327}328run(accessor: ServicesAccessor): void {329const commandService = accessor.get(ICommandService);330commandService.executeCommand('workbench.action.openWalkthrough', 'SetupAccessibility');331}332}333334class AskVSCodeCopilot extends Action2 {335static readonly ID = 'workbench.action.askVScode';336337constructor() {338super({339id: AskVSCodeCopilot.ID,340title: localize2('askVScode', 'Ask @vscode'),341category: Categories.Help,342f1: true,343precondition: ContextKeyExpr.equals('chatSetupHidden', false)344});345}346347async run(accessor: ServicesAccessor): Promise<void> {348const commandService = accessor.get(ICommandService);349commandService.executeCommand('workbench.action.chat.open', { mode: 'ask', query: '@vscode ', isPartialQuery: true });350}351}352353MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, {354command: {355id: AskVSCodeCopilot.ID,356title: localize2('askVScode', 'Ask @vscode'),357},358order: 7,359group: '1_welcome',360when: ContextKeyExpr.equals('chatSetupHidden', false)361});362363// --- Actions Registration364365if (KeybindingsReferenceAction.AVAILABLE) {366registerAction2(KeybindingsReferenceAction);367}368369if (OpenIntroductoryVideosUrlAction.AVAILABLE) {370registerAction2(OpenIntroductoryVideosUrlAction);371}372373if (OpenTipsAndTricksUrlAction.AVAILABLE) {374registerAction2(OpenTipsAndTricksUrlAction);375}376377if (OpenDocumentationUrlAction.AVAILABLE) {378registerAction2(OpenDocumentationUrlAction);379}380381if (OpenNewsletterSignupUrlAction.AVAILABLE) {382registerAction2(OpenNewsletterSignupUrlAction);383}384385if (OpenYouTubeUrlAction.AVAILABLE) {386registerAction2(OpenYouTubeUrlAction);387}388389if (OpenRequestFeatureUrlAction.AVAILABLE) {390registerAction2(OpenRequestFeatureUrlAction);391}392393if (OpenLicenseUrlAction.AVAILABLE) {394registerAction2(OpenLicenseUrlAction);395}396397if (OpenPrivacyStatementUrlAction.AVAILABLE) {398registerAction2(OpenPrivacyStatementUrlAction);399}400401registerAction2(GetStartedWithAccessibilityFeatures);402403registerAction2(AskVSCodeCopilot);404405406