import { registerEditorCommand, EditorCommand } from "../../../browser/editorExtensions.mjs";
import { RawContextKey, IContextKeyService } from "../../../../platform/contextkey/common/contextkey.mjs";
import { CancellationTokenSource } from "../../../../base/common/cancellation.mjs";
import { LinkedList } from "../../../../base/common/linkedList.mjs";
import { createDecorator } from "../../../../platform/instantiation/common/instantiation.mjs";
import { registerSingleton } from "../../../../platform/instantiation/common/extensions.mjs";
import { localize } from "../../../../nls.mjs";
const IEditorCancellationTokens = createDecorator("IEditorCancelService");
const ctxCancellableOperation = new RawContextKey("cancellableOperation", false, localize("cancellableOperation", "Whether the editor runs a cancellable operation, e.g. like 'Peek References'"));
registerSingleton(IEditorCancellationTokens, class {
  constructor() {
    this._tokens = /* @__PURE__ */ new WeakMap();
  }
  add(editor, cts) {
    let data = this._tokens.get(editor);
    if (!data) {
      data = editor.invokeWithinContext((accessor) => {
        const key = ctxCancellableOperation.bindTo(accessor.get(IContextKeyService));
        const tokens = new LinkedList();
        return { key, tokens };
      });
      this._tokens.set(editor, data);
    }
    let removeFn;
    data.key.set(true);
    removeFn = data.tokens.push(cts);
    return () => {
      if (removeFn) {
        removeFn();
        data.key.set(!data.tokens.isEmpty());
        removeFn = void 0;
      }
    };
  }
  cancel(editor) {
    const data = this._tokens.get(editor);
    if (!data) {
      return;
    }
    const cts = data.tokens.pop();
    if (cts) {
      cts.cancel();
      data.key.set(!data.tokens.isEmpty());
    }
  }
}, true);
class EditorKeybindingCancellationTokenSource extends CancellationTokenSource {
  constructor(editor, parent) {
    super(parent);
    this.editor = editor;
    this._unregister = editor.invokeWithinContext((accessor) => accessor.get(IEditorCancellationTokens).add(editor, this));
  }
  dispose() {
    this._unregister();
    super.dispose();
  }
}
registerEditorCommand(new class extends EditorCommand {
  constructor() {
    super({
      id: "editor.cancelOperation",
      kbOpts: {
        weight: 100,
        primary: 9
        /* Escape */
      },
      precondition: ctxCancellableOperation
    });
  }
  runEditorCommand(accessor, editor) {
    accessor.get(IEditorCancellationTokens).cancel(editor);
  }
}());
export {
  EditorKeybindingCancellationTokenSource
};
