Show More
@@ -437,7 +437,7 IPython.utils = (function (IPython) { | |||
|
437 | 437 | return decodeURIComponent($('body').data(key)); |
|
438 | 438 | }; |
|
439 | 439 | |
|
440 | var absolute_cursor_pos = function (cm, cursor) { | |
|
440 | var to_absolute_cursor_pos = function (cm, cursor) { | |
|
441 | 441 | // get the absolute cursor position from CodeMirror's col, ch |
|
442 | 442 | if (!cursor) { |
|
443 | 443 | cursor = cm.getCursor(); |
@@ -449,6 +449,27 IPython.utils = (function (IPython) { | |||
|
449 | 449 | return cursor_pos; |
|
450 | 450 | }; |
|
451 | 451 | |
|
452 | var from_absolute_cursor_pos = function (cm, cursor_pos) { | |
|
453 | // turn absolute cursor postion into CodeMirror col, ch cursor | |
|
454 | var i, line; | |
|
455 | var offset = 0; | |
|
456 | for (i = 0, line=cm.getLine(i); line !== undefined; i++, line=cm.getLine(i)) { | |
|
457 | if (offset + line.length < cursor_pos) { | |
|
458 | offset += line.length + 1; | |
|
459 | } else { | |
|
460 | return { | |
|
461 | line : i, | |
|
462 | ch : cursor_pos - offset, | |
|
463 | }; | |
|
464 | } | |
|
465 | } | |
|
466 | // reached end, return endpoint | |
|
467 | return { | |
|
468 | ch : line.length - 1, | |
|
469 | line : i - 1, | |
|
470 | }; | |
|
471 | }; | |
|
472 | ||
|
452 | 473 | // http://stackoverflow.com/questions/2400935/browser-detection-in-javascript |
|
453 | 474 | var browser = (function() { |
|
454 | 475 | if (typeof navigator === 'undefined') { |
@@ -457,7 +478,7 IPython.utils = (function (IPython) { | |||
|
457 | 478 | } |
|
458 | 479 | var N= navigator.appName, ua= navigator.userAgent, tem; |
|
459 | 480 | var M= ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i); |
|
460 | if (M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1]; | |
|
481 | if (M && (tem= ua.match(/version\/([\.\d]+)/i)) !== null) M[2]= tem[1]; | |
|
461 | 482 | M= M? [M[1], M[2]]: [N, navigator.appVersion,'-?']; |
|
462 | 483 | return M; |
|
463 | 484 | })(); |
@@ -523,7 +544,8 IPython.utils = (function (IPython) { | |||
|
523 | 544 | splitext : splitext, |
|
524 | 545 | escape_html : escape_html, |
|
525 | 546 | always_new : always_new, |
|
526 | absolute_cursor_pos : absolute_cursor_pos, | |
|
547 | to_absolute_cursor_pos : to_absolute_cursor_pos, | |
|
548 | from_absolute_cursor_pos : from_absolute_cursor_pos, | |
|
527 | 549 | browser : browser, |
|
528 | 550 | platform: platform, |
|
529 | 551 | is_or_has : is_or_has, |
@@ -11,15 +11,16 var IPython = (function (IPython) { | |||
|
11 | 11 | |
|
12 | 12 | // easier key mapping |
|
13 | 13 | var keycodes = IPython.keyboard.keycodes; |
|
14 | var utils = IPython.utils; | |
|
14 | 15 | |
|
15 |
|
|
|
16 | var prepend_n_prc = function(str, n) { | |
|
16 | 17 | for( var i =0 ; i< n ; i++){ |
|
17 | 18 | str = '%'+str ; |
|
18 | 19 | } |
|
19 | 20 | return str; |
|
20 | 21 | }; |
|
21 | 22 | |
|
22 |
|
|
|
23 | var _existing_completion = function(item, completion_array){ | |
|
23 | 24 | for( var i=0; i < completion_array.length; i++) { |
|
24 | 25 | if (completion_array[i].trim().substr(-item.length) == item) { |
|
25 | 26 | return true; |
@@ -147,13 +148,14 var IPython = (function (IPython) { | |||
|
147 | 148 | |
|
148 | 149 | // one kernel completion came back, finish_completing will be called with the results |
|
149 | 150 | // we fork here and directly call finish completing if kernel is busy |
|
151 | var cursor_pos = utils.to_absolute_cursor_pos(this.editor, cur); | |
|
150 | 152 | if (this.skip_kernel_completion) { |
|
151 | this.finish_completing({ | |
|
153 | this.finish_completing({ content: { | |
|
152 | 154 | matches: [], |
|
153 | matched_text: "" | |
|
154 | }); | |
|
155 | cursor_start: cursor_pos, | |
|
156 | cursor_end: cursor_pos, | |
|
157 | }}); | |
|
155 | 158 | } else { |
|
156 | var cursor_pos = IPython.utils.absolute_cursor_pos(this.editor, cur); | |
|
157 | 159 | this.cell.kernel.complete(this.editor.getValue(), cursor_pos, |
|
158 | 160 | $.proxy(this.finish_completing, this) |
|
159 | 161 | ); |
@@ -164,7 +166,8 var IPython = (function (IPython) { | |||
|
164 | 166 | // let's build a function that wrap all that stuff into what is needed |
|
165 | 167 | // for the new completer: |
|
166 | 168 | var content = msg.content; |
|
167 |
var |
|
|
169 | var start = content.cursor_start; | |
|
170 | var end = content.cursor_end; | |
|
168 | 171 | var matches = content.matches; |
|
169 | 172 | |
|
170 | 173 | var cur = this.editor.getCursor(); |
@@ -172,7 +175,8 var IPython = (function (IPython) { | |||
|
172 | 175 | var filtered_results = []; |
|
173 | 176 | //remove results from context completion |
|
174 | 177 | //that are already in kernel completion |
|
175 | for (var i=0; i < results.length; i++) { | |
|
178 | var i; | |
|
179 | for (i=0; i < results.length; i++) { | |
|
176 | 180 | if (!_existing_completion(results[i].str, matches)) { |
|
177 | 181 | filtered_results.push(results[i]); |
|
178 | 182 | } |
@@ -181,18 +185,12 var IPython = (function (IPython) { | |||
|
181 | 185 | // append the introspection result, in order, at at the beginning of |
|
182 | 186 | // the table and compute the replacement range from current cursor |
|
183 | 187 | // positon and matched_text length. |
|
184 |
for ( |
|
|
188 | for (i = matches.length - 1; i >= 0; --i) { | |
|
185 | 189 | filtered_results.unshift({ |
|
186 | 190 | str: matches[i], |
|
187 | 191 | type: "introspection", |
|
188 | from: { | |
|
189 | line: cur.line, | |
|
190 | ch: cur.ch - matched_text.length | |
|
191 | }, | |
|
192 | to: { | |
|
193 | line: cur.line, | |
|
194 | ch: cur.ch | |
|
195 | } | |
|
192 | from: utils.from_absolute_cursor_pos(this.editor, start), | |
|
193 | to: utils.from_absolute_cursor_pos(this.editor, end) | |
|
196 | 194 | }); |
|
197 | 195 | } |
|
198 | 196 | |
@@ -256,8 +254,9 var IPython = (function (IPython) { | |||
|
256 | 254 | |
|
257 | 255 | // After everything is on the page, compute the postion. |
|
258 | 256 | // We put it above the code if it is too close to the bottom of the page. |
|
259 | cur.ch = cur.ch-matched_text.length; | |
|
260 | var pos = this.editor.cursorCoords(cur); | |
|
257 | var pos = this.editor.cursorCoords( | |
|
258 | utils.from_absolute_cursor_pos(this.editor, start) | |
|
259 | ); | |
|
261 | 260 | var left = pos.left-3; |
|
262 | 261 | var top; |
|
263 | 262 | var cheight = this.complete.height(); |
@@ -229,7 +229,7 var IPython = (function (IPython) { | |||
|
229 | 229 | this.cancel_pending(); |
|
230 | 230 | var editor = cell.code_mirror; |
|
231 | 231 | var cursor = editor.getCursor(); |
|
232 |
var cursor_pos = |
|
|
232 | var cursor_pos = utils.to_absolute_cursor_pos(editor, cursor); | |
|
233 | 233 | var text = cell.get_text(); |
|
234 | 234 | |
|
235 | 235 | this._hide_if_no_docstring = hide_if_no_docstring; |
@@ -138,6 +138,9 class Status(Reference): | |||
|
138 | 138 | |
|
139 | 139 | class CompleteReply(Reference): |
|
140 | 140 | matches = List(Unicode) |
|
141 | cursor_start = Integer() | |
|
142 | cursor_end = Integer() | |
|
143 | status = Unicode() | |
|
141 | 144 | |
|
142 | 145 | |
|
143 | 146 | class KernelInfoReply(Reference): |
@@ -496,7 +496,9 class Kernel(Configurable): | |||
|
496 | 496 | |
|
497 | 497 | txt, matches = self.shell.complete('', code, cursor_pos) |
|
498 | 498 | matches = {'matches' : matches, |
|
499 |
' |
|
|
499 | 'cursor_end' : cursor_pos, | |
|
500 | 'cursor_start' : cursor_pos - len(txt), | |
|
501 | 'metadata' : {}, | |
|
500 | 502 | 'status' : 'ok'} |
|
501 | 503 | matches = json_clean(matches) |
|
502 | 504 | completion_msg = self.session.send(stream, 'complete_reply', |
@@ -146,22 +146,12 class IPythonWidget(FrontendWidget): | |||
|
146 | 146 | info = self._request_info.get('complete') |
|
147 | 147 | if info and info.id == rep['parent_header']['msg_id'] and \ |
|
148 | 148 | info.pos == cursor.position(): |
|
149 |
|
|
|
150 |
|
|
|
151 | offset = len(text) | |
|
152 | ||
|
153 | # Clean up matches with period and path separators if the matched | |
|
154 | # text has not been transformed. This is done by truncating all | |
|
155 | # but the last component and then suitably decreasing the offset | |
|
156 | # between the current cursor position and the start of completion. | |
|
157 | if len(matches) > 1 and matches[0][:offset] == text: | |
|
158 | parts = re.split(r'[./\\]', text) | |
|
159 | sep_count = len(parts) - 1 | |
|
160 | if sep_count: | |
|
161 | chop_length = sum(map(len, parts[:sep_count])) + sep_count | |
|
162 | matches = [ match[chop_length:] for match in matches ] | |
|
163 | offset -= chop_length | |
|
164 | ||
|
149 | content = rep['content'] | |
|
150 | matches = content['matches'] | |
|
151 | start = content['cursor_start'] | |
|
152 | end = content['cursor_end'] | |
|
153 | ||
|
154 | offset = end - start | |
|
165 | 155 | # Move the cursor to the start of the match and complete. |
|
166 | 156 | cursor.movePosition(QtGui.QTextCursor.Left, n=offset) |
|
167 | 157 | self._complete_with_items(cursor, matches) |
General Comments 0
You need to be logged in to leave comments.
Login now