Skip to content

Commit cf5cb64

Browse files
authored
Implemented Split Cell for multicursor (#4824)
* Added multicursor cell splitting * Empty cells are ok, fixed cursor equality check
1 parent d406b8c commit cf5cb64

File tree

3 files changed

+60
-13
lines changed

3 files changed

+60
-13
lines changed

notebook/static/notebook/js/actions.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ define([
235235
}
236236
},
237237
'split-cell-at-cursor': {
238-
cmd: i18n.msg._('split cell at cursor'),
239-
help : i18n.msg._('split cell at cursor'),
238+
cmd: i18n.msg._('split cell at cursor(s)'),
239+
help : i18n.msg._('split cell at cursor(s)'),
240240
help_index : 'ea',
241241
handler : function (env) {
242242
env.notebook.split_cell();

notebook/static/notebook/js/cell.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,52 @@ define([
586586
return text;
587587
};
588588

589+
590+
/**
591+
* @return {Array} - the text between cursors and within selections (multicursor/sorted)
592+
* @method get_split_text
593+
**/
594+
Cell.prototype.get_split_text = function () {
595+
var ranges = this.code_mirror.listSelections();
596+
597+
var cursors = [{line: 0, ch: 0}];
598+
599+
for (var i = 0; i < ranges.length; i++) {
600+
// append both to handle selections
601+
if (ranges[i].head.sticky == 'before') {
602+
cursors.push(ranges[i].anchor);
603+
cursors.push(ranges[i].head);
604+
} else {
605+
cursors.push(ranges[i].head);
606+
cursors.push(ranges[i].anchor);
607+
}
608+
}
609+
610+
var last_line_num = this.code_mirror.lineCount()-1;
611+
var last_line_len = this.code_mirror.getLine(last_line_num).length;
612+
var end = {line:last_line_num, ch:last_line_len};
613+
cursors.push(end);
614+
615+
// Cursors is now sorted, but likely has duplicates due to anchor and head being the same for cursors
616+
var locations = [cursors[0]];
617+
for (var i = 1; i < cursors.length; i++) {
618+
var last = locations[locations.length-1];
619+
var current = cursors[i];
620+
if ((last.line != current.line) || (last.ch != current.ch)) {
621+
locations.push(cursors[i]);
622+
}
623+
}
624+
625+
// Split text
626+
var text_list = [];
627+
for (var i = 1; i < locations.length; i++) {
628+
var text = this.code_mirror.getRange(locations[i-1], locations[i]);
629+
text = text.replace(/^\n+/, '').replace(/\n+$/, ''); // removes newlines at beginning and end
630+
text_list.push(text);
631+
}
632+
return text_list;
633+
};
634+
589635
/**
590636
* Show/Hide CodeMirror LineNumber
591637
* @method show_line_numbers

notebook/static/notebook/js/notebook.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,18 +1756,19 @@ define([
17561756
Notebook.prototype.split_cell = function () {
17571757
var cell = this.get_selected_cell();
17581758
if (cell.is_splittable()) {
1759-
var texta = cell.get_pre_cursor();
1760-
var textb = cell.get_post_cursor();
1761-
// current cell becomes the second one
1759+
var text_list = cell.get_split_text();
1760+
for (var i = 0; i < text_list.length-1; i++) {
1761+
// Create new cell with same type
1762+
var new_cell = this.insert_cell_above(cell.cell_type);
1763+
// Unrender the new cell so we can call set_text.
1764+
new_cell.unrender();
1765+
new_cell.set_text(text_list[i]);
1766+
// Duplicate metadata
1767+
new_cell.metadata = JSON.parse(JSON.stringify(cell.metadata));
1768+
}
1769+
// Original cell becomes the last one
17621770
// so we don't need to worry about selection
1763-
cell.set_text(textb);
1764-
// create new cell with same type
1765-
var new_cell = this.insert_cell_above(cell.cell_type);
1766-
// Unrender the new cell so we can call set_text.
1767-
new_cell.unrender();
1768-
new_cell.set_text(texta);
1769-
// duplicate metadata
1770-
new_cell.metadata = JSON.parse(JSON.stringify(cell.metadata));
1771+
cell.set_text(text_list[text_list.length-1]);
17711772
}
17721773
};
17731774

0 commit comments

Comments
 (0)