|
@@ -88,13 +88,13 @@ export class NotebookActions {
|
|
|
*/
|
|
|
export namespace NotebookActions {
|
|
|
/**
|
|
|
- * Split the active cell into two cells.
|
|
|
+ * Split the active cell into two or more cells.
|
|
|
*
|
|
|
* @param widget - The target notebook widget.
|
|
|
*
|
|
|
* #### Notes
|
|
|
* It will preserve the existing mode.
|
|
|
- * The second cell will be activated.
|
|
|
+ * The last cell will be activated.
|
|
|
* The existing selection will be cleared.
|
|
|
* The leading whitespace in the second cell will be removed.
|
|
|
* If there is no content, two empty cells will be created.
|
|
@@ -114,35 +114,58 @@ export namespace NotebookActions {
|
|
|
const index = notebook.activeCellIndex;
|
|
|
const child = notebook.widgets[index];
|
|
|
const editor = child.editor;
|
|
|
- const position = editor.getCursorPosition();
|
|
|
- const offset = editor.getOffsetAt(position);
|
|
|
+ const selections = editor.getSelections();
|
|
|
const orig = child.model.value.text;
|
|
|
|
|
|
- // Create new models to preserve history.
|
|
|
- const clone0 = Private.cloneCell(nbModel, child.model);
|
|
|
- const clone1 = Private.cloneCell(nbModel, child.model);
|
|
|
+ let offsets = [0];
|
|
|
+
|
|
|
+ for (let i = 0; i < selections.length; i++) {
|
|
|
+ // append start and end to handle selections
|
|
|
+ // cursors will have same start and end
|
|
|
+ let start = editor.getOffsetAt(selections[i].start);
|
|
|
+ let end = editor.getOffsetAt(selections[i].end);
|
|
|
+ if (start < end) {
|
|
|
+ offsets.push(start);
|
|
|
+ offsets.push(end);
|
|
|
+ } else if (end < start) {
|
|
|
+ offsets.push(end);
|
|
|
+ offsets.push(start);
|
|
|
+ } else {
|
|
|
+ offsets.push(start);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ offsets.push(orig.length);
|
|
|
|
|
|
- if (clone0.type === 'code') {
|
|
|
- (clone0 as ICodeCellModel).outputs.clear();
|
|
|
+ let clones: ICellModel[] = [];
|
|
|
+ for (let i = 0; i + 1 < offsets.length; i++) {
|
|
|
+ let clone = Private.cloneCell(nbModel, child.model);
|
|
|
+ clones.push(clone);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let i = 0; i < clones.length; i++) {
|
|
|
+ if (i !== clones.length - 1 && clones[i].type === 'code') {
|
|
|
+ (clones[i] as ICodeCellModel).outputs.clear();
|
|
|
+ }
|
|
|
+ clones[i].value.text = orig
|
|
|
+ .slice(offsets[i], offsets[i + 1])
|
|
|
+ .replace(/^\n+/, '')
|
|
|
+ .replace(/\n+$/, '');
|
|
|
}
|
|
|
- clone0.value.text = orig
|
|
|
- .slice(0, offset)
|
|
|
- .replace(/^\n+/, '')
|
|
|
- .replace(/\n+$/, '');
|
|
|
- clone1.value.text = orig
|
|
|
- .slice(offset)
|
|
|
- .replace(/^\n+/, '')
|
|
|
- .replace(/\n+$/, '');
|
|
|
|
|
|
- // Make the changes while preserving history.
|
|
|
const cells = nbModel.cells;
|
|
|
|
|
|
cells.beginCompoundOperation();
|
|
|
- cells.set(index, clone0);
|
|
|
- cells.insert(index + 1, clone1);
|
|
|
+ for (let i = 0; i < clones.length; i++) {
|
|
|
+ if (i === 0) {
|
|
|
+ cells.set(index, clones[i]);
|
|
|
+ } else {
|
|
|
+ cells.insert(index + i, clones[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
cells.endCompoundOperation();
|
|
|
|
|
|
- notebook.activeCellIndex++;
|
|
|
+ notebook.activeCellIndex = index + clones.length - 1;
|
|
|
Private.handleState(notebook, state);
|
|
|
}
|
|
|
|