//---------------------------------------------------------------------------- // 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. //---------------------------------------------------------------------------- //============================================================================ // CodeCell //============================================================================ var IPython = (function (IPython) { var utils = IPython.utils; var CodeCell = function (notebook) { this.code_mirror = null; this.input_prompt_number = ' '; this.is_completing = false; this.completion_cursor = null; this.outputs = []; this.collapsed = false; IPython.Cell.apply(this, arguments); }; CodeCell.prototype = new IPython.Cell(); CodeCell.prototype.create_element = function () { var cell = $('
').addClass('cell border-box-sizing code_cell vbox'); cell.attr('tabindex','2'); var input = $('
').addClass('input hbox'); input.append($('
').addClass('prompt input_prompt')); var input_area = $('
').addClass('input_area box-flex1'); this.code_mirror = CodeMirror(input_area.get(0), { indentUnit : 4, mode: 'python', theme: 'ipython', readOnly: this.read_only, onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this) }); input.append(input_area); var output = $('
').addClass('output vbox'); cell.append(input).append(output); this.element = cell; this.collapse() }; 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. if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) { // Always ignore shift-enter in CodeMirror as we handle it. return true; } else if (event.keyCode === 9 && event.type == 'keydown') { // Tab completion. 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. return false; } else { // Autocomplete the current line. event.stop(); var line = editor.getLine(cur.line); this.is_completing = true; this.completion_cursor = cur; IPython.notebook.complete_cell(this, line, cur.ch); return true; } } else if (event.keyCode === 8 && event.type == 'keydown') { // If backspace and the line ends with 4 spaces, remove them. var cur = editor.getCursor(); var line = editor.getLine(cur.line); var ending = line.slice(-4); if (ending === ' ') { editor.replaceRange('', {line: cur.line, ch: cur.ch-4}, {line: cur.line, ch: cur.ch} ); event.stop(); return true; } else { return false; }; } 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; if (ed_cur.line !== cc_cur.line || ed_cur.ch !== cc_cur.ch) { this.is_completing = false; this.completion_cursor = null; }; }; return false; }; }; CodeCell.prototype.finish_completing = function (matched_text, matches) { // console.log("Got matches", matched_text, matches); if (!this.is_completing || matches.length === 0) {return;} var that = this; var cur = this.completion_cursor; var insert = function (selected_text) { that.code_mirror.replaceRange( selected_text, {line: cur.line, ch: (cur.ch-matched_text.length)}, {line: cur.line, ch: cur.ch} ); }; if (matches.length === 1) { insert(matches[0]); setTimeout(function(){that.code_mirror.focus();}, 50); return; }; var complete = $('
').addClass('completions'); var select = $('