UNPKG

@codingame/monaco-vscode-extensions-service-override

Version:

VSCode public API plugged on the monaco editor - extensions service-override

325 lines (321 loc) 16.1 kB
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6'; import { DisposableStore, DisposableMap } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle'; import { FileOperation } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files'; import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service'; import { extHostNamedCustomer } from '../../services/extensions/common/extHostCustomers.js'; import { ExtHostContext, MainContext } from '@codingame/monaco-vscode-api/vscode/vs/workbench/api/common/extHost.protocol'; import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls'; import { IWorkingCopyFileService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyFileService.service'; import { IBulkEditService } from '@codingame/monaco-vscode-api/vscode/vs/editor/browser/services/bulkEditService.service'; import { ProgressLocation } from '@codingame/monaco-vscode-api/vscode/vs/platform/progress/common/progress'; import { IProgressService } from '@codingame/monaco-vscode-api/vscode/vs/platform/progress/common/progress.service'; import { raceCancellation } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async'; import { CancellationTokenSource } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation'; import { IDialogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service'; import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity'; import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage'; import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service'; import { registerAction2, Action2 } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions'; import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service'; import { IEnvironmentService } from '@codingame/monaco-vscode-api/vscode/vs/platform/environment/common/environment.service'; import { IUriIdentityService } from '@codingame/monaco-vscode-api/vscode/vs/platform/uriIdentity/common/uriIdentity.service'; import { reviveWorkspaceEditDto } from './mainThreadBulkEdits.js'; import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri'; var MainThreadFileSystemEventService_1; let MainThreadFileSystemEventService = class MainThreadFileSystemEventService { static { MainThreadFileSystemEventService_1 = this; } static { this.MementoKeyAdditionalEdits = `file.particpants.additionalEdits`; } constructor( extHostContext, _fileService, workingCopyFileService, bulkEditService, progressService, dialogService, storageService, logService, envService, uriIdentService, _logService ) { this._fileService = _fileService; this._logService = _logService; this._listener = ( new DisposableStore()); this._watches = ( new DisposableMap()); this._proxy = ( extHostContext.getProxy(ExtHostContext.ExtHostFileSystemEventService)); this._listener.add(_fileService.onDidFilesChange(event => { this._proxy.$onFileEvent({ created: event.rawAdded, changed: event.rawUpdated, deleted: event.rawDeleted }); })); const that = this; const fileOperationParticipant = new (class { async participate(files, operation, undoInfo, timeout, token) { if (undoInfo?.isUndoing) { return; } const cts = ( new CancellationTokenSource(token)); const timer = setTimeout(() => cts.cancel(), timeout); const data = await progressService.withProgress({ location: ProgressLocation.Notification, title: this._progressLabel(operation), cancellable: true, delay: Math.min(timeout / 2, 3000) }, () => { const onWillEvent = that._proxy.$onWillRunFileOperation(operation, files, timeout, cts.token); return raceCancellation(onWillEvent, cts.token); }, () => { cts.cancel(); }).finally(() => { cts.dispose(); clearTimeout(timer); }); if (!data || data.edit.edits.length === 0) { return; } const needsConfirmation = ( data.edit.edits.some(edit => edit.metadata?.needsConfirmation)); let showPreview = storageService.getBoolean( MainThreadFileSystemEventService_1.MementoKeyAdditionalEdits, StorageScope.PROFILE ); if (envService.extensionTestsLocationURI) { showPreview = false; } if (showPreview === undefined) { let message; if (data.extensionNames.length === 1) { if (operation === FileOperation.CREATE) { message = ( localize( 2605, "Extension '{0}' wants to make refactoring changes with this file creation", data.extensionNames[0] )); } else if (operation === FileOperation.COPY) { message = ( localize( 2606, "Extension '{0}' wants to make refactoring changes with this file copy", data.extensionNames[0] )); } else if (operation === FileOperation.MOVE) { message = ( localize( 2607, "Extension '{0}' wants to make refactoring changes with this file move", data.extensionNames[0] )); } else { message = ( localize( 2608, "Extension '{0}' wants to make refactoring changes with this file deletion", data.extensionNames[0] )); } } else { if (operation === FileOperation.CREATE) { message = ( localize( 2609, "{0} extensions want to make refactoring changes with this file creation", data.extensionNames.length )); } else if (operation === FileOperation.COPY) { message = ( localize( 2610, "{0} extensions want to make refactoring changes with this file copy", data.extensionNames.length )); } else if (operation === FileOperation.MOVE) { message = ( localize( 2611, "{0} extensions want to make refactoring changes with this file move", data.extensionNames.length )); } else { message = ( localize( 2612, "{0} extensions want to make refactoring changes with this file deletion", data.extensionNames.length )); } } if (needsConfirmation) { const { confirmed } = await dialogService.confirm({ type: Severity.Info, message, primaryButton: ( localize(2613, "Show &&Preview")), cancelButton: ( localize(2614, "Skip Changes")) }); showPreview = true; if (!confirmed) { return; } } else { let Choice; (function(Choice) { Choice[Choice["OK"] = 0] = "OK"; Choice[Choice["Preview"] = 1] = "Preview"; Choice[Choice["Cancel"] = 2] = "Cancel"; })(Choice || (Choice = {})); const { result, checkboxChecked } = await dialogService.prompt({ type: Severity.Info, message, buttons: [{ label: ( localize(2615, "&&OK")), run: () => Choice.OK }, { label: ( localize(2613, "Show &&Preview")), run: () => Choice.Preview }], cancelButton: { label: ( localize(2614, "Skip Changes")), run: () => Choice.Cancel }, checkbox: { label: ( localize(2616, "Do not ask me again")) } }); if (result === Choice.Cancel) { return; } showPreview = result === Choice.Preview; if (checkboxChecked) { storageService.store( MainThreadFileSystemEventService_1.MementoKeyAdditionalEdits, showPreview, StorageScope.PROFILE, StorageTarget.USER ); } } } logService.info( "[onWill-handler] applying additional workspace edit from extensions", data.extensionNames ); await bulkEditService.apply(reviveWorkspaceEditDto(data.edit, uriIdentService), { undoRedoGroupId: undoInfo?.undoRedoGroupId, showPreview }); } _progressLabel(operation) { switch (operation) { case FileOperation.CREATE: return localize(2617, "Running 'File Create' participants..."); case FileOperation.MOVE: return localize(2618, "Running 'File Rename' participants..."); case FileOperation.COPY: return localize(2619, "Running 'File Copy' participants..."); case FileOperation.DELETE: return localize(2620, "Running 'File Delete' participants..."); case FileOperation.WRITE: return localize(2621, "Running 'File Write' participants..."); } } })(); this._listener.add( workingCopyFileService.addFileOperationParticipant(fileOperationParticipant) ); this._listener.add( workingCopyFileService.onDidRunWorkingCopyFileOperation(e => this._proxy.$onDidRunFileOperation(e.operation, e.files)) ); } async $watch(extensionId, session, resource, unvalidatedOpts, correlate) { const uri = URI.revive(resource); const canHandleWatcher = await this._fileService.canHandleResource(uri); if (!canHandleWatcher) { this._logService.warn( `MainThreadFileSystemEventService#$watch(): cannot watch resource as its scheme is not handled by the file service (extension: ${extensionId}, path: ${( uri.toString(true))})` ); } const opts = { ...unvalidatedOpts }; if (opts.recursive) { try { const stat = await this._fileService.stat(uri); if (!stat.isDirectory) { opts.recursive = false; } } catch (error) {} } if (correlate && !opts.recursive) { this._logService.trace( `MainThreadFileSystemEventService#$watch(): request to start watching correlated (extension: ${extensionId}, path: ${( uri.toString(true))}, recursive: ${opts.recursive}, session: ${session}, excludes: ${JSON.stringify(opts.excludes)}, includes: ${JSON.stringify(opts.includes)})` ); const watcherDisposables = ( new DisposableStore()); const subscription = watcherDisposables.add(this._fileService.createWatcher(uri, { ...opts, recursive: false })); watcherDisposables.add(subscription.onDidChange(event => { this._proxy.$onFileEvent({ session, created: event.rawAdded, changed: event.rawUpdated, deleted: event.rawDeleted }); })); this._watches.set(session, watcherDisposables); } else { this._logService.trace( `MainThreadFileSystemEventService#$watch(): request to start watching uncorrelated (extension: ${extensionId}, path: ${( uri.toString(true))}, recursive: ${opts.recursive}, session: ${session}, excludes: ${JSON.stringify(opts.excludes)}, includes: ${JSON.stringify(opts.includes)})` ); const subscription = this._fileService.watch(uri, opts); this._watches.set(session, subscription); } } $unwatch(session) { if (( this._watches.has(session))) { this._logService.trace( `MainThreadFileSystemEventService#$unwatch(): request to stop watching (session: ${session})` ); this._watches.deleteAndDispose(session); } } dispose() { this._listener.dispose(); this._watches.dispose(); } }; MainThreadFileSystemEventService = MainThreadFileSystemEventService_1 = __decorate([ extHostNamedCustomer(MainContext.MainThreadFileSystemEventService), ( __param(1, IFileService)), ( __param(2, IWorkingCopyFileService)), ( __param(3, IBulkEditService)), ( __param(4, IProgressService)), ( __param(5, IDialogService)), ( __param(6, IStorageService)), ( __param(7, ILogService)), ( __param(8, IEnvironmentService)), ( __param(9, IUriIdentityService)), ( __param(10, ILogService)) ], MainThreadFileSystemEventService); registerAction2(class ResetMemento extends Action2 { constructor() { super({ id: "files.participants.resetChoice", title: { value: ( localize(2622, "Reset choice for 'File operation needs preview'")), original: `Reset choice for 'File operation needs preview'` }, f1: true }); } run(accessor) { accessor.get(IStorageService).remove( MainThreadFileSystemEventService.MementoKeyAdditionalEdits, StorageScope.PROFILE ); } }); export { MainThreadFileSystemEventService };