##// END OF EJS Templates
Fix the "test for nothing was streamed" so it doesn't add empty elements -- but only when there wasn't already something there.
Fix the "test for nothing was streamed" so it doesn't add empty elements -- but only when there wasn't already something there.

File last commit:

r7193:2ea1b486
r7340:4c1fd039
Show More
completer.js
276 lines | 8.8 KiB | application/javascript | JavascriptLexer
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 // function completer.
//
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142 // completer should be a class that take an cell instance
Matthias BUSSONNIER
space before function keyword in js
r7191 var IPython = (function (IPython) {
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142 // that will prevent us from misspelling
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 "use strict";
// easyier key mapping
Matthias BUSSONNIER
import Utils keycodes into the completer
r7137 var key = IPython.utils.keycodes;
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 // what is the common start of all completions
Matthias BUSSONNIER
beautify completer.js
r7190
Matthias BUSSONNIER
remove CamelCasse methods from completer.js
r7192 function shared_start(B) {
Matthias BUSSONNIER
beautify completer.js
r7190 if (B.length == 1) {
return B[0];
}
var A = new Array();
for (var i = 0; i < B.length; i++) {
A.push(B[i].str);
}
if (A.length > 1) {
var tem1, tem2, s;
A = A.slice(0).sort();
tem1 = A[0];
s = tem1.length;
tem2 = A.pop();
while (s && tem2.indexOf(tem1) == -1) {
tem1 = tem1.substring(0, --s);
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 }
Matthias BUSSONNIER
beautify completer.js
r7190 if (tem1 == "" || tem2.indexOf(tem1) != 0) {
return null;
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 }
Matthias BUSSONNIER
beautify completer.js
r7190 return {
str: tem1,
type: "computed",
from: B[0].from,
to: B[0].to
};
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 }
Matthias BUSSONNIER
beautify completer.js
r7190 return null;
}
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
Matthias BUSSONNIER
move more code into the completer itself
r7141
Matthias BUSSONNIER
space before function keyword in js
r7191 var Completer = function (cell) {
Matthias BUSSONNIER
beautify completer.js
r7190 this.editor = cell.code_mirror;
var that = this;
Matthias BUSSONNIER
space before function keyword in js
r7191 $([IPython.events]).on('status_busy.Kernel', function () {
Matthias BUSSONNIER
beautify completer.js
r7190 that.skip_kernel_completion = true;
});
Matthias BUSSONNIER
space before function keyword in js
r7191 $([IPython.events]).on('status_idle.Kernel', function () {
Matthias BUSSONNIER
beautify completer.js
r7190 that.skip_kernel_completion = false;
});
Matthias BUSSONNIER
simplify completer logic as we don't exec on behalf of cell...
r7174
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
Matthias BUSSONNIER
beautify completer.js
r7190 };
Matthias BUSSONNIER
move more code into the completer itself
r7141
Matthias BUSSONNIER
simplify completer logic as we don't exec on behalf of cell...
r7174
Matthias BUSSONNIER
space before function keyword in js
r7191 Completer.prototype.startCompletion = function () {
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142 // call for a 'first' completion, that will set the editor and do some
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 // special behaviour like autopicking if only one completion availlable
//
if (this.editor.somethingSelected()) return;
this.done = false;
// use to get focus back on opera
Matthias BUSSONNIER
remove CamelCasse methods from completer.js
r7192 this.carry_on_completion(true);
Matthias BUSSONNIER
Clean code, retab and minor fix...
r7170 };
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
Matthias BUSSONNIER
remove CamelCasse methods from completer.js
r7192 Completer.prototype.carry_on_completion = function (ff) {
Matthias BUSSONNIER
more cleaning
r7143 // Pass true as parameter if you want the commpleter to autopick when
// only one completion. This function is automatically reinvoked at
// each keystroke with ff = false
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 var cur = this.editor.getCursor();
Matthias BUSSONNIER
simplify completer logic as we don't exec on behalf of cell...
r7174 var line = this.editor.getLine(cur.line);
Matthias BUSSONNIER
beautify completer.js
r7190 var pre_cursor = this.editor.getRange({
line: cur.line,
ch: cur.ch - 1
}, cur);
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142 // we need to check that we are still on a word boundary
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 // because while typing the completer is still reinvoking itself
Matthias BUSSONNIER
beautify completer.js
r7190 if (!/[0-9a-z._]/i.test(pre_cursor)) {
this.close();
return;
}
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 this.autopick = false;
Matthias BUSSONNIER
beautify completer.js
r7190 if (ff != 'undefined' && ff == true) {
this.autopick = true;
}
Matthias BUSSONNIER
more cleaning
r7143
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 // We want a single cursor position.
if (this.editor.somethingSelected()) return;
Matthias BUSSONNIER
simplify completer logic as we don't exec on behalf of cell...
r7174 // one kernel completion came back, finish_completing will be called with the results
// we fork here and directly call finish completing if kernel is busy
Matthias BUSSONNIER
beautify completer.js
r7190 if (this.skip_kernel_completion == true) {
this.finish_completing({
'matches': [],
matched_text: ""
})
Matthias BUSSONNIER
simplify completer logic as we don't exec on behalf of cell...
r7174 } else {
Matthias BUSSONNIER
beautify completer.js
r7190 var callbacks = {
'complete_reply': $.proxy(this.finish_completing, this)
};
Matthias BUSSONNIER
simplify completer logic as we don't exec on behalf of cell...
r7174 IPython.notebook.kernel.complete(line, cur.ch, callbacks);
}
Matthias BUSSONNIER
Clean code, retab and minor fix...
r7170 };
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142
Matthias BUSSONNIER
space before function keyword in js
r7191 Completer.prototype.finish_completing = function (content) {
Matthias BUSSONNIER
more cleaning
r7143 // let's build a function that wrap all that stuff into what is needed
// for the new completer:
Brian Granger
Major refactoring of the Notebook, Kernel and CodeCell JavaScript....
r7168 var matched_text = content.matched_text;
var matches = content.matches;
Matthias BUSSONNIER
more cleaning
r7143
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142 var cur = this.editor.getCursor();
var results = CodeMirror.contextHint(this.editor);
Matthias BUSSONNIER
more cleaning
r7143 // append the introspection result, in order, at at the beginning of
// the table and compute the replacement range from current cursor
// positon and matched_text length.
Matthias BUSSONNIER
beautify completer.js
r7190 for (var i = matches.length - 1; i >= 0; --i) {
results.unshift({
str: matches[i],
type: "introspection",
from: {
line: cur.line,
ch: cur.ch - matched_text.length
},
to: {
line: cur.line,
ch: cur.ch
}
});
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142 }
// one the 2 sources results have been merge, deal with it
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 this.raw_result = results;
// if empty result return
if (!this.raw_result || !this.raw_result.length) return;
// When there is only one completion, use it directly.
Matthias BUSSONNIER
beautify completer.js
r7190 if (this.autopick == true && this.raw_result.length == 1) {
Matthias BUSSONNIER
Clean code, retab and minor fix...
r7170 this.insert(this.raw_result[0]);
return;
}
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
Matthias BUSSONNIER
beautify completer.js
r7190 if (this.raw_result.length == 1) {
Matthias BUSSONNIER
more cleaning
r7143 // test if first and only completion totally matches
// what is typed, in this case dismiss
Matthias BUSSONNIER
Clean code, retab and minor fix...
r7170 var str = this.raw_result[0].str;
Matthias BUSSONNIER
beautify completer.js
r7190 var pre_cursor = this.editor.getRange({
line: cur.line,
ch: cur.ch - str.length
}, cur);
if (pre_cursor == str) {
this.close();
return;
}
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 }
this.complete = $('<div/>').addClass('completions');
Matthias BUSSONNIER
beautify completer.js
r7190 this.complete.attr('id', 'complete');
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
Matthias BUSSONNIER
beautify completer.js
r7190 this.sel = $('<select/>').attr('multiple', 'true').attr('size', Math.min(10, this.raw_result.length));
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 var pos = this.editor.cursorCoords();
// TODO: I propose to remove enough horizontal pixel
// to align the text later
Matthias BUSSONNIER
beautify completer.js
r7190 this.complete.css('left', pos.x + 'px');
this.complete.css('top', pos.yBot + 'px');
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 this.complete.append(this.sel);
$('body').append(this.complete);
//build the container
var that = this;
Matthias BUSSONNIER
space before function keyword in js
r7191 this.sel.dblclick(function () {
Matthias BUSSONNIER
beautify completer.js
r7190 that.pick();
});
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 this.sel.blur(this.close);
Matthias BUSSONNIER
space before function keyword in js
r7191 this.sel.keydown(function (event) {
Matthias BUSSONNIER
beautify completer.js
r7190 that.keydown(event);
});
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
this.build_gui_list(this.raw_result);
this.sel.focus();
// Opera sometimes ignores focusing a freshly created node
Matthias BUSSONNIER
space before function keyword in js
r7191 if (window.opera) setTimeout(function () {
Matthias BUSSONNIER
beautify completer.js
r7190 if (!this.done) this.sel.focus();
}, 100);
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 return true;
}
Matthias BUSSONNIER
space before function keyword in js
r7191 Completer.prototype.insert = function (completion) {
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 this.editor.replaceRange(completion.str, completion.from, completion.to);
Matthias BUSSONNIER
beautify completer.js
r7190 }
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
Matthias BUSSONNIER
space before function keyword in js
r7191 Completer.prototype.build_gui_list = function (completions) {
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 // Need to clear the all list
for (var i = 0; i < completions.length; ++i) {
Matthias BUSSONNIER
beautify completer.js
r7190 var opt = $('<option/>').text(completions[i].str).addClass(completions[i].type);
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 this.sel.append(opt);
}
Matthias BUSSONNIER
beautify completer.js
r7190 this.sel.children().first().attr('selected', 'true');
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 }
Matthias BUSSONNIER
space before function keyword in js
r7191 Completer.prototype.close = function () {
Matthias BUSSONNIER
beautify completer.js
r7190 if (this.done) return;
this.done = true;
$('.completions').remove();
}
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
Matthias BUSSONNIER
space before function keyword in js
r7191 Completer.prototype.pick = function () {
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 this.insert(this.raw_result[this.sel[0].selectedIndex]);
this.close();
var that = this;
Matthias BUSSONNIER
space before function keyword in js
r7191 setTimeout(function () {
Matthias BUSSONNIER
beautify completer.js
r7190 that.editor.focus();
}, 50);
}
Matthias BUSSONNIER
implement the completer in a separate class...
r7131
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142
Matthias BUSSONNIER
space before function keyword in js
r7191 Completer.prototype.keydown = function (event) {
Matthias BUSSONNIER
beautify completer.js
r7190 var code = event.keyCode;
var that = this;
// Enter
Matthias BUSSONNIER
Uppercase constant keycode in utils.js
r7193 if (code == key.ENTER) {
Matthias BUSSONNIER
beautify completer.js
r7190 CodeMirror.e_stop(event);
this.pick();
}
// Escape or backspace
Matthias BUSSONNIER
Uppercase constant keycode in utils.js
r7193 else if (code == key.ESC) {
Matthias BUSSONNIER
beautify completer.js
r7190 CodeMirror.e_stop(event);
this.close();
this.editor.focus();
Matthias BUSSONNIER
Uppercase constant keycode in utils.js
r7193 } else if (code == key.SPACE || code == key.BACKSPACE) {
Matthias BUSSONNIER
beautify completer.js
r7190 this.close();
this.editor.focus();
Matthias BUSSONNIER
Uppercase constant keycode in utils.js
r7193 } else if (code == key.TAB) {
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142 //all the fastforwarding operation,
Matthias BUSSONNIER
use strict and clean a little....
r7132 //Check that shared start is not null which can append with prefixed completion
// like %pylab , pylab have no shred start, and ff will result in py<tab><tab>
// to erase py
Matthias BUSSONNIER
remove CamelCasse methods from completer.js
r7192 var sh = shared_start(this.raw_result);
Matthias BUSSONNIER
beautify completer.js
r7190 if (sh) {
Matthias BUSSONNIER
use strict and clean a little....
r7132 this.insert(sh);
}
Matthias BUSSONNIER
clean code, remove duplicate unused lines
r7142 this.close();
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 CodeMirror.e_stop(event);
this.editor.focus();
//reinvoke self
Matthias BUSSONNIER
space before function keyword in js
r7191 setTimeout(function () {
Matthias BUSSONNIER
remove CamelCasse methods from completer.js
r7192 that.carry_on_completion();
Matthias BUSSONNIER
beautify completer.js
r7190 }, 50);
Matthias BUSSONNIER
Uppercase constant keycode in utils.js
r7193 } else if (code == key.UPARROW || code == key.DOWNARROW) {
Matthias BUSSONNIER
beautify completer.js
r7190 // need to do that to be able to move the arrow
// when on the first or last line ofo a code cell
event.stopPropagation();
Matthias BUSSONNIER
Uppercase constant keycode in utils.js
r7193 } else if (code != key.UPARROW && code != key.DOWNARROW) {
Matthias BUSSONNIER
beautify completer.js
r7190 this.close();
this.editor.focus();
//we give focus to the editor immediately and call sell in 50 ms
Matthias BUSSONNIER
space before function keyword in js
r7191 setTimeout(function () {
Matthias BUSSONNIER
remove CamelCasse methods from completer.js
r7192 that.carry_on_completion();
Matthias BUSSONNIER
beautify completer.js
r7190 }, 50);
}
Matthias BUSSONNIER
implement the completer in a separate class...
r7131 }
IPython.Completer = Completer;
return IPython;
}(IPython));