Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Ctrl-X: Cut line on no selection #7212

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion src/editor/EditorCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,43 @@ define(function (require, exports, module) {
// Do nothing. The shell will call the native handler for the command.
return (new $.Deferred()).reject().promise();
}

/**
* @private
* Cuts the selected text of editor to clipboard. If there are cursors (empty selections) then the selected lines
* (which the cursors are active at) will be cut to clipboard.
* @param (!Editor) editor The editor to operate on.
*/
function cut(editor) {
// Returns true if the selection is cursor (i.e. no text selected).
function _isCursor(selection) {
return selection.start.line === selection.end.line && selection.start.ch === selection.end.ch;
}

editor = editor || EditorManager.getFocusedEditor();
if (!editor) {
return;
}

//Get the cursors (no-text selections) and ranges (text selections).
var _selections = _.groupBy(editor.getSelections(), function (selection) { return _isCursor(selection) ? "cursors" : "ranges"; });

// Convert all cursors to line selections.
var _convertedCursors = _.pluck(editor.convertToLineSelections(_selections.cursors, {expandEndAtStartOfLine: true, mergeAdjacent: false}), "selectionForEdit");

// Concat old ranges and new cursor selections.
var _newSelections = _convertedCursors;
if (_selections.ranges) {
_newSelections = _newSelections.concat(_selections.ranges);
}

// Set the new selections.
editor.setSelections(_newSelections);

// Since the shell needs to perform the actual cut to clipboard, and the cursors now have been
// transformed to line selections, the command can be ignored in order for the native shell to do the cutting.
return ignoreCommand();
}

function _handleSelectAll() {
var result = new $.Deferred(),
Expand Down Expand Up @@ -1080,7 +1117,7 @@ define(function (require, exports, module) {

CommandManager.register(Strings.CMD_UNDO, Commands.EDIT_UNDO, handleUndo);
CommandManager.register(Strings.CMD_REDO, Commands.EDIT_REDO, handleRedo);
CommandManager.register(Strings.CMD_CUT, Commands.EDIT_CUT, ignoreCommand);
CommandManager.register(Strings.CMD_CUT, Commands.EDIT_CUT, cut);
CommandManager.register(Strings.CMD_COPY, Commands.EDIT_COPY, ignoreCommand);
CommandManager.register(Strings.CMD_PASTE, Commands.EDIT_PASTE, ignoreCommand);
CommandManager.register(Strings.CMD_SELECT_ALL, Commands.EDIT_SELECT_ALL, _handleSelectAll);
Expand Down
43 changes: 43 additions & 0 deletions test/spec/EditorCommandHandlers-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3489,5 +3489,48 @@ define(function (require, exports, module) {
});
});
});

describe("Cut command", function () {
beforeEach(setupFullEditor);

it("should not alter selection", function () {
var _selection = {start: {line: 1, ch: 1}, end: {line: 1, ch: 2}};
myEditor.setSelection(_selection.start, _selection.end);
CommandManager.execute(Commands.EDIT_CUT, myEditor);

expectSelection(_selection);
});

it("should convert cursor to line selection", function () {
myEditor.setCursorPos({line: 1, ch: 5});
CommandManager.execute(Commands.EDIT_CUT, myEditor);

expectSelection({start: {line: 1, ch: 0}, end: {line: 2, ch: 0}});
});

describe("with multiple selections", function () {
it("should convert cursors to line selections", function () {
myEditor.setSelections([{start: {line: 1, ch: 1}, end: {line: 1, ch: 1}},
{start: {line: 2, ch: 4}, end: {line: 2, ch: 6}},
{start: {line: 4, ch: 5}, end: {line: 4, ch: 5}}]);
CommandManager.execute(Commands.EDIT_CUT, myEditor);

expectSelections([{start: {line: 1, ch: 0}, end: {line: 2, ch: 0}, reversed: false, primary: false},
{start: {line: 2, ch: 4}, end: {line: 2, ch: 6}, reversed: false, primary: false},
{start: {line: 4, ch: 0}, end: {line: 5, ch: 0}, reversed: false, primary: true}]);
});

it("should be able to handle overlapping cursor and selections", function () {
myEditor.setSelections([{start: {line: 1, ch: 1}, end: {line: 1, ch: 1}},
{start: {line: 1, ch: 3}, end: {line: 1, ch: 3}},
{start: {line: 3, ch: 4}, end: {line: 3, ch: 6}},
{start: {line: 3, ch: 8}, end: {line: 3, ch: 8}}]);
CommandManager.execute(Commands.EDIT_CUT, myEditor);

expectSelections([{start: {line: 1, ch: 0}, end: {line: 2, ch: 0}, reversed: false, primary: false},
{start: {line: 3, ch: 0}, end: {line: 4, ch: 0}, reversed: false, primary: true}]);
});
});
});
});
});