Show More
@@ -1,75 +1,75 | |||||
1 | """ Greedy completer extension for IPython |
|
1 | """ Greedy completer extension for IPython | |
2 |
|
2 | |||
3 | Normal tab completer refuses to evaluate nonsafe stuff. This will evaluate |
|
3 | Normal tab completer refuses to evaluate nonsafe stuff. This will evaluate | |
4 | everything, so you need to consider the consequences of pressing tab |
|
4 | everything, so you need to consider the consequences of pressing tab | |
5 | yourself! |
|
5 | yourself! | |
6 |
|
6 | |||
7 | Note that this extension simplifies readline interaction by setting |
|
7 | Note that this extension simplifies readline interaction by setting | |
8 | only whitespace as completer delimiter. If this works well, we will |
|
8 | only whitespace as completer delimiter. If this works well, we will | |
9 | do the same in default completer. |
|
9 | do the same in default completer. | |
10 |
|
10 | |||
11 | """ |
|
11 | """ | |
12 | from IPython import generics,ipapi |
|
12 | from IPython import generics,ipapi | |
13 | from IPython.genutils import dir2 |
|
13 | from IPython.genutils import dir2 | |
14 |
|
14 | |||
15 | def attr_matches(self, text): |
|
15 | def attr_matches(self, text): | |
16 | """Compute matches when text contains a dot. |
|
16 | """Compute matches when text contains a dot. | |
17 |
|
17 | |||
18 | MONKEYPATCHED VERSION (ipy_greedycompleter.py) |
|
18 | MONKEYPATCHED VERSION (ipy_greedycompleter.py) | |
19 |
|
19 | |||
20 | Assuming the text is of the form NAME.NAME....[NAME], and is |
|
20 | Assuming the text is of the form NAME.NAME....[NAME], and is | |
21 | evaluatable in self.namespace or self.global_namespace, it will be |
|
21 | evaluatable in self.namespace or self.global_namespace, it will be | |
22 | evaluated and its attributes (as revealed by dir()) are used as |
|
22 | evaluated and its attributes (as revealed by dir()) are used as | |
23 | possible completions. (For class instances, class members are are |
|
23 | possible completions. (For class instances, class members are are | |
24 | also considered.) |
|
24 | also considered.) | |
25 |
|
25 | |||
26 | WARNING: this can still invoke arbitrary C code, if an object |
|
26 | WARNING: this can still invoke arbitrary C code, if an object | |
27 | with a __getattr__ hook is evaluated. |
|
27 | with a __getattr__ hook is evaluated. | |
28 |
|
28 | |||
29 | """ |
|
29 | """ | |
30 | import re |
|
30 | import re | |
31 |
|
31 | |||
32 | force_complete = 1 |
|
32 | force_complete = 1 | |
33 | # Another option, seems to work great. Catches things like ''.<tab> |
|
33 | # Another option, seems to work great. Catches things like ''.<tab> | |
34 | m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text) |
|
34 | m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text) | |
35 |
|
35 | |||
36 | if m: |
|
36 | if m: | |
37 | expr, attr = m.group(1, 3) |
|
37 | expr, attr = m.group(1, 3) | |
38 | else: |
|
38 | else: | |
39 | # force match - eval anything that ends with colon |
|
39 | # force match - eval anything that ends with colon | |
40 | if not force_complete: |
|
40 | if not force_complete: | |
41 | return [] |
|
41 | return [] | |
42 |
|
42 | |||
43 | m2 = re.match(r"(.+)\.(\w*)$", self.lbuf) |
|
43 | m2 = re.match(r"(.+)\.(\w*)$", self.lbuf) | |
44 | if not m2: |
|
44 | if not m2: | |
45 | return [] |
|
45 | return [] | |
46 | expr, attr = m2.group(1,2) |
|
46 | expr, attr = m2.group(1,2) | |
47 |
|
47 | |||
48 |
|
48 | |||
49 | try: |
|
49 | try: | |
50 | obj = eval(expr, self.namespace) |
|
50 | obj = eval(expr, self.namespace) | |
51 | except: |
|
51 | except: | |
52 | try: |
|
52 | try: | |
53 | obj = eval(expr, self.global_namespace) |
|
53 | obj = eval(expr, self.global_namespace) | |
54 | except: |
|
54 | except: | |
55 | return [] |
|
55 | return [] | |
56 |
|
56 | |||
57 | words = dir2(obj) |
|
57 | words = dir2(obj) | |
58 |
|
58 | |||
59 | try: |
|
59 | try: | |
60 | words = generics.complete_object(obj, words) |
|
60 | words = generics.complete_object(obj, words) | |
61 | except ipapi.TryNext: |
|
61 | except ipapi.TryNext: | |
62 | pass |
|
62 | pass | |
63 | # Build match list to return |
|
63 | # Build match list to return | |
64 | n = len(attr) |
|
64 | n = len(attr) | |
65 | res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ] |
|
65 | res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ] | |
66 | return res |
|
66 | return res | |
67 |
|
67 | |||
68 | def main(): |
|
68 | def main(): | |
69 | import readline |
|
69 | import IPython.rlineimpl as readline | |
70 | readline.set_completer_delims(" \n\t") |
|
70 | readline.set_completer_delims(" \n\t") | |
71 | # monkeypatch - the code will be folded to normal completer later on |
|
71 | # monkeypatch - the code will be folded to normal completer later on | |
72 | import IPython.completer |
|
72 | import IPython.completer | |
73 | IPython.completer.Completer.attr_matches = attr_matches |
|
73 | IPython.completer.Completer.attr_matches = attr_matches | |
74 |
|
74 | |||
75 | main() No newline at end of file |
|
75 | main() |
General Comments 0
You need to be logged in to leave comments.
Login now