##// END OF EJS Templates
Improvements to tab completion in Qt GUI with new api....
Fernando Perez -
Show More
@@ -193,7 +193,7 b' class CompletionSplitter(object):'
193 193
194 194
195 195 class Completer(object):
196 def __init__(self,namespace=None,global_namespace=None):
196 def __init__(self, namespace=None, global_namespace=None):
197 197 """Create a new completer for the command line.
198 198
199 199 Completer([namespace,global_namespace]) -> completer instance.
@@ -343,10 +343,12 b' class IPCompleter(Completer):'
343 343 without readline, though in that case callers must provide some extra
344 344 information on each call about the current line."""
345 345
346 Completer.__init__(self,namespace,global_namespace)
346 Completer.__init__(self, namespace, global_namespace)
347 347
348 348 self.magic_escape = ESC_MAGIC
349 349
350 self.splitter = CompletionSplitter()
351
350 352 # Readline-dependent code
351 353 self.use_readline = use_readline
352 354 if use_readline:
@@ -662,16 +664,20 b' class IPCompleter(Completer):'
662 664
663 665 return None
664 666
665 def complete(self, text, line_buffer, cursor_pos=None):
667 def complete(self, text=None, line_buffer=None, cursor_pos=None):
666 668 """Return the state-th possible completion for 'text'.
667 669
668 670 This is called successively with state == 0, 1, 2, ... until it
669 671 returns None. The completion should begin with 'text'.
670 672
673 Note that both the text and the line_buffer are optional, but at least
674 one of them must be given.
675
671 676 Parameters
672 677 ----------
673 text : string
674 Text to perform the completion on.
678 text : string, optional
679 Text to perform the completion on. If not given, the line buffer
680 is split using the instance's CompletionSplitter object.
675 681
676 682 line_buffer : string, optional
677 683 If not given, the completer attempts to obtain the current line
@@ -683,7 +689,20 b' class IPCompleter(Completer):'
683 689 Index of the cursor in the full line buffer. Should be provided by
684 690 remote frontends where kernel has no access to frontend state.
685 691 """
686 #io.rprint('COMP', text, line_buffer, cursor_pos) # dbg
692 #io.rprint('COMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
693
694 # if the cursor position isn't given, the only sane assumption we can
695 # make is that it's at the end of the line (the common case)
696 if cursor_pos is None:
697 cursor_pos = len(line_buffer) if text is None else len(text)
698
699 # if text is either None or an empty string, rely on the line buffer
700 if not text:
701 text = self.splitter.split_line(line_buffer, cursor_pos)
702
703 # If no line buffer is given, assume the input text is all there was
704 if line_buffer is None:
705 line_buffer = text
687 706
688 707 magic_escape = self.magic_escape
689 708 self.full_lbuf = line_buffer
@@ -692,6 +711,8 b' class IPCompleter(Completer):'
692 711 if text.startswith('~'):
693 712 text = os.path.expanduser(text)
694 713
714 #io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
715
695 716 # Start with a clean slate of completions
696 717 self.matches[:] = []
697 718 custom_res = self.dispatch_custom_completer(text)
@@ -716,8 +737,8 b' class IPCompleter(Completer):'
716 737 # simply collapse the dict into a list for readline, but we'd have
717 738 # richer completion semantics in other evironments.
718 739 self.matches = sorted(set(self.matches))
719 #io.rprint('MATCHES', self.matches) # dbg
720 return self.matches
740 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
741 return text, self.matches
721 742
722 743 def rlcomplete(self, text, state):
723 744 """Return the state-th possible completion for 'text'.
@@ -1370,13 +1370,15 b' class InteractiveShell(Configurable, Magic):'
1370 1370 #-------------------------------------------------------------------------
1371 1371
1372 1372 def complete(self, text, line=None, cursor_pos=None):
1373 """Return a sorted list of all possible completions on text.
1373 """Return the completed text and a list of completions.
1374 1374
1375 1375 Parameters
1376 1376 ----------
1377 1377
1378 1378 text : string
1379 A string of text to be completed on.
1379 A string of text to be completed on. It can be given as empty and
1380 instead a line/position pair are given. In this case, the
1381 completer itself will split the line like readline does.
1380 1382
1381 1383 line : string, optional
1382 1384 The complete line that text is part of.
@@ -1384,6 +1386,14 b' class InteractiveShell(Configurable, Magic):'
1384 1386 cursor_pos : int, optional
1385 1387 The position of the cursor on the input line.
1386 1388
1389 Returns
1390 -------
1391 text : string
1392 The actual text that was completed.
1393
1394 matches : list
1395 A sorted list with all possible completions.
1396
1387 1397 The optional arguments allow the completion to take more context into
1388 1398 account, and are part of the low-level completion API.
1389 1399
@@ -1394,23 +1404,17 b' class InteractiveShell(Configurable, Magic):'
1394 1404
1395 1405 Simple usage example:
1396 1406
1397 In [7]: x = 'hello'
1398
1399 In [8]: x
1400 Out[8]: 'hello'
1401
1402 In [9]: print x
1403 hello
1407 In [1]: x = 'hello'
1404 1408
1405 In [10]: _ip.complete('x.l')
1406 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1409 In [2]: _ip.complete('x.l')
1410 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1407 1411 """
1408 1412
1409 1413 # Inject names into __builtin__ so we can complete on the added names.
1410 1414 with self.builtin_trap:
1411 return self.Completer.complete(text,line_buffer=text)
1415 return self.Completer.complete(text, line, cursor_pos)
1412 1416
1413 def set_custom_completer(self,completer,pos=0):
1417 def set_custom_completer(self, completer, pos=0):
1414 1418 """Adds a new custom completer function.
1415 1419
1416 1420 The position argument (defaults to 0) is the index in the completers
@@ -69,10 +69,9 b' class CompletionSplitterTestCase(unittest.TestCase):'
69 69 self.sp = completer.CompletionSplitter()
70 70
71 71 def test_delim_setting(self):
72 self.sp.delims = ' '
73 # Validate that property handling works ok
74 nt.assert_equal(self.sp.delims, ' ')
75 nt.assert_equal(self.sp.delim_expr, '[\ ]')
72 self.sp.set_delims(' ')
73 nt.assert_equal(self.sp.get_delims(), ' ')
74 nt.assert_equal(self.sp._delim_expr, '[\ ]')
76 75
77 76 def test_spaces(self):
78 77 """Test with only spaces as split chars."""
@@ -181,7 +181,10 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
181 181 cursor = self._get_cursor()
182 182 if rep['parent_header']['msg_id'] == self._complete_id and \
183 183 cursor.position() == self._complete_pos:
184 text = '.'.join(self._get_context())
184 # The completer tells us what text was actually used for the
185 # matching, so we must move that many characters left to apply the
186 # completions.
187 text = rep['content']['matched_text']
185 188 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
186 189 self._complete_with_items(cursor, rep['content']['matches'])
187 190
@@ -294,14 +297,22 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
294 297 """ Performs completion at the current cursor location.
295 298 """
296 299 # Decide if it makes sense to do completion
297 context = self._get_context()
298 if not context:
300
301 # We should return only if the line is empty. Otherwise, let the
302 # kernel split the line up.
303 line = self._get_input_buffer_cursor_line()
304 if not line:
299 305 return False
300 306
307 # We let the kernel split the input line, so we *always* send an empty
308 # text field. Readline-based frontends do get a real text field which
309 # they can use.
310 text = ''
311
301 312 # Send the completion request to the kernel
302 313 self._complete_id = self.kernel_manager.xreq_channel.complete(
303 '.'.join(context), # text
304 self._get_input_buffer_cursor_line(), # line
314 text, # text
315 line, # line
305 316 self._get_input_buffer_cursor_column(), # cursor_pos
306 317 self.input_buffer) # block
307 318 self._complete_pos = self._get_cursor().position()
General Comments 0
You need to be logged in to leave comments. Login now