Skip to content

Commit d0db0ae

Browse files
author
Jackson Kearl
committed
Add explorer.enableUndo config to warn/allow/disable explorer undo
Closes #117621
1 parent a19eb0a commit d0db0ae

File tree

4 files changed

+39
-10
lines changed

4 files changed

+39
-10
lines changed

src/vs/workbench/contrib/files/browser/fileActions.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { URI } from 'vs/base/common/uri';
1111
import { toErrorMessage } from 'vs/base/common/errorMessage';
1212
import { Action } from 'vs/base/common/actions';
1313
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
14-
import { VIEWLET_ID, IFilesConfiguration, VIEW_ID } from 'vs/workbench/contrib/files/common/files';
14+
import { VIEWLET_ID, IFilesConfiguration, VIEW_ID, UndoEnablement } from 'vs/workbench/contrib/files/common/files';
1515
import { IFileService } from 'vs/platform/files/common/files';
1616
import { EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor';
1717
import { IQuickInputService, ItemActivation } from 'vs/platform/quickinput/common/quickInput';
@@ -1037,10 +1037,11 @@ export const pasteFileHandler = async (accessor: ServicesAccessor) => {
10371037
} else {
10381038
const resourceFileEdits = sourceTargetPairs.map(pair => new ResourceFileEdit(pair.source, pair.target, { copy: true }));
10391039
const options = {
1040+
confirmBeforeUndo: configurationService.getValue<IFilesConfiguration>().explorer.enableUndo === UndoEnablement.Warn,
10401041
progressLabel: sourceTargetPairs.length > 1 ? nls.localize({ key: 'copyingBulkEdit', comment: ['Placeholder will be replaced by the number of files being copied'] }, "Copying {0} files", sourceTargetPairs.length)
10411042
: nls.localize({ key: 'copyingFileBulkEdit', comment: ['Placeholder will be replaced by the name of the file copied.'] }, "Copying {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target)),
1042-
undoLabel: sourceTargetPairs.length > 1 ? nls.localize({ key: 'copyBulkEdit', comment: ['Placeholder will be replaced by the number of files being copied'] }, "Copy {0} files", sourceTargetPairs.length)
1043-
: nls.localize({ key: 'copyFileBulkEdit', comment: ['Placeholder will be replaced by the name of the file copied.'] }, "Copy {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target))
1043+
undoLabel: sourceTargetPairs.length > 1 ? nls.localize({ key: 'copyBulkEdit', comment: ['Placeholder will be replaced by the number of files being copied'] }, "Paste {0} files", sourceTargetPairs.length)
1044+
: nls.localize({ key: 'copyFileBulkEdit', comment: ['Placeholder will be replaced by the name of the file copied.'] }, "Paste {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target))
10441045
};
10451046
await explorerService.applyBulkEdit(resourceFileEdits, options);
10461047
}

src/vs/workbench/contrib/files/browser/fileImportExport.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ByteSize, FileSystemProviderCapabilities, IFileService, IFileStatWithMe
1010
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
1111
import { IProgress, IProgressService, IProgressStep, ProgressLocation } from 'vs/platform/progress/common/progress';
1212
import { IExplorerService } from 'vs/workbench/contrib/files/browser/files';
13-
import { VIEW_ID } from 'vs/workbench/contrib/files/common/files';
13+
import { IFilesConfiguration, UndoEnablement, VIEW_ID } from 'vs/workbench/contrib/files/common/files';
1414
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
1515
import { Limiter, Promises, RunOnceWorker } from 'vs/base/common/async';
1616
import { newWriteableBufferStream, VSBuffer } from 'vs/base/common/buffer';
@@ -32,6 +32,7 @@ import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
3232
import { once } from 'vs/base/common/functional';
3333
import { coalesce } from 'vs/base/common/arrays';
3434
import { canceled } from 'vs/base/common/errors';
35+
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
3536

3637
//#region Browser File Upload (drag and drop, input element)
3738

@@ -387,6 +388,7 @@ export class ExternalFileImport {
387388
@IFileService private readonly fileService: IFileService,
388389
@IHostService private readonly hostService: IHostService,
389390
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
391+
@IConfigurationService private readonly configurationService: IConfigurationService,
390392
@IDialogService private readonly dialogService: IDialogService,
391393
@IWorkspaceEditingService private readonly workspaceEditingService: IWorkspaceEditingService,
392394
@IExplorerService private readonly explorerService: IExplorerService,
@@ -530,12 +532,13 @@ export class ExternalFileImport {
530532

531533
await this.explorerService.applyBulkEdit(resourceFileEdits, {
532534
undoLabel: resourcesFiltered.length === 1 ?
533-
localize('copyFile', "Copy {0}", basename(resourcesFiltered[0])) :
534-
localize('copynFile', "Copy {0} resources", resourcesFiltered.length),
535+
localize('importFile', "Import {0}", basename(resourcesFiltered[0])) :
536+
localize('importnFile', "Import {0} resources", resourcesFiltered.length),
535537
progressLabel: resourcesFiltered.length === 1 ?
536538
localize('copyingFile', "Copying {0}", basename(resourcesFiltered[0])) :
537539
localize('copyingnFile', "Copying {0} resources", resourcesFiltered.length),
538-
progressLocation: ProgressLocation.Window
540+
progressLocation: ProgressLocation.Window,
541+
confirmBeforeUndo: this.configurationService.getValue<IFilesConfiguration>().explorer.enableUndo === UndoEnablement.Warn,
539542
});
540543

541544
// if we only add one file, just open it directly

src/vs/workbench/contrib/files/browser/files.contribution.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions, Configur
1010
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
1111
import { IFileEditorInput, IEditorFactoryRegistry, EditorExtensions } from 'vs/workbench/common/editor';
1212
import { AutoSaveConfiguration, HotExitConfiguration, FILES_EXCLUDE_CONFIG, FILES_ASSOCIATIONS_CONFIG } from 'vs/platform/files/common/files';
13-
import { SortOrder, LexicographicOptions, FILE_EDITOR_INPUT_ID, BINARY_TEXT_FILE_MODE } from 'vs/workbench/contrib/files/common/files';
13+
import { SortOrder, LexicographicOptions, FILE_EDITOR_INPUT_ID, BINARY_TEXT_FILE_MODE, UndoEnablement, IFilesConfiguration } from 'vs/workbench/contrib/files/common/files';
1414
import { TextFileEditorTracker } from 'vs/workbench/contrib/files/browser/editors/textFileEditorTracker';
1515
import { TextFileSaveErrorHandler } from 'vs/workbench/contrib/files/browser/editors/textFileSaveErrorHandler';
1616
import { FileEditorInput } from 'vs/workbench/contrib/files/browser/editors/fileEditorInput';
@@ -34,6 +34,7 @@ import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
3434
import { IExplorerService } from 'vs/workbench/contrib/files/browser/files';
3535
import { FileEditorInputSerializer, FileEditorWorkingCopyEditorHandler } from 'vs/workbench/contrib/files/browser/editors/fileEditorHandler';
3636
import { ModesRegistry } from 'vs/editor/common/languages/modesRegistry';
37+
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
3738

3839
class FileUriLabelContribution implements IWorkbenchContribution {
3940

@@ -369,6 +370,17 @@ configurationRegistry.registerConfiguration({
369370
'description': nls.localize('confirmDelete', "Controls whether the explorer should ask for confirmation when deleting a file via the trash."),
370371
'default': true
371372
},
373+
'explorer.enableUndo': {
374+
'type': 'string',
375+
'enum': [UndoEnablement.Warn, UndoEnablement.Allow, UndoEnablement.Disable],
376+
'description': nls.localize('confirmUndo', "Controls how the explorer participates in undoing file and folder edits."),
377+
'default': UndoEnablement.Warn,
378+
'enumDescriptions': [
379+
nls.localize('enableUndo.warn', 'Explorer will prompt before undoing all file and folder creation events.'),
380+
nls.localize('enableUndo.allow', 'Explorer will undo file and folder creation events without prompting.'),
381+
nls.localize('enableUndo.disable', 'Explorer does not participte in undo events.'),
382+
],
383+
},
372384
'explorer.expandSingleFolderWorkspaces': {
373385
'type': 'boolean',
374386
'description': nls.localize('expandSingleFolderWorkspaces', "Controls whether the explorer should expand multi-root workspaces containing only one folder during initilization"),
@@ -445,7 +457,10 @@ configurationRegistry.registerConfiguration({
445457
UndoCommand.addImplementation(110, 'explorer', (accessor: ServicesAccessor) => {
446458
const undoRedoService = accessor.get(IUndoRedoService);
447459
const explorerService = accessor.get(IExplorerService);
448-
if (explorerService.hasViewFocus() && undoRedoService.canUndo(UNDO_REDO_SOURCE)) {
460+
const configurationService = accessor.get(IConfigurationService);
461+
462+
const explorerCanUndo = configurationService.getValue<IFilesConfiguration>().explorer.enableUndo !== UndoEnablement.Disable;
463+
if (explorerService.hasViewFocus() && undoRedoService.canUndo(UNDO_REDO_SOURCE) && explorerCanUndo) {
449464
undoRedoService.undo(UNDO_REDO_SOURCE);
450465
return true;
451466
}
@@ -456,7 +471,10 @@ UndoCommand.addImplementation(110, 'explorer', (accessor: ServicesAccessor) => {
456471
RedoCommand.addImplementation(110, 'explorer', (accessor: ServicesAccessor) => {
457472
const undoRedoService = accessor.get(IUndoRedoService);
458473
const explorerService = accessor.get(IExplorerService);
459-
if (explorerService.hasViewFocus() && undoRedoService.canRedo(UNDO_REDO_SOURCE)) {
474+
const configurationService = accessor.get(IConfigurationService);
475+
476+
const explorerCanUndo = configurationService.getValue<IFilesConfiguration>().explorer.enableUndo !== UndoEnablement.Disable;
477+
if (explorerService.hasViewFocus() && undoRedoService.canRedo(UNDO_REDO_SOURCE) && explorerCanUndo) {
460478
undoRedoService.redo(UNDO_REDO_SOURCE);
461479
return true;
462480
}

src/vs/workbench/contrib/files/common/files.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export interface IFilesConfiguration extends PlatformIFilesConfiguration, IWorkb
8888
autoReveal: boolean | 'focusNoScroll';
8989
enableDragAndDrop: boolean;
9090
confirmDelete: boolean;
91+
enableUndo: UndoEnablement;
9192
expandSingleFolderWorkspaces: boolean;
9293
sortOrder: SortOrder;
9394
sortOrderLexicographicOptions: LexicographicOptions;
@@ -113,6 +114,12 @@ export const enum SortOrder {
113114
Modified = 'modified'
114115
}
115116

117+
export const enum UndoEnablement {
118+
Warn = 'warn',
119+
Allow = 'allow',
120+
Disable = 'disable',
121+
}
122+
116123
export const enum LexicographicOptions {
117124
Default = 'default',
118125
Upper = 'upper',

0 commit comments

Comments
 (0)