{"version":3,"sources":["browser/monaco-editor-provider.ts"],"names":[],"mappings":"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","file":"../../src/browser/monaco-editor-provider.d.ts","sourcesContent":["import {inject, injectable, named} from 'inversify';\r\nimport {MonacoEditorService} from './monaco-editor-service';\r\nimport {MonacoEditor, MonacoEditorServices} from './monaco-editor';\r\nimport URI from '@tartjs/core/lib/common/uri';\r\nimport {MonacoCommandServiceFactory} from './monaco-command-service';\r\nimport {ContributionProvider, deepClone, Disposable, DisposableCollection} from '@tartjs/core/lib/common';\r\nimport {DiffUris, FormatType, KeybindingRegistry, open, OpenerService, WidgetOpenerOptions} from '@tartjs/core';\r\nimport {MonacoTextModelService} from './monaco-text-model-service';\r\nimport {MonacoContextMenuService} from './monaco-context-menu';\r\nimport {MonacoBulkEditService} from './monaco-bulk-edit-service';\r\nimport {HttpOpenHandlerOptions} from '@tartjs/core/lib/browser/http-open-handler';\r\nimport {DiffNavigator, EditorPreferenceChange, EditorPreferences, TextEditor} from '@tartjs/editor';\r\nimport {MonacoQuickInputImplementation} from './monaco-quick-input-service';\r\nimport {MonacoResolvedKeybinding} from './monaco-resolved-keybinding';\r\nimport {MonacoEditorModel, WillSaveMonacoModelEvent} from './monaco-editor-model';\r\nimport {TextDocumentSaveReason} from 'vscode-languageserver-protocol';\r\nimport {MonacoDiffEditor} from './monaco-diff-editor';\r\nimport {MonacoDiffNavigatorFactory} from './monaco-diff-navigator-factory';\r\nimport {MonacoToProtocolConverter} from './monaco-to-protocol-converter';\r\nimport {ProtocolToMonacoConverter} from './protocol-to-monaco-converter';\r\nimport IEditorOverrideServices = monaco.editor.IEditorOverrideServices;\r\n\r\nexport const MonacoEditorFactory = Symbol('MonacoEditorFactory');\r\n\r\nexport interface MonacoEditorFactory {\r\n    readonly scheme: string;\r\n\r\n    create(model: MonacoEditorModel, defaultOptions: MonacoEditor.IOptions, defaultOverrides: IEditorOverrideServices): MonacoEditor;\r\n}\r\n\r\n\r\n@injectable()\r\nexport class MonacoEditorProvider {\r\n  @inject(ContributionProvider)\r\n  @named(MonacoEditorFactory)\r\n  protected readonly factories: ContributionProvider<MonacoEditorFactory>;\r\n\r\n  @inject(MonacoBulkEditService)\r\n  protected readonly bulkEditService: MonacoBulkEditService;\r\n\r\n  @inject(MonacoEditorServices)\r\n  protected readonly services: MonacoEditorServices;\r\n\r\n  @inject(OpenerService)\r\n  protected readonly openerService: OpenerService;\r\n\r\n  @inject(MonacoQuickInputImplementation)\r\n  protected readonly quickInputService: MonacoQuickInputImplementation;\r\n\r\n  @inject(KeybindingRegistry)\r\n  protected readonly keybindingRegistry: KeybindingRegistry;\r\n\r\n  constructor(\r\n      @inject(MonacoEditorService) protected readonly codeEditorService: MonacoEditorService,\r\n      @inject(MonacoTextModelService) protected readonly textModelService: MonacoTextModelService,\r\n      @inject(MonacoContextMenuService) protected readonly contextMenuService: MonacoContextMenuService,\r\n      @inject(MonacoToProtocolConverter) protected readonly m2p: MonacoToProtocolConverter,\r\n      @inject(ProtocolToMonacoConverter) protected readonly p2m: ProtocolToMonacoConverter,\r\n      @inject(MonacoDiffNavigatorFactory) protected readonly diffNavigatorFactory: MonacoDiffNavigatorFactory,\r\n      @inject(EditorPreferences) protected readonly editorPreferences: EditorPreferences,\r\n      @inject(MonacoCommandServiceFactory) protected readonly commandServiceFactory: MonacoCommandServiceFactory,\r\n      @inject(monaco.contextKeyService.ContextKeyService) protected readonly contextKeyService: monaco.contextKeyService.ContextKeyService\r\n  ) {\r\n    const staticServices = monaco.services.StaticServices;\r\n    const init = staticServices.init.bind(monaco.services.StaticServices);\r\n\r\n    monaco.services.StaticServices.init = o => {\r\n      const result = init(o);\r\n      result[0].set(monaco.services.ICodeEditorService, codeEditorService);\r\n      return result;\r\n    };\r\n  }\r\n\r\n  protected _current: MonacoEditor | undefined;\r\n\r\n  /**\r\n   * Returns the last focused MonacoEditor.\r\n   * It takes into account inline editors as well.\r\n   * If you are interested only in standalone editors then use `MonacoEditor.getCurrent(EditorManager)`\r\n   */\r\n  get current(): MonacoEditor | undefined {\r\n    return this._current;\r\n  }\r\n\r\n  protected get preferencePrefixes(): string[] {\r\n    return ['editor.'];\r\n  }\r\n\r\n  protected get diffPreferencePrefixes(): string[] {\r\n    return [...this.preferencePrefixes, 'diffEditor.'];\r\n  }\r\n\r\n  async get(uri: URI): Promise<MonacoEditor> {\r\n    await this.editorPreferences.ready;\r\n    return this.doCreateEditor(uri, (override, toDispose) => this.createEditor(uri, override, toDispose));\r\n  }\r\n\r\n  getDiffNavigator(editor: TextEditor): DiffNavigator {\r\n    if (editor instanceof MonacoDiffEditor) {\r\n      return editor.diffNavigator;\r\n    }\r\n    return MonacoDiffNavigatorFactory.nullNavigator;\r\n  }\r\n\r\n  protected async doCreateEditor(uri: URI, factory: (override: IEditorOverrideServices, toDispose: DisposableCollection) => Promise<MonacoEditor>): Promise<MonacoEditor> {\r\n    const commandService = this.commandServiceFactory();\r\n    const domNode = document.createElement('div');\r\n    const contextKeyService = this.contextKeyService.createScoped(domNode);\r\n    const {codeEditorService, textModelService, contextMenuService} = this;\r\n    const IWorkspaceEditService = this.bulkEditService;\r\n    const toDispose = new DisposableCollection(commandService);\r\n    const openerService = new monaco.services.OpenerService(codeEditorService, commandService);\r\n    openerService.registerOpener({\r\n      open: (u, options) => this.interceptOpen(u, options)\r\n    });\r\n    const editor = await factory({\r\n      codeEditorService,\r\n      textModelService,\r\n      contextMenuService,\r\n      commandService,\r\n      IWorkspaceEditService,\r\n      contextKeyService,\r\n      openerService,\r\n      quickInputService: this.quickInputService\r\n    }, toDispose);\r\n    editor.onDispose(() => toDispose.dispose());\r\n\r\n    this.suppressMonacoKeybindingListener(editor);\r\n    this.injectKeybindingResolver(editor);\r\n\r\n    const standaloneCommandService = new monaco.services.StandaloneCommandService(editor.instantiationService);\r\n    commandService.setDelegate(standaloneCommandService);\r\n    toDispose.push(this.installReferencesController(editor));\r\n\r\n    toDispose.push(editor.onFocusChanged(focused => {\r\n      if (focused) {\r\n        this._current = editor;\r\n      }\r\n    }));\r\n    toDispose.push(Disposable.create(() => {\r\n      if (this._current === editor) {\r\n        this._current = undefined;\r\n      }\r\n    }));\r\n\r\n    return editor;\r\n  }\r\n\r\n  protected injectKeybindingResolver(editor: MonacoEditor): void {\r\n    const keybindingService = editor.getControl()._standaloneKeybindingService;\r\n    keybindingService.resolveKeybinding = keybinding => [new MonacoResolvedKeybinding(MonacoResolvedKeybinding.keySequence(keybinding), this.keybindingRegistry)];\r\n    keybindingService.resolveKeyboardEvent = keyboardEvent => {\r\n      const keybinding = new monaco.keybindings.SimpleKeybinding(\r\n          keyboardEvent.ctrlKey,\r\n          keyboardEvent.shiftKey,\r\n          keyboardEvent.altKey,\r\n          keyboardEvent.metaKey,\r\n          keyboardEvent.keyCode\r\n      ).toChord();\r\n      return new MonacoResolvedKeybinding(MonacoResolvedKeybinding.keySequence(keybinding), this.keybindingRegistry);\r\n    };\r\n  }\r\n\r\n  protected createEditor(uri: URI, override: IEditorOverrideServices, toDispose: DisposableCollection): Promise<MonacoEditor> {\r\n    if (DiffUris.isDiffUri(uri)) {\r\n      return this.createMonacoDiffEditor(uri, override, toDispose);\r\n    }\r\n    return this.createMonacoEditor(uri, override, toDispose);\r\n  }\r\n\r\n  protected async createMonacoEditor(uri: URI, override: IEditorOverrideServices, toDispose: DisposableCollection): Promise<MonacoEditor> {\r\n    const model = await this.getModel(uri, toDispose);\r\n    const options = this.createMonacoEditorOptions(model);\r\n    const factory = this.factories.getContributions().find(({scheme}) => uri.scheme === scheme);\r\n    const editor = factory\r\n        ? factory.create(model, options, override)\r\n        : new MonacoEditor(uri, model, document.createElement('div'), this.services, options, override);\r\n    toDispose.push(this.editorPreferences.onPreferenceChanged(event => {\r\n      if (event.affects(uri.toString(), model.languageId)) {\r\n        this.updateMonacoEditorOptions(editor, event);\r\n      }\r\n    }));\r\n    toDispose.push(editor.onLanguageChanged(() => this.updateMonacoEditorOptions(editor)));\r\n    editor.document.onWillSaveModel(event => event.waitUntil(this.formatOnSave(editor, event)));\r\n    return editor;\r\n  }\r\n\r\n  protected createMonacoEditorOptions(model: MonacoEditorModel): MonacoEditor.IOptions {\r\n    const options = this.createOptions(this.preferencePrefixes, model.uri, model.languageId);\r\n    options.model = model.textEditorModel;\r\n    options.readOnly = model.readOnly;\r\n    options.lineNumbersMinChars = model.lineNumbersMinChars;\r\n    return options;\r\n  }\r\n\r\n  protected updateMonacoEditorOptions(editor: MonacoEditor, event?: EditorPreferenceChange): void {\r\n    if (event) {\r\n      const preferenceName = event.preferenceName;\r\n      const overrideIdentifier = editor.document.languageId;\r\n      const newValue = this.editorPreferences.get({\r\n        preferenceName,\r\n        overrideIdentifier\r\n      }, undefined, editor.uri.toString());\r\n      editor.getControl().updateOptions(this.setOption(preferenceName, newValue, this.preferencePrefixes));\r\n    } else {\r\n      const options = this.createMonacoEditorOptions(editor.document);\r\n      delete options.model;\r\n      editor.getControl().updateOptions(options);\r\n    }\r\n  }\r\n\r\n  protected shouldFormat(editor: MonacoEditor, event: WillSaveMonacoModelEvent): boolean {\r\n    if (event.reason !== TextDocumentSaveReason.Manual) {\r\n      return false;\r\n    }\r\n    if (event.options?.formatType) {\r\n      switch (event.options.formatType) {\r\n        case FormatType.ON:\r\n          return true;\r\n        case FormatType.OFF:\r\n          return false;\r\n        case FormatType.DIRTY:\r\n          return editor.document.dirty;\r\n      }\r\n    }\r\n    return true;\r\n  }\r\n\r\n  protected async formatOnSave(editor: MonacoEditor, event: WillSaveMonacoModelEvent): Promise<monaco.editor.IIdentifiedSingleEditOperation[]> {\r\n    if (!this.shouldFormat(editor, event)) {\r\n      return [];\r\n    }\r\n    const overrideIdentifier = editor.document.languageId;\r\n    const uri = editor.uri.toString();\r\n    const formatOnSave = this.editorPreferences.get({\r\n      preferenceName: 'editor.formatOnSave',\r\n      overrideIdentifier\r\n    }, undefined, uri)!;\r\n    if (formatOnSave) {\r\n      const formatOnSaveTimeout = this.editorPreferences.get({\r\n        preferenceName: 'editor.formatOnSaveTimeout',\r\n        overrideIdentifier\r\n      }, undefined, uri)!;\r\n      await Promise.race([\r\n        new Promise((_, reject) => setTimeout(() => reject(new Error(`Aborted format on save after ${formatOnSaveTimeout}ms`)), formatOnSaveTimeout)),\r\n        editor.runAction('editor.action.formatDocument')\r\n      ]);\r\n    }\r\n    // const shouldRemoveWhiteSpace = this.filePreferences.get({ preferenceName: 'files.trimTrailingWhitespace', overrideIdentifier }, undefined, uri);\r\n    // if (shouldRemoveWhiteSpace) {\r\n    //     await editor.runAction('editor.action.trimTrailingWhitespace');\r\n    // }\r\n    return [];\r\n  }\r\n\r\n  protected async getModel(uri: URI, toDispose: DisposableCollection): Promise<MonacoEditorModel> {\r\n    const reference = await this.textModelService.createModelReference(uri);\r\n    // if document is invalid makes sure that all events from underlying resource are processed before throwing invalid model\r\n    if (!reference.object.valid) {\r\n      await reference.object.sync();\r\n    }\r\n    if (!reference.object.valid) {\r\n      reference.dispose();\r\n      throw Object.assign(new Error(`'${uri.toString()}' is invalid`), {code: 'MODEL_IS_INVALID'});\r\n    }\r\n    toDispose.push(reference);\r\n    return reference.object;\r\n  }\r\n\r\n  protected async createMonacoDiffEditor(uri: URI, override: IEditorOverrideServices, toDispose: DisposableCollection): Promise<MonacoDiffEditor> {\r\n    const [original, modified] = DiffUris.decode(uri);\r\n\r\n    const [originalModel, modifiedModel] = await Promise.all([this.getModel(original, toDispose), this.getModel(modified, toDispose)]);\r\n\r\n    const options = this.createMonacoDiffEditorOptions(originalModel, modifiedModel);\r\n    const editor = new MonacoDiffEditor(\r\n        uri,\r\n        document.createElement('div'),\r\n        originalModel, modifiedModel,\r\n        this.services,\r\n        this.diffNavigatorFactory,\r\n        options,\r\n        override);\r\n    toDispose.push(this.editorPreferences.onPreferenceChanged(event => {\r\n      const originalFileUri = original.withoutQuery().withScheme('file').toString();\r\n      if (event.affects(originalFileUri, editor.document.languageId)) {\r\n        this.updateMonacoDiffEditorOptions(editor, event, originalFileUri);\r\n      }\r\n    }));\r\n    toDispose.push(editor.onLanguageChanged(() => this.updateMonacoDiffEditorOptions(editor)));\r\n    return editor;\r\n  }\r\n\r\n  protected createMonacoDiffEditorOptions(original: MonacoEditorModel, modified: MonacoEditorModel): MonacoDiffEditor.IOptions {\r\n    const options = this.createOptions(this.diffPreferencePrefixes, modified.uri, modified.languageId);\r\n    options.originalEditable = !original.readOnly;\r\n    options.readOnly = modified.readOnly;\r\n    return options;\r\n  }\r\n\r\n  protected updateMonacoDiffEditorOptions(editor: MonacoDiffEditor, event?: EditorPreferenceChange, resourceUri?: string): void {\r\n    if (event) {\r\n      const preferenceName = event.preferenceName;\r\n      const overrideIdentifier = editor.document.languageId;\r\n      const newValue = this.editorPreferences.get({preferenceName, overrideIdentifier}, undefined, resourceUri);\r\n      editor.diffEditor.updateOptions(this.setOption(preferenceName, newValue, this.diffPreferencePrefixes));\r\n    } else {\r\n      const options = this.createMonacoDiffEditorOptions(editor.originalModel, editor.modifiedModel);\r\n      editor.diffEditor.updateOptions(options);\r\n    }\r\n  }\r\n\r\n\r\n  /** @deprecated always pass a language as an overrideIdentifier */\r\n  protected createOptions(prefixes: string[], uri: string): { [name: string]: any };\r\n  protected createOptions(prefixes: string[], uri: string, overrideIdentifier: string): { [name: string]: any };\r\n  protected createOptions(prefixes: string[], uri: string, overrideIdentifier?: string): { [name: string]: any } {\r\n    return Object.keys(this.editorPreferences).reduce((options, preferenceName) => {\r\n      const value = (<any>this.editorPreferences).get({preferenceName, overrideIdentifier}, undefined, uri);\r\n      return this.setOption(preferenceName, deepClone(value), prefixes, options);\r\n    }, {});\r\n  }\r\n\r\n  protected setOption(preferenceName: string, value: any, prefixes: string[], options: { [name: string]: any } = {}): {\r\n    [name: string]: any;\r\n  } {\r\n    const optionName = this.toOptionName(preferenceName, prefixes);\r\n    this.doSetOption(options, value, optionName.split('.'));\r\n    return options;\r\n  }\r\n\r\n  protected toOptionName(preferenceName: string, prefixes: string[]): string {\r\n    for (const prefix of prefixes) {\r\n      if (preferenceName.startsWith(prefix)) {\r\n        return preferenceName.substr(prefix.length);\r\n      }\r\n    }\r\n    return preferenceName;\r\n  }\r\n\r\n  protected doSetOption(obj: { [name: string]: any }, value: any, names: string[], idx: number = 0): void {\r\n    const name = names[idx];\r\n    if (!obj[name]) {\r\n      if (names.length > (idx + 1)) {\r\n        obj[name] = {};\r\n        this.doSetOption(obj[name], value, names, (idx + 1));\r\n      } else {\r\n        obj[name] = value;\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Suppresses Monaco keydown listener to avoid triggering default Monaco keybindings\r\n   * if they are overridden by a user. Monaco keybindings should be registered as Wm keybindings\r\n   * to allow a user to customize them.\r\n   */\r\n  protected suppressMonacoKeybindingListener(editor: MonacoEditor): void {\r\n    let keydownListener: monaco.IDisposable | undefined;\r\n    const keybindingService = editor.getControl()._standaloneKeybindingService;\r\n    for (const listener of keybindingService._store._toDispose) {\r\n      if ('_type' in listener && listener['_type'] === 'keydown') {\r\n        keydownListener = listener;\r\n        break;\r\n      }\r\n    }\r\n    if (keydownListener) {\r\n      keydownListener.dispose();\r\n    }\r\n  }\r\n\r\n  protected installReferencesController(editor: MonacoEditor): Disposable {\r\n    const control = editor.getControl();\r\n    const referencesController = control._contributions['editor.contrib.referencesController'];\r\n    const originalGotoReference = referencesController._gotoReference;\r\n    referencesController._gotoReference = async ref => {\r\n      if (referencesController._widget) {\r\n        referencesController._widget.hide();\r\n      }\r\n\r\n      referencesController._ignoreModelChangeEvent = true;\r\n      const range = monaco.Range.lift(ref.range).collapseToStart();\r\n\r\n      // preserve the model that it does not get disposed if an editor preview replaces an editor\r\n      const model = referencesController._model;\r\n      referencesController._model = undefined;\r\n\r\n      referencesController._editorService.openCodeEditor({\r\n        resource: ref.uri,\r\n        options: {selection: range}\r\n      }, control).then(openedEditor => {\r\n        referencesController._model = model;\r\n        referencesController._ignoreModelChangeEvent = false;\r\n        if (!openedEditor) {\r\n          referencesController.closeWidget();\r\n          return;\r\n        }\r\n        if (openedEditor !== control) {\r\n          // preserve the model that it does not get disposed in `referencesController.closeWidget`\r\n          referencesController._model = undefined;\r\n\r\n          // to preserve the active editor\r\n          const focus = control.focus;\r\n          control.focus = () => {\r\n          };\r\n          referencesController.closeWidget();\r\n          control.focus = focus;\r\n\r\n          const modelPromise = Promise.resolve(model) as any;\r\n          modelPromise.cancel = () => {\r\n          };\r\n          openedEditor._contributions['editor.contrib.referencesController'].toggleWidget(range, modelPromise, true);\r\n          return;\r\n        }\r\n\r\n        if (referencesController._widget) {\r\n          referencesController._widget.show(range);\r\n          referencesController._widget.focusOnReferenceTree();\r\n        }\r\n\r\n      }, (e: any) => {\r\n        referencesController._ignoreModelChangeEvent = false;\r\n        monaco.error.onUnexpectedError(e);\r\n      });\r\n    };\r\n    return Disposable.create(() => referencesController._gotoReference = originalGotoReference);\r\n  }\r\n\r\n  /**\r\n   * Intercept internal Monaco open calls and delegate to OpenerService.\r\n   */\r\n  protected async interceptOpen(monacoUri: monaco.Uri | string, monacoOptions?: monaco.services.OpenInternalOptions | monaco.services.OpenExternalOptions): Promise<boolean> {\r\n    let options = undefined;\r\n    if (monacoOptions) {\r\n      if ('openToSide' in monacoOptions && monacoOptions.openToSide) {\r\n        options = Object.assign(options || {}, <WidgetOpenerOptions>{\r\n          widgetOptions: {\r\n            mode: 'split-right'\r\n          }\r\n        });\r\n      }\r\n      if ('openExternal' in monacoOptions && monacoOptions.openExternal) {\r\n        options = Object.assign(options || {}, <HttpOpenHandlerOptions>{\r\n          openExternal: true\r\n        });\r\n      }\r\n    }\r\n    const uri = new URI(monacoUri.toString());\r\n    try {\r\n      await open(this.openerService, uri, options);\r\n      return true;\r\n    } catch (e) {\r\n      console.error(`Fail to open '${uri.toString()}':`, e);\r\n      return false;\r\n    }\r\n  }\r\n\r\n  async createInline(uri: URI, node: HTMLElement, options?: MonacoEditor.IOptions): Promise<MonacoEditor> {\r\n    return this.doCreateEditor(uri, async (override, toDispose) => {\r\n      override.contextMenuService = {\r\n        showContextMenu: () => {/* no-op*/\r\n        }\r\n      };\r\n      const document = new MonacoEditorModel({\r\n        uri,\r\n        readContents: async () => '',\r\n        dispose: () => {\r\n        }\r\n      }, this.m2p, this.p2m);\r\n      toDispose.push(document);\r\n      const model = (await document.load()).textEditorModel;\r\n      return new MonacoEditor(\r\n          uri,\r\n          document,\r\n          node,\r\n          this.services,\r\n          Object.assign({\r\n            model,\r\n            isSimpleWidget: true,\r\n            autoSizing: false,\r\n            minHeight: 1,\r\n            maxHeight: 1\r\n          }, MonacoEditorProvider.inlineOptions, options),\r\n          override\r\n      );\r\n    });\r\n  }\r\n\r\n  static inlineOptions: monaco.editor.IEditorConstructionOptions = {\r\n    wordWrap: 'on',\r\n    overviewRulerLanes: 0,\r\n    glyphMargin: false,\r\n    lineNumbers: 'off',\r\n    folding: false,\r\n    selectOnLineNumbers: false,\r\n    hideCursorInOverviewRuler: true,\r\n    selectionHighlight: false,\r\n    scrollbar: {\r\n      horizontal: 'hidden'\r\n    },\r\n    lineDecorationsWidth: 0,\r\n    overviewRulerBorder: false,\r\n    scrollBeyondLastLine: false,\r\n    renderLineHighlight: 'none',\r\n    fixedOverflowWidgets: true,\r\n    acceptSuggestionOnEnter: 'smart',\r\n    minimap: {\r\n      enabled: false\r\n    }\r\n  };\r\n\r\n}\r\n"]}