UNPKG

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

Version:

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

316 lines (313 loc) 17 kB
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js'; import { DisposableStore, DisposableMap } from 'vscode/vscode/vs/base/common/lifecycle'; import { FileOperation } from 'vscode/vscode/vs/platform/files/common/files'; import { IFileService } from 'vscode/vscode/vs/platform/files/common/files.service'; import { extHostNamedCustomer } from '../../services/extensions/common/extHostCustomers.js'; import { ExtHostContext, MainContext } from 'vscode/vscode/vs/workbench/api/common/extHost.protocol'; import { localize } from 'vscode/vscode/vs/nls'; import { IWorkingCopyFileService } from 'vscode/vscode/vs/workbench/services/workingCopy/common/workingCopyFileService.service'; import { IBulkEditService } from 'vscode/vscode/vs/editor/browser/services/bulkEditService'; import { ProgressLocation } from 'vscode/vscode/vs/platform/progress/common/progress'; import { IProgressService } from 'vscode/vscode/vs/platform/progress/common/progress.service'; import { raceCancellation } from 'vscode/vscode/vs/base/common/async'; import { CancellationTokenSource } from 'vscode/vscode/vs/base/common/cancellation'; import { IDialogService } from 'vscode/vscode/vs/platform/dialogs/common/dialogs.service'; import Severity$1 from 'vscode/vscode/vs/base/common/severity'; import { StorageScope, StorageTarget } from 'vscode/vscode/vs/platform/storage/common/storage'; import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage.service'; import { registerAction2, Action2 } from 'vscode/vscode/vs/platform/actions/common/actions'; import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service'; import { IEnvironmentService } from 'vscode/vscode/vs/platform/environment/common/environment.service'; import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity.service'; import { reviveWorkspaceEditDto } from './mainThreadBulkEdits.js'; import { GLOBSTAR } from 'vscode/vscode/vs/base/common/glob'; import { rtrim } from 'vscode/vscode/vs/base/common/strings'; import { URI } from 'vscode/vscode/vs/base/common/uri'; import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration.service'; import { normalizeWatcherPattern } from 'vscode/vscode/vs/platform/files/common/watcher'; import { IWorkspaceContextService } from 'vscode/vscode/vs/platform/workspace/common/workspace.service'; 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, _contextService, _logService, _configurationService) { this._fileService = _fileService; this._contextService = _contextService; this._logService = _logService; this._configurationService = _configurationService; 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( 4841, "Extension '{0}' wants to make refactoring changes with this file creation", data.extensionNames[0] )); } else if (operation === FileOperation.COPY) { message = ( localize( 4842, "Extension '{0}' wants to make refactoring changes with this file copy", data.extensionNames[0] )); } else if (operation === FileOperation.MOVE) { message = ( localize( 4843, "Extension '{0}' wants to make refactoring changes with this file move", data.extensionNames[0] )); } else { message = ( localize( 4844, "Extension '{0}' wants to make refactoring changes with this file deletion", data.extensionNames[0] )); } } else { if (operation === FileOperation.CREATE) { message = ( localize( 4845, "{0} extensions want to make refactoring changes with this file creation", data.extensionNames.length )); } else if (operation === FileOperation.COPY) { message = ( localize( 4846, "{0} extensions want to make refactoring changes with this file copy", data.extensionNames.length )); } else if (operation === FileOperation.MOVE) { message = ( localize( 4847, "{0} extensions want to make refactoring changes with this file move", data.extensionNames.length )); } else { message = ( localize( 4848, "{0} extensions want to make refactoring changes with this file deletion", data.extensionNames.length )); } } if (needsConfirmation) { const { confirmed } = await dialogService.confirm({ type: Severity$1.Info, message, primaryButton: ( localize(4849, "Show &&Preview")), cancelButton: ( localize(4850, "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$1.Info, message, buttons: [ { label: ( localize(4851, "&&OK")), run: () => Choice.OK }, { label: ( localize(4849, "Show &&Preview")), run: () => Choice.Preview } ], cancelButton: { label: ( localize(4850, "Skip Changes")), run: () => Choice.Cancel }, checkbox: { label: ( localize(4852, "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(4853, "Running 'File Create' participants...")); case FileOperation.MOVE: return ( localize(4854, "Running 'File Rename' participants...")); case FileOperation.COPY: return ( localize(4855, "Running 'File Copy' participants...")); case FileOperation.DELETE: return ( localize(4856, "Running 'File Delete' participants...")); case FileOperation.WRITE: return ( localize(4857, "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 opts = { ...unvalidatedOpts }; if (opts.recursive) { try { const stat = await this._fileService.stat(uri); if (!stat.isDirectory) { opts.recursive = false; } } catch (error) { } } if (correlate) { this._logService.trace(`MainThreadFileSystemEventService#$watch(): request to start watching correlated (extension: ${extensionId}, path: ${( (uri.toString(true)))}, recursive: ${opts.recursive}, session: ${session})`); const watcherDisposables = ( (new DisposableStore())); const subscription = watcherDisposables.add(this._fileService.createWatcher(uri, opts)); 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})`); const workspaceFolder = this._contextService.getWorkspaceFolder(uri); if (opts.recursive && opts.excludes.length === 0) { const config = this._configurationService.getValue(); if (config.files?.watcherExclude) { for (const key in config.files.watcherExclude) { if (key && config.files.watcherExclude[key] === true) { opts.excludes.push(key); } } } } else if (!opts.recursive && workspaceFolder) { const config = this._configurationService.getValue(); if (config.files?.watcherExclude) { for (const key in config.files.watcherExclude) { if (key && config.files.watcherExclude[key] === true) { if (!opts.includes) { opts.includes = []; } const includePattern = `${rtrim(key, '/')}/${GLOBSTAR}`; opts.includes.push(normalizeWatcherPattern(workspaceFolder.uri.fsPath, includePattern)); } } } if (!opts.includes || opts.includes.length === 0) { this._logService.trace(`MainThreadFileSystemEventService#$watch(): ignoring request to start watching because path is inside workspace and no excludes are configured (extension: ${extensionId}, path: ${( (uri.toString(true)))}, recursive: ${opts.recursive}, session: ${session})`); return; } } 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, IWorkspaceContextService))), ( (__param(11, ILogService))), ( (__param(12, IConfigurationService))) ], MainThreadFileSystemEventService); registerAction2(class ResetMemento extends Action2 { constructor() { super({ id: 'files.participants.resetChoice', title: { value: ( localize(4858, "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 };