4bb74e28db86561e3469b87980f10e1824bb4e759857d0f5650709a68faf5830f7f71b65d41145a7f6203cc6aaae96c2fa61117f2b9a18a413c64f56937697 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  6. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  7. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  8. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  9. return c > 3 && r && Object.defineProperty(target, key, r), r;
  10. };
  11. var __param = (this && this.__param) || function (paramIndex, decorator) {
  12. return function (target, key) { decorator(target, key, paramIndex); }
  13. };
  14. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  15. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  16. return new (P || (P = Promise))(function (resolve, reject) {
  17. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  18. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  19. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  20. step((generator = generator.apply(thisArg, _arguments || [])).next());
  21. });
  22. };
  23. import { raceCancellation } from '../../../../base/common/async.js';
  24. import { VSDataTransfer } from '../../../../base/common/dataTransfer.js';
  25. import { Disposable } from '../../../../base/common/lifecycle.js';
  26. import { Mimes } from '../../../../base/common/mime.js';
  27. import { relativePath } from '../../../../base/common/resources.js';
  28. import { URI } from '../../../../base/common/uri.js';
  29. import { addExternalEditorsDropData, toVSDataTransfer, UriList } from '../../../browser/dnd.js';
  30. import { registerEditorContribution } from '../../../browser/editorExtensions.js';
  31. import { IBulkEditService, ResourceEdit } from '../../../browser/services/bulkEditService.js';
  32. import { Range } from '../../../common/core/range.js';
  33. import { Selection } from '../../../common/core/selection.js';
  34. import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.js';
  35. import { EditorStateCancellationTokenSource } from '../../editorState/browser/editorState.js';
  36. import { performSnippetEdit } from '../../snippet/browser/snippetController2.js';
  37. import { SnippetParser } from '../../snippet/browser/snippetParser.js';
  38. import { localize } from '../../../../nls.js';
  39. import { IProgressService } from '../../../../platform/progress/common/progress.js';
  40. import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js';
  41. let DropIntoEditorController = class DropIntoEditorController extends Disposable {
  42. constructor(editor, _bulkEditService, _languageFeaturesService, _progressService, workspaceContextService) {
  43. super();
  44. this._bulkEditService = _bulkEditService;
  45. this._languageFeaturesService = _languageFeaturesService;
  46. this._progressService = _progressService;
  47. this._register(editor.onDropIntoEditor(e => this.onDropIntoEditor(editor, e.position, e.event)));
  48. this._languageFeaturesService.documentOnDropEditProvider.register('*', new DefaultOnDropProvider(workspaceContextService));
  49. }
  50. onDropIntoEditor(editor, position, dragEvent) {
  51. return __awaiter(this, void 0, void 0, function* () {
  52. if (!dragEvent.dataTransfer || !editor.hasModel()) {
  53. return;
  54. }
  55. const model = editor.getModel();
  56. const initialModelVersion = model.getVersionId();
  57. const ourDataTransfer = yield this.extractDataTransferData(dragEvent);
  58. if (ourDataTransfer.size === 0) {
  59. return;
  60. }
  61. if (editor.getModel().getVersionId() !== initialModelVersion) {
  62. return;
  63. }
  64. const tokenSource = new EditorStateCancellationTokenSource(editor, 1 /* CodeEditorStateFlag.Value */);
  65. try {
  66. const providers = this._languageFeaturesService.documentOnDropEditProvider.ordered(model);
  67. const edit = yield this._progressService.withProgress({
  68. location: 15 /* ProgressLocation.Notification */,
  69. delay: 750,
  70. title: localize('dropProgressTitle', "Running drop handlers..."),
  71. cancellable: true,
  72. }, () => {
  73. return raceCancellation((() => __awaiter(this, void 0, void 0, function* () {
  74. for (const provider of providers) {
  75. const edit = yield provider.provideDocumentOnDropEdits(model, position, ourDataTransfer, tokenSource.token);
  76. if (tokenSource.token.isCancellationRequested) {
  77. return undefined;
  78. }
  79. if (edit) {
  80. return edit;
  81. }
  82. }
  83. return undefined;
  84. }))(), tokenSource.token);
  85. }, () => {
  86. tokenSource.cancel();
  87. });
  88. if (tokenSource.token.isCancellationRequested || editor.getModel().getVersionId() !== initialModelVersion) {
  89. return;
  90. }
  91. if (edit) {
  92. const range = new Range(position.lineNumber, position.column, position.lineNumber, position.column);
  93. performSnippetEdit(editor, typeof edit.insertText === 'string' ? SnippetParser.escape(edit.insertText) : edit.insertText.snippet, [Selection.fromRange(range, 0 /* SelectionDirection.LTR */)]);
  94. if (edit.additionalEdit) {
  95. yield this._bulkEditService.apply(ResourceEdit.convert(edit.additionalEdit), { editor });
  96. }
  97. return;
  98. }
  99. }
  100. finally {
  101. tokenSource.dispose();
  102. }
  103. });
  104. }
  105. extractDataTransferData(dragEvent) {
  106. return __awaiter(this, void 0, void 0, function* () {
  107. if (!dragEvent.dataTransfer) {
  108. return new VSDataTransfer();
  109. }
  110. const textEditorDataTransfer = toVSDataTransfer(dragEvent.dataTransfer);
  111. addExternalEditorsDropData(textEditorDataTransfer, dragEvent);
  112. return textEditorDataTransfer;
  113. });
  114. }
  115. };
  116. DropIntoEditorController.ID = 'editor.contrib.dropIntoEditorController';
  117. DropIntoEditorController = __decorate([
  118. __param(1, IBulkEditService),
  119. __param(2, ILanguageFeaturesService),
  120. __param(3, IProgressService),
  121. __param(4, IWorkspaceContextService)
  122. ], DropIntoEditorController);
  123. export { DropIntoEditorController };
  124. let DefaultOnDropProvider = class DefaultOnDropProvider {
  125. constructor(_workspaceContextService) {
  126. this._workspaceContextService = _workspaceContextService;
  127. }
  128. provideDocumentOnDropEdits(_model, _position, dataTransfer, _token) {
  129. var _a;
  130. return __awaiter(this, void 0, void 0, function* () {
  131. const urlListEntry = dataTransfer.get(Mimes.uriList);
  132. if (urlListEntry) {
  133. const urlList = yield urlListEntry.asString();
  134. const snippet = this.getUriListInsertText(urlList);
  135. if (snippet) {
  136. return { insertText: snippet };
  137. }
  138. }
  139. const textEntry = (_a = dataTransfer.get('text')) !== null && _a !== void 0 ? _a : dataTransfer.get(Mimes.text);
  140. if (textEntry) {
  141. const text = yield textEntry.asString();
  142. return { insertText: text };
  143. }
  144. return undefined;
  145. });
  146. }
  147. getUriListInsertText(strUriList) {
  148. const uris = [];
  149. for (const resource of UriList.parse(strUriList)) {
  150. try {
  151. uris.push(URI.parse(resource));
  152. }
  153. catch (_a) {
  154. // noop
  155. }
  156. }
  157. if (!uris.length) {
  158. return;
  159. }
  160. return uris
  161. .map(uri => {
  162. const root = this._workspaceContextService.getWorkspaceFolder(uri);
  163. if (root) {
  164. const rel = relativePath(root.uri, uri);
  165. if (rel) {
  166. return rel;
  167. }
  168. }
  169. return uri.fsPath;
  170. })
  171. .join(' ');
  172. }
  173. };
  174. DefaultOnDropProvider = __decorate([
  175. __param(0, IWorkspaceContextService)
  176. ], DefaultOnDropProvider);
  177. registerEditorContribution(DropIntoEditorController.ID, DropIntoEditorController);