import { Delayer } from "../../../../base/common/async.mjs";
import { Disposable } from "../../../../base/common/lifecycle.mjs";
import { escapeRegExpCharacters } from "../../../../base/common/strings.mjs";
import { registerMultiEditorAction, MultiEditorAction, registerEditorContribution, registerEditorAction, EditorCommand, registerEditorCommand, EditorAction } from "../../../browser/editorExtensions.mjs";
import { EditorContextKeys } from "../../../common/editorContextKeys.mjs";
import { FIND_IDS, CONTEXT_FIND_WIDGET_VISIBLE, ToggleCaseSensitiveKeybinding, ToggleWholeWordKeybinding, ToggleRegexKeybinding, ToggleSearchScopeKeybinding, TogglePreserveCaseKeybinding, CONTEXT_REPLACE_INPUT_FOCUSED, CONTEXT_FIND_INPUT_FOCUSED, FindModelBoundToEditorModel } from "./findModel.mjs";
import { FindOptionsWidget } from "./findOptionsWidget.mjs";
import { FindReplaceState } from "./findState.mjs";
import { FindWidget } from "./findWidget.mjs";
import { localize } from "../../../../nls.mjs";
import { MenuId } from "../../../../platform/actions/common/actions.mjs";
import { IClipboardService } from "../../../../platform/clipboard/common/clipboardService.mjs";
import { IContextKeyService, ContextKeyExpr } from "../../../../platform/contextkey/common/contextkey.mjs";
import { IContextViewService } from "../../../../platform/contextview/browser/contextView.mjs";
import { IKeybindingService } from "../../../../platform/keybinding/common/keybinding.mjs";
import { INotificationService } from "../../../../platform/notification/common/notification.mjs";
import { IStorageService } from "../../../../platform/storage/common/storage.mjs";
import { IThemeService } from "../../../../platform/theme/common/themeService.mjs";
var __decorate = globalThis && globalThis.__decorate || function(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  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;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = globalThis && globalThis.__param || function(paramIndex, decorator) {
  return function(target, key) {
    decorator(target, key, paramIndex);
  };
};
var __awaiter = globalThis && globalThis.__awaiter || function(thisArg, _arguments, P, generator) {
  function adopt(value) {
    return value instanceof P ? value : new P(function(resolve) {
      resolve(value);
    });
  }
  return new (P || (P = Promise))(function(resolve, reject) {
    function fulfilled(value) {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    }
    function rejected(value) {
      try {
        step(generator["throw"](value));
      } catch (e) {
        reject(e);
      }
    }
    function step(result) {
      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
    }
    step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
};
const SEARCH_STRING_MAX_LENGTH = 524288;
function getSelectionSearchString(editor, seedSearchStringFromSelection = "single", seedSearchStringFromNonEmptySelection = false) {
  if (!editor.hasModel()) {
    return null;
  }
  const selection = editor.getSelection();
  if (seedSearchStringFromSelection === "single" && selection.startLineNumber === selection.endLineNumber || seedSearchStringFromSelection === "multiple") {
    if (selection.isEmpty()) {
      const wordAtPosition = editor.getConfiguredWordAtPosition(selection.getStartPosition());
      if (wordAtPosition && false === seedSearchStringFromNonEmptySelection) {
        return wordAtPosition.word;
      }
    } else {
      if (editor.getModel().getValueLengthInRange(selection) < SEARCH_STRING_MAX_LENGTH) {
        return editor.getModel().getValueInRange(selection);
      }
    }
  }
  return null;
}
let CommonFindController = class CommonFindController2 extends Disposable {
  constructor(editor, contextKeyService, storageService, clipboardService) {
    super();
    this._editor = editor;
    this._findWidgetVisible = CONTEXT_FIND_WIDGET_VISIBLE.bindTo(contextKeyService);
    this._contextKeyService = contextKeyService;
    this._storageService = storageService;
    this._clipboardService = clipboardService;
    this._updateHistoryDelayer = new Delayer(500);
    this._state = this._register(new FindReplaceState());
    this.loadQueryState();
    this._register(this._state.onFindReplaceStateChange((e) => this._onStateChanged(e)));
    this._model = null;
    this._register(this._editor.onDidChangeModel(() => {
      let shouldRestartFind = this._editor.getModel() && this._state.isRevealed;
      this.disposeModel();
      this._state.change({
        searchScope: null,
        matchCase: this._storageService.getBoolean("editor.matchCase", 1, false),
        wholeWord: this._storageService.getBoolean("editor.wholeWord", 1, false),
        isRegex: this._storageService.getBoolean("editor.isRegex", 1, false),
        preserveCase: this._storageService.getBoolean("editor.preserveCase", 1, false)
      }, false);
      if (shouldRestartFind) {
        this._start({
          forceRevealReplace: false,
          seedSearchStringFromSelection: "none",
          seedSearchStringFromNonEmptySelection: false,
          seedSearchStringFromGlobalClipboard: false,
          shouldFocus: 0,
          shouldAnimate: false,
          updateSearchScope: false,
          loop: this._editor.getOption(
            35
            /* find */
          ).loop
        });
      }
    }));
  }
  get editor() {
    return this._editor;
  }
  static get(editor) {
    return editor.getContribution(CommonFindController2.ID);
  }
  dispose() {
    this.disposeModel();
    super.dispose();
  }
  disposeModel() {
    if (this._model) {
      this._model.dispose();
      this._model = null;
    }
  }
  _onStateChanged(e) {
    this.saveQueryState(e);
    if (e.isRevealed) {
      if (this._state.isRevealed) {
        this._findWidgetVisible.set(true);
      } else {
        this._findWidgetVisible.reset();
        this.disposeModel();
      }
    }
    if (e.searchString) {
      this.setGlobalBufferTerm(this._state.searchString);
    }
  }
  saveQueryState(e) {
    if (e.isRegex) {
      this._storageService.store(
        "editor.isRegex",
        this._state.actualIsRegex,
        1,
        0
        /* USER */
      );
    }
    if (e.wholeWord) {
      this._storageService.store(
        "editor.wholeWord",
        this._state.actualWholeWord,
        1,
        0
        /* USER */
      );
    }
    if (e.matchCase) {
      this._storageService.store(
        "editor.matchCase",
        this._state.actualMatchCase,
        1,
        0
        /* USER */
      );
    }
    if (e.preserveCase) {
      this._storageService.store(
        "editor.preserveCase",
        this._state.actualPreserveCase,
        1,
        0
        /* USER */
      );
    }
  }
  loadQueryState() {
    this._state.change({
      matchCase: this._storageService.getBoolean("editor.matchCase", 1, this._state.matchCase),
      wholeWord: this._storageService.getBoolean("editor.wholeWord", 1, this._state.wholeWord),
      isRegex: this._storageService.getBoolean("editor.isRegex", 1, this._state.isRegex),
      preserveCase: this._storageService.getBoolean("editor.preserveCase", 1, this._state.preserveCase)
    }, false);
  }
  isFindInputFocused() {
    return !!CONTEXT_FIND_INPUT_FOCUSED.getValue(this._contextKeyService);
  }
  getState() {
    return this._state;
  }
  closeFindWidget() {
    this._state.change({
      isRevealed: false,
      searchScope: null
    }, false);
    this._editor.focus();
  }
  toggleCaseSensitive() {
    this._state.change({ matchCase: !this._state.matchCase }, false);
    if (!this._state.isRevealed) {
      this.highlightFindOptions();
    }
  }
  toggleWholeWords() {
    this._state.change({ wholeWord: !this._state.wholeWord }, false);
    if (!this._state.isRevealed) {
      this.highlightFindOptions();
    }
  }
  toggleRegex() {
    this._state.change({ isRegex: !this._state.isRegex }, false);
    if (!this._state.isRevealed) {
      this.highlightFindOptions();
    }
  }
  togglePreserveCase() {
    this._state.change({ preserveCase: !this._state.preserveCase }, false);
    if (!this._state.isRevealed) {
      this.highlightFindOptions();
    }
  }
  toggleSearchScope() {
    if (this._state.searchScope) {
      this._state.change({ searchScope: null }, true);
    } else {
      if (this._editor.hasModel()) {
        let selections = this._editor.getSelections();
        selections.map((selection) => {
          if (selection.endColumn === 1 && selection.endLineNumber > selection.startLineNumber) {
            selection = selection.setEndPosition(selection.endLineNumber - 1, this._editor.getModel().getLineMaxColumn(selection.endLineNumber - 1));
          }
          if (!selection.isEmpty()) {
            return selection;
          }
          return null;
        }).filter((element) => !!element);
        if (selections.length) {
          this._state.change({ searchScope: selections }, true);
        }
      }
    }
  }
  setSearchString(searchString) {
    if (this._state.isRegex) {
      searchString = escapeRegExpCharacters(searchString);
    }
    this._state.change({ searchString }, false);
  }
  highlightFindOptions(ignoreWhenVisible = false) {
  }
  _start(opts, newState) {
    return __awaiter(this, void 0, void 0, function* () {
      this.disposeModel();
      if (!this._editor.hasModel()) {
        return;
      }
      let stateChanges = Object.assign(Object.assign({}, newState), { isRevealed: true });
      if (opts.seedSearchStringFromSelection === "single") {
        let selectionSearchString = getSelectionSearchString(this._editor, opts.seedSearchStringFromSelection, opts.seedSearchStringFromNonEmptySelection);
        if (selectionSearchString) {
          if (this._state.isRegex) {
            stateChanges.searchString = escapeRegExpCharacters(selectionSearchString);
          } else {
            stateChanges.searchString = selectionSearchString;
          }
        }
      } else if (opts.seedSearchStringFromSelection === "multiple" && !opts.updateSearchScope) {
        let selectionSearchString = getSelectionSearchString(this._editor, opts.seedSearchStringFromSelection);
        if (selectionSearchString) {
          stateChanges.searchString = selectionSearchString;
        }
      }
      if (!stateChanges.searchString && opts.seedSearchStringFromGlobalClipboard) {
        let selectionSearchString = yield this.getGlobalBufferTerm();
        if (!this._editor.hasModel()) {
          return;
        }
        if (selectionSearchString) {
          stateChanges.searchString = selectionSearchString;
        }
      }
      if (opts.forceRevealReplace || stateChanges.isReplaceRevealed) {
        stateChanges.isReplaceRevealed = true;
      } else if (!this._findWidgetVisible.get()) {
        stateChanges.isReplaceRevealed = false;
      }
      if (opts.updateSearchScope) {
        let currentSelections = this._editor.getSelections();
        if (currentSelections.some((selection) => !selection.isEmpty())) {
          stateChanges.searchScope = currentSelections;
        }
      }
      stateChanges.loop = opts.loop;
      this._state.change(stateChanges, false);
      if (!this._model) {
        this._model = new FindModelBoundToEditorModel(this._editor, this._state);
      }
    });
  }
  start(opts, newState) {
    return this._start(opts, newState);
  }
  moveToNextMatch() {
    if (this._model) {
      this._model.moveToNextMatch();
      return true;
    }
    return false;
  }
  moveToPrevMatch() {
    if (this._model) {
      this._model.moveToPrevMatch();
      return true;
    }
    return false;
  }
  replace() {
    if (this._model) {
      this._model.replace();
      return true;
    }
    return false;
  }
  replaceAll() {
    if (this._model) {
      this._model.replaceAll();
      return true;
    }
    return false;
  }
  selectAllMatches() {
    if (this._model) {
      this._model.selectAllMatches();
      this._editor.focus();
      return true;
    }
    return false;
  }
  getGlobalBufferTerm() {
    return __awaiter(this, void 0, void 0, function* () {
      if (this._editor.getOption(
        35
        /* find */
      ).globalFindClipboard && this._editor.hasModel() && !this._editor.getModel().isTooLargeForSyncing()) {
        return this._clipboardService.readFindText();
      }
      return "";
    });
  }
  setGlobalBufferTerm(text) {
    if (this._editor.getOption(
      35
      /* find */
    ).globalFindClipboard && this._editor.hasModel() && !this._editor.getModel().isTooLargeForSyncing()) {
      this._clipboardService.writeFindText(text);
    }
  }
};
CommonFindController.ID = "editor.contrib.findController";
CommonFindController = __decorate([
  __param(1, IContextKeyService),
  __param(2, IStorageService),
  __param(3, IClipboardService)
], CommonFindController);
let FindController = class FindController2 extends CommonFindController {
  constructor(editor, _contextViewService, _contextKeyService, _keybindingService, _themeService, _notificationService, _storageService, clipboardService) {
    super(editor, _contextKeyService, _storageService, clipboardService);
    this._contextViewService = _contextViewService;
    this._keybindingService = _keybindingService;
    this._themeService = _themeService;
    this._notificationService = _notificationService;
    this._widget = null;
    this._findOptionsWidget = null;
  }
  _start(opts, newState) {
    const _super = Object.create(null, {
      _start: { get: () => super._start }
    });
    return __awaiter(this, void 0, void 0, function* () {
      if (!this._widget) {
        this._createFindWidget();
      }
      const selection = this._editor.getSelection();
      let updateSearchScope = false;
      switch (this._editor.getOption(
        35
        /* find */
      ).autoFindInSelection) {
        case "always":
          updateSearchScope = true;
          break;
        case "never":
          updateSearchScope = false;
          break;
        case "multiline": {
          const isSelectionMultipleLine = !!selection && selection.startLineNumber !== selection.endLineNumber;
          updateSearchScope = isSelectionMultipleLine;
          break;
        }
      }
      opts.updateSearchScope = opts.updateSearchScope || updateSearchScope;
      yield _super._start.call(this, opts, newState);
      if (this._widget) {
        if (opts.shouldFocus === 2) {
          this._widget.focusReplaceInput();
        } else if (opts.shouldFocus === 1) {
          this._widget.focusFindInput();
        }
      }
    });
  }
  highlightFindOptions(ignoreWhenVisible = false) {
    if (!this._widget) {
      this._createFindWidget();
    }
    if (this._state.isRevealed && !ignoreWhenVisible) {
      this._widget.highlightFindOptions();
    } else {
      this._findOptionsWidget.highlightFindOptions();
    }
  }
  _createFindWidget() {
    this._widget = this._register(new FindWidget(this._editor, this, this._state, this._contextViewService, this._keybindingService, this._contextKeyService, this._themeService, this._storageService, this._notificationService));
    this._findOptionsWidget = this._register(new FindOptionsWidget(this._editor, this._state, this._keybindingService, this._themeService));
  }
};
FindController = __decorate([
  __param(1, IContextViewService),
  __param(2, IContextKeyService),
  __param(3, IKeybindingService),
  __param(4, IThemeService),
  __param(5, INotificationService),
  __param(6, IStorageService),
  __param(7, IClipboardService)
], FindController);
const StartFindAction = registerMultiEditorAction(new MultiEditorAction({
  id: FIND_IDS.StartFindAction,
  label: localize("startFindAction", "Find"),
  alias: "Find",
  precondition: ContextKeyExpr.or(EditorContextKeys.focus, ContextKeyExpr.has("editorIsOpen")),
  kbOpts: {
    kbExpr: null,
    primary: 2048 | 36,
    weight: 100
    /* EditorContrib */
  },
  menuOpts: {
    menuId: MenuId.MenubarEditMenu,
    group: "3_find",
    title: localize({ key: "miFind", comment: ["&& denotes a mnemonic"] }, "&&Find"),
    order: 1
  }
}));
StartFindAction.addImplementation(0, (accessor, editor, args) => {
  const controller = CommonFindController.get(editor);
  if (!controller) {
    return false;
  }
  return controller.start({
    forceRevealReplace: false,
    seedSearchStringFromSelection: editor.getOption(
      35
      /* find */
    ).seedSearchStringFromSelection !== "never" ? "single" : "none",
    seedSearchStringFromNonEmptySelection: editor.getOption(
      35
      /* find */
    ).seedSearchStringFromSelection === "selection",
    seedSearchStringFromGlobalClipboard: editor.getOption(
      35
      /* find */
    ).globalFindClipboard,
    shouldFocus: 1,
    shouldAnimate: true,
    updateSearchScope: false,
    loop: editor.getOption(
      35
      /* find */
    ).loop
  });
});
const findArgDescription = {
  description: "Open a new In-Editor Find Widget.",
  args: [{
    name: "Open a new In-Editor Find Widget args",
    schema: {
      properties: {
        searchString: { type: "string" },
        replaceString: { type: "string" },
        regex: { type: "boolean" },
        regexOverride: {
          type: "number",
          description: localize("actions.find.isRegexOverride", 'Overrides "Use Regular Expression" flag.\nThe flag will not be saved for the future.\n0: Do Nothing\n1: True\n2: False')
        },
        wholeWord: { type: "boolean" },
        wholeWordOverride: {
          type: "number",
          description: localize("actions.find.wholeWordOverride", 'Overrides "Match Whole Word" flag.\nThe flag will not be saved for the future.\n0: Do Nothing\n1: True\n2: False')
        },
        matchCase: { type: "boolean" },
        matchCaseOverride: {
          type: "number",
          description: localize("actions.find.matchCaseOverride", 'Overrides "Math Case" flag.\nThe flag will not be saved for the future.\n0: Do Nothing\n1: True\n2: False')
        },
        preserveCase: { type: "boolean" },
        preserveCaseOverride: {
          type: "number",
          description: localize("actions.find.preserveCaseOverride", 'Overrides "Preserve Case" flag.\nThe flag will not be saved for the future.\n0: Do Nothing\n1: True\n2: False')
        },
        findInSelection: { type: "boolean" }
      }
    }
  }]
};
class StartFindWithArgsAction extends EditorAction {
  constructor() {
    super({
      id: FIND_IDS.StartFindWithArgs,
      label: localize("startFindWithArgsAction", "Find With Arguments"),
      alias: "Find With Arguments",
      precondition: void 0,
      kbOpts: {
        kbExpr: null,
        primary: 0,
        weight: 100
        /* EditorContrib */
      },
      description: findArgDescription
    });
  }
  run(accessor, editor, args) {
    return __awaiter(this, void 0, void 0, function* () {
      const controller = CommonFindController.get(editor);
      if (controller) {
        const newState = args ? {
          searchString: args.searchString,
          replaceString: args.replaceString,
          isReplaceRevealed: args.replaceString !== void 0,
          isRegex: args.isRegex,
          // isRegexOverride: args.regexOverride,
          wholeWord: args.matchWholeWord,
          // wholeWordOverride: args.wholeWordOverride,
          matchCase: args.isCaseSensitive,
          // matchCaseOverride: args.matchCaseOverride,
          preserveCase: args.preserveCase
          // preserveCaseOverride: args.preserveCaseOverride,
        } : {};
        yield controller.start({
          forceRevealReplace: false,
          seedSearchStringFromSelection: controller.getState().searchString.length === 0 && editor.getOption(
            35
            /* find */
          ).seedSearchStringFromSelection !== "never" ? "single" : "none",
          seedSearchStringFromNonEmptySelection: editor.getOption(
            35
            /* find */
          ).seedSearchStringFromSelection === "selection",
          seedSearchStringFromGlobalClipboard: true,
          shouldFocus: 1,
          shouldAnimate: true,
          updateSearchScope: (args === null || args === void 0 ? void 0 : args.findInSelection) || false,
          loop: editor.getOption(
            35
            /* find */
          ).loop
        }, newState);
        controller.setGlobalBufferTerm(controller.getState().searchString);
      }
    });
  }
}
class StartFindWithSelectionAction extends EditorAction {
  constructor() {
    super({
      id: FIND_IDS.StartFindWithSelection,
      label: localize("startFindWithSelectionAction", "Find With Selection"),
      alias: "Find With Selection",
      precondition: void 0,
      kbOpts: {
        kbExpr: null,
        primary: 0,
        mac: {
          primary: 2048 | 35
        },
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(accessor, editor) {
    return __awaiter(this, void 0, void 0, function* () {
      const controller = CommonFindController.get(editor);
      if (controller) {
        yield controller.start({
          forceRevealReplace: false,
          seedSearchStringFromSelection: "multiple",
          seedSearchStringFromNonEmptySelection: false,
          seedSearchStringFromGlobalClipboard: false,
          shouldFocus: 0,
          shouldAnimate: true,
          updateSearchScope: false,
          loop: editor.getOption(
            35
            /* find */
          ).loop
        });
        controller.setGlobalBufferTerm(controller.getState().searchString);
      }
    });
  }
}
class MatchFindAction extends EditorAction {
  run(accessor, editor) {
    return __awaiter(this, void 0, void 0, function* () {
      const controller = CommonFindController.get(editor);
      if (controller && !this._run(controller)) {
        yield controller.start({
          forceRevealReplace: false,
          seedSearchStringFromSelection: controller.getState().searchString.length === 0 && editor.getOption(
            35
            /* find */
          ).seedSearchStringFromSelection !== "never" ? "single" : "none",
          seedSearchStringFromNonEmptySelection: editor.getOption(
            35
            /* find */
          ).seedSearchStringFromSelection === "selection",
          seedSearchStringFromGlobalClipboard: true,
          shouldFocus: 0,
          shouldAnimate: true,
          updateSearchScope: false,
          loop: editor.getOption(
            35
            /* find */
          ).loop
        });
        this._run(controller);
      }
    });
  }
}
class NextMatchFindAction extends MatchFindAction {
  constructor() {
    super({
      id: FIND_IDS.NextMatchFindAction,
      label: localize("findNextMatchAction", "Find Next"),
      alias: "Find Next",
      precondition: void 0,
      kbOpts: [{
        kbExpr: EditorContextKeys.focus,
        primary: 61,
        mac: { primary: 2048 | 37, secondary: [
          61
          /* F3 */
        ] },
        weight: 100
        /* EditorContrib */
      }, {
        kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, CONTEXT_FIND_INPUT_FOCUSED),
        primary: 3,
        weight: 100
        /* EditorContrib */
      }]
    });
  }
  _run(controller) {
    const result = controller.moveToNextMatch();
    if (result) {
      controller.editor.pushUndoStop();
      return true;
    }
    return false;
  }
}
class PreviousMatchFindAction extends MatchFindAction {
  constructor() {
    super({
      id: FIND_IDS.PreviousMatchFindAction,
      label: localize("findPreviousMatchAction", "Find Previous"),
      alias: "Find Previous",
      precondition: void 0,
      kbOpts: [
        {
          kbExpr: EditorContextKeys.focus,
          primary: 1024 | 61,
          mac: { primary: 2048 | 1024 | 37, secondary: [
            1024 | 61
            /* F3 */
          ] },
          weight: 100
          /* EditorContrib */
        },
        {
          kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, CONTEXT_FIND_INPUT_FOCUSED),
          primary: 1024 | 3,
          weight: 100
          /* EditorContrib */
        }
      ]
    });
  }
  _run(controller) {
    return controller.moveToPrevMatch();
  }
}
class SelectionMatchFindAction extends EditorAction {
  run(accessor, editor) {
    return __awaiter(this, void 0, void 0, function* () {
      const controller = CommonFindController.get(editor);
      if (!controller) {
        return;
      }
      const seedSearchStringFromNonEmptySelection = editor.getOption(
        35
        /* find */
      ).seedSearchStringFromSelection === "selection";
      let selectionSearchString = null;
      if (editor.getOption(
        35
        /* find */
      ).seedSearchStringFromSelection !== "never") {
        selectionSearchString = getSelectionSearchString(editor, "single", seedSearchStringFromNonEmptySelection);
      }
      if (selectionSearchString) {
        controller.setSearchString(selectionSearchString);
      }
      if (!this._run(controller)) {
        yield controller.start({
          forceRevealReplace: false,
          seedSearchStringFromSelection: editor.getOption(
            35
            /* find */
          ).seedSearchStringFromSelection !== "never" ? "single" : "none",
          seedSearchStringFromNonEmptySelection,
          seedSearchStringFromGlobalClipboard: false,
          shouldFocus: 0,
          shouldAnimate: true,
          updateSearchScope: false,
          loop: editor.getOption(
            35
            /* find */
          ).loop
        });
        this._run(controller);
      }
    });
  }
}
class NextSelectionMatchFindAction extends SelectionMatchFindAction {
  constructor() {
    super({
      id: FIND_IDS.NextSelectionMatchFindAction,
      label: localize("nextSelectionMatchFindAction", "Find Next Selection"),
      alias: "Find Next Selection",
      precondition: void 0,
      kbOpts: {
        kbExpr: EditorContextKeys.focus,
        primary: 2048 | 61,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  _run(controller) {
    return controller.moveToNextMatch();
  }
}
class PreviousSelectionMatchFindAction extends SelectionMatchFindAction {
  constructor() {
    super({
      id: FIND_IDS.PreviousSelectionMatchFindAction,
      label: localize("previousSelectionMatchFindAction", "Find Previous Selection"),
      alias: "Find Previous Selection",
      precondition: void 0,
      kbOpts: {
        kbExpr: EditorContextKeys.focus,
        primary: 2048 | 1024 | 61,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  _run(controller) {
    return controller.moveToPrevMatch();
  }
}
const StartFindReplaceAction = registerMultiEditorAction(new MultiEditorAction({
  id: FIND_IDS.StartFindReplaceAction,
  label: localize("startReplace", "Replace"),
  alias: "Replace",
  precondition: ContextKeyExpr.or(EditorContextKeys.focus, ContextKeyExpr.has("editorIsOpen")),
  kbOpts: {
    kbExpr: null,
    primary: 2048 | 38,
    mac: {
      primary: 2048 | 512 | 36
      /* KeyF */
    },
    weight: 100
    /* EditorContrib */
  },
  menuOpts: {
    menuId: MenuId.MenubarEditMenu,
    group: "3_find",
    title: localize({ key: "miReplace", comment: ["&& denotes a mnemonic"] }, "&&Replace"),
    order: 2
  }
}));
StartFindReplaceAction.addImplementation(0, (accessor, editor, args) => {
  if (!editor.hasModel() || editor.getOption(
    81
    /* readOnly */
  )) {
    return false;
  }
  const controller = CommonFindController.get(editor);
  if (!controller) {
    return false;
  }
  const currentSelection = editor.getSelection();
  const findInputFocused = controller.isFindInputFocused();
  const seedSearchStringFromSelection = !currentSelection.isEmpty() && currentSelection.startLineNumber === currentSelection.endLineNumber && editor.getOption(
    35
    /* find */
  ).seedSearchStringFromSelection !== "never" && !findInputFocused;
  const shouldFocus = findInputFocused || seedSearchStringFromSelection ? 2 : 1;
  return controller.start({
    forceRevealReplace: true,
    seedSearchStringFromSelection: seedSearchStringFromSelection ? "single" : "none",
    seedSearchStringFromNonEmptySelection: editor.getOption(
      35
      /* find */
    ).seedSearchStringFromSelection === "selection",
    seedSearchStringFromGlobalClipboard: editor.getOption(
      35
      /* find */
    ).seedSearchStringFromSelection !== "never",
    shouldFocus,
    shouldAnimate: true,
    updateSearchScope: false,
    loop: editor.getOption(
      35
      /* find */
    ).loop
  });
});
registerEditorContribution(CommonFindController.ID, FindController);
registerEditorAction(StartFindWithArgsAction);
registerEditorAction(StartFindWithSelectionAction);
registerEditorAction(NextMatchFindAction);
registerEditorAction(PreviousMatchFindAction);
registerEditorAction(NextSelectionMatchFindAction);
registerEditorAction(PreviousSelectionMatchFindAction);
const FindCommand = EditorCommand.bindToContribution(CommonFindController.get);
registerEditorCommand(new FindCommand({
  id: FIND_IDS.CloseFindWidgetCommand,
  precondition: CONTEXT_FIND_WIDGET_VISIBLE,
  handler: (x) => x.closeFindWidget(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, ContextKeyExpr.not("isComposing")),
    primary: 9,
    secondary: [
      1024 | 9
      /* Escape */
    ]
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.ToggleCaseSensitiveCommand,
  precondition: void 0,
  handler: (x) => x.toggleCaseSensitive(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: EditorContextKeys.focus,
    primary: ToggleCaseSensitiveKeybinding.primary,
    mac: ToggleCaseSensitiveKeybinding.mac,
    win: ToggleCaseSensitiveKeybinding.win,
    linux: ToggleCaseSensitiveKeybinding.linux
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.ToggleWholeWordCommand,
  precondition: void 0,
  handler: (x) => x.toggleWholeWords(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: EditorContextKeys.focus,
    primary: ToggleWholeWordKeybinding.primary,
    mac: ToggleWholeWordKeybinding.mac,
    win: ToggleWholeWordKeybinding.win,
    linux: ToggleWholeWordKeybinding.linux
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.ToggleRegexCommand,
  precondition: void 0,
  handler: (x) => x.toggleRegex(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: EditorContextKeys.focus,
    primary: ToggleRegexKeybinding.primary,
    mac: ToggleRegexKeybinding.mac,
    win: ToggleRegexKeybinding.win,
    linux: ToggleRegexKeybinding.linux
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.ToggleSearchScopeCommand,
  precondition: void 0,
  handler: (x) => x.toggleSearchScope(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: EditorContextKeys.focus,
    primary: ToggleSearchScopeKeybinding.primary,
    mac: ToggleSearchScopeKeybinding.mac,
    win: ToggleSearchScopeKeybinding.win,
    linux: ToggleSearchScopeKeybinding.linux
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.TogglePreserveCaseCommand,
  precondition: void 0,
  handler: (x) => x.togglePreserveCase(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: EditorContextKeys.focus,
    primary: TogglePreserveCaseKeybinding.primary,
    mac: TogglePreserveCaseKeybinding.mac,
    win: TogglePreserveCaseKeybinding.win,
    linux: TogglePreserveCaseKeybinding.linux
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.ReplaceOneAction,
  precondition: CONTEXT_FIND_WIDGET_VISIBLE,
  handler: (x) => x.replace(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: EditorContextKeys.focus,
    primary: 2048 | 1024 | 22
    /* Digit1 */
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.ReplaceOneAction,
  precondition: CONTEXT_FIND_WIDGET_VISIBLE,
  handler: (x) => x.replace(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, CONTEXT_REPLACE_INPUT_FOCUSED),
    primary: 3
    /* Enter */
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.ReplaceAllAction,
  precondition: CONTEXT_FIND_WIDGET_VISIBLE,
  handler: (x) => x.replaceAll(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: EditorContextKeys.focus,
    primary: 2048 | 512 | 3
    /* Enter */
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.ReplaceAllAction,
  precondition: CONTEXT_FIND_WIDGET_VISIBLE,
  handler: (x) => x.replaceAll(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, CONTEXT_REPLACE_INPUT_FOCUSED),
    primary: void 0,
    mac: {
      primary: 2048 | 3
    }
  }
}));
registerEditorCommand(new FindCommand({
  id: FIND_IDS.SelectAllMatchesAction,
  precondition: CONTEXT_FIND_WIDGET_VISIBLE,
  handler: (x) => x.selectAllMatches(),
  kbOpts: {
    weight: 100 + 5,
    kbExpr: EditorContextKeys.focus,
    primary: 512 | 3
    /* Enter */
  }
}));
export {
  CommonFindController,
  FindController,
  MatchFindAction,
  NextMatchFindAction,
  NextSelectionMatchFindAction,
  PreviousMatchFindAction,
  PreviousSelectionMatchFindAction,
  SelectionMatchFindAction,
  StartFindAction,
  StartFindReplaceAction,
  StartFindWithArgsAction,
  StartFindWithSelectionAction,
  getSelectionSearchString
};
