diff --git a/IPython/html/static/notebook/js/notebook.js b/IPython/html/static/notebook/js/notebook.js
index 8aaf8b4..8b837ee 100644
--- a/IPython/html/static/notebook/js/notebook.js
+++ b/IPython/html/static/notebook/js/notebook.js
@@ -53,7 +53,7 @@ define([
// base_url : string
// notebook_path : string
// notebook_name : string
- this.config = options.config || {};
+ this.config = utils.mergeopt(Notebook, options.config);
this.base_url = options.base_url;
this.notebook_path = options.notebook_path;
this.notebook_name = options.notebook_name;
@@ -63,6 +63,7 @@ define([
this.tooltip = new tooltip.Tooltip(this.events);
this.ws_url = options.ws_url;
this._session_starting = false;
+ this.default_cell_type = this.config.default_cell_type || 'code';
// default_kernel_name is a temporary measure while we implement proper
// kernel selection and delayed start. Do not rely on it.
this.default_kernel_name = 'python';
@@ -134,6 +135,14 @@ define([
rawcell_celltoolbar.register(this);
slideshow_celltoolbar.register(this);
};
+
+ Notebook.options_default = {
+ // can be any cell type, or the special values of
+ // 'above', 'below', or 'selected' to get the value from another cell.
+ Notebook: {
+ default_cell_type: 'code',
+ }
+ };
/**
@@ -835,10 +844,25 @@ define([
Notebook.prototype.insert_cell_at_index = function(type, index){
var ncells = this.ncells();
- index = Math.min(index,ncells);
- index = Math.max(index,0);
+ index = Math.min(index, ncells);
+ index = Math.max(index, 0);
var cell = null;
- type = type || this.get_selected_cell().cell_type;
+ type = type || this.default_cell_type;
+ if (type === 'above') {
+ if (index > 0) {
+ type = this.get_cell(index-1).cell_type;
+ } else {
+ type = 'code';
+ }
+ } else if (type === 'below') {
+ if (index < ncells) {
+ type = this.get_cell(index).cell_type;
+ } else {
+ type = 'code';
+ }
+ } else if (type === 'selected') {
+ type = this.get_selected_cell().cell_type;
+ }
if (ncells === 0 || this.is_valid_cell_index(index) || index === ncells) {
var cell_options = {
diff --git a/IPython/html/tests/notebook/dualmode_cellinsert.js b/IPython/html/tests/notebook/dualmode_cellinsert.js
index e87f895..039babe 100644
--- a/IPython/html/tests/notebook/dualmode_cellinsert.js
+++ b/IPython/html/tests/notebook/dualmode_cellinsert.js
@@ -12,31 +12,66 @@ casper.notebook_test(function () {
var c = 'print("c")';
index = this.append_cell(c);
this.execute_cell_then(index);
-
+
+ this.thenEvaluate(function() {
+ IPython.notebook.default_cell_type = 'code';
+ });
+
this.then(function () {
// Cell insertion
this.select_cell(2);
+ this.trigger_keydown('m'); // Make it markdown
this.trigger_keydown('a'); // Creates one cell
this.test.assertEquals(this.get_cell_text(2), '', 'a; New cell 2 text is empty');
- this.test.assertEquals(this.get_cell(2).cell_type, 'code', 'a; inserts a code cell when on code cell');
+ this.test.assertEquals(this.get_cell(2).cell_type, 'code', 'a; inserts a code cell');
this.validate_notebook_state('a', 'command', 2);
this.trigger_keydown('b'); // Creates one cell
this.test.assertEquals(this.get_cell_text(2), '', 'b; Cell 2 text is still empty');
this.test.assertEquals(this.get_cell_text(3), '', 'b; New cell 3 text is empty');
- this.test.assertEquals(this.get_cell(3).cell_type, 'code', 'b; inserts a code cell when on code cell');
+ this.test.assertEquals(this.get_cell(3).cell_type, 'code', 'b; inserts a code cell');
this.validate_notebook_state('b', 'command', 3);
});
+
+ this.thenEvaluate(function() {
+ IPython.notebook.default_cell_type = 'selected';
+ });
+
this.then(function () {
- // Cell insertion
this.select_cell(2);
this.trigger_keydown('m'); // switch it to markdown for the next test
- this.trigger_keydown('a'); // Creates one cell
- this.test.assertEquals(this.get_cell_text(2), '', 'a; New cell 2 text is empty');
- this.test.assertEquals(this.get_cell(2).cell_type, 'markdown', 'a; inserts a markdown cell when on markdown cell');
- this.validate_notebook_state('a', 'command', 2);
- this.trigger_keydown('b'); // Creates one cell
- this.test.assertEquals(this.get_cell_text(2), '', 'b; Cell 2 text is still empty');
- this.test.assertEquals(this.get_cell(3).cell_type, 'markdown', 'b; inserts a markdown cell when on markdown cell');
- this.validate_notebook_state('b', 'command', 3);
+ this.test.assertEquals(this.get_cell(2).cell_type, 'markdown', 'test cell is markdown');
+ this.trigger_keydown('a'); // new cell above
+ this.test.assertEquals(this.get_cell(2).cell_type, 'markdown', 'a; inserts a markdown cell when markdown selected');
+ this.trigger_keydown('b'); // new cell below
+ this.test.assertEquals(this.get_cell(3).cell_type, 'markdown', 'b; inserts a markdown cell when markdown selected');
+ });
+
+ this.thenEvaluate(function() {
+ IPython.notebook.default_cell_type = 'above';
+ });
+
+ this.then(function () {
+ this.select_cell(2);
+ this.trigger_keydown('1'); // switch it to heading for the next test
+ this.test.assertEquals(this.get_cell(2).cell_type, 'heading', 'test cell is heading');
+ this.trigger_keydown('b'); // new cell below
+ this.test.assertEquals(this.get_cell(3).cell_type, 'heading', 'b; inserts a heading cell below heading cell');
+ this.trigger_keydown('a'); // new cell above
+ this.test.assertEquals(this.get_cell(3).cell_type, 'heading', 'a; inserts a heading cell below heading cell');
+ });
+
+ this.thenEvaluate(function() {
+ IPython.notebook.default_cell_type = 'below';
+ });
+
+ this.then(function () {
+ this.select_cell(2);
+ this.trigger_keydown('r'); // switch it to markdown for the next test
+ this.test.assertEquals(this.get_cell(2).cell_type, 'raw', 'test cell is raw');
+ this.trigger_keydown('a'); // new cell above
+ this.test.assertEquals(this.get_cell(2).cell_type, 'raw', 'a; inserts a raw cell above raw cell');
+ this.trigger_keydown('y'); // switch it to code for the next test
+ this.trigger_keydown('b'); // new cell below
+ this.test.assertEquals(this.get_cell(3).cell_type, 'raw', 'b; inserts a raw cell above raw cell');
});
});