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