Path: blob/main/src/vs/workbench/contrib/files/browser/fileActions.contribution.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 * as nls from '../../../../nls.js';6import { ToggleAutoSaveAction, FocusFilesExplorer, GlobalCompareResourcesAction, ShowActiveFileInExplorer, CompareWithClipboardAction, NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, TRIGGER_RENAME_LABEL, MOVE_FILE_TO_TRASH_LABEL, COPY_FILE_LABEL, PASTE_FILE_LABEL, FileCopiedContext, renameHandler, moveFileToTrashHandler, copyFileHandler, pasteFileHandler, deleteFileHandler, cutFileHandler, DOWNLOAD_COMMAND_ID, openFilePreserveFocusHandler, DOWNLOAD_LABEL, OpenActiveFileInEmptyWorkspace, UPLOAD_COMMAND_ID, UPLOAD_LABEL, CompareNewUntitledTextFilesAction, SetActiveEditorReadonlyInSession, SetActiveEditorWriteableInSession, ToggleActiveEditorReadonlyInSession, ResetActiveEditorReadonlyInSession } from './fileActions.js';7import { revertLocalChangesCommand, acceptLocalChangesCommand, CONFLICT_RESOLUTION_CONTEXT } from './editors/textFileSaveErrorHandler.js';8import { MenuId, MenuRegistry, registerAction2 } from '../../../../platform/actions/common/actions.js';9import { ICommandAction } from '../../../../platform/action/common/action.js';10import { KeyMod, KeyCode } from '../../../../base/common/keyCodes.js';11import { openWindowCommand, newWindowCommand } from './fileCommands.js';12import { COPY_PATH_COMMAND_ID, REVEAL_IN_EXPLORER_COMMAND_ID, OPEN_TO_SIDE_COMMAND_ID, REVERT_FILE_COMMAND_ID, SAVE_FILE_COMMAND_ID, SAVE_FILE_LABEL, SAVE_FILE_AS_COMMAND_ID, SAVE_FILE_AS_LABEL, SAVE_ALL_IN_GROUP_COMMAND_ID, OpenEditorsGroupContext, COMPARE_WITH_SAVED_COMMAND_ID, COMPARE_RESOURCE_COMMAND_ID, SELECT_FOR_COMPARE_COMMAND_ID, ResourceSelectedForCompareContext, OpenEditorsDirtyEditorContext, COMPARE_SELECTED_COMMAND_ID, REMOVE_ROOT_FOLDER_COMMAND_ID, REMOVE_ROOT_FOLDER_LABEL, SAVE_FILES_COMMAND_ID, COPY_RELATIVE_PATH_COMMAND_ID, SAVE_FILE_WITHOUT_FORMATTING_COMMAND_ID, SAVE_FILE_WITHOUT_FORMATTING_LABEL, OpenEditorsReadonlyEditorContext, OPEN_WITH_EXPLORER_COMMAND_ID, NEW_UNTITLED_FILE_COMMAND_ID, NEW_UNTITLED_FILE_LABEL, SAVE_ALL_COMMAND_ID, OpenEditorsSelectedFileOrUntitledContext } from './fileConstants.js';13import { CommandsRegistry, ICommandHandler } from '../../../../platform/commands/common/commands.js';14import { ContextKeyExpr, ContextKeyExpression } from '../../../../platform/contextkey/common/contextkey.js';15import { KeybindingsRegistry, KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';16import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext, ExplorerResourceWritableContext, ExplorerResourceCut, ExplorerResourceMoveableToTrash, ExplorerResourceAvailableEditorIdsContext, FoldersViewVisibleContext } from '../common/files.js';17import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL } from '../../../browser/actions/workspaceCommands.js';18import { CLOSE_SAVED_EDITORS_COMMAND_ID, CLOSE_EDITORS_IN_GROUP_COMMAND_ID, CLOSE_EDITOR_COMMAND_ID, CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID, REOPEN_WITH_COMMAND_ID } from '../../../browser/parts/editor/editorCommands.js';19import { AutoSaveAfterShortDelayContext } from '../../../services/filesConfiguration/common/filesConfigurationService.js';20import { WorkbenchListDoubleSelection } from '../../../../platform/list/browser/listService.js';21import { Schemas } from '../../../../base/common/network.js';22import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, MultipleEditorsSelectedInGroupContext, TwoEditorsSelectedInGroupContext, SelectedEditorsInGroupFileOrUntitledResourceContextKey } from '../../../common/contextkeys.js';23import { IsWebContext } from '../../../../platform/contextkey/common/contextkeys.js';24import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';25import { ThemeIcon } from '../../../../base/common/themables.js';26import { IExplorerService } from './files.js';27import { Codicon } from '../../../../base/common/codicons.js';28import { Categories } from '../../../../platform/action/common/actionCommonCategories.js';2930// Contribute Global Actions3132registerAction2(GlobalCompareResourcesAction);33registerAction2(FocusFilesExplorer);34registerAction2(ShowActiveFileInExplorer);35registerAction2(CompareWithClipboardAction);36registerAction2(CompareNewUntitledTextFilesAction);37registerAction2(ToggleAutoSaveAction);38registerAction2(OpenActiveFileInEmptyWorkspace);39registerAction2(SetActiveEditorReadonlyInSession);40registerAction2(SetActiveEditorWriteableInSession);41registerAction2(ToggleActiveEditorReadonlyInSession);42registerAction2(ResetActiveEditorReadonlyInSession);4344// Commands45CommandsRegistry.registerCommand('_files.windowOpen', openWindowCommand);46CommandsRegistry.registerCommand('_files.newWindow', newWindowCommand);4748const explorerCommandsWeightBonus = 10; // give our commands a little bit more weight over other default list/tree commands4950const RENAME_ID = 'renameFile';51KeybindingsRegistry.registerCommandAndKeybindingRule({52id: RENAME_ID,53weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,54when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerRootContext.toNegated(), ExplorerResourceWritableContext),55primary: KeyCode.F2,56mac: {57primary: KeyCode.Enter58},59handler: renameHandler60});6162const MOVE_FILE_TO_TRASH_ID = 'moveFileToTrash';63KeybindingsRegistry.registerCommandAndKeybindingRule({64id: MOVE_FILE_TO_TRASH_ID,65weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,66when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceMoveableToTrash),67primary: KeyCode.Delete,68mac: {69primary: KeyMod.CtrlCmd | KeyCode.Backspace,70secondary: [KeyCode.Delete]71},72handler: moveFileToTrashHandler73});7475const DELETE_FILE_ID = 'deleteFile';76KeybindingsRegistry.registerCommandAndKeybindingRule({77id: DELETE_FILE_ID,78weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,79when: FilesExplorerFocusCondition,80primary: KeyMod.Shift | KeyCode.Delete,81mac: {82primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Backspace83},84handler: deleteFileHandler85});8687KeybindingsRegistry.registerCommandAndKeybindingRule({88id: DELETE_FILE_ID,89weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,90when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceMoveableToTrash.toNegated()),91primary: KeyCode.Delete,92mac: {93primary: KeyMod.CtrlCmd | KeyCode.Backspace94},95handler: deleteFileHandler96});9798const CUT_FILE_ID = 'filesExplorer.cut';99KeybindingsRegistry.registerCommandAndKeybindingRule({100id: CUT_FILE_ID,101weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,102when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerRootContext.toNegated(), ExplorerResourceWritableContext),103primary: KeyMod.CtrlCmd | KeyCode.KeyX,104handler: cutFileHandler,105});106107const COPY_FILE_ID = 'filesExplorer.copy';108KeybindingsRegistry.registerCommandAndKeybindingRule({109id: COPY_FILE_ID,110weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,111when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerRootContext.toNegated()),112primary: KeyMod.CtrlCmd | KeyCode.KeyC,113handler: copyFileHandler,114});115116const PASTE_FILE_ID = 'filesExplorer.paste';117118CommandsRegistry.registerCommand(PASTE_FILE_ID, pasteFileHandler);119120KeybindingsRegistry.registerKeybindingRule({121id: `^${PASTE_FILE_ID}`, // the `^` enables pasting files into the explorer by preventing default bubble up122weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,123when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceWritableContext),124primary: KeyMod.CtrlCmd | KeyCode.KeyV,125});126127KeybindingsRegistry.registerCommandAndKeybindingRule({128id: 'filesExplorer.cancelCut',129weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,130when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceCut),131primary: KeyCode.Escape,132handler: async (accessor: ServicesAccessor) => {133const explorerService = accessor.get(IExplorerService);134await explorerService.setToCopy([], true);135}136});137138KeybindingsRegistry.registerCommandAndKeybindingRule({139id: 'filesExplorer.openFilePreserveFocus',140weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,141when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerFolderContext.toNegated()),142primary: KeyCode.Space,143handler: openFilePreserveFocusHandler144});145146const copyPathCommand = {147id: COPY_PATH_COMMAND_ID,148title: nls.localize('copyPath', "Copy Path")149};150151const copyRelativePathCommand = {152id: COPY_RELATIVE_PATH_COMMAND_ID,153title: nls.localize('copyRelativePath', "Copy Relative Path")154};155156export const revealInSideBarCommand = {157id: REVEAL_IN_EXPLORER_COMMAND_ID,158title: nls.localize('revealInSideBar', "Reveal in Explorer View")159};160161// Editor Title Context Menu162appendEditorTitleContextMenuItem(COPY_PATH_COMMAND_ID, copyPathCommand.title, ResourceContextKey.IsFileSystemResource, '1_cutcopypaste', true);163appendEditorTitleContextMenuItem(COPY_RELATIVE_PATH_COMMAND_ID, copyRelativePathCommand.title, ResourceContextKey.IsFileSystemResource, '1_cutcopypaste', true);164appendEditorTitleContextMenuItem(revealInSideBarCommand.id, revealInSideBarCommand.title, ResourceContextKey.IsFileSystemResource, '2_files', false, 1);165166export function appendEditorTitleContextMenuItem(id: string, title: string, when: ContextKeyExpression | undefined, group: string, supportsMultiSelect: boolean, order?: number): void {167const precondition = supportsMultiSelect !== true ? MultipleEditorsSelectedInGroupContext.negate() : undefined;168169// Menu170MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, {171command: { id, title, precondition },172when,173group,174order,175});176}177178// Editor Title Menu for Conflict Resolution179appendSaveConflictEditorTitleAction('workbench.files.action.acceptLocalChanges', nls.localize('acceptLocalChanges', "Use your changes and overwrite file contents"), Codicon.check, -10, acceptLocalChangesCommand);180appendSaveConflictEditorTitleAction('workbench.files.action.revertLocalChanges', nls.localize('revertLocalChanges', "Discard your changes and revert to file contents"), Codicon.discard, -9, revertLocalChangesCommand);181182function appendSaveConflictEditorTitleAction(id: string, title: string, icon: ThemeIcon, order: number, command: ICommandHandler): void {183184// Command185CommandsRegistry.registerCommand(id, command);186187// Action188MenuRegistry.appendMenuItem(MenuId.EditorTitle, {189command: { id, title, icon },190when: ContextKeyExpr.equals(CONFLICT_RESOLUTION_CONTEXT, true),191group: 'navigation',192order193});194}195196// Menu registration - command palette197198export function appendToCommandPalette({ id, title, category, metadata }: ICommandAction, when?: ContextKeyExpression): void {199MenuRegistry.appendMenuItem(MenuId.CommandPalette, {200command: {201id,202title,203category,204metadata205},206when207});208}209210appendToCommandPalette({211id: COPY_PATH_COMMAND_ID,212title: nls.localize2('copyPathOfActive', "Copy Path of Active File"),213category: Categories.File214});215appendToCommandPalette({216id: COPY_RELATIVE_PATH_COMMAND_ID,217title: nls.localize2('copyRelativePathOfActive', "Copy Relative Path of Active File"),218category: Categories.File219});220221appendToCommandPalette({222id: SAVE_FILE_COMMAND_ID,223title: SAVE_FILE_LABEL,224category: Categories.File225});226227appendToCommandPalette({228id: SAVE_FILE_WITHOUT_FORMATTING_COMMAND_ID,229title: SAVE_FILE_WITHOUT_FORMATTING_LABEL,230category: Categories.File231});232233appendToCommandPalette({234id: SAVE_ALL_IN_GROUP_COMMAND_ID,235title: nls.localize2('saveAllInGroup', "Save All in Group"),236category: Categories.File237});238239appendToCommandPalette({240id: SAVE_FILES_COMMAND_ID,241title: nls.localize2('saveFiles', "Save All Files"),242category: Categories.File243});244245appendToCommandPalette({246id: REVERT_FILE_COMMAND_ID,247title: nls.localize2('revert', "Revert File"),248category: Categories.File249});250251appendToCommandPalette({252id: COMPARE_WITH_SAVED_COMMAND_ID,253title: nls.localize2('compareActiveWithSaved', "Compare Active File with Saved"),254category: Categories.File,255metadata: {256description: nls.localize2('compareActiveWithSavedMeta', "Opens a new diff editor to compare the active file with the version on disk.")257}258});259260appendToCommandPalette({261id: SAVE_FILE_AS_COMMAND_ID,262title: SAVE_FILE_AS_LABEL,263category: Categories.File264});265266appendToCommandPalette({267id: NEW_FILE_COMMAND_ID,268title: NEW_FILE_LABEL,269category: Categories.File270}, WorkspaceFolderCountContext.notEqualsTo('0'));271272appendToCommandPalette({273id: NEW_FOLDER_COMMAND_ID,274title: NEW_FOLDER_LABEL,275category: Categories.File,276metadata: { description: nls.localize2('newFolderDescription', "Create a new folder or directory") }277}, WorkspaceFolderCountContext.notEqualsTo('0'));278279appendToCommandPalette({280id: NEW_UNTITLED_FILE_COMMAND_ID,281title: NEW_UNTITLED_FILE_LABEL,282category: Categories.File283});284285// Menu registration - open editors286287const isFileOrUntitledResourceContextKey = ContextKeyExpr.or(ResourceContextKey.IsFileSystemResource, ResourceContextKey.Scheme.isEqualTo(Schemas.untitled));288289const openToSideCommand = {290id: OPEN_TO_SIDE_COMMAND_ID,291title: nls.localize('openToSide', "Open to the Side")292};293MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {294group: 'navigation',295order: 10,296command: openToSideCommand,297when: isFileOrUntitledResourceContextKey298});299300MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {301group: '1_open',302order: 10,303command: {304id: REOPEN_WITH_COMMAND_ID,305title: nls.localize('reopenWith', "Reopen Editor With...")306},307when: ContextKeyExpr.and(308// Editors with Available Choices to Open With309ActiveEditorAvailableEditorIdsContext,310// Not: editor groups311OpenEditorsGroupContext.toNegated()312)313});314315MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {316group: '1_cutcopypaste',317order: 10,318command: copyPathCommand,319when: ResourceContextKey.IsFileSystemResource320});321322MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {323group: '1_cutcopypaste',324order: 20,325command: copyRelativePathCommand,326when: ResourceContextKey.IsFileSystemResource327});328329MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {330group: '2_save',331order: 10,332command: {333id: SAVE_FILE_COMMAND_ID,334title: SAVE_FILE_LABEL,335precondition: OpenEditorsDirtyEditorContext336},337when: ContextKeyExpr.or(338// Untitled Editors339ResourceContextKey.Scheme.isEqualTo(Schemas.untitled),340// Or:341ContextKeyExpr.and(342// Not: editor groups343OpenEditorsGroupContext.toNegated(),344// Not: readonly editors345OpenEditorsReadonlyEditorContext.toNegated(),346// Not: auto save after short delay347AutoSaveAfterShortDelayContext.toNegated()348)349)350});351352MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {353group: '2_save',354order: 20,355command: {356id: REVERT_FILE_COMMAND_ID,357title: nls.localize('revert', "Revert File"),358precondition: OpenEditorsDirtyEditorContext359},360when: ContextKeyExpr.and(361// Not: editor groups362OpenEditorsGroupContext.toNegated(),363// Not: readonly editors364OpenEditorsReadonlyEditorContext.toNegated(),365// Not: untitled editors (revert closes them)366ResourceContextKey.Scheme.notEqualsTo(Schemas.untitled),367// Not: auto save after short delay368AutoSaveAfterShortDelayContext.toNegated()369)370});371372MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {373group: '2_save',374order: 30,375command: {376id: SAVE_ALL_IN_GROUP_COMMAND_ID,377title: nls.localize('saveAll', "Save All"),378precondition: DirtyWorkingCopiesContext379},380// Editor Group381when: OpenEditorsGroupContext382});383384MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {385group: '3_compare',386order: 10,387command: {388id: COMPARE_WITH_SAVED_COMMAND_ID,389title: nls.localize('compareWithSaved', "Compare with Saved"),390precondition: OpenEditorsDirtyEditorContext391},392when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, AutoSaveAfterShortDelayContext.toNegated(), WorkbenchListDoubleSelection.toNegated())393});394395const compareResourceCommand = {396id: COMPARE_RESOURCE_COMMAND_ID,397title: nls.localize('compareWithSelected', "Compare with Selected")398};399MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {400group: '3_compare',401order: 20,402command: compareResourceCommand,403when: ContextKeyExpr.and(ResourceContextKey.HasResource, ResourceSelectedForCompareContext, isFileOrUntitledResourceContextKey, WorkbenchListDoubleSelection.toNegated())404});405406const selectForCompareCommand = {407id: SELECT_FOR_COMPARE_COMMAND_ID,408title: nls.localize('compareSource', "Select for Compare")409};410MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {411group: '3_compare',412order: 30,413command: selectForCompareCommand,414when: ContextKeyExpr.and(ResourceContextKey.HasResource, isFileOrUntitledResourceContextKey, WorkbenchListDoubleSelection.toNegated())415});416417const compareSelectedCommand = {418id: COMPARE_SELECTED_COMMAND_ID,419title: nls.localize('compareSelected', "Compare Selected")420};421MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {422group: '3_compare',423order: 30,424command: compareSelectedCommand,425when: ContextKeyExpr.and(ResourceContextKey.HasResource, WorkbenchListDoubleSelection, OpenEditorsSelectedFileOrUntitledContext)426});427428MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, {429group: '1_compare',430order: 30,431command: compareSelectedCommand,432when: ContextKeyExpr.and(ResourceContextKey.HasResource, TwoEditorsSelectedInGroupContext, SelectedEditorsInGroupFileOrUntitledResourceContextKey)433});434435MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {436group: '4_close',437order: 10,438command: {439id: CLOSE_EDITOR_COMMAND_ID,440title: nls.localize('close', "Close")441},442when: OpenEditorsGroupContext.toNegated()443});444445MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {446group: '4_close',447order: 20,448command: {449id: CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID,450title: nls.localize('closeOthers', "Close Others")451},452when: OpenEditorsGroupContext.toNegated()453});454455MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {456group: '4_close',457order: 30,458command: {459id: CLOSE_SAVED_EDITORS_COMMAND_ID,460title: nls.localize('closeSaved', "Close Saved")461}462});463464MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {465group: '4_close',466order: 40,467command: {468id: CLOSE_EDITORS_IN_GROUP_COMMAND_ID,469title: nls.localize('closeAll', "Close All")470}471});472473// Menu registration - explorer474475MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {476group: 'navigation',477order: 4,478command: {479id: NEW_FILE_COMMAND_ID,480title: NEW_FILE_LABEL,481precondition: ExplorerResourceWritableContext482},483when: ExplorerFolderContext484});485486MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {487group: 'navigation',488order: 6,489command: {490id: NEW_FOLDER_COMMAND_ID,491title: NEW_FOLDER_LABEL,492precondition: ExplorerResourceWritableContext493},494when: ExplorerFolderContext495});496497MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {498group: 'navigation',499order: 10,500command: openToSideCommand,501when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.HasResource)502});503504MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {505group: 'navigation',506order: 20,507command: {508id: OPEN_WITH_EXPLORER_COMMAND_ID,509title: nls.localize('explorerOpenWith', "Open With..."),510},511when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ExplorerResourceAvailableEditorIdsContext),512});513514MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {515group: '3_compare',516order: 20,517command: compareResourceCommand,518when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.HasResource, ResourceSelectedForCompareContext, WorkbenchListDoubleSelection.toNegated())519});520521MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {522group: '3_compare',523order: 30,524command: selectForCompareCommand,525when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.HasResource, WorkbenchListDoubleSelection.toNegated())526});527528MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {529group: '3_compare',530order: 30,531command: compareSelectedCommand,532when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.HasResource, WorkbenchListDoubleSelection)533});534535MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {536group: '5_cutcopypaste',537order: 8,538command: {539id: CUT_FILE_ID,540title: nls.localize('cut', "Cut"),541},542when: ContextKeyExpr.and(ExplorerRootContext.toNegated(), ExplorerResourceWritableContext)543});544545MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {546group: '5_cutcopypaste',547order: 10,548command: {549id: COPY_FILE_ID,550title: COPY_FILE_LABEL,551},552when: ExplorerRootContext.toNegated()553});554555MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {556group: '5_cutcopypaste',557order: 20,558command: {559id: PASTE_FILE_ID,560title: PASTE_FILE_LABEL,561precondition: ContextKeyExpr.and(ExplorerResourceWritableContext, FileCopiedContext)562},563when: ExplorerFolderContext564});565566MenuRegistry.appendMenuItem(MenuId.ExplorerContext, ({567group: '5b_importexport',568order: 10,569command: {570id: DOWNLOAD_COMMAND_ID,571title: DOWNLOAD_LABEL572},573when: ContextKeyExpr.or(574// native: for any remote resource575ContextKeyExpr.and(IsWebContext.toNegated(), ResourceContextKey.Scheme.notEqualsTo(Schemas.file)),576// web: for any files577ContextKeyExpr.and(IsWebContext, ExplorerFolderContext.toNegated(), ExplorerRootContext.toNegated()),578// web: for any folders if file system API support is provided579ContextKeyExpr.and(IsWebContext, HasWebFileSystemAccess)580)581}));582583MenuRegistry.appendMenuItem(MenuId.ExplorerContext, ({584group: '5b_importexport',585order: 20,586command: {587id: UPLOAD_COMMAND_ID,588title: UPLOAD_LABEL,589},590when: ContextKeyExpr.and(591// only in web592IsWebContext,593// only on folders594ExplorerFolderContext,595// only on writable folders596ExplorerResourceWritableContext597)598}));599600MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {601group: '6_copypath',602order: 10,603command: copyPathCommand,604when: ResourceContextKey.IsFileSystemResource605});606607MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {608group: '6_copypath',609order: 20,610command: copyRelativePathCommand,611when: ResourceContextKey.IsFileSystemResource612});613614MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {615group: '2_workspace',616order: 10,617command: {618id: ADD_ROOT_FOLDER_COMMAND_ID,619title: ADD_ROOT_FOLDER_LABEL,620},621when: ContextKeyExpr.and(ExplorerRootContext, ContextKeyExpr.or(EnterMultiRootWorkspaceSupportContext, WorkbenchStateContext.isEqualTo('workspace')))622});623624MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {625group: '2_workspace',626order: 30,627command: {628id: REMOVE_ROOT_FOLDER_COMMAND_ID,629title: REMOVE_ROOT_FOLDER_LABEL,630},631when: ContextKeyExpr.and(ExplorerRootContext, ExplorerFolderContext, ContextKeyExpr.and(WorkspaceFolderCountContext.notEqualsTo('0'), ContextKeyExpr.or(EnterMultiRootWorkspaceSupportContext, WorkbenchStateContext.isEqualTo('workspace'))))632});633634MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {635group: '7_modification',636order: 10,637command: {638id: RENAME_ID,639title: TRIGGER_RENAME_LABEL,640precondition: ExplorerResourceWritableContext,641},642when: ExplorerRootContext.toNegated()643});644645MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {646group: '7_modification',647order: 20,648command: {649id: MOVE_FILE_TO_TRASH_ID,650title: MOVE_FILE_TO_TRASH_LABEL651},652alt: {653id: DELETE_FILE_ID,654title: nls.localize('deleteFile', "Delete Permanently")655},656when: ContextKeyExpr.and(ExplorerRootContext.toNegated(), ExplorerResourceMoveableToTrash)657});658659MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {660group: '7_modification',661order: 20,662command: {663id: DELETE_FILE_ID,664title: nls.localize('deleteFile', "Delete Permanently")665},666when: ContextKeyExpr.and(ExplorerRootContext.toNegated(), ExplorerResourceMoveableToTrash.toNegated())667});668669// Empty Editor Group / Editor Tabs Container Context Menu670for (const menuId of [MenuId.EmptyEditorGroupContext, MenuId.EditorTabsBarContext]) {671MenuRegistry.appendMenuItem(menuId, { command: { id: NEW_UNTITLED_FILE_COMMAND_ID, title: nls.localize('newFile', "New Text File") }, group: '1_file', order: 10 });672MenuRegistry.appendMenuItem(menuId, { command: { id: 'workbench.action.quickOpen', title: nls.localize('openFile', "Open File...") }, group: '1_file', order: 20 });673}674675// File menu676677MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {678group: '1_new',679command: {680id: NEW_UNTITLED_FILE_COMMAND_ID,681title: nls.localize({ key: 'miNewFile', comment: ['&& denotes a mnemonic'] }, "&&New Text File")682},683order: 1684});685686MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {687group: '4_save',688command: {689id: SAVE_FILE_COMMAND_ID,690title: nls.localize({ key: 'miSave', comment: ['&& denotes a mnemonic'] }, "&&Save"),691precondition: ContextKeyExpr.or(ActiveEditorContext, ContextKeyExpr.and(FoldersViewVisibleContext, SidebarFocusContext))692},693order: 1694});695696MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {697group: '4_save',698command: {699id: SAVE_FILE_AS_COMMAND_ID,700title: nls.localize({ key: 'miSaveAs', comment: ['&& denotes a mnemonic'] }, "Save &&As..."),701precondition: ContextKeyExpr.or(ActiveEditorContext, ContextKeyExpr.and(FoldersViewVisibleContext, SidebarFocusContext))702},703order: 2704});705706MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {707group: '4_save',708command: {709id: SAVE_ALL_COMMAND_ID,710title: nls.localize({ key: 'miSaveAll', comment: ['&& denotes a mnemonic'] }, "Save A&&ll"),711precondition: DirtyWorkingCopiesContext712},713order: 3714});715716MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {717group: '5_autosave',718command: {719id: ToggleAutoSaveAction.ID,720title: nls.localize({ key: 'miAutoSave', comment: ['&& denotes a mnemonic'] }, "A&&uto Save"),721toggled: ContextKeyExpr.notEquals('config.files.autoSave', 'off')722},723order: 1724});725726MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {727group: '6_close',728command: {729id: REVERT_FILE_COMMAND_ID,730title: nls.localize({ key: 'miRevert', comment: ['&& denotes a mnemonic'] }, "Re&&vert File"),731precondition: ContextKeyExpr.or(732// Active editor can revert733ContextKeyExpr.and(ActiveEditorCanRevertContext),734// Explorer focused but not on untitled735ContextKeyExpr.and(ResourceContextKey.Scheme.notEqualsTo(Schemas.untitled), FoldersViewVisibleContext, SidebarFocusContext)736),737},738order: 1739});740741MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {742group: '6_close',743command: {744id: CLOSE_EDITOR_COMMAND_ID,745title: nls.localize({ key: 'miCloseEditor', comment: ['&& denotes a mnemonic'] }, "&&Close Editor"),746precondition: ContextKeyExpr.or(ActiveEditorContext, ContextKeyExpr.and(FoldersViewVisibleContext, SidebarFocusContext))747},748order: 2749});750751// Go to menu752753MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {754group: '3_global_nav',755command: {756id: 'workbench.action.quickOpen',757title: nls.localize({ key: 'miGotoFile', comment: ['&& denotes a mnemonic'] }, "Go to &&File...")758},759order: 1760});761762763// Chat used attachment anchor context menu764765MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, {766group: 'navigation',767order: 10,768command: openToSideCommand,769when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, ExplorerFolderContext.toNegated())770});771772MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, {773group: 'navigation',774order: 20,775command: revealInSideBarCommand,776when: ResourceContextKey.IsFileSystemResource777});778779MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, {780group: '1_cutcopypaste',781order: 10,782command: copyPathCommand,783when: ResourceContextKey.IsFileSystemResource784});785786MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, {787group: '1_cutcopypaste',788order: 20,789command: copyRelativePathCommand,790when: ResourceContextKey.IsFileSystemResource791});792793// Chat resource anchor attachments/anchors context menu794795for (const menuId of [MenuId.ChatInlineResourceAnchorContext, MenuId.ChatInputResourceAttachmentContext]) {796MenuRegistry.appendMenuItem(menuId, {797group: 'navigation',798order: 10,799command: openToSideCommand,800when: ContextKeyExpr.and(ResourceContextKey.HasResource, ExplorerFolderContext.toNegated())801});802803MenuRegistry.appendMenuItem(menuId, {804group: 'navigation',805order: 20,806command: revealInSideBarCommand,807when: ResourceContextKey.IsFileSystemResource808});809810MenuRegistry.appendMenuItem(menuId, {811group: '1_cutcopypaste',812order: 10,813command: copyPathCommand,814when: ResourceContextKey.IsFileSystemResource815});816817MenuRegistry.appendMenuItem(menuId, {818group: '1_cutcopypaste',819order: 20,820command: copyRelativePathCommand,821when: ResourceContextKey.IsFileSystemResource822});823}824825826