##// END OF EJS Templates
only complete on current line...
MinRK -
Show More
@@ -1,16 +1,8 b''
1 # coding: utf-8
1 # coding: utf-8
2 """test the IPython Kernel"""
2 """test the IPython Kernel"""
3
3
4 #-------------------------------------------------------------------------------
4 # Copyright (c) IPython Development Team.
5 # Copyright (C) 2013 The IPython Development Team
5 # Distributed under the terms of the Modified BSD License.
6 #
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
9 #-------------------------------------------------------------------------------
10
11 #-------------------------------------------------------------------------------
12 # Imports
13 #-------------------------------------------------------------------------------
14
6
15 import io
7 import io
16 import os.path
8 import os.path
@@ -26,10 +18,6 b' from IPython.utils.tempdir import TemporaryDirectory'
26 from .utils import (new_kernel, kernel, TIMEOUT, assemble_output, execute,
18 from .utils import (new_kernel, kernel, TIMEOUT, assemble_output, execute,
27 flush_channels, wait_for_idle)
19 flush_channels, wait_for_idle)
28
20
29 #-------------------------------------------------------------------------------
30 # Tests
31 #-------------------------------------------------------------------------------
32
33
21
34 def _check_mp_mode(kc, expected=False, stream="stdout"):
22 def _check_mp_mode(kc, expected=False, stream="stdout"):
35 execute(kc=kc, code="import sys")
23 execute(kc=kc, code="import sys")
@@ -213,7 +201,7 b' def test_is_complete():'
213 reply = kc.get_shell_msg(block=True, timeout=TIMEOUT)
201 reply = kc.get_shell_msg(block=True, timeout=TIMEOUT)
214 assert reply['content']['status'] == 'complete'
202 assert reply['content']['status'] == 'complete'
215
203
216 # SyntaxError should mean it's complete
204 # SyntaxError should mean it's complete
217 kc.is_complete('raise = 2')
205 kc.is_complete('raise = 2')
218 reply = kc.get_shell_msg(block=True, timeout=TIMEOUT)
206 reply = kc.get_shell_msg(block=True, timeout=TIMEOUT)
219 assert reply['content']['status'] == 'invalid'
207 assert reply['content']['status'] == 'invalid'
@@ -221,4 +209,20 b' def test_is_complete():'
221 kc.is_complete('a = [1,\n2,')
209 kc.is_complete('a = [1,\n2,')
222 reply = kc.get_shell_msg(block=True, timeout=TIMEOUT)
210 reply = kc.get_shell_msg(block=True, timeout=TIMEOUT)
223 assert reply['content']['status'] == 'incomplete'
211 assert reply['content']['status'] == 'incomplete'
224 assert reply['content']['indent'] == '' No newline at end of file
212 assert reply['content']['indent'] == ''
213
214 def test_complete():
215 with kernel() as kc:
216 execute(u'a = 1', kc=kc)
217 wait_for_idle(kc)
218 cell = 'import IPython\nb = a.'
219 kc.complete(cell)
220 reply = kc.get_shell_msg(block=True, timeout=TIMEOUT)
221 c = reply['content']
222 nt.assert_equal(c['status'], 'ok')
223 nt.assert_equal(c['cursor_start'], cell.find('a.'))
224 nt.assert_equal(c['cursor_end'], cell.find('a.') + 2)
225 matches = c['matches']
226 nt.assert_greater(len(matches), 0)
227 for match in matches:
228 nt.assert_equal(match[:2], 'a.')
@@ -79,6 +79,8 b' def start_global_kernel():'
79 if KM is None:
79 if KM is None:
80 KM, KC = start_new_kernel()
80 KM, KC = start_new_kernel()
81 atexit.register(stop_global_kernel)
81 atexit.register(stop_global_kernel)
82 else:
83 flush_channels(KC)
82 return KC
84 return KC
83
85
84 @contextmanager
86 @contextmanager
@@ -6,7 +6,7 b' import traceback'
6
6
7 from IPython.core import release
7 from IPython.core import release
8 from IPython.utils.py3compat import builtin_mod, PY3
8 from IPython.utils.py3compat import builtin_mod, PY3
9 from IPython.utils.tokenutil import token_at_cursor
9 from IPython.utils.tokenutil import token_at_cursor, line_at_cursor
10 from IPython.utils.traitlets import Instance, Type, Any
10 from IPython.utils.traitlets import Instance, Type, Any
11 from IPython.utils.decorators import undoc
11 from IPython.utils.decorators import undoc
12
12
@@ -186,7 +186,15 b' class IPythonKernel(KernelBase):'
186 return reply_content
186 return reply_content
187
187
188 def do_complete(self, code, cursor_pos):
188 def do_complete(self, code, cursor_pos):
189 txt, matches = self.shell.complete('', code, cursor_pos)
189 # FIXME: IPython completers currently assume single line,
190 # but completion messages give multi-line context
191 # For now, extract line from cell, based on cursor_pos:
192 if cursor_pos is None:
193 cursor_pos = len(code)
194 line, offset = line_at_cursor(code, cursor_pos)
195 line_cursor = cursor_pos - offset
196
197 txt, matches = self.shell.complete('', line, line_cursor)
190 return {'matches' : matches,
198 return {'matches' : matches,
191 'cursor_end' : cursor_pos,
199 'cursor_end' : cursor_pos,
192 'cursor_start' : cursor_pos - len(txt),
200 'cursor_start' : cursor_pos - len(txt),
@@ -23,6 +23,34 b' def generate_tokens(readline):'
23 # catch EOF error
23 # catch EOF error
24 return
24 return
25
25
26 def line_at_cursor(cell, cursor_pos=0):
27 """Return the line in a cell at a given cursor position
28
29 Used for calling line-based APIs that don't support multi-line input, yet.
30
31 Parameters
32 ----------
33
34 cell: text
35 multiline block of text
36 cursor_pos: integer
37 the cursor position
38
39 Returns
40 -------
41
42 (line, offset): (text, integer)
43 The line with the current cursor, and the character offset of the start of the line.
44 """
45 offset = 0
46 lines = cell.splitlines(True)
47 for line in lines:
48 next_offset = offset + len(line)
49 if next_offset >= cursor_pos:
50 break
51 offset = next_offset
52 return (line, offset)
53
26 def token_at_cursor(cell, cursor_pos=0):
54 def token_at_cursor(cell, cursor_pos=0):
27 """Get the token at a given cursor
55 """Get the token at a given cursor
28
56
General Comments 0
You need to be logged in to leave comments. Login now