First attempt at multi-cell selection

It works, but I'm not quite happy with how it works
Thomas Kluyver 11 years ago
parent 6992965967
commit 450597d754

@ -100,6 +100,28 @@ define(function(require){
}
}
},
'extend-selection-previous' : {
help: 'extend selection above',
help_index : 'dc',
handler : function (env) {
var index = env.notebook.get_selected_index();
if (index !== (env.notebook.ncells()-1) && index !== null) {
env.notebook.select_prev(true);
env.notebook.focus_cell();
}
}
},
'extend-selection-next' : {
help: 'extend selection below',
help_index : 'dd',
handler : function (env) {
var index = env.notebook.get_selected_index();
if (index !== (env.notebook.ncells()-1) && index !== null) {
env.notebook.select_next(true);
env.notebook.focus_cell();
}
}
},
'cut-selected-cell' : {
icon: 'fa-cut',
help_index : 'ee',

@ -55,6 +55,7 @@ define([
this.placeholder = config.placeholder || '';
this.selected = false;
this.in_selection = false;
this.rendered = false;
this.mode = 'command';
@ -142,7 +143,7 @@ define([
* Call after this.element exists to initialize the css classes
* related to selected, rendered and mode.
*/
if (this.selected) {
if (this.in_selection) {
this.element.addClass('selected');
} else {
this.element.addClass('unselected');
@ -254,6 +255,7 @@ define([
this.element.addClass('selected');
this.element.removeClass('unselected');
this.selected = true;
this.in_selection = true;
return true;
} else {
return false;
@ -261,19 +263,20 @@ define([
};
/**
* handle cell level logic when a cell is unselected
* handle cell level logic when the cursor moves away from a cell
* @method unselect
* @param {bool} leave_selected - true to move cursor away and extend selection
* @return is the action being taken
*/
Cell.prototype.unselect = function () {
if (this.selected) {
Cell.prototype.unselect = function (leave_selected) {
var was_selected_cell = this.selected;
this.selected = false;
if ((!leave_selected) && this.in_selection) {
this.in_selection = false;
this.element.addClass('unselected');
this.element.removeClass('selected');
this.selected = false;
return true;
} else {
return false;
}
return was_selected_cell;
};
/**

@ -535,14 +535,14 @@ define([
};
/**
* handle cell level logic when a cell is unselected
* handle cell level logic when the cursor moves away from a cell
* @method unselect
* @return is the action being taken
*/
CodeCell.prototype.unselect = function () {
var cont = Cell.prototype.unselect.apply(this);
CodeCell.prototype.unselect = function (leave_selected) {
var cont = Cell.prototype.unselect.apply(this, [leave_selected]);
if (cont) {
// When a code cell is usnelected, make sure that the corresponding
// When a code cell is unselected, make sure that the corresponding
// tooltip and completer to that cell is closed.
this.tooltip.remove_and_cancel_tooltip(true);
if (this.completer !== null) {

@ -98,6 +98,8 @@ define([
'up' : 'ipython.select-previous-cell',
'k' : 'ipython.select-previous-cell',
'j' : 'ipython.select-next-cell',
'shift-k': 'ipython.extend-selection-previous',
'shift-j': 'ipython.extend-selection-next',
'x' : 'ipython.cut-selected-cell',
'c' : 'ipython.copy-selected-cell',
'v' : 'ipython.paste-cell-after',

@ -600,6 +600,17 @@ define(function (require) {
return result;
};
/**
* Get an array of the cells in the currently selected range
*
* @return {Array} The selected cells
*/
Notebook.prototype.get_selected_cells = function () {
return this.get_cells().filter(function(cell) {
return cell.in_selection;
});
};
// Cell selection.
@ -607,9 +618,10 @@ define(function (require) {
* Programmatically select a cell.
*
* @param {integer} index - A cell's index
* @param {bool} add_to_selection - whether to add to the current selection
* @return {Notebook} This notebook
*/
Notebook.prototype.select = function (index) {
Notebook.prototype.select = function (index, add_to_selection) {
if (this.is_valid_cell_index(index)) {
var sindex = this.get_selected_index();
if (sindex !== null && index !== sindex) {
@ -618,8 +630,12 @@ define(function (require) {
if (this.mode !== 'command') {
this.command_mode();
}
this.get_cell(sindex).unselect();
}
var current_selection = this.get_selected_cells();
for (var i=0; i<current_selection.length; i++) {
current_selection[i].unselect(add_to_selection)
}
var cell = this.get_cell(index);
cell.select();
if (cell.cell_type === 'heading') {
@ -638,22 +654,40 @@ define(function (require) {
/**
* Programmatically select the next cell.
*
* @param {bool} extend_selection - whether to add to the current selection
* @return {Notebook} This notebook
*/
Notebook.prototype.select_next = function () {
Notebook.prototype.select_next = function (extend_selection) {
var index = this.get_selected_index();
this.select(index+1);
// XXX: If we're extending the range selection to an already-selected
// cell, the cursor is moving back into the selected range, and we
// actually want to contract the selection by unselecting the cell at
// the previous cursor position. Not entirely happy with this, but it's
// the best idea I have for now.
if (extend_selection && this.get_cell(index+1).in_selection) {
this.get_cell(index).unselect();
}
this.select(index+1, extend_selection);
return this;
};
/**
* Programmatically select the previous cell.
*
* @param {bool} extend_selection - whether to add to the current selection
* @return {Notebook} This notebook
*/
Notebook.prototype.select_prev = function () {
Notebook.prototype.select_prev = function (extend_selection) {
var index = this.get_selected_index();
this.select(index-1);
// XXX: If we're extending the range selection to an already-selected
// cell, the cursor is moving back into the selected range, and we
// actually want to contract the selection by unselecting the cell at
// the previous cursor position. Not entirely happy with this, but it's
// the best idea I have for now.
if (extend_selection && this.get_cell(index-1).in_selection) {
this.get_cell(index).unselect();
}
this.select(index-1, extend_selection);
return this;
};

Loading…
Cancel
Save