diff --git a/notebook/static/notebook/js/actions.js b/notebook/static/notebook/js/actions.js index ba40fe2183..c99df730d6 100644 --- a/notebook/static/notebook/js/actions.js +++ b/notebook/static/notebook/js/actions.js @@ -235,8 +235,8 @@ define([ } }, 'split-cell-at-cursor': { - cmd: i18n.msg._('split cell at cursor'), - help : i18n.msg._('split cell at cursor'), + cmd: i18n.msg._('split cell at cursor(s)'), + help : i18n.msg._('split cell at cursor(s)'), help_index : 'ea', handler : function (env) { env.notebook.split_cell(); diff --git a/notebook/static/notebook/js/cell.js b/notebook/static/notebook/js/cell.js index 20a7e5deb2..023b3d3756 100644 --- a/notebook/static/notebook/js/cell.js +++ b/notebook/static/notebook/js/cell.js @@ -586,6 +586,52 @@ define([ return text; }; + + /** + * @return {Array} - the text between cursors and within selections (multicursor/sorted) + * @method get_split_text + **/ + Cell.prototype.get_split_text = function () { + var ranges = this.code_mirror.listSelections(); + + var cursors = [{line: 0, ch: 0}]; + + for (var i = 0; i < ranges.length; i++) { + // append both to handle selections + if (ranges[i].head.sticky == 'before') { + cursors.push(ranges[i].anchor); + cursors.push(ranges[i].head); + } else { + cursors.push(ranges[i].head); + cursors.push(ranges[i].anchor); + } + } + + var last_line_num = this.code_mirror.lineCount()-1; + var last_line_len = this.code_mirror.getLine(last_line_num).length; + var end = {line:last_line_num, ch:last_line_len}; + cursors.push(end); + + // Cursors is now sorted, but likely has duplicates due to anchor and head being the same for cursors + var locations = [cursors[0]]; + for (var i = 1; i < cursors.length; i++) { + var last = locations[locations.length-1]; + var current = cursors[i]; + if ((last.line != current.line) || (last.ch != current.ch)) { + locations.push(cursors[i]); + } + } + + // Split text + var text_list = []; + for (var i = 1; i < locations.length; i++) { + var text = this.code_mirror.getRange(locations[i-1], locations[i]); + text = text.replace(/^\n+/, '').replace(/\n+$/, ''); // removes newlines at beginning and end + text_list.push(text); + } + return text_list; + }; + /** * Show/Hide CodeMirror LineNumber * @method show_line_numbers diff --git a/notebook/static/notebook/js/notebook.js b/notebook/static/notebook/js/notebook.js index 6e2f86f4e4..0e7ce37cec 100644 --- a/notebook/static/notebook/js/notebook.js +++ b/notebook/static/notebook/js/notebook.js @@ -1755,18 +1755,19 @@ define([ Notebook.prototype.split_cell = function () { var cell = this.get_selected_cell(); if (cell.is_splittable()) { - var texta = cell.get_pre_cursor(); - var textb = cell.get_post_cursor(); - // current cell becomes the second one + var text_list = cell.get_split_text(); + for (var i = 0; i < text_list.length-1; i++) { + // Create new cell with same type + var new_cell = this.insert_cell_above(cell.cell_type); + // Unrender the new cell so we can call set_text. + new_cell.unrender(); + new_cell.set_text(text_list[i]); + // Duplicate metadata + new_cell.metadata = JSON.parse(JSON.stringify(cell.metadata)); + } + // Original cell becomes the last one // so we don't need to worry about selection - cell.set_text(textb); - // create new cell with same type - var new_cell = this.insert_cell_above(cell.cell_type); - // Unrender the new cell so we can call set_text. - new_cell.unrender(); - new_cell.set_text(texta); - // duplicate metadata - new_cell.metadata = JSON.parse(JSON.stringify(cell.metadata)); + cell.set_text(text_list[text_list.length-1]); } };