##// END OF EJS Templates
allow IPython.zmq.completer to be imported without readline...
MinRK -
Show More
@@ -1,87 +1,91 b''
1 """Tab-completion over zmq"""
1 """Tab-completion over zmq"""
2
2
3 # Trying to get print statements to work during completion, not very
3 # Trying to get print statements to work during completion, not very
4 # successfully...
4 # successfully...
5 from __future__ import print_function
5 from __future__ import print_function
6
6
7 import itertools
7 import itertools
8 import readline
8 try:
9 import readline
10 except ImportError:
11 readline = None
9 import rlcompleter
12 import rlcompleter
10 import time
13 import time
11
14
12 import session
15 import session
13
16
14 class KernelCompleter(object):
17 class KernelCompleter(object):
15 """Kernel-side completion machinery."""
18 """Kernel-side completion machinery."""
16 def __init__(self, namespace):
19 def __init__(self, namespace):
17 self.namespace = namespace
20 self.namespace = namespace
18 self.completer = rlcompleter.Completer(namespace)
21 self.completer = rlcompleter.Completer(namespace)
19
22
20 def complete(self, line, text):
23 def complete(self, line, text):
21 # We'll likely use linel later even if now it's not used for anything
24 # We'll likely use linel later even if now it's not used for anything
22 matches = []
25 matches = []
23 complete = self.completer.complete
26 complete = self.completer.complete
24 for state in itertools.count():
27 for state in itertools.count():
25 comp = complete(text, state)
28 comp = complete(text, state)
26 if comp is None:
29 if comp is None:
27 break
30 break
28 matches.append(comp)
31 matches.append(comp)
29 return matches
32 return matches
30
33
31
34
32 class ClientCompleter(object):
35 class ClientCompleter(object):
33 """Client-side completion machinery.
36 """Client-side completion machinery.
34
37
35 How it works: self.complete will be called multiple times, with
38 How it works: self.complete will be called multiple times, with
36 state=0,1,2,... When state=0 it should compute ALL the completion matches,
39 state=0,1,2,... When state=0 it should compute ALL the completion matches,
37 and then return them for each value of state."""
40 and then return them for each value of state."""
38
41
39 def __init__(self, client, session, socket):
42 def __init__(self, client, session, socket):
40 # ugly, but we get called asynchronously and need access to some
43 # ugly, but we get called asynchronously and need access to some
41 # client state, like backgrounded code
44 # client state, like backgrounded code
45 assert readline is not None, "ClientCompleter depends on readline"
42 self.client = client
46 self.client = client
43 self.session = session
47 self.session = session
44 self.socket = socket
48 self.socket = socket
45 self.matches = []
49 self.matches = []
46
50
47 def request_completion(self, text):
51 def request_completion(self, text):
48 # Get full line to give to the kernel in case it wants more info.
52 # Get full line to give to the kernel in case it wants more info.
49 line = readline.get_line_buffer()
53 line = readline.get_line_buffer()
50 # send completion request to kernel
54 # send completion request to kernel
51 msg = self.session.send(self.socket,
55 msg = self.session.send(self.socket,
52 'complete_request',
56 'complete_request',
53 dict(text=text, line=line))
57 dict(text=text, line=line))
54
58
55 # Give the kernel up to 0.5s to respond
59 # Give the kernel up to 0.5s to respond
56 for i in range(5):
60 for i in range(5):
57 ident,rep = self.session.recv(self.socket)
61 ident,rep = self.session.recv(self.socket)
58 rep = Message(rep)
62 rep = Message(rep)
59 if rep is not None and rep.msg_type == 'complete_reply':
63 if rep is not None and rep.msg_type == 'complete_reply':
60 matches = rep.content.matches
64 matches = rep.content.matches
61 break
65 break
62 time.sleep(0.1)
66 time.sleep(0.1)
63 else:
67 else:
64 # timeout
68 # timeout
65 print ('TIMEOUT') # Can't see this message...
69 print ('TIMEOUT') # Can't see this message...
66 matches = None
70 matches = None
67 return matches
71 return matches
68
72
69 def complete(self, text, state):
73 def complete(self, text, state):
70
74
71 if self.client.backgrounded > 0:
75 if self.client.backgrounded > 0:
72 print("\n[Not completing, background tasks active]")
76 print("\n[Not completing, background tasks active]")
73 print(readline.get_line_buffer(), end='')
77 print(readline.get_line_buffer(), end='')
74 return None
78 return None
75
79
76 if state==0:
80 if state==0:
77 matches = self.request_completion(text)
81 matches = self.request_completion(text)
78 if matches is None:
82 if matches is None:
79 self.matches = []
83 self.matches = []
80 print('WARNING: Kernel timeout on tab completion.')
84 print('WARNING: Kernel timeout on tab completion.')
81 else:
85 else:
82 self.matches = matches
86 self.matches = matches
83
87
84 try:
88 try:
85 return self.matches[state]
89 return self.matches[state]
86 except IndexError:
90 except IndexError:
87 return None
91 return None
General Comments 0
You need to be logged in to leave comments. Login now