"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const keyCodes = require("../../../../base/common/keyCodes.js");
const coreCommands = require("../../../browser/coreCommands.js");
const editorExtensions = require("../../../browser/editorExtensions.js");
const replaceCommand = require("../../../common/commands/replaceCommand.js");
const trimTrailingWhitespaceCommand = require("../../../common/commands/trimTrailingWhitespaceCommand.js");
const cursorTypeOperations = require("../../../common/cursor/cursorTypeOperations.js");
const editOperation = require("../../../common/core/editOperation.js");
const position = require("../../../common/core/position.js");
const range = require("../../../common/core/range.js");
const selection = require("../../../common/core/selection.js");
const editorContextKeys = require("../../../common/editorContextKeys.js");
const copyLinesCommand = require("./copyLinesCommand.js");
const moveLinesCommand = require("./moveLinesCommand.js");
const sortLinesCommand = require("./sortLinesCommand.js");
const nls = require("../../../../nls.js");
const actions = require("../../../../platform/actions/common/actions.js");
class AbstractCopyLinesAction extends editorExtensions.EditorAction {
  constructor(down, opts) {
    super(opts);
    this.down = down;
  }
  run(_accessor, editor) {
    if (!editor.hasModel()) {
      return;
    }
    const selections = editor.getSelections().map((selection2, index) => ({ selection: selection2, index, ignore: false }));
    selections.sort((a, b) => range.Range.compareRangesUsingStarts(a.selection, b.selection));
    let prev = selections[0];
    for (let i = 1; i < selections.length; i++) {
      const curr = selections[i];
      if (prev.selection.endLineNumber === curr.selection.startLineNumber) {
        if (prev.index < curr.index) {
          curr.ignore = true;
        } else {
          prev.ignore = true;
          prev = curr;
        }
      }
    }
    const commands = [];
    for (const selection2 of selections) {
      commands.push(new copyLinesCommand.CopyLinesCommand(selection2.selection, this.down, selection2.ignore));
    }
    editor.pushUndoStop();
    editor.executeCommands(this.id, commands);
    editor.pushUndoStop();
  }
}
class CopyLinesUpAction extends AbstractCopyLinesAction {
  constructor() {
    super(false, {
      id: "editor.action.copyLinesUpAction",
      label: nls.localize("lines.copyUp", "Copy Line Up"),
      alias: "Copy Line Up",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 512 | 1024 | 16,
        linux: {
          primary: 2048 | 512 | 1024 | 16
          /* UpArrow */
        },
        weight: 100
        /* EditorContrib */
      },
      menuOpts: {
        menuId: actions.MenuId.MenubarSelectionMenu,
        group: "2_line",
        title: nls.localize({ key: "miCopyLinesUp", comment: ["&& denotes a mnemonic"] }, "&&Copy Line Up"),
        order: 1
      }
    });
  }
}
class CopyLinesDownAction extends AbstractCopyLinesAction {
  constructor() {
    super(true, {
      id: "editor.action.copyLinesDownAction",
      label: nls.localize("lines.copyDown", "Copy Line Down"),
      alias: "Copy Line Down",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 512 | 1024 | 18,
        linux: {
          primary: 2048 | 512 | 1024 | 18
          /* DownArrow */
        },
        weight: 100
        /* EditorContrib */
      },
      menuOpts: {
        menuId: actions.MenuId.MenubarSelectionMenu,
        group: "2_line",
        title: nls.localize({ key: "miCopyLinesDown", comment: ["&& denotes a mnemonic"] }, "Co&&py Line Down"),
        order: 2
      }
    });
  }
}
class DuplicateSelectionAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.duplicateSelection",
      label: nls.localize("duplicateSelection", "Duplicate Selection"),
      alias: "Duplicate Selection",
      precondition: editorContextKeys.EditorContextKeys.writable,
      menuOpts: {
        menuId: actions.MenuId.MenubarSelectionMenu,
        group: "2_line",
        title: nls.localize({ key: "miDuplicateSelection", comment: ["&& denotes a mnemonic"] }, "&&Duplicate Selection"),
        order: 5
      }
    });
  }
  run(accessor, editor, args) {
    if (!editor.hasModel()) {
      return;
    }
    const commands = [];
    const selections = editor.getSelections();
    const model = editor.getModel();
    for (const selection$1 of selections) {
      if (selection$1.isEmpty()) {
        commands.push(new copyLinesCommand.CopyLinesCommand(selection$1, true));
      } else {
        const insertSelection = new selection.Selection(selection$1.endLineNumber, selection$1.endColumn, selection$1.endLineNumber, selection$1.endColumn);
        commands.push(new replaceCommand.ReplaceCommandThatSelectsText(insertSelection, model.getValueInRange(selection$1)));
      }
    }
    editor.pushUndoStop();
    editor.executeCommands(this.id, commands);
    editor.pushUndoStop();
  }
}
class AbstractMoveLinesAction extends editorExtensions.EditorAction {
  constructor(down, opts) {
    super(opts);
    this.down = down;
  }
  run(_accessor, editor) {
    let commands = [];
    let selections = editor.getSelections() || [];
    const autoIndent = editor.getOption(
      9
      /* autoIndent */
    );
    for (const selection2 of selections) {
      commands.push(new moveLinesCommand.MoveLinesCommand(selection2, this.down, autoIndent));
    }
    editor.pushUndoStop();
    editor.executeCommands(this.id, commands);
    editor.pushUndoStop();
  }
}
class MoveLinesUpAction extends AbstractMoveLinesAction {
  constructor() {
    super(false, {
      id: "editor.action.moveLinesUpAction",
      label: nls.localize("lines.moveUp", "Move Line Up"),
      alias: "Move Line Up",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 512 | 16,
        linux: {
          primary: 512 | 16
          /* UpArrow */
        },
        weight: 100
        /* EditorContrib */
      },
      menuOpts: {
        menuId: actions.MenuId.MenubarSelectionMenu,
        group: "2_line",
        title: nls.localize({ key: "miMoveLinesUp", comment: ["&& denotes a mnemonic"] }, "Mo&&ve Line Up"),
        order: 3
      }
    });
  }
}
class MoveLinesDownAction extends AbstractMoveLinesAction {
  constructor() {
    super(true, {
      id: "editor.action.moveLinesDownAction",
      label: nls.localize("lines.moveDown", "Move Line Down"),
      alias: "Move Line Down",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 512 | 18,
        linux: {
          primary: 512 | 18
          /* DownArrow */
        },
        weight: 100
        /* EditorContrib */
      },
      menuOpts: {
        menuId: actions.MenuId.MenubarSelectionMenu,
        group: "2_line",
        title: nls.localize({ key: "miMoveLinesDown", comment: ["&& denotes a mnemonic"] }, "Move &&Line Down"),
        order: 4
      }
    });
  }
}
class AbstractSortLinesAction extends editorExtensions.EditorAction {
  constructor(descending, opts) {
    super(opts);
    this.descending = descending;
  }
  run(_accessor, editor) {
    const selections = editor.getSelections() || [];
    for (const selection2 of selections) {
      if (!sortLinesCommand.SortLinesCommand.canRun(editor.getModel(), selection2, this.descending)) {
        return;
      }
    }
    let commands = [];
    for (let i = 0, len = selections.length; i < len; i++) {
      commands[i] = new sortLinesCommand.SortLinesCommand(selections[i], this.descending);
    }
    editor.pushUndoStop();
    editor.executeCommands(this.id, commands);
    editor.pushUndoStop();
  }
}
class SortLinesAscendingAction extends AbstractSortLinesAction {
  constructor() {
    super(false, {
      id: "editor.action.sortLinesAscending",
      label: nls.localize("lines.sortAscending", "Sort Lines Ascending"),
      alias: "Sort Lines Ascending",
      precondition: editorContextKeys.EditorContextKeys.writable
    });
  }
}
class SortLinesDescendingAction extends AbstractSortLinesAction {
  constructor() {
    super(true, {
      id: "editor.action.sortLinesDescending",
      label: nls.localize("lines.sortDescending", "Sort Lines Descending"),
      alias: "Sort Lines Descending",
      precondition: editorContextKeys.EditorContextKeys.writable
    });
  }
}
class DeleteDuplicateLinesAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.removeDuplicateLines",
      label: nls.localize("lines.deleteDuplicates", "Delete Duplicate Lines"),
      alias: "Delete Duplicate Lines",
      precondition: editorContextKeys.EditorContextKeys.writable
    });
  }
  run(_accessor, editor) {
    if (!editor.hasModel()) {
      return;
    }
    let model = editor.getModel();
    if (model.getLineCount() === 1 && model.getLineMaxColumn(1) === 1) {
      return;
    }
    let edits = [];
    let endCursorState = [];
    let linesDeleted = 0;
    for (let selection$1 of editor.getSelections()) {
      let uniqueLines = /* @__PURE__ */ new Set();
      let lines = [];
      for (let i = selection$1.startLineNumber; i <= selection$1.endLineNumber; i++) {
        let line = model.getLineContent(i);
        if (uniqueLines.has(line)) {
          continue;
        }
        lines.push(line);
        uniqueLines.add(line);
      }
      let selectionToReplace = new selection.Selection(selection$1.startLineNumber, 1, selection$1.endLineNumber, model.getLineMaxColumn(selection$1.endLineNumber));
      let adjustedSelectionStart = selection$1.startLineNumber - linesDeleted;
      let finalSelection = new selection.Selection(adjustedSelectionStart, 1, adjustedSelectionStart + lines.length - 1, lines[lines.length - 1].length);
      edits.push(editOperation.EditOperation.replace(selectionToReplace, lines.join("\n")));
      endCursorState.push(finalSelection);
      linesDeleted += selection$1.endLineNumber - selection$1.startLineNumber + 1 - lines.length;
    }
    editor.pushUndoStop();
    editor.executeEdits(this.id, edits, endCursorState);
    editor.pushUndoStop();
  }
}
class TrimTrailingWhitespaceAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: TrimTrailingWhitespaceAction.ID,
      label: nls.localize("lines.trimTrailingWhitespace", "Trim Trailing Whitespace"),
      alias: "Trim Trailing Whitespace",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: keyCodes.KeyChord(
          2048 | 41,
          2048 | 54
          /* KeyX */
        ),
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor, args) {
    let cursors = [];
    if (args.reason === "auto-save") {
      cursors = (editor.getSelections() || []).map((s) => new position.Position(s.positionLineNumber, s.positionColumn));
    }
    let selection2 = editor.getSelection();
    if (selection2 === null) {
      return;
    }
    let command = new trimTrailingWhitespaceCommand.TrimTrailingWhitespaceCommand(selection2, cursors);
    editor.pushUndoStop();
    editor.executeCommands(this.id, [command]);
    editor.pushUndoStop();
  }
}
TrimTrailingWhitespaceAction.ID = "editor.action.trimTrailingWhitespace";
class DeleteLinesAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.deleteLines",
      label: nls.localize("lines.delete", "Delete Line"),
      alias: "Delete Line",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.textInputFocus,
        primary: 2048 | 1024 | 41,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor) {
    if (!editor.hasModel()) {
      return;
    }
    let ops = this._getLinesToRemove(editor);
    let model = editor.getModel();
    if (model.getLineCount() === 1 && model.getLineMaxColumn(1) === 1) {
      return;
    }
    let linesDeleted = 0;
    let edits = [];
    let cursorState = [];
    for (let i = 0, len = ops.length; i < len; i++) {
      const op = ops[i];
      let startLineNumber = op.startLineNumber;
      let endLineNumber = op.endLineNumber;
      let startColumn = 1;
      let endColumn = model.getLineMaxColumn(endLineNumber);
      if (endLineNumber < model.getLineCount()) {
        endLineNumber += 1;
        endColumn = 1;
      } else if (startLineNumber > 1) {
        startLineNumber -= 1;
        startColumn = model.getLineMaxColumn(startLineNumber);
      }
      edits.push(editOperation.EditOperation.replace(new selection.Selection(startLineNumber, startColumn, endLineNumber, endColumn), ""));
      cursorState.push(new selection.Selection(startLineNumber - linesDeleted, op.positionColumn, startLineNumber - linesDeleted, op.positionColumn));
      linesDeleted += op.endLineNumber - op.startLineNumber + 1;
    }
    editor.pushUndoStop();
    editor.executeEdits(this.id, edits, cursorState);
    editor.pushUndoStop();
  }
  _getLinesToRemove(editor) {
    let operations = editor.getSelections().map((s) => {
      let endLineNumber = s.endLineNumber;
      if (s.startLineNumber < s.endLineNumber && s.endColumn === 1) {
        endLineNumber -= 1;
      }
      return {
        startLineNumber: s.startLineNumber,
        selectionStartColumn: s.selectionStartColumn,
        endLineNumber,
        positionColumn: s.positionColumn
      };
    });
    operations.sort((a, b) => {
      if (a.startLineNumber === b.startLineNumber) {
        return a.endLineNumber - b.endLineNumber;
      }
      return a.startLineNumber - b.startLineNumber;
    });
    let mergedOperations = [];
    let previousOperation = operations[0];
    for (let i = 1; i < operations.length; i++) {
      if (previousOperation.endLineNumber + 1 >= operations[i].startLineNumber) {
        previousOperation.endLineNumber = operations[i].endLineNumber;
      } else {
        mergedOperations.push(previousOperation);
        previousOperation = operations[i];
      }
    }
    mergedOperations.push(previousOperation);
    return mergedOperations;
  }
}
class IndentLinesAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.indentLines",
      label: nls.localize("lines.indent", "Indent Line"),
      alias: "Indent Line",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 2048 | 89,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor) {
    const viewModel = editor._getViewModel();
    if (!viewModel) {
      return;
    }
    editor.pushUndoStop();
    editor.executeCommands(this.id, cursorTypeOperations.TypeOperations.indent(viewModel.cursorConfig, editor.getModel(), editor.getSelections()));
    editor.pushUndoStop();
  }
}
class OutdentLinesAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.outdentLines",
      label: nls.localize("lines.outdent", "Outdent Line"),
      alias: "Outdent Line",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 2048 | 87,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor) {
    coreCommands.CoreEditingCommands.Outdent.runEditorCommand(_accessor, editor, null);
  }
}
class InsertLineBeforeAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.insertLineBefore",
      label: nls.localize("lines.insertBefore", "Insert Line Above"),
      alias: "Insert Line Above",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 2048 | 1024 | 3,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor) {
    const viewModel = editor._getViewModel();
    if (!viewModel) {
      return;
    }
    editor.pushUndoStop();
    editor.executeCommands(this.id, cursorTypeOperations.TypeOperations.lineInsertBefore(viewModel.cursorConfig, editor.getModel(), editor.getSelections()));
  }
}
class InsertLineAfterAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.insertLineAfter",
      label: nls.localize("lines.insertAfter", "Insert Line Below"),
      alias: "Insert Line Below",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 2048 | 3,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor) {
    const viewModel = editor._getViewModel();
    if (!viewModel) {
      return;
    }
    editor.pushUndoStop();
    editor.executeCommands(this.id, cursorTypeOperations.TypeOperations.lineInsertAfter(viewModel.cursorConfig, editor.getModel(), editor.getSelections()));
  }
}
class AbstractDeleteAllToBoundaryAction extends editorExtensions.EditorAction {
  run(_accessor, editor) {
    if (!editor.hasModel()) {
      return;
    }
    const primaryCursor = editor.getSelection();
    let rangesToDelete = this._getRangesToDelete(editor);
    let effectiveRanges = [];
    for (let i = 0, count = rangesToDelete.length - 1; i < count; i++) {
      let range$1 = rangesToDelete[i];
      let nextRange = rangesToDelete[i + 1];
      if (range.Range.intersectRanges(range$1, nextRange) === null) {
        effectiveRanges.push(range$1);
      } else {
        rangesToDelete[i + 1] = range.Range.plusRange(range$1, nextRange);
      }
    }
    effectiveRanges.push(rangesToDelete[rangesToDelete.length - 1]);
    let endCursorState = this._getEndCursorState(primaryCursor, effectiveRanges);
    let edits = effectiveRanges.map((range2) => {
      return editOperation.EditOperation.replace(range2, "");
    });
    editor.pushUndoStop();
    editor.executeEdits(this.id, edits, endCursorState);
    editor.pushUndoStop();
  }
}
class DeleteAllLeftAction extends AbstractDeleteAllToBoundaryAction {
  constructor() {
    super({
      id: "deleteAllLeft",
      label: nls.localize("lines.deleteAllLeft", "Delete All Left"),
      alias: "Delete All Left",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.textInputFocus,
        primary: 0,
        mac: {
          primary: 2048 | 1
          /* Backspace */
        },
        weight: 100
        /* EditorContrib */
      }
    });
  }
  _getEndCursorState(primaryCursor, rangesToDelete) {
    let endPrimaryCursor = null;
    let endCursorState = [];
    let deletedLines = 0;
    rangesToDelete.forEach((range2) => {
      let endCursor;
      if (range2.endColumn === 1 && deletedLines > 0) {
        let newStartLine = range2.startLineNumber - deletedLines;
        endCursor = new selection.Selection(newStartLine, range2.startColumn, newStartLine, range2.startColumn);
      } else {
        endCursor = new selection.Selection(range2.startLineNumber, range2.startColumn, range2.startLineNumber, range2.startColumn);
      }
      deletedLines += range2.endLineNumber - range2.startLineNumber;
      if (range2.intersectRanges(primaryCursor)) {
        endPrimaryCursor = endCursor;
      } else {
        endCursorState.push(endCursor);
      }
    });
    if (endPrimaryCursor) {
      endCursorState.unshift(endPrimaryCursor);
    }
    return endCursorState;
  }
  _getRangesToDelete(editor) {
    let selections = editor.getSelections();
    if (selections === null) {
      return [];
    }
    let rangesToDelete = selections;
    let model = editor.getModel();
    if (model === null) {
      return [];
    }
    rangesToDelete.sort(range.Range.compareRangesUsingStarts);
    rangesToDelete = rangesToDelete.map((selection2) => {
      if (selection2.isEmpty()) {
        if (selection2.startColumn === 1) {
          let deleteFromLine = Math.max(1, selection2.startLineNumber - 1);
          let deleteFromColumn = selection2.startLineNumber === 1 ? 1 : model.getLineContent(deleteFromLine).length + 1;
          return new range.Range(deleteFromLine, deleteFromColumn, selection2.startLineNumber, 1);
        } else {
          return new range.Range(selection2.startLineNumber, 1, selection2.startLineNumber, selection2.startColumn);
        }
      } else {
        return new range.Range(selection2.startLineNumber, 1, selection2.endLineNumber, selection2.endColumn);
      }
    });
    return rangesToDelete;
  }
}
class DeleteAllRightAction extends AbstractDeleteAllToBoundaryAction {
  constructor() {
    super({
      id: "deleteAllRight",
      label: nls.localize("lines.deleteAllRight", "Delete All Right"),
      alias: "Delete All Right",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.textInputFocus,
        primary: 0,
        mac: { primary: 256 | 41, secondary: [
          2048 | 20
          /* Delete */
        ] },
        weight: 100
        /* EditorContrib */
      }
    });
  }
  _getEndCursorState(primaryCursor, rangesToDelete) {
    let endPrimaryCursor = null;
    let endCursorState = [];
    for (let i = 0, len = rangesToDelete.length, offset = 0; i < len; i++) {
      let range2 = rangesToDelete[i];
      let endCursor = new selection.Selection(range2.startLineNumber - offset, range2.startColumn, range2.startLineNumber - offset, range2.startColumn);
      if (range2.intersectRanges(primaryCursor)) {
        endPrimaryCursor = endCursor;
      } else {
        endCursorState.push(endCursor);
      }
    }
    if (endPrimaryCursor) {
      endCursorState.unshift(endPrimaryCursor);
    }
    return endCursorState;
  }
  _getRangesToDelete(editor) {
    let model = editor.getModel();
    if (model === null) {
      return [];
    }
    let selections = editor.getSelections();
    if (selections === null) {
      return [];
    }
    let rangesToDelete = selections.map((sel) => {
      if (sel.isEmpty()) {
        const maxColumn = model.getLineMaxColumn(sel.startLineNumber);
        if (sel.startColumn === maxColumn) {
          return new range.Range(sel.startLineNumber, sel.startColumn, sel.startLineNumber + 1, 1);
        } else {
          return new range.Range(sel.startLineNumber, sel.startColumn, sel.startLineNumber, maxColumn);
        }
      }
      return sel;
    });
    rangesToDelete.sort(range.Range.compareRangesUsingStarts);
    return rangesToDelete;
  }
}
class JoinLinesAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.joinLines",
      label: nls.localize("lines.joinLines", "Join Lines"),
      alias: "Join Lines",
      precondition: editorContextKeys.EditorContextKeys.writable,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 0,
        mac: {
          primary: 256 | 40
          /* KeyJ */
        },
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor) {
    let selections = editor.getSelections();
    if (selections === null) {
      return;
    }
    let primaryCursor = editor.getSelection();
    if (primaryCursor === null) {
      return;
    }
    selections.sort(range.Range.compareRangesUsingStarts);
    let reducedSelections = [];
    let lastSelection = selections.reduce((previousValue, currentValue) => {
      if (previousValue.isEmpty()) {
        if (previousValue.endLineNumber === currentValue.startLineNumber) {
          if (primaryCursor.equalsSelection(previousValue)) {
            primaryCursor = currentValue;
          }
          return currentValue;
        }
        if (currentValue.startLineNumber > previousValue.endLineNumber + 1) {
          reducedSelections.push(previousValue);
          return currentValue;
        } else {
          return new selection.Selection(previousValue.startLineNumber, previousValue.startColumn, currentValue.endLineNumber, currentValue.endColumn);
        }
      } else {
        if (currentValue.startLineNumber > previousValue.endLineNumber) {
          reducedSelections.push(previousValue);
          return currentValue;
        } else {
          return new selection.Selection(previousValue.startLineNumber, previousValue.startColumn, currentValue.endLineNumber, currentValue.endColumn);
        }
      }
    });
    reducedSelections.push(lastSelection);
    let model = editor.getModel();
    if (model === null) {
      return;
    }
    let edits = [];
    let endCursorState = [];
    let endPrimaryCursor = primaryCursor;
    let lineOffset = 0;
    for (let i = 0, len = reducedSelections.length; i < len; i++) {
      let selection$1 = reducedSelections[i];
      let startLineNumber = selection$1.startLineNumber;
      let startColumn = 1;
      let columnDeltaOffset = 0;
      let endLineNumber, endColumn;
      let selectionEndPositionOffset = model.getLineContent(selection$1.endLineNumber).length - selection$1.endColumn;
      if (selection$1.isEmpty() || selection$1.startLineNumber === selection$1.endLineNumber) {
        let position2 = selection$1.getStartPosition();
        if (position2.lineNumber < model.getLineCount()) {
          endLineNumber = startLineNumber + 1;
          endColumn = model.getLineMaxColumn(endLineNumber);
        } else {
          endLineNumber = position2.lineNumber;
          endColumn = model.getLineMaxColumn(position2.lineNumber);
        }
      } else {
        endLineNumber = selection$1.endLineNumber;
        endColumn = model.getLineMaxColumn(endLineNumber);
      }
      let trimmedLinesContent = model.getLineContent(startLineNumber);
      for (let i2 = startLineNumber + 1; i2 <= endLineNumber; i2++) {
        let lineText = model.getLineContent(i2);
        let firstNonWhitespaceIdx = model.getLineFirstNonWhitespaceColumn(i2);
        if (firstNonWhitespaceIdx >= 1) {
          let insertSpace = true;
          if (trimmedLinesContent === "") {
            insertSpace = false;
          }
          if (insertSpace && (trimmedLinesContent.charAt(trimmedLinesContent.length - 1) === " " || trimmedLinesContent.charAt(trimmedLinesContent.length - 1) === "	")) {
            insertSpace = false;
            trimmedLinesContent = trimmedLinesContent.replace(/[\s\uFEFF\xA0]+$/g, " ");
          }
          let lineTextWithoutIndent = lineText.substr(firstNonWhitespaceIdx - 1);
          trimmedLinesContent += (insertSpace ? " " : "") + lineTextWithoutIndent;
          if (insertSpace) {
            columnDeltaOffset = lineTextWithoutIndent.length + 1;
          } else {
            columnDeltaOffset = lineTextWithoutIndent.length;
          }
        } else {
          columnDeltaOffset = 0;
        }
      }
      let deleteSelection = new range.Range(startLineNumber, startColumn, endLineNumber, endColumn);
      if (!deleteSelection.isEmpty()) {
        let resultSelection;
        if (selection$1.isEmpty()) {
          edits.push(editOperation.EditOperation.replace(deleteSelection, trimmedLinesContent));
          resultSelection = new selection.Selection(deleteSelection.startLineNumber - lineOffset, trimmedLinesContent.length - columnDeltaOffset + 1, startLineNumber - lineOffset, trimmedLinesContent.length - columnDeltaOffset + 1);
        } else {
          if (selection$1.startLineNumber === selection$1.endLineNumber) {
            edits.push(editOperation.EditOperation.replace(deleteSelection, trimmedLinesContent));
            resultSelection = new selection.Selection(selection$1.startLineNumber - lineOffset, selection$1.startColumn, selection$1.endLineNumber - lineOffset, selection$1.endColumn);
          } else {
            edits.push(editOperation.EditOperation.replace(deleteSelection, trimmedLinesContent));
            resultSelection = new selection.Selection(selection$1.startLineNumber - lineOffset, selection$1.startColumn, selection$1.startLineNumber - lineOffset, trimmedLinesContent.length - selectionEndPositionOffset);
          }
        }
        if (range.Range.intersectRanges(deleteSelection, primaryCursor) !== null) {
          endPrimaryCursor = resultSelection;
        } else {
          endCursorState.push(resultSelection);
        }
      }
      lineOffset += deleteSelection.endLineNumber - deleteSelection.startLineNumber;
    }
    endCursorState.unshift(endPrimaryCursor);
    editor.pushUndoStop();
    editor.executeEdits(this.id, edits, endCursorState);
    editor.pushUndoStop();
  }
}
class TransposeAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.transpose",
      label: nls.localize("editor.transpose", "Transpose characters around the cursor"),
      alias: "Transpose characters around the cursor",
      precondition: editorContextKeys.EditorContextKeys.writable
    });
  }
  run(_accessor, editor) {
    let selections = editor.getSelections();
    if (selections === null) {
      return;
    }
    let model = editor.getModel();
    if (model === null) {
      return;
    }
    let commands = [];
    for (let i = 0, len = selections.length; i < len; i++) {
      let selection$1 = selections[i];
      if (!selection$1.isEmpty()) {
        continue;
      }
      let cursor = selection$1.getStartPosition();
      let maxColumn = model.getLineMaxColumn(cursor.lineNumber);
      if (cursor.column >= maxColumn) {
        if (cursor.lineNumber === model.getLineCount()) {
          continue;
        }
        let deleteSelection = new range.Range(cursor.lineNumber, Math.max(1, cursor.column - 1), cursor.lineNumber + 1, 1);
        let chars = model.getValueInRange(deleteSelection).split("").reverse().join("");
        commands.push(new replaceCommand.ReplaceCommand(new selection.Selection(cursor.lineNumber, Math.max(1, cursor.column - 1), cursor.lineNumber + 1, 1), chars));
      } else {
        let deleteSelection = new range.Range(cursor.lineNumber, Math.max(1, cursor.column - 1), cursor.lineNumber, cursor.column + 1);
        let chars = model.getValueInRange(deleteSelection).split("").reverse().join("");
        commands.push(new replaceCommand.ReplaceCommandThatPreservesSelection(deleteSelection, chars, new selection.Selection(cursor.lineNumber, cursor.column + 1, cursor.lineNumber, cursor.column + 1)));
      }
    }
    editor.pushUndoStop();
    editor.executeCommands(this.id, commands);
    editor.pushUndoStop();
  }
}
class AbstractCaseAction extends editorExtensions.EditorAction {
  run(_accessor, editor) {
    const selections = editor.getSelections();
    if (selections === null) {
      return;
    }
    const model = editor.getModel();
    if (model === null) {
      return;
    }
    const wordSeparators = editor.getOption(
      117
      /* wordSeparators */
    );
    const textEdits = [];
    for (const selection2 of selections) {
      if (selection2.isEmpty()) {
        const cursor = selection2.getStartPosition();
        const word = editor.getConfiguredWordAtPosition(cursor);
        if (!word) {
          continue;
        }
        const wordRange = new range.Range(cursor.lineNumber, word.startColumn, cursor.lineNumber, word.endColumn);
        const text = model.getValueInRange(wordRange);
        textEdits.push(editOperation.EditOperation.replace(wordRange, this._modifyText(text, wordSeparators)));
      } else {
        const text = model.getValueInRange(selection2);
        textEdits.push(editOperation.EditOperation.replace(selection2, this._modifyText(text, wordSeparators)));
      }
    }
    editor.pushUndoStop();
    editor.executeEdits(this.id, textEdits);
    editor.pushUndoStop();
  }
}
class UpperCaseAction extends AbstractCaseAction {
  constructor() {
    super({
      id: "editor.action.transformToUppercase",
      label: nls.localize("editor.transformToUppercase", "Transform to Uppercase"),
      alias: "Transform to Uppercase",
      precondition: editorContextKeys.EditorContextKeys.writable
    });
  }
  _modifyText(text, wordSeparators) {
    return text.toLocaleUpperCase();
  }
}
class LowerCaseAction extends AbstractCaseAction {
  constructor() {
    super({
      id: "editor.action.transformToLowercase",
      label: nls.localize("editor.transformToLowercase", "Transform to Lowercase"),
      alias: "Transform to Lowercase",
      precondition: editorContextKeys.EditorContextKeys.writable
    });
  }
  _modifyText(text, wordSeparators) {
    return text.toLocaleLowerCase();
  }
}
class BackwardsCompatibleRegExp {
  constructor(_pattern, _flags) {
    this._pattern = _pattern;
    this._flags = _flags;
    this._actual = null;
    this._evaluated = false;
  }
  get() {
    if (!this._evaluated) {
      this._evaluated = true;
      try {
        this._actual = new RegExp(this._pattern, this._flags);
      } catch (err) {
      }
    }
    return this._actual;
  }
  isSupported() {
    return this.get() !== null;
  }
}
class TitleCaseAction extends AbstractCaseAction {
  constructor() {
    super({
      id: "editor.action.transformToTitlecase",
      label: nls.localize("editor.transformToTitlecase", "Transform to Title Case"),
      alias: "Transform to Title Case",
      precondition: editorContextKeys.EditorContextKeys.writable
    });
  }
  _modifyText(text, wordSeparators) {
    const titleBoundary = TitleCaseAction.titleBoundary.get();
    if (!titleBoundary) {
      return text;
    }
    return text.toLocaleLowerCase().replace(titleBoundary, (b) => b.toLocaleUpperCase());
  }
}
TitleCaseAction.titleBoundary = new BackwardsCompatibleRegExp("(^|[^\\p{L}\\p{N}']|((^|\\P{L})'))\\p{L}", "gmu");
class SnakeCaseAction extends AbstractCaseAction {
  constructor() {
    super({
      id: "editor.action.transformToSnakecase",
      label: nls.localize("editor.transformToSnakecase", "Transform to Snake Case"),
      alias: "Transform to Snake Case",
      precondition: editorContextKeys.EditorContextKeys.writable
    });
  }
  _modifyText(text, wordSeparators) {
    const caseBoundary = SnakeCaseAction.caseBoundary.get();
    const singleLetters = SnakeCaseAction.singleLetters.get();
    if (!caseBoundary || !singleLetters) {
      return text;
    }
    return text.replace(caseBoundary, "$1_$2").replace(singleLetters, "$1_$2$3").toLocaleLowerCase();
  }
}
SnakeCaseAction.caseBoundary = new BackwardsCompatibleRegExp("(\\p{Ll})(\\p{Lu})", "gmu");
SnakeCaseAction.singleLetters = new BackwardsCompatibleRegExp("(\\p{Lu}|\\p{N})(\\p{Lu})(\\p{Ll})", "gmu");
editorExtensions.registerEditorAction(CopyLinesUpAction);
editorExtensions.registerEditorAction(CopyLinesDownAction);
editorExtensions.registerEditorAction(DuplicateSelectionAction);
editorExtensions.registerEditorAction(MoveLinesUpAction);
editorExtensions.registerEditorAction(MoveLinesDownAction);
editorExtensions.registerEditorAction(SortLinesAscendingAction);
editorExtensions.registerEditorAction(SortLinesDescendingAction);
editorExtensions.registerEditorAction(DeleteDuplicateLinesAction);
editorExtensions.registerEditorAction(TrimTrailingWhitespaceAction);
editorExtensions.registerEditorAction(DeleteLinesAction);
editorExtensions.registerEditorAction(IndentLinesAction);
editorExtensions.registerEditorAction(OutdentLinesAction);
editorExtensions.registerEditorAction(InsertLineBeforeAction);
editorExtensions.registerEditorAction(InsertLineAfterAction);
editorExtensions.registerEditorAction(DeleteAllLeftAction);
editorExtensions.registerEditorAction(DeleteAllRightAction);
editorExtensions.registerEditorAction(JoinLinesAction);
editorExtensions.registerEditorAction(TransposeAction);
editorExtensions.registerEditorAction(UpperCaseAction);
editorExtensions.registerEditorAction(LowerCaseAction);
if (SnakeCaseAction.caseBoundary.isSupported() && SnakeCaseAction.singleLetters.isSupported()) {
  editorExtensions.registerEditorAction(SnakeCaseAction);
}
if (TitleCaseAction.titleBoundary.isSupported()) {
  editorExtensions.registerEditorAction(TitleCaseAction);
}
exports.AbstractCaseAction = AbstractCaseAction;
exports.AbstractDeleteAllToBoundaryAction = AbstractDeleteAllToBoundaryAction;
exports.AbstractSortLinesAction = AbstractSortLinesAction;
exports.DeleteAllLeftAction = DeleteAllLeftAction;
exports.DeleteAllRightAction = DeleteAllRightAction;
exports.DeleteDuplicateLinesAction = DeleteDuplicateLinesAction;
exports.DeleteLinesAction = DeleteLinesAction;
exports.DuplicateSelectionAction = DuplicateSelectionAction;
exports.IndentLinesAction = IndentLinesAction;
exports.InsertLineAfterAction = InsertLineAfterAction;
exports.InsertLineBeforeAction = InsertLineBeforeAction;
exports.JoinLinesAction = JoinLinesAction;
exports.LowerCaseAction = LowerCaseAction;
exports.SnakeCaseAction = SnakeCaseAction;
exports.SortLinesAscendingAction = SortLinesAscendingAction;
exports.SortLinesDescendingAction = SortLinesDescendingAction;
exports.TitleCaseAction = TitleCaseAction;
exports.TransposeAction = TransposeAction;
exports.TrimTrailingWhitespaceAction = TrimTrailingWhitespaceAction;
exports.UpperCaseAction = UpperCaseAction;
