diff --git a/IPython/frontend/html/notebook/static/codemirror/theme/ipython.css b/IPython/frontend/html/notebook/static/codemirror/theme/ipython.css index 16ef8ad..2ad5b33 100644 --- a/IPython/frontend/html/notebook/static/codemirror/theme/ipython.css +++ b/IPython/frontend/html/notebook/static/codemirror/theme/ipython.css @@ -1,7 +1,7 @@ .cm-s-ipython span.cm-keyword {color: #008000; font-weight: bold;} -.cm-s-ipython span.cm-number {color: #666666;} +.cm-s-ipython span.cm-number {color: #0A32C8;} .cm-s-ipython span.cm-operator {color: #AA22FF; font-weight: bold;} .cm-s-ipython span.cm-meta {color: #AA22FF;} .cm-s-ipython span.cm-comment {color: #408080; font-style: italic;} diff --git a/IPython/frontend/html/notebook/static/css/base.css b/IPython/frontend/html/notebook/static/css/base.css index 3365bb5..8d2631c 100644 --- a/IPython/frontend/html/notebook/static/css/base.css +++ b/IPython/frontend/html/notebook/static/css/base.css @@ -22,7 +22,7 @@ div#header { /* Initially hidden to prevent FLOUC */ display: none; position: relative; - height: 45px; + height: 40px; padding: 5px; margin: 0px; width: 100%; @@ -35,7 +35,7 @@ span#ipython_notebook { span#ipython_notebook h1 { font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif; - font-size: 197%; + font-size: 150%; display: inline; color: black; } diff --git a/IPython/frontend/html/notebook/static/css/notebook.css b/IPython/frontend/html/notebook/static/css/notebook.css index 6143b99..e56090f 100644 --- a/IPython/frontend/html/notebook/static/css/notebook.css +++ b/IPython/frontend/html/notebook/static/css/notebook.css @@ -1,4 +1,3 @@ - /** * Primary styles * @@ -19,12 +18,18 @@ body { } span#save_widget { - position: absolute; + position: static; left: 0px; padding: 5px 0px; margin: 0px 0px 0px 0px; } +span#quick_help_area { + position: static; + padding: 5px 0px; + margin: 0px 0px 0px 0px; +} + input#notebook_name { height: 1em; line-height: 1em; @@ -35,9 +40,10 @@ span#kernel_status { position: absolute; padding: 8px 5px 5px 5px; right: 10px; - font-weight: bold; + font-weight: bold; } + .status_idle { color: gray; } @@ -156,7 +162,7 @@ div#notebook { overflow-x: auto; width: 100%; /* This spaces the cell away from the edge of the notebook area */ - padding: 15px 15px 15px 15px; + padding: 5px 5px 15px 5px; margin: 0px background-color: white; } @@ -172,9 +178,9 @@ div#pager { div.cell { width: 100%; - padding: 5px; + padding: 5px 5px 5px 0px; /* This acts as a spacer between cells, that is outside the border */ - margin: 5px 0px 5px 0px; + margin: 2px 0px 2px 0px; } div.code_cell { @@ -200,7 +206,7 @@ div.input_area { color: black; border: 1px solid #ddd; border-radius: 3px; - background: #fafafa; + background: #f7f7f7; } div.input_prompt { @@ -330,9 +336,10 @@ div.text_cell_render { .shortcut_key { display: inline-block; - width: 10ex; + width: 13ex; text-align: right; + font-family: monospace; } .shortcut_descr { -} \ No newline at end of file +} diff --git a/IPython/frontend/html/notebook/static/js/codecell.js b/IPython/frontend/html/notebook/static/js/codecell.js index 71eb219..83ebd37 100644 --- a/IPython/frontend/html/notebook/static/js/codecell.js +++ b/IPython/frontend/html/notebook/static/js/codecell.js @@ -48,9 +48,10 @@ var IPython = (function (IPython) { CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) { - // This method gets called in CodeMirror's onKeyDown/onKeyPress handlers and - // is used to provide custom key handling. Its return value is used to determine - // if CodeMirror should ignore the event: true = ignore, false = don't ignore. + // This method gets called in CodeMirror's onKeyDown/onKeyPress + // handlers and is used to provide custom key handling. Its return + // value is used to determine if CodeMirror should ignore the event: + // true = ignore, false = don't ignore. if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) { // Always ignore shift-enter in CodeMirror as we handle it. return true; @@ -59,8 +60,8 @@ var IPython = (function (IPython) { var cur = editor.getCursor(); var pre_cursor = editor.getRange({line:cur.line,ch:0},cur).trim(); if (pre_cursor === "") { - // Don't autocomplete if the part of the line before the cursor is empty. - // In this case, let CodeMirror handle indentation. + // Don't autocomplete if the part of the line before the cursor + // is empty. In this case, let CodeMirror handle indentation. return false; } else { // Autocomplete the current line. @@ -86,9 +87,14 @@ var IPython = (function (IPython) { } else { return false; }; - } else { - // keypress/keyup also trigger on TAB press, and we don't want to use those - // to disable tab completion. + } else if (event.keyCode === 76 && event.ctrlKey && event.shiftKey + && event.type == 'keydown') { + // toggle line numbers with Ctrl-Shift-L + this.toggle_line_numbers(); + } + else { + // keypress/keyup also trigger on TAB press, and we don't want to + // use those to disable tab completion. if (this.is_completing && event.keyCode !== 9) { var ed_cur = editor.getCursor(); var cc_cur = this.completion_cursor; @@ -177,6 +183,14 @@ var IPython = (function (IPython) { select.focus(); }; + CodeCell.prototype.toggle_line_numbers = function () { + if (this.code_mirror.getOption('lineNumbers') == false) { + this.code_mirror.setOption('lineNumbers', true); + } else { + this.code_mirror.setOption('lineNumbers', false); + } + this.code_mirror.refresh() + }; CodeCell.prototype.select = function () { IPython.Cell.prototype.select.apply(this); @@ -470,4 +484,3 @@ var IPython = (function (IPython) { return IPython; }(IPython)); - diff --git a/IPython/frontend/html/notebook/static/js/notebook.js b/IPython/frontend/html/notebook/static/js/notebook.js index 159a48c..d149ac3 100644 --- a/IPython/frontend/html/notebook/static/js/notebook.js +++ b/IPython/frontend/html/notebook/static/js/notebook.js @@ -130,9 +130,24 @@ var IPython = (function (IPython) { that.select_next(); that.control_key_active = false; return false; + } else if (event.which === 76 && that.control_key_active) { + // Toggle line numbers = l + that.cell_toggle_line_numbers(); + that.control_key_active = false; + return false; + } else if (event.which === 73 && that.control_key_active) { + // Interrupt kernel = i + IPython.notebook.kernel.interrupt(); + that.control_key_active = false; + return false; + } else if (event.which === 190 && that.control_key_active) { + // Restart kernel = . # matches qt console + IPython.notebook.restart_kernel(); + that.control_key_active = false; + return false; } else if (event.which === 72 && that.control_key_active) { // Show keyboard shortcuts = h - that.show_keyboard_shortcuts(); + that.toggle_keyboard_shortcuts(); that.control_key_active = false; return false; } else if (that.control_key_active) { @@ -181,15 +196,25 @@ var IPython = (function (IPython) { }; - Notebook.prototype.show_keyboard_shortcuts = function () { + Notebook.prototype.toggle_keyboard_shortcuts = function () { + // toggles display of keyboard shortcut dialog + var that = this; + if ( this.shortcut_dialog ){ + // if dialog is already shown, close it + this.shortcut_dialog.dialog("close"); + this.shortcut_dialog = null; + return; + } var dialog = $('
'); + this.shortcut_dialog = dialog; var shortcuts = [ {key: 'Shift-Enter', help: 'run cell'}, - {key: 'Ctrl-Enter', help: 'run cell in terminal mode'}, + {key: 'Ctrl-Enter', help: 'run cell in-place'}, {key: 'Ctrl-m d', help: 'delete cell'}, {key: 'Ctrl-m a', help: 'insert cell above'}, {key: 'Ctrl-m b', help: 'insert cell below'}, {key: 'Ctrl-m t', help: 'toggle output'}, + {key: 'Ctrl-m l', help: 'toggle line numbers'}, {key: 'Ctrl-m s', help: 'save notebook'}, {key: 'Ctrl-m j', help: 'move cell down'}, {key: 'Ctrl-m k', help: 'move cell up'}, @@ -197,7 +222,9 @@ var IPython = (function (IPython) { {key: 'Ctrl-m m', help: 'markdown cell'}, {key: 'Ctrl-m p', help: 'select previous'}, {key: 'Ctrl-m n', help: 'select next'}, - {key: 'Ctrl-m h', help: 'display keyboard shortcuts'} + {key: 'Ctrl-m i', help: 'interrupt kernel'}, + {key: 'Ctrl-m .', help: 'restart kernel'}, + {key: 'Ctrl-m h', help: 'show keyboard shortcuts'} ]; for (var i=0; i'). @@ -205,6 +232,10 @@ var IPython = (function (IPython) { append($('').addClass('shortcut_descr').html(' : ' + shortcuts[i].help)) ); }; + dialog.bind('dialogclose', function(event) { + // dialog has been closed, allow it to be drawn again. + that.shortcut_dialog = null; + }); dialog.dialog({title: 'Keyboard shortcuts'}); }; @@ -602,6 +633,11 @@ var IPython = (function (IPython) { this.dirty = true; }; + // Other cell functions: line numbers, ... + + Notebook.prototype.cell_toggle_line_numbers = function() { + this.selected_cell().toggle_line_numbers() + }; // Kernel related things @@ -613,8 +649,26 @@ var IPython = (function (IPython) { Notebook.prototype.restart_kernel = function () { + var that = this; var notebook_id = IPython.save_widget.get_notebook_id(); - this.kernel.restart($.proxy(this.kernel_started, this)); + + var dialog = $('
'); + dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.'); + $(document).append(dialog); + dialog.dialog({ + resizable: false, + modal: true, + title: "Restart kernel or continue running?", + buttons : { + "Restart": function () { + that.kernel.restart($.proxy(that.kernel_started, that)); + $(this).dialog('close'); + }, + "Continue running": function () { + $(this).dialog('close'); + } + } + }); }; @@ -694,11 +748,11 @@ var IPython = (function (IPython) { modal: true, title: "Dead kernel", buttons : { - "Yes": function () { + "Restart": function () { that.start_kernel(); $(this).dialog('close'); }, - "No": function () { + "Continue running": function () { $(this).dialog('close'); } } diff --git a/IPython/frontend/html/notebook/static/js/notebook_main.js b/IPython/frontend/html/notebook/static/js/notebook_main.js index d4e6ea6..095d098 100644 --- a/IPython/frontend/html/notebook/static/js/notebook_main.js +++ b/IPython/frontend/html/notebook/static/js/notebook_main.js @@ -32,6 +32,7 @@ $(document).ready(function () { IPython.pager = new IPython.Pager('div#pager', 'div#pager_splitter'); IPython.left_panel = new IPython.LeftPanel('div#left_panel', 'div#left_panel_splitter'); IPython.save_widget = new IPython.SaveWidget('span#save_widget'); + IPython.quick_help = new IPython.QuickHelp('span#quick_help_area'); IPython.print_widget = new IPython.PrintWidget('span#print_widget'); IPython.notebook = new IPython.Notebook('div#notebook'); IPython.kernel_status_widget = new IPython.KernelStatusWidget('#kernel_status'); diff --git a/IPython/frontend/html/notebook/static/js/quickhelp.js b/IPython/frontend/html/notebook/static/js/quickhelp.js new file mode 100644 index 0000000..0831819 --- /dev/null +++ b/IPython/frontend/html/notebook/static/js/quickhelp.js @@ -0,0 +1,39 @@ +//---------------------------------------------------------------------------- +// Copyright (C) 2008-2011 The IPython Development Team +// +// Distributed under the terms of the BSD License. The full license is in +// the file COPYING, distributed as part of this software. +//---------------------------------------------------------------------------- + +//============================================================================ +// QuickHelp button +//============================================================================ + +var IPython = (function (IPython) { + + var QuickHelp = function (selector) { + this.selector = selector; + if (this.selector !== undefined) { + this.element = $(selector); + this.style(); + this.bind_events(); + } + }; + + QuickHelp.prototype.style = function () { + this.element.find('button#quick_help').button(); + }; + + QuickHelp.prototype.bind_events = function () { + var that = this; + this.element.find("button#quick_help").click(function () { + IPython.notebook.toggle_keyboard_shortcuts(); + }); + }; + + // Set module variables + IPython.QuickHelp = QuickHelp; + + return IPython; + +}(IPython)); diff --git a/IPython/frontend/html/notebook/templates/notebook.html b/IPython/frontend/html/notebook/templates/notebook.html index a9a84e2..b77c1df 100644 --- a/IPython/frontend/html/notebook/templates/notebook.html +++ b/IPython/frontend/html/notebook/templates/notebook.html @@ -56,13 +56,16 @@ + + + Idle