##// END OF EJS Templates
Fix Emacs tab-completion support....
Fernando Perez -
Show More
@@ -1,658 +1,658 b''
1 """Word completion for IPython.
1 """Word completion for IPython.
2
2
3 This module is a fork of the rlcompleter module in the Python standard
3 This module is a fork of the rlcompleter module in the Python standard
4 library. The original enhancements made to rlcompleter have been sent
4 library. The original enhancements made to rlcompleter have been sent
5 upstream and were accepted as of Python 2.3, but we need a lot more
5 upstream and were accepted as of Python 2.3, but we need a lot more
6 functionality specific to IPython, so this module will continue to live as an
6 functionality specific to IPython, so this module will continue to live as an
7 IPython-specific utility.
7 IPython-specific utility.
8
8
9 Original rlcompleter documentation:
9 Original rlcompleter documentation:
10
10
11 This requires the latest extension to the readline module (the
11 This requires the latest extension to the readline module (the
12 completes keywords, built-ins and globals in __main__; when completing
12 completes keywords, built-ins and globals in __main__; when completing
13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 completes its attributes.
14 completes its attributes.
15
15
16 It's very cool to do "import string" type "string.", hit the
16 It's very cool to do "import string" type "string.", hit the
17 completion key (twice), and see the list of names defined by the
17 completion key (twice), and see the list of names defined by the
18 string module!
18 string module!
19
19
20 Tip: to use the tab key as the completion key, call
20 Tip: to use the tab key as the completion key, call
21
21
22 readline.parse_and_bind("tab: complete")
22 readline.parse_and_bind("tab: complete")
23
23
24 Notes:
24 Notes:
25
25
26 - Exceptions raised by the completer function are *ignored* (and
26 - Exceptions raised by the completer function are *ignored* (and
27 generally cause the completion to fail). This is a feature -- since
27 generally cause the completion to fail). This is a feature -- since
28 readline sets the tty device in raw (or cbreak) mode, printing a
28 readline sets the tty device in raw (or cbreak) mode, printing a
29 traceback wouldn't work well without some complicated hoopla to save,
29 traceback wouldn't work well without some complicated hoopla to save,
30 reset and restore the tty state.
30 reset and restore the tty state.
31
31
32 - The evaluation of the NAME.NAME... form may cause arbitrary
32 - The evaluation of the NAME.NAME... form may cause arbitrary
33 application defined code to be executed if an object with a
33 application defined code to be executed if an object with a
34 __getattr__ hook is found. Since it is the responsibility of the
34 __getattr__ hook is found. Since it is the responsibility of the
35 application (or the user) to enable this feature, I consider this an
35 application (or the user) to enable this feature, I consider this an
36 acceptable risk. More complicated expressions (e.g. function calls or
36 acceptable risk. More complicated expressions (e.g. function calls or
37 indexing operations) are *not* evaluated.
37 indexing operations) are *not* evaluated.
38
38
39 - GNU readline is also used by the built-in functions input() and
39 - GNU readline is also used by the built-in functions input() and
40 raw_input(), and thus these also benefit/suffer from the completer
40 raw_input(), and thus these also benefit/suffer from the completer
41 features. Clearly an interactive application can benefit by
41 features. Clearly an interactive application can benefit by
42 specifying its own completer function and using raw_input() for all
42 specifying its own completer function and using raw_input() for all
43 its input.
43 its input.
44
44
45 - When the original stdin is not a tty device, GNU readline is never
45 - When the original stdin is not a tty device, GNU readline is never
46 used, and this module (and the readline module) are silently inactive.
46 used, and this module (and the readline module) are silently inactive.
47 """
47 """
48
48
49 #*****************************************************************************
49 #*****************************************************************************
50 #
50 #
51 # Since this file is essentially a minimally modified copy of the rlcompleter
51 # Since this file is essentially a minimally modified copy of the rlcompleter
52 # module which is part of the standard Python distribution, I assume that the
52 # module which is part of the standard Python distribution, I assume that the
53 # proper procedure is to maintain its copyright as belonging to the Python
53 # proper procedure is to maintain its copyright as belonging to the Python
54 # Software Foundation (in addition to my own, for all new code).
54 # Software Foundation (in addition to my own, for all new code).
55 #
55 #
56 # Copyright (C) 2008-2010 IPython Development Team
56 # Copyright (C) 2008-2010 IPython Development Team
57 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
57 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 #
59 #
60 # Distributed under the terms of the BSD License. The full license is in
60 # Distributed under the terms of the BSD License. The full license is in
61 # the file COPYING, distributed as part of this software.
61 # the file COPYING, distributed as part of this software.
62 #
62 #
63 #*****************************************************************************
63 #*****************************************************************************
64
64
65 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
66 # Imports
66 # Imports
67 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
68
68
69 import __builtin__
69 import __builtin__
70 import __main__
70 import __main__
71 import glob
71 import glob
72 import inspect
72 import inspect
73 import itertools
73 import itertools
74 import keyword
74 import keyword
75 import os
75 import os
76 import re
76 import re
77 import shlex
77 import shlex
78 import sys
78 import sys
79
79
80 from IPython.core.error import TryNext
80 from IPython.core.error import TryNext
81 from IPython.core.prefilter import ESC_MAGIC
81 from IPython.core.prefilter import ESC_MAGIC
82 from IPython.utils import generics
82 from IPython.utils import generics
83 from IPython.utils.frame import debugx
83 from IPython.utils.frame import debugx
84 from IPython.utils.dir2 import dir2
84 from IPython.utils.dir2 import dir2
85 import IPython.utils.rlineimpl as readline
85 import IPython.utils.rlineimpl as readline
86
86
87 #-----------------------------------------------------------------------------
87 #-----------------------------------------------------------------------------
88 # Globals
88 # Globals
89 #-----------------------------------------------------------------------------
89 #-----------------------------------------------------------------------------
90
90
91 # Public API
91 # Public API
92 __all__ = ['Completer','IPCompleter']
92 __all__ = ['Completer','IPCompleter']
93
93
94 if sys.platform == 'win32':
94 if sys.platform == 'win32':
95 PROTECTABLES = ' '
95 PROTECTABLES = ' '
96 else:
96 else:
97 PROTECTABLES = ' ()'
97 PROTECTABLES = ' ()'
98
98
99 #-----------------------------------------------------------------------------
99 #-----------------------------------------------------------------------------
100 # Main functions and classes
100 # Main functions and classes
101 #-----------------------------------------------------------------------------
101 #-----------------------------------------------------------------------------
102
102
103 def protect_filename(s):
103 def protect_filename(s):
104 """Escape a string to protect certain characters."""
104 """Escape a string to protect certain characters."""
105
105
106 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
106 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
107 for ch in s])
107 for ch in s])
108
108
109
109
110 def single_dir_expand(matches):
110 def single_dir_expand(matches):
111 "Recursively expand match lists containing a single dir."
111 "Recursively expand match lists containing a single dir."
112
112
113 if len(matches) == 1 and os.path.isdir(matches[0]):
113 if len(matches) == 1 and os.path.isdir(matches[0]):
114 # Takes care of links to directories also. Use '/'
114 # Takes care of links to directories also. Use '/'
115 # explicitly, even under Windows, so that name completions
115 # explicitly, even under Windows, so that name completions
116 # don't end up escaped.
116 # don't end up escaped.
117 d = matches[0]
117 d = matches[0]
118 if d[-1] in ['/','\\']:
118 if d[-1] in ['/','\\']:
119 d = d[:-1]
119 d = d[:-1]
120
120
121 subdirs = os.listdir(d)
121 subdirs = os.listdir(d)
122 if subdirs:
122 if subdirs:
123 matches = [ (d + '/' + p) for p in subdirs]
123 matches = [ (d + '/' + p) for p in subdirs]
124 return single_dir_expand(matches)
124 return single_dir_expand(matches)
125 else:
125 else:
126 return matches
126 return matches
127 else:
127 else:
128 return matches
128 return matches
129
129
130 class Bunch: pass
130 class Bunch: pass
131
131
132 class Completer:
132 class Completer:
133 def __init__(self,namespace=None,global_namespace=None):
133 def __init__(self,namespace=None,global_namespace=None):
134 """Create a new completer for the command line.
134 """Create a new completer for the command line.
135
135
136 Completer([namespace,global_namespace]) -> completer instance.
136 Completer([namespace,global_namespace]) -> completer instance.
137
137
138 If unspecified, the default namespace where completions are performed
138 If unspecified, the default namespace where completions are performed
139 is __main__ (technically, __main__.__dict__). Namespaces should be
139 is __main__ (technically, __main__.__dict__). Namespaces should be
140 given as dictionaries.
140 given as dictionaries.
141
141
142 An optional second namespace can be given. This allows the completer
142 An optional second namespace can be given. This allows the completer
143 to handle cases where both the local and global scopes need to be
143 to handle cases where both the local and global scopes need to be
144 distinguished.
144 distinguished.
145
145
146 Completer instances should be used as the completion mechanism of
146 Completer instances should be used as the completion mechanism of
147 readline via the set_completer() call:
147 readline via the set_completer() call:
148
148
149 readline.set_completer(Completer(my_namespace).complete)
149 readline.set_completer(Completer(my_namespace).complete)
150 """
150 """
151
151
152 # Don't bind to namespace quite yet, but flag whether the user wants a
152 # Don't bind to namespace quite yet, but flag whether the user wants a
153 # specific namespace or to use __main__.__dict__. This will allow us
153 # specific namespace or to use __main__.__dict__. This will allow us
154 # to bind to __main__.__dict__ at completion time, not now.
154 # to bind to __main__.__dict__ at completion time, not now.
155 if namespace is None:
155 if namespace is None:
156 self.use_main_ns = 1
156 self.use_main_ns = 1
157 else:
157 else:
158 self.use_main_ns = 0
158 self.use_main_ns = 0
159 self.namespace = namespace
159 self.namespace = namespace
160
160
161 # The global namespace, if given, can be bound directly
161 # The global namespace, if given, can be bound directly
162 if global_namespace is None:
162 if global_namespace is None:
163 self.global_namespace = {}
163 self.global_namespace = {}
164 else:
164 else:
165 self.global_namespace = global_namespace
165 self.global_namespace = global_namespace
166
166
167 def complete(self, text, state):
167 def complete(self, text, state):
168 """Return the next possible completion for 'text'.
168 """Return the next possible completion for 'text'.
169
169
170 This is called successively with state == 0, 1, 2, ... until it
170 This is called successively with state == 0, 1, 2, ... until it
171 returns None. The completion should begin with 'text'.
171 returns None. The completion should begin with 'text'.
172
172
173 """
173 """
174 if self.use_main_ns:
174 if self.use_main_ns:
175 self.namespace = __main__.__dict__
175 self.namespace = __main__.__dict__
176
176
177 if state == 0:
177 if state == 0:
178 if "." in text:
178 if "." in text:
179 self.matches = self.attr_matches(text)
179 self.matches = self.attr_matches(text)
180 else:
180 else:
181 self.matches = self.global_matches(text)
181 self.matches = self.global_matches(text)
182 try:
182 try:
183 return self.matches[state]
183 return self.matches[state]
184 except IndexError:
184 except IndexError:
185 return None
185 return None
186
186
187 def global_matches(self, text):
187 def global_matches(self, text):
188 """Compute matches when text is a simple name.
188 """Compute matches when text is a simple name.
189
189
190 Return a list of all keywords, built-in functions and names currently
190 Return a list of all keywords, built-in functions and names currently
191 defined in self.namespace or self.global_namespace that match.
191 defined in self.namespace or self.global_namespace that match.
192
192
193 """
193 """
194 #print 'Completer->global_matches, txt=%r' % text # dbg
194 #print 'Completer->global_matches, txt=%r' % text # dbg
195 matches = []
195 matches = []
196 match_append = matches.append
196 match_append = matches.append
197 n = len(text)
197 n = len(text)
198 for lst in [keyword.kwlist,
198 for lst in [keyword.kwlist,
199 __builtin__.__dict__.keys(),
199 __builtin__.__dict__.keys(),
200 self.namespace.keys(),
200 self.namespace.keys(),
201 self.global_namespace.keys()]:
201 self.global_namespace.keys()]:
202 for word in lst:
202 for word in lst:
203 if word[:n] == text and word != "__builtins__":
203 if word[:n] == text and word != "__builtins__":
204 match_append(word)
204 match_append(word)
205 return matches
205 return matches
206
206
207 def attr_matches(self, text):
207 def attr_matches(self, text):
208 """Compute matches when text contains a dot.
208 """Compute matches when text contains a dot.
209
209
210 Assuming the text is of the form NAME.NAME....[NAME], and is
210 Assuming the text is of the form NAME.NAME....[NAME], and is
211 evaluatable in self.namespace or self.global_namespace, it will be
211 evaluatable in self.namespace or self.global_namespace, it will be
212 evaluated and its attributes (as revealed by dir()) are used as
212 evaluated and its attributes (as revealed by dir()) are used as
213 possible completions. (For class instances, class members are are
213 possible completions. (For class instances, class members are are
214 also considered.)
214 also considered.)
215
215
216 WARNING: this can still invoke arbitrary C code, if an object
216 WARNING: this can still invoke arbitrary C code, if an object
217 with a __getattr__ hook is evaluated.
217 with a __getattr__ hook is evaluated.
218
218
219 """
219 """
220
220
221 #print 'Completer->attr_matches, txt=%r' % text # dbg
221 #print 'Completer->attr_matches, txt=%r' % text # dbg
222 # Another option, seems to work great. Catches things like ''.<tab>
222 # Another option, seems to work great. Catches things like ''.<tab>
223 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
223 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
224
224
225 if not m:
225 if not m:
226 return []
226 return []
227
227
228 expr, attr = m.group(1, 3)
228 expr, attr = m.group(1, 3)
229 try:
229 try:
230 obj = eval(expr, self.namespace)
230 obj = eval(expr, self.namespace)
231 except:
231 except:
232 try:
232 try:
233 obj = eval(expr, self.global_namespace)
233 obj = eval(expr, self.global_namespace)
234 except:
234 except:
235 return []
235 return []
236
236
237 words = dir2(obj)
237 words = dir2(obj)
238
238
239 try:
239 try:
240 words = generics.complete_object(obj, words)
240 words = generics.complete_object(obj, words)
241 except TryNext:
241 except TryNext:
242 pass
242 pass
243 # Build match list to return
243 # Build match list to return
244 n = len(attr)
244 n = len(attr)
245 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
245 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
246 return res
246 return res
247
247
248
248
249 class IPCompleter(Completer):
249 class IPCompleter(Completer):
250 """Extension of the completer class with IPython-specific features"""
250 """Extension of the completer class with IPython-specific features"""
251
251
252 def __init__(self,shell,namespace=None,global_namespace=None,
252 def __init__(self,shell,namespace=None,global_namespace=None,
253 omit__names=0,alias_table=None):
253 omit__names=0,alias_table=None):
254 """IPCompleter() -> completer
254 """IPCompleter() -> completer
255
255
256 Return a completer object suitable for use by the readline library
256 Return a completer object suitable for use by the readline library
257 via readline.set_completer().
257 via readline.set_completer().
258
258
259 Inputs:
259 Inputs:
260
260
261 - shell: a pointer to the ipython shell itself. This is needed
261 - shell: a pointer to the ipython shell itself. This is needed
262 because this completer knows about magic functions, and those can
262 because this completer knows about magic functions, and those can
263 only be accessed via the ipython instance.
263 only be accessed via the ipython instance.
264
264
265 - namespace: an optional dict where completions are performed.
265 - namespace: an optional dict where completions are performed.
266
266
267 - global_namespace: secondary optional dict for completions, to
267 - global_namespace: secondary optional dict for completions, to
268 handle cases (such as IPython embedded inside functions) where
268 handle cases (such as IPython embedded inside functions) where
269 both Python scopes are visible.
269 both Python scopes are visible.
270
270
271 - The optional omit__names parameter sets the completer to omit the
271 - The optional omit__names parameter sets the completer to omit the
272 'magic' names (__magicname__) for python objects unless the text
272 'magic' names (__magicname__) for python objects unless the text
273 to be completed explicitly starts with one or more underscores.
273 to be completed explicitly starts with one or more underscores.
274
274
275 - If alias_table is supplied, it should be a dictionary of aliases
275 - If alias_table is supplied, it should be a dictionary of aliases
276 to complete. """
276 to complete. """
277
277
278 Completer.__init__(self,namespace,global_namespace)
278 Completer.__init__(self,namespace,global_namespace)
279
279
280 self.magic_escape = ESC_MAGIC
280 self.magic_escape = ESC_MAGIC
281 self.readline = readline
281 self.readline = readline
282 delims = self.readline.get_completer_delims()
282 delims = self.readline.get_completer_delims()
283 delims = delims.replace(self.magic_escape,'')
283 delims = delims.replace(self.magic_escape,'')
284 self.readline.set_completer_delims(delims)
284 self.readline.set_completer_delims(delims)
285 self.get_line_buffer = self.readline.get_line_buffer
285 self.get_line_buffer = self.readline.get_line_buffer
286 self.get_endidx = self.readline.get_endidx
286 self.get_endidx = self.readline.get_endidx
287 self.omit__names = omit__names
287 self.omit__names = omit__names
288 self.merge_completions = shell.readline_merge_completions
288 self.merge_completions = shell.readline_merge_completions
289 self.shell = shell.shell
289 self.shell = shell.shell
290 if alias_table is None:
290 if alias_table is None:
291 alias_table = {}
291 alias_table = {}
292 self.alias_table = alias_table
292 self.alias_table = alias_table
293 # Regexp to split filenames with spaces in them
293 # Regexp to split filenames with spaces in them
294 self.space_name_re = re.compile(r'([^\\] )')
294 self.space_name_re = re.compile(r'([^\\] )')
295 # Hold a local ref. to glob.glob for speed
295 # Hold a local ref. to glob.glob for speed
296 self.glob = glob.glob
296 self.glob = glob.glob
297
297
298 # Determine if we are running on 'dumb' terminals, like (X)Emacs
298 # Determine if we are running on 'dumb' terminals, like (X)Emacs
299 # buffers, to avoid completion problems.
299 # buffers, to avoid completion problems.
300 term = os.environ.get('TERM','xterm')
300 term = os.environ.get('TERM','xterm')
301 self.dumb_terminal = term in ['dumb','emacs']
301 self.dumb_terminal = term in ['dumb','emacs']
302
302
303 # Special handling of backslashes needed in win32 platforms
303 # Special handling of backslashes needed in win32 platforms
304 if sys.platform == "win32":
304 if sys.platform == "win32":
305 self.clean_glob = self._clean_glob_win32
305 self.clean_glob = self._clean_glob_win32
306 else:
306 else:
307 self.clean_glob = self._clean_glob
307 self.clean_glob = self._clean_glob
308
308
309 # All active matcher routines for completion
309 # All active matcher routines for completion
310 self.matchers = [self.python_matches,
310 self.matchers = [self.python_matches,
311 self.file_matches,
311 self.file_matches,
312 self.magic_matches,
312 self.magic_matches,
313 self.alias_matches,
313 self.alias_matches,
314 self.python_func_kw_matches]
314 self.python_func_kw_matches]
315
315
316 # Code contributed by Alex Schmolck, for ipython/emacs integration
316 # Code contributed by Alex Schmolck, for ipython/emacs integration
317 def all_completions(self, text):
317 def all_completions(self, text):
318 """Return all possible completions for the benefit of emacs."""
318 """Return all possible completions for the benefit of emacs."""
319
319
320 completions = []
320 completions = []
321 comp_append = completions.append
321 comp_append = completions.append
322 try:
322 try:
323 for i in xrange(sys.maxint):
323 for i in xrange(sys.maxint):
324 res = self.complete(text, i)
324 res = self.complete(text, i, text)
325 if not res:
325 if not res:
326 break
326 break
327 comp_append(res)
327 comp_append(res)
328 #XXX workaround for ``notDefined.<tab>``
328 #XXX workaround for ``notDefined.<tab>``
329 except NameError:
329 except NameError:
330 pass
330 pass
331 return completions
331 return completions
332 # /end Alex Schmolck code.
332 # /end Alex Schmolck code.
333
333
334 def _clean_glob(self,text):
334 def _clean_glob(self,text):
335 return self.glob("%s*" % text)
335 return self.glob("%s*" % text)
336
336
337 def _clean_glob_win32(self,text):
337 def _clean_glob_win32(self,text):
338 return [f.replace("\\","/")
338 return [f.replace("\\","/")
339 for f in self.glob("%s*" % text)]
339 for f in self.glob("%s*" % text)]
340
340
341 def file_matches(self, text):
341 def file_matches(self, text):
342 """Match filenames, expanding ~USER type strings.
342 """Match filenames, expanding ~USER type strings.
343
343
344 Most of the seemingly convoluted logic in this completer is an
344 Most of the seemingly convoluted logic in this completer is an
345 attempt to handle filenames with spaces in them. And yet it's not
345 attempt to handle filenames with spaces in them. And yet it's not
346 quite perfect, because Python's readline doesn't expose all of the
346 quite perfect, because Python's readline doesn't expose all of the
347 GNU readline details needed for this to be done correctly.
347 GNU readline details needed for this to be done correctly.
348
348
349 For a filename with a space in it, the printed completions will be
349 For a filename with a space in it, the printed completions will be
350 only the parts after what's already been typed (instead of the
350 only the parts after what's already been typed (instead of the
351 full completions, as is normally done). I don't think with the
351 full completions, as is normally done). I don't think with the
352 current (as of Python 2.3) Python readline it's possible to do
352 current (as of Python 2.3) Python readline it's possible to do
353 better."""
353 better."""
354
354
355 #print 'Completer->file_matches: <%s>' % text # dbg
355 #print 'Completer->file_matches: <%s>' % text # dbg
356
356
357 # chars that require escaping with backslash - i.e. chars
357 # chars that require escaping with backslash - i.e. chars
358 # that readline treats incorrectly as delimiters, but we
358 # that readline treats incorrectly as delimiters, but we
359 # don't want to treat as delimiters in filename matching
359 # don't want to treat as delimiters in filename matching
360 # when escaped with backslash
360 # when escaped with backslash
361
361
362 if text.startswith('!'):
362 if text.startswith('!'):
363 text = text[1:]
363 text = text[1:]
364 text_prefix = '!'
364 text_prefix = '!'
365 else:
365 else:
366 text_prefix = ''
366 text_prefix = ''
367
367
368 lbuf = self.lbuf
368 lbuf = self.lbuf
369 open_quotes = 0 # track strings with open quotes
369 open_quotes = 0 # track strings with open quotes
370 try:
370 try:
371 lsplit = shlex.split(lbuf)[-1]
371 lsplit = shlex.split(lbuf)[-1]
372 except ValueError:
372 except ValueError:
373 # typically an unmatched ", or backslash without escaped char.
373 # typically an unmatched ", or backslash without escaped char.
374 if lbuf.count('"')==1:
374 if lbuf.count('"')==1:
375 open_quotes = 1
375 open_quotes = 1
376 lsplit = lbuf.split('"')[-1]
376 lsplit = lbuf.split('"')[-1]
377 elif lbuf.count("'")==1:
377 elif lbuf.count("'")==1:
378 open_quotes = 1
378 open_quotes = 1
379 lsplit = lbuf.split("'")[-1]
379 lsplit = lbuf.split("'")[-1]
380 else:
380 else:
381 return []
381 return []
382 except IndexError:
382 except IndexError:
383 # tab pressed on empty line
383 # tab pressed on empty line
384 lsplit = ""
384 lsplit = ""
385
385
386 if lsplit != protect_filename(lsplit):
386 if lsplit != protect_filename(lsplit):
387 # if protectables are found, do matching on the whole escaped
387 # if protectables are found, do matching on the whole escaped
388 # name
388 # name
389 has_protectables = 1
389 has_protectables = 1
390 text0,text = text,lsplit
390 text0,text = text,lsplit
391 else:
391 else:
392 has_protectables = 0
392 has_protectables = 0
393 text = os.path.expanduser(text)
393 text = os.path.expanduser(text)
394
394
395 if text == "":
395 if text == "":
396 return [text_prefix + protect_filename(f) for f in self.glob("*")]
396 return [text_prefix + protect_filename(f) for f in self.glob("*")]
397
397
398 m0 = self.clean_glob(text.replace('\\',''))
398 m0 = self.clean_glob(text.replace('\\',''))
399 if has_protectables:
399 if has_protectables:
400 # If we had protectables, we need to revert our changes to the
400 # If we had protectables, we need to revert our changes to the
401 # beginning of filename so that we don't double-write the part
401 # beginning of filename so that we don't double-write the part
402 # of the filename we have so far
402 # of the filename we have so far
403 len_lsplit = len(lsplit)
403 len_lsplit = len(lsplit)
404 matches = [text_prefix + text0 +
404 matches = [text_prefix + text0 +
405 protect_filename(f[len_lsplit:]) for f in m0]
405 protect_filename(f[len_lsplit:]) for f in m0]
406 else:
406 else:
407 if open_quotes:
407 if open_quotes:
408 # if we have a string with an open quote, we don't need to
408 # if we have a string with an open quote, we don't need to
409 # protect the names at all (and we _shouldn't_, as it
409 # protect the names at all (and we _shouldn't_, as it
410 # would cause bugs when the filesystem call is made).
410 # would cause bugs when the filesystem call is made).
411 matches = m0
411 matches = m0
412 else:
412 else:
413 matches = [text_prefix +
413 matches = [text_prefix +
414 protect_filename(f) for f in m0]
414 protect_filename(f) for f in m0]
415
415
416 #print 'mm',matches # dbg
416 #print 'mm',matches # dbg
417 return single_dir_expand(matches)
417 return single_dir_expand(matches)
418
418
419 def magic_matches(self, text):
419 def magic_matches(self, text):
420 """Match magics"""
420 """Match magics"""
421 #print 'Completer->magic_matches:',text,'lb',self.lbuf # dbg
421 #print 'Completer->magic_matches:',text,'lb',self.lbuf # dbg
422 # Get all shell magics now rather than statically, so magics loaded at
422 # Get all shell magics now rather than statically, so magics loaded at
423 # runtime show up too
423 # runtime show up too
424 magics = self.shell.lsmagic()
424 magics = self.shell.lsmagic()
425 pre = self.magic_escape
425 pre = self.magic_escape
426 baretext = text.lstrip(pre)
426 baretext = text.lstrip(pre)
427 return [ pre+m for m in magics if m.startswith(baretext)]
427 return [ pre+m for m in magics if m.startswith(baretext)]
428
428
429 def alias_matches(self, text):
429 def alias_matches(self, text):
430 """Match internal system aliases"""
430 """Match internal system aliases"""
431 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
431 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
432
432
433 # if we are not in the first 'item', alias matching
433 # if we are not in the first 'item', alias matching
434 # doesn't make sense - unless we are starting with 'sudo' command.
434 # doesn't make sense - unless we are starting with 'sudo' command.
435 if ' ' in self.lbuf.lstrip() and \
435 if ' ' in self.lbuf.lstrip() and \
436 not self.lbuf.lstrip().startswith('sudo'):
436 not self.lbuf.lstrip().startswith('sudo'):
437 return []
437 return []
438 text = os.path.expanduser(text)
438 text = os.path.expanduser(text)
439 aliases = self.alias_table.keys()
439 aliases = self.alias_table.keys()
440 if text == "":
440 if text == "":
441 return aliases
441 return aliases
442 else:
442 else:
443 return [alias for alias in aliases if alias.startswith(text)]
443 return [alias for alias in aliases if alias.startswith(text)]
444
444
445 def python_matches(self,text):
445 def python_matches(self,text):
446 """Match attributes or global python names"""
446 """Match attributes or global python names"""
447
447
448 #print 'Completer->python_matches, txt=%r' % text # dbg
448 #print 'Completer->python_matches, txt=%r' % text # dbg
449 if "." in text:
449 if "." in text:
450 try:
450 try:
451 matches = self.attr_matches(text)
451 matches = self.attr_matches(text)
452 if text.endswith('.') and self.omit__names:
452 if text.endswith('.') and self.omit__names:
453 if self.omit__names == 1:
453 if self.omit__names == 1:
454 # true if txt is _not_ a __ name, false otherwise:
454 # true if txt is _not_ a __ name, false otherwise:
455 no__name = (lambda txt:
455 no__name = (lambda txt:
456 re.match(r'.*\.__.*?__',txt) is None)
456 re.match(r'.*\.__.*?__',txt) is None)
457 else:
457 else:
458 # true if txt is _not_ a _ name, false otherwise:
458 # true if txt is _not_ a _ name, false otherwise:
459 no__name = (lambda txt:
459 no__name = (lambda txt:
460 re.match(r'.*\._.*?',txt) is None)
460 re.match(r'.*\._.*?',txt) is None)
461 matches = filter(no__name, matches)
461 matches = filter(no__name, matches)
462 except NameError:
462 except NameError:
463 # catches <undefined attributes>.<tab>
463 # catches <undefined attributes>.<tab>
464 matches = []
464 matches = []
465 else:
465 else:
466 matches = self.global_matches(text)
466 matches = self.global_matches(text)
467
467
468 return matches
468 return matches
469
469
470 def _default_arguments(self, obj):
470 def _default_arguments(self, obj):
471 """Return the list of default arguments of obj if it is callable,
471 """Return the list of default arguments of obj if it is callable,
472 or empty list otherwise."""
472 or empty list otherwise."""
473
473
474 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
474 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
475 # for classes, check for __init__,__new__
475 # for classes, check for __init__,__new__
476 if inspect.isclass(obj):
476 if inspect.isclass(obj):
477 obj = (getattr(obj,'__init__',None) or
477 obj = (getattr(obj,'__init__',None) or
478 getattr(obj,'__new__',None))
478 getattr(obj,'__new__',None))
479 # for all others, check if they are __call__able
479 # for all others, check if they are __call__able
480 elif hasattr(obj, '__call__'):
480 elif hasattr(obj, '__call__'):
481 obj = obj.__call__
481 obj = obj.__call__
482 # XXX: is there a way to handle the builtins ?
482 # XXX: is there a way to handle the builtins ?
483 try:
483 try:
484 args,_,_1,defaults = inspect.getargspec(obj)
484 args,_,_1,defaults = inspect.getargspec(obj)
485 if defaults:
485 if defaults:
486 return args[-len(defaults):]
486 return args[-len(defaults):]
487 except TypeError: pass
487 except TypeError: pass
488 return []
488 return []
489
489
490 def python_func_kw_matches(self,text):
490 def python_func_kw_matches(self,text):
491 """Match named parameters (kwargs) of the last open function"""
491 """Match named parameters (kwargs) of the last open function"""
492
492
493 if "." in text: # a parameter cannot be dotted
493 if "." in text: # a parameter cannot be dotted
494 return []
494 return []
495 try: regexp = self.__funcParamsRegex
495 try: regexp = self.__funcParamsRegex
496 except AttributeError:
496 except AttributeError:
497 regexp = self.__funcParamsRegex = re.compile(r'''
497 regexp = self.__funcParamsRegex = re.compile(r'''
498 '.*?' | # single quoted strings or
498 '.*?' | # single quoted strings or
499 ".*?" | # double quoted strings or
499 ".*?" | # double quoted strings or
500 \w+ | # identifier
500 \w+ | # identifier
501 \S # other characters
501 \S # other characters
502 ''', re.VERBOSE | re.DOTALL)
502 ''', re.VERBOSE | re.DOTALL)
503 # 1. find the nearest identifier that comes before an unclosed
503 # 1. find the nearest identifier that comes before an unclosed
504 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
504 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
505 tokens = regexp.findall(self.get_line_buffer())
505 tokens = regexp.findall(self.get_line_buffer())
506 tokens.reverse()
506 tokens.reverse()
507 iterTokens = iter(tokens); openPar = 0
507 iterTokens = iter(tokens); openPar = 0
508 for token in iterTokens:
508 for token in iterTokens:
509 if token == ')':
509 if token == ')':
510 openPar -= 1
510 openPar -= 1
511 elif token == '(':
511 elif token == '(':
512 openPar += 1
512 openPar += 1
513 if openPar > 0:
513 if openPar > 0:
514 # found the last unclosed parenthesis
514 # found the last unclosed parenthesis
515 break
515 break
516 else:
516 else:
517 return []
517 return []
518 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
518 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
519 ids = []
519 ids = []
520 isId = re.compile(r'\w+$').match
520 isId = re.compile(r'\w+$').match
521 while True:
521 while True:
522 try:
522 try:
523 ids.append(iterTokens.next())
523 ids.append(iterTokens.next())
524 if not isId(ids[-1]):
524 if not isId(ids[-1]):
525 ids.pop(); break
525 ids.pop(); break
526 if not iterTokens.next() == '.':
526 if not iterTokens.next() == '.':
527 break
527 break
528 except StopIteration:
528 except StopIteration:
529 break
529 break
530 # lookup the candidate callable matches either using global_matches
530 # lookup the candidate callable matches either using global_matches
531 # or attr_matches for dotted names
531 # or attr_matches for dotted names
532 if len(ids) == 1:
532 if len(ids) == 1:
533 callableMatches = self.global_matches(ids[0])
533 callableMatches = self.global_matches(ids[0])
534 else:
534 else:
535 callableMatches = self.attr_matches('.'.join(ids[::-1]))
535 callableMatches = self.attr_matches('.'.join(ids[::-1]))
536 argMatches = []
536 argMatches = []
537 for callableMatch in callableMatches:
537 for callableMatch in callableMatches:
538 try:
538 try:
539 namedArgs = self._default_arguments(eval(callableMatch,
539 namedArgs = self._default_arguments(eval(callableMatch,
540 self.namespace))
540 self.namespace))
541 except:
541 except:
542 continue
542 continue
543 for namedArg in namedArgs:
543 for namedArg in namedArgs:
544 if namedArg.startswith(text):
544 if namedArg.startswith(text):
545 argMatches.append("%s=" %namedArg)
545 argMatches.append("%s=" %namedArg)
546 return argMatches
546 return argMatches
547
547
548 def dispatch_custom_completer(self,text):
548 def dispatch_custom_completer(self,text):
549 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
549 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
550 line = self.full_lbuf
550 line = self.full_lbuf
551 if not line.strip():
551 if not line.strip():
552 return None
552 return None
553
553
554 event = Bunch()
554 event = Bunch()
555 event.line = line
555 event.line = line
556 event.symbol = text
556 event.symbol = text
557 cmd = line.split(None,1)[0]
557 cmd = line.split(None,1)[0]
558 event.command = cmd
558 event.command = cmd
559 #print "\ncustom:{%s]\n" % event # dbg
559 #print "\ncustom:{%s]\n" % event # dbg
560
560
561 # for foo etc, try also to find completer for %foo
561 # for foo etc, try also to find completer for %foo
562 if not cmd.startswith(self.magic_escape):
562 if not cmd.startswith(self.magic_escape):
563 try_magic = self.custom_completers.s_matches(
563 try_magic = self.custom_completers.s_matches(
564 self.magic_escape + cmd)
564 self.magic_escape + cmd)
565 else:
565 else:
566 try_magic = []
566 try_magic = []
567
567
568 for c in itertools.chain(self.custom_completers.s_matches(cmd),
568 for c in itertools.chain(self.custom_completers.s_matches(cmd),
569 try_magic,
569 try_magic,
570 self.custom_completers.flat_matches(self.lbuf)):
570 self.custom_completers.flat_matches(self.lbuf)):
571 #print "try",c # dbg
571 #print "try",c # dbg
572 try:
572 try:
573 res = c(event)
573 res = c(event)
574 # first, try case sensitive match
574 # first, try case sensitive match
575 withcase = [r for r in res if r.startswith(text)]
575 withcase = [r for r in res if r.startswith(text)]
576 if withcase:
576 if withcase:
577 return withcase
577 return withcase
578 # if none, then case insensitive ones are ok too
578 # if none, then case insensitive ones are ok too
579 text_low = text.lower()
579 text_low = text.lower()
580 return [r for r in res if r.lower().startswith(text_low)]
580 return [r for r in res if r.lower().startswith(text_low)]
581 except TryNext:
581 except TryNext:
582 pass
582 pass
583
583
584 return None
584 return None
585
585
586 def complete(self, text, state,line_buffer=None):
586 def complete(self, text, state, line_buffer=None):
587 """Return the next possible completion for 'text'.
587 """Return the next possible completion for 'text'.
588
588
589 This is called successively with state == 0, 1, 2, ... until it
589 This is called successively with state == 0, 1, 2, ... until it
590 returns None. The completion should begin with 'text'.
590 returns None. The completion should begin with 'text'.
591
591
592 :Keywords:
592 :Keywords:
593 - line_buffer: string
593 - line_buffer: string
594 If not given, the completer attempts to obtain the current line buffer
594 If not given, the completer attempts to obtain the current line buffer
595 via readline. This keyword allows clients which are requesting for
595 via readline. This keyword allows clients which are requesting for
596 text completions in non-readline contexts to inform the completer of
596 text completions in non-readline contexts to inform the completer of
597 the entire text.
597 the entire text.
598 """
598 """
599
599
600 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
600 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
601
601
602 # if there is only a tab on a line with only whitespace, instead
602 # if there is only a tab on a line with only whitespace, instead
603 # of the mostly useless 'do you want to see all million
603 # of the mostly useless 'do you want to see all million
604 # completions' message, just do the right thing and give the user
604 # completions' message, just do the right thing and give the user
605 # his tab! Incidentally, this enables pasting of tabbed text from
605 # his tab! Incidentally, this enables pasting of tabbed text from
606 # an editor (as long as autoindent is off).
606 # an editor (as long as autoindent is off).
607
607
608 # It should be noted that at least pyreadline still shows
608 # It should be noted that at least pyreadline still shows
609 # file completions - is there a way around it?
609 # file completions - is there a way around it?
610
610
611 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
611 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
612 # don't interfere with their own tab-completion mechanism.
612 # don't interfere with their own tab-completion mechanism.
613 if line_buffer is None:
613 if line_buffer is None:
614 self.full_lbuf = self.get_line_buffer()
614 self.full_lbuf = self.get_line_buffer()
615 else:
615 else:
616 self.full_lbuf = line_buffer
616 self.full_lbuf = line_buffer
617
617
618 if not (self.dumb_terminal or self.full_lbuf.strip()):
618 if not (self.dumb_terminal or self.full_lbuf.strip()):
619 self.readline.insert_text('\t')
619 self.readline.insert_text('\t')
620 return None
620 return None
621
621
622 magic_escape = self.magic_escape
622 magic_escape = self.magic_escape
623
623
624 self.lbuf = self.full_lbuf[:self.get_endidx()]
624 self.lbuf = self.full_lbuf[:self.get_endidx()]
625
625
626 try:
626 try:
627 if text.startswith('~'):
627 if text.startswith('~'):
628 text = os.path.expanduser(text)
628 text = os.path.expanduser(text)
629 if state == 0:
629 if state == 0:
630 custom_res = self.dispatch_custom_completer(text)
630 custom_res = self.dispatch_custom_completer(text)
631 if custom_res is not None:
631 if custom_res is not None:
632 # did custom completers produce something?
632 # did custom completers produce something?
633 self.matches = custom_res
633 self.matches = custom_res
634 else:
634 else:
635 # Extend the list of completions with the results of each
635 # Extend the list of completions with the results of each
636 # matcher, so we return results to the user from all
636 # matcher, so we return results to the user from all
637 # namespaces.
637 # namespaces.
638 if self.merge_completions:
638 if self.merge_completions:
639 self.matches = []
639 self.matches = []
640 for matcher in self.matchers:
640 for matcher in self.matchers:
641 self.matches.extend(matcher(text))
641 self.matches.extend(matcher(text))
642 else:
642 else:
643 for matcher in self.matchers:
643 for matcher in self.matchers:
644 self.matches = matcher(text)
644 self.matches = matcher(text)
645 if self.matches:
645 if self.matches:
646 break
646 break
647 self.matches = list(set(self.matches))
647 self.matches = list(set(self.matches))
648 try:
648 try:
649 #print "MATCH: %r" % self.matches[state] # dbg
649 #print "MATCH: %r" % self.matches[state] # dbg
650 return self.matches[state]
650 return self.matches[state]
651 except IndexError:
651 except IndexError:
652 return None
652 return None
653 except:
653 except:
654 #from IPython.core.ultratb import AutoFormattedTB; # dbg
654 #from IPython.core.ultratb import AutoFormattedTB; # dbg
655 #tb=AutoFormattedTB('Verbose');tb() #dbg
655 #tb=AutoFormattedTB('Verbose');tb() #dbg
656
656
657 # If completion fails, don't annoy the user.
657 # If completion fails, don't annoy the user.
658 return None
658 return None
@@ -1,491 +1,492 b''
1 ;;; ipython.el --- Adds support for IPython to python-mode.el
1 ;;; ipython.el --- Adds support for IPython to python-mode.el
2
2
3 ;; Copyright (C) 2002, 2003, 2004, 2005 Alexander Schmolck
3 ;; Copyright (C) 2002, 2003, 2004, 2005 Alexander Schmolck
4 ;; Author: Alexander Schmolck
4 ;; Author: Alexander Schmolck
5 ;; Keywords: ipython python languages oop
5 ;; Keywords: ipython python languages oop
6 ;; URL: http://ipython.scipy.org
6 ;; URL: http://ipython.scipy.org
7 ;; Compatibility: Emacs21, XEmacs21
7 ;; Compatibility: Emacs21, XEmacs21
8 ;; FIXME: #$@! INPUT RING
8 ;; FIXME: #$@! INPUT RING
9 (defconst ipython-version "$Revision: 2927 $"
9 (defconst ipython-version "0.11"
10 "VC version number.")
10 "Tied to IPython main version number.")
11
11
12 ;;; Commentary
12 ;;; Commentary
13 ;; This library makes all the functionality python-mode has when running with
13 ;; This library makes all the functionality python-mode has when running with
14 ;; the normal python-interpreter available for ipython, too. It also enables a
14 ;; the normal python-interpreter available for ipython, too. It also enables a
15 ;; persistent py-shell command history across sessions (if you exit python
15 ;; persistent py-shell command history across sessions (if you exit python
16 ;; with C-d in py-shell) and defines the command `ipython-to-doctest', which
16 ;; with C-d in py-shell) and defines the command `ipython-to-doctest', which
17 ;; can be used to convert bits of a ipython session into something that can be
17 ;; can be used to convert bits of a ipython session into something that can be
18 ;; used for doctests. To install, put this file somewhere in your emacs
18 ;; used for doctests. To install, put this file somewhere in your emacs
19 ;; `load-path' [1] and add the following line to your ~/.emacs file (the first
19 ;; `load-path' [1] and add the following line to your ~/.emacs file (the first
20 ;; line only needed if the default (``"ipython"``) is wrong)::
20 ;; line only needed if the default (``"ipython"``) is wrong)::
21 ;;
21 ;;
22 ;; (setq ipython-command "/SOME-PATH/ipython")
22 ;; (setq ipython-command "/SOME-PATH/ipython")
23 ;; (require 'ipython)
23 ;; (require 'ipython)
24 ;;
24 ;;
25 ;; Ipython will be set as the default python shell, but only if the ipython
25 ;; Ipython will be set as the default python shell, but only if the ipython
26 ;; executable is in the path. For ipython sessions autocompletion with <tab>
26 ;; executable is in the path. For ipython sessions autocompletion with <tab>
27 ;; is also enabled (experimental feature!). Please also note that all the
27 ;; is also enabled (experimental feature!). Please also note that all the
28 ;; terminal functions in py-shell are handled by emacs's comint, **not** by
28 ;; terminal functions in py-shell are handled by emacs's comint, **not** by
29 ;; (i)python, so importing readline etc. will have 0 effect.
29 ;; (i)python, so importing readline etc. will have 0 effect.
30 ;;
30 ;;
31 ;; To start an interactive ipython session run `py-shell' with ``M-x py-shell``
31 ;; To start an interactive ipython session run `py-shell' with ``M-x py-shell``
32 ;; (or the default keybinding ``C-c C-!``).
32 ;; (or the default keybinding ``C-c C-!``).
33 ;;
33 ;;
34 ;; You can customize the arguments passed to the IPython instance at startup by
34 ;; You can customize the arguments passed to the IPython instance at startup by
35 ;; setting the ``py-python-command-args`` variable. For example, to start
35 ;; setting the ``py-python-command-args`` variable. For example, to start
36 ;; always in ``pylab`` mode with hardcoded light-background colors, you can
36 ;; always in ``pylab`` mode with hardcoded light-background colors, you can
37 ;; use::
37 ;; use::
38 ;;
38 ;;
39 ;; (setq py-python-command-args '("-pylab" "-colors" "LightBG"))
39 ;; (setq py-python-command-args '("-pylab" "--colors" "LightBG"))
40 ;;
40 ;;
41 ;;
41 ;;
42 ;; NOTE: This mode is currently somewhat alpha and although I hope that it
42 ;; NOTE: This mode is currently somewhat alpha and although I hope that it
43 ;; will work fine for most cases, doing certain things (like the
43 ;; will work fine for most cases, doing certain things (like the
44 ;; autocompletion and a decent scheme to switch between python interpreters)
44 ;; autocompletion and a decent scheme to switch between python interpreters)
45 ;; properly will also require changes to ipython that will likely have to wait
45 ;; properly will also require changes to ipython that will likely have to wait
46 ;; for a larger rewrite scheduled some time in the future.
46 ;; for a larger rewrite scheduled some time in the future.
47 ;;
47 ;;
48 ;;
48 ;;
49 ;; Further note that I don't know whether this runs under windows or not and
49 ;; Further note that I don't know whether this runs under windows or not and
50 ;; that if it doesn't I can't really help much, not being afflicted myself.
50 ;; that if it doesn't I can't really help much, not being afflicted myself.
51 ;;
51 ;;
52 ;;
52 ;;
53 ;; Hints for effective usage
53 ;; Hints for effective usage
54 ;; -------------------------
54 ;; -------------------------
55 ;;
55 ;;
56 ;; - IMO the best feature by far of the ipython/emacs combo is how much easier
56 ;; - IMO the best feature by far of the ipython/emacs combo is how much easier
57 ;; it makes it to find and fix bugs thanks to the ``%pdb on or %debug``/
57 ;; it makes it to find and fix bugs thanks to the ``%pdb on or %debug``/
58 ;; pdbtrack combo. Try it: first in the ipython to shell do ``%pdb on`` then
58 ;; pdbtrack combo. Try it: first in the ipython to shell do ``%pdb on`` then
59 ;; do something that will raise an exception (FIXME nice example), or type
59 ;; do something that will raise an exception (FIXME nice example), or type
60 ;; ``%debug`` after the exception has been raised. YOu'll be amazed at how
60 ;; ``%debug`` after the exception has been raised. YOu'll be amazed at how
61 ;; easy it is to inspect the live objects in each stack frames and to jump to
61 ;; easy it is to inspect the live objects in each stack frames and to jump to
62 ;; the corresponding sourcecode locations as you walk up and down the stack
62 ;; the corresponding sourcecode locations as you walk up and down the stack
63 ;; trace (even without ``%pdb on`` you can always use ``C-c -``
63 ;; trace (even without ``%pdb on`` you can always use ``C-c -``
64 ;; (`py-up-exception') to jump to the corresponding source code locations).
64 ;; (`py-up-exception') to jump to the corresponding source code locations).
65 ;;
65 ;;
66 ;; - emacs gives you much more powerful commandline editing and output searching
66 ;; - emacs gives you much more powerful commandline editing and output searching
67 ;; capabilities than ipython-standalone -- isearch is your friend if you
67 ;; capabilities than ipython-standalone -- isearch is your friend if you
68 ;; quickly want to print 'DEBUG ...' to stdout out etc.
68 ;; quickly want to print 'DEBUG ...' to stdout out etc.
69 ;;
69 ;;
70 ;; - This is not really specific to ipython, but for more convenient history
70 ;; - This is not really specific to ipython, but for more convenient history
71 ;; access you might want to add something like the following to *the beggining*
71 ;; access you might want to add something like the following to *the beggining*
72 ;; of your ``.emacs`` (if you want behavior that's more similar to stand-alone
72 ;; of your ``.emacs`` (if you want behavior that's more similar to stand-alone
73 ;; ipython, you can change ``meta p`` etc. for ``control p``)::
73 ;; ipython, you can change ``meta p`` etc. for ``control p``)::
74 ;;
74 ;;
75 ;; (require 'comint)
75 ;; (require 'comint)
76 ;; (define-key comint-mode-map [(meta p)]
76 ;; (define-key comint-mode-map [(meta p)]
77 ;; 'comint-previous-matching-input-from-input)
77 ;; 'comint-previous-matching-input-from-input)
78 ;; (define-key comint-mode-map [(meta n)]
78 ;; (define-key comint-mode-map [(meta n)]
79 ;; 'comint-next-matching-input-from-input)
79 ;; 'comint-next-matching-input-from-input)
80 ;; (define-key comint-mode-map [(control meta n)]
80 ;; (define-key comint-mode-map [(control meta n)]
81 ;; 'comint-next-input)
81 ;; 'comint-next-input)
82 ;; (define-key comint-mode-map [(control meta p)]
82 ;; (define-key comint-mode-map [(control meta p)]
83 ;; 'comint-previous-input)
83 ;; 'comint-previous-input)
84 ;;
84 ;;
85 ;; - Be aware that if you customize py-python-command previously, this value
85 ;; - Be aware that if you customize py-python-command previously, this value
86 ;; will override what ipython.el does (because loading the customization
86 ;; will override what ipython.el does (because loading the customization
87 ;; variables comes later).
87 ;; variables comes later).
88 ;;
88 ;;
89 ;; Please send comments and feedback to the ipython-list
89 ;; Please send comments and feedback to the ipython-list
90 ;; (<ipython-user@scipy.org>) where I (a.s.) or someone else will try to
90 ;; (<ipython-user@scipy.org>) where I (a.s.) or someone else will try to
91 ;; answer them (it helps if you specify your emacs version, OS etc;
91 ;; answer them (it helps if you specify your emacs version, OS etc;
92 ;; familiarity with <http://www.catb.org/~esr/faqs/smart-questions.html> might
92 ;; familiarity with <http://www.catb.org/~esr/faqs/smart-questions.html> might
93 ;; speed up things further).
93 ;; speed up things further).
94 ;;
94 ;;
95 ;; Footnotes:
95 ;; Footnotes:
96 ;;
96 ;;
97 ;; [1] If you don't know what `load-path' is, C-h v load-path will tell
97 ;; [1] If you don't know what `load-path' is, C-h v load-path will tell
98 ;; you; if required you can also add a new directory. So assuming that
98 ;; you; if required you can also add a new directory. So assuming that
99 ;; ipython.el resides in ~/el/, put this in your emacs:
99 ;; ipython.el resides in ~/el/, put this in your emacs:
100 ;;
100 ;;
101 ;;
101 ;;
102 ;; (add-to-list 'load-path "~/el")
102 ;; (add-to-list 'load-path "~/el")
103 ;; (setq ipython-command "/some-path/ipython")
103 ;; (setq ipython-command "/some-path/ipython")
104 ;; (require 'ipython)
104 ;; (require 'ipython)
105 ;;
105 ;;
106 ;;
106 ;;
107 ;;
107 ;;
108 ;;
108 ;;
109 ;; TODO:
109 ;; TODO:
110 ;; - do autocompletion properly
110 ;; - do autocompletion properly
111 ;; - implement a proper switching between python interpreters
111 ;; - implement a proper switching between python interpreters
112 ;;
112 ;;
113 ;; BUGS:
113 ;; BUGS:
114 ;; - neither::
114 ;; - neither::
115 ;;
115 ;;
116 ;; (py-shell "-c print 'FOOBAR'")
116 ;; (py-shell "-c print 'FOOBAR'")
117 ;;
117 ;;
118 ;; nor::
118 ;; nor::
119 ;;
119 ;;
120 ;; (let ((py-python-command-args (append py-python-command-args
120 ;; (let ((py-python-command-args (append py-python-command-args
121 ;; '("-c" "print 'FOOBAR'"))))
121 ;; '("-c" "print 'FOOBAR'"))))
122 ;; (py-shell))
122 ;; (py-shell))
123 ;;
123 ;;
124 ;; seem to print anything as they should
124 ;; seem to print anything as they should
125 ;;
125 ;;
126 ;; - look into init priority issues with `py-python-command' (if it's set
126 ;; - look into init priority issues with `py-python-command' (if it's set
127 ;; via custom)
127 ;; via custom)
128
128
129
129
130 ;;; Code
130 ;;; Code
131 (require 'cl)
131 (require 'cl)
132 (require 'shell)
132 (require 'shell)
133 (require 'executable)
133 (require 'executable)
134 (require 'ansi-color)
134 (require 'ansi-color)
135
135
136 (defcustom ipython-command "ipython"
136 (defcustom ipython-command "ipython"
137 "*Shell command used to start ipython."
137 "*Shell command used to start ipython."
138 :type 'string
138 :type 'string
139 :group 'python)
139 :group 'python)
140
140
141 ;; Users can set this to nil
141 ;; Users can set this to nil
142 (defvar py-shell-initial-switch-buffers t
142 (defvar py-shell-initial-switch-buffers t
143 "If nil, don't switch to the *Python* buffer on the first call to
143 "If nil, don't switch to the *Python* buffer on the first call to
144 `py-shell'.")
144 `py-shell'.")
145
145
146 (defvar ipython-backup-of-py-python-command nil
146 (defvar ipython-backup-of-py-python-command nil
147 "HACK")
147 "HACK")
148
148
149
149
150 (defvar ipython-de-input-prompt-regexp "\\(?:
150 (defvar ipython-de-input-prompt-regexp "\\(?:
151 In \\[[0-9]+\\]: *.*
151 In \\[[0-9]+\\]: *.*
152 ----+> \\(.*
152 ----+> \\(.*
153 \\)[\n]?\\)\\|\\(?:
153 \\)[\n]?\\)\\|\\(?:
154 In \\[[0-9]+\\]: *\\(.*
154 In \\[[0-9]+\\]: *\\(.*
155 \\)\\)\\|^[ ]\\{3\\}[.]\\{3,\\}: *\\(.*
155 \\)\\)\\|^[ ]\\{3\\}[.]\\{3,\\}: *\\(.*
156 \\)"
156 \\)"
157 "A regular expression to match the IPython input prompt and the python
157 "A regular expression to match the IPython input prompt and the python
158 command after it. The first match group is for a command that is rewritten,
158 command after it. The first match group is for a command that is rewritten,
159 the second for a 'normal' command, and the third for a multiline command.")
159 the second for a 'normal' command, and the third for a multiline command.")
160 (defvar ipython-de-output-prompt-regexp "^Out\\[[0-9]+\\]: "
160 (defvar ipython-de-output-prompt-regexp "^Out\\[[0-9]+\\]: "
161 "A regular expression to match the output prompt of IPython.")
161 "A regular expression to match the output prompt of IPython.")
162
162
163
163
164 (if (not (executable-find ipython-command))
164 (if (not (executable-find ipython-command))
165 (message (format "Can't find executable %s - ipython.el *NOT* activated!!!"
165 (message (format "Can't find executable %s - ipython.el *NOT* activated!!!"
166 ipython-command))
166 ipython-command))
167 ;; XXX load python-mode, so that we can screw around with its variables
167 ;; XXX load python-mode, so that we can screw around with its variables
168 ;; this has the disadvantage that python-mode is loaded even if no
168 ;; this has the disadvantage that python-mode is loaded even if no
169 ;; python-file is ever edited etc. but it means that `py-shell' works
169 ;; python-file is ever edited etc. but it means that `py-shell' works
170 ;; without loading a python-file first. Obviously screwing around with
170 ;; without loading a python-file first. Obviously screwing around with
171 ;; python-mode's variables like this is a mess, but well.
171 ;; python-mode's variables like this is a mess, but well.
172 (require 'python-mode)
172 (require 'python-mode)
173 ;; turn on ansi colors for ipython and activate completion
173 ;; turn on ansi colors for ipython and activate completion
174 (defun ipython-shell-hook ()
174 (defun ipython-shell-hook ()
175 ;; the following is to synchronize dir-changes
175 ;; the following is to synchronize dir-changes
176 (make-local-variable 'shell-dirstack)
176 (make-local-variable 'shell-dirstack)
177 (setq shell-dirstack nil)
177 (setq shell-dirstack nil)
178 (make-local-variable 'shell-last-dir)
178 (make-local-variable 'shell-last-dir)
179 (setq shell-last-dir nil)
179 (setq shell-last-dir nil)
180 (make-local-variable 'shell-dirtrackp)
180 (make-local-variable 'shell-dirtrackp)
181 (setq shell-dirtrackp t)
181 (setq shell-dirtrackp t)
182 (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t)
182 (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t)
183
183
184 (ansi-color-for-comint-mode-on)
184 (ansi-color-for-comint-mode-on)
185 (define-key py-shell-map [tab] 'ipython-complete)
185 (define-key py-shell-map [tab] 'ipython-complete)
186 ;; Add this so that tab-completion works both in X11 frames and inside
186 ;; Add this so that tab-completion works both in X11 frames and inside
187 ;; terminals (such as when emacs is called with -nw).
187 ;; terminals (such as when emacs is called with -nw).
188 (define-key py-shell-map "\t" 'ipython-complete)
188 (define-key py-shell-map "\t" 'ipython-complete)
189 ;;XXX this is really just a cheap hack, it only completes symbols in the
189 ;;XXX this is really just a cheap hack, it only completes symbols in the
190 ;;interactive session -- useful nonetheless.
190 ;;interactive session -- useful nonetheless.
191 (define-key py-mode-map [(meta tab)] 'ipython-complete)
191 (define-key py-mode-map [(meta tab)] 'ipython-complete)
192
192
193 )
193 )
194 (add-hook 'py-shell-hook 'ipython-shell-hook)
194 (add-hook 'py-shell-hook 'ipython-shell-hook)
195 ;; Regular expression that describes tracebacks for IPython in context and
195 ;; Regular expression that describes tracebacks for IPython in context and
196 ;; verbose mode.
196 ;; verbose mode.
197
197
198 ;;Adapt python-mode settings for ipython.
198 ;;Adapt python-mode settings for ipython.
199 ;; (this works for %xmode 'verbose' or 'context')
199 ;; (this works for %xmode 'verbose' or 'context')
200
200
201 ;; XXX putative regexps for syntax errors; unfortunately the
201 ;; XXX putative regexps for syntax errors; unfortunately the
202 ;; current python-mode traceback-line-re scheme is too primitive,
202 ;; current python-mode traceback-line-re scheme is too primitive,
203 ;; so it's either matching syntax errors, *or* everything else
203 ;; so it's either matching syntax errors, *or* everything else
204 ;; (XXX: should ask Fernando for a change)
204 ;; (XXX: should ask Fernando for a change)
205 ;;"^ File \"\\(.*?\\)\", line \\([0-9]+\\).*\n.*\n.*\nSyntaxError:"
205 ;;"^ File \"\\(.*?\\)\", line \\([0-9]+\\).*\n.*\n.*\nSyntaxError:"
206 ;;^ File \"\\(.*?\\)\", line \\([0-9]+\\)"
206 ;;^ File \"\\(.*?\\)\", line \\([0-9]+\\)"
207
207
208 (setq py-traceback-line-re
208 (setq py-traceback-line-re
209 "\\(^[^\t >].+?\\.py\\).*\n +[0-9]+[^\00]*?\n-+> \\([0-9]+\\)+")
209 "\\(^[^\t >].+?\\.py\\).*\n +[0-9]+[^\00]*?\n-+> \\([0-9]+\\)+")
210
210
211
211
212 ;; Recognize the ipython pdb, whose prompt is 'ipdb>' or 'ipydb>'
212 ;; Recognize the ipython pdb, whose prompt is 'ipdb>' or 'ipydb>'
213 ;;instead of '(Pdb)'
213 ;;instead of '(Pdb)'
214 (setq py-pdbtrack-input-prompt "\n[(<]*[Ii]?[Pp]y?db[>)]+ ")
214 (setq py-pdbtrack-input-prompt "\n[(<]*[Ii]?[Pp]y?db[>)]+ ")
215 (setq pydb-pydbtrack-input-prompt "\n[(]*ipydb[>)]+ ")
215 (setq pydb-pydbtrack-input-prompt "\n[(]*ipydb[>)]+ ")
216
216
217 (setq py-shell-input-prompt-1-regexp "^In \\[[0-9]+\\]: *"
217 (setq py-shell-input-prompt-1-regexp "^In \\[[0-9]+\\]: *"
218 py-shell-input-prompt-2-regexp "^ [.][.][.]+: *" )
218 py-shell-input-prompt-2-regexp "^ [.][.][.]+: *" )
219 ;; select a suitable color-scheme
219 ;; select a suitable color-scheme
220 (unless (member "-colors" py-python-command-args)
220 (unless (member "--colors" py-python-command-args)
221 (setq py-python-command-args
221 (setq py-python-command-args
222 (nconc py-python-command-args
222 (nconc py-python-command-args
223 (list "-colors"
223 (list "--colors"
224 (cond
224 (cond
225 ((eq frame-background-mode 'dark)
225 ((eq frame-background-mode 'dark)
226 "Linux")
226 "Linux")
227 ((eq frame-background-mode 'light)
227 ((eq frame-background-mode 'light)
228 "LightBG")
228 "LightBG")
229 (t ; default (backg-mode isn't always set by XEmacs)
229 (t ; default (backg-mode isn't always set by XEmacs)
230 "LightBG"))))))
230 "LightBG"))))))
231 (unless (equal ipython-backup-of-py-python-command py-python-command)
231 (unless (equal ipython-backup-of-py-python-command py-python-command)
232 (setq ipython-backup-of-py-python-command py-python-command))
232 (setq ipython-backup-of-py-python-command py-python-command))
233 (setq py-python-command ipython-command))
233 (setq py-python-command ipython-command))
234
234
235
235
236 ;; MODIFY py-shell so that it loads the editing history
236 ;; MODIFY py-shell so that it loads the editing history
237 (defadvice py-shell (around py-shell-with-history)
237 (defadvice py-shell (around py-shell-with-history)
238 "Add persistent command-history support (in
238 "Add persistent command-history support (in
239 $PYTHONHISTORY (or \"~/.ipython/history\", if we use IPython)). Also, if
239 $PYTHONHISTORY (or \"~/.ipython/history\", if we use IPython)). Also, if
240 `py-shell-initial-switch-buffers' is nil, it only switches to *Python* if that
240 `py-shell-initial-switch-buffers' is nil, it only switches to *Python* if that
241 buffer already exists."
241 buffer already exists."
242 (if (comint-check-proc "*Python*")
242 (if (comint-check-proc "*Python*")
243 ad-do-it
243 ad-do-it
244 (setq comint-input-ring-file-name
244 (setq comint-input-ring-file-name
245 (if (string-equal py-python-command ipython-command)
245 (if (string-equal py-python-command ipython-command)
246 (concat (or (getenv "IPYTHONDIR") "~/.ipython") "/history")
246 (concat (or (getenv "IPYTHONDIR") "~/.ipython") "/history")
247 (or (getenv "PYTHONHISTORY") "~/.python-history.py")))
247 (or (getenv "PYTHONHISTORY") "~/.python-history.py")))
248 (comint-read-input-ring t)
248 (comint-read-input-ring t)
249 (let ((buf (current-buffer)))
249 (let ((buf (current-buffer)))
250 ad-do-it
250 ad-do-it
251 (unless py-shell-initial-switch-buffers
251 (unless py-shell-initial-switch-buffers
252 (switch-to-buffer-other-window buf)))))
252 (switch-to-buffer-other-window buf)))))
253 (ad-activate 'py-shell)
253 (ad-activate 'py-shell)
254 ;; (defadvice py-execute-region (before py-execute-buffer-ensure-process)
254 ;; (defadvice py-execute-region (before py-execute-buffer-ensure-process)
255 ;; "HACK: test that ipython is already running before executing something.
255 ;; "HACK: test that ipython is already running before executing something.
256 ;; Doing this properly seems not worth the bother (unless people actually
256 ;; Doing this properly seems not worth the bother (unless people actually
257 ;; request it)."
257 ;; request it)."
258 ;; (unless (comint-check-proc "*Python*")
258 ;; (unless (comint-check-proc "*Python*")
259 ;; (error "Sorry you have to first do M-x py-shell to send something to ipython.")))
259 ;; (error "Sorry you have to first do M-x py-shell to send something to ipython.")))
260 ;; (ad-activate 'py-execute-region)
260 ;; (ad-activate 'py-execute-region)
261
261
262 (defadvice py-execute-region (around py-execute-buffer-ensure-process)
262 (defadvice py-execute-region (around py-execute-buffer-ensure-process)
263 "HACK: if `py-shell' is not active or ASYNC is explicitly desired, fall back
263 "HACK: if `py-shell' is not active or ASYNC is explicitly desired, fall back
264 to python instead of ipython."
264 to python instead of ipython."
265 (let ((py-which-shell (if (and (comint-check-proc "*Python*") (not async))
265 (let ((py-which-shell (if (and (comint-check-proc "*Python*") (not async))
266 py-python-command
266 py-python-command
267 ipython-backup-of-py-python-command)))
267 ipython-backup-of-py-python-command)))
268 ad-do-it))
268 ad-do-it))
269 (ad-activate 'py-execute-region)
269 (ad-activate 'py-execute-region)
270
270
271 (defun ipython-to-doctest (start end)
271 (defun ipython-to-doctest (start end)
272 "Transform a cut-and-pasted bit from an IPython session into something that
272 "Transform a cut-and-pasted bit from an IPython session into something that
273 looks like it came from a normal interactive python session, so that it can
273 looks like it came from a normal interactive python session, so that it can
274 be used in doctests. Example:
274 be used in doctests. Example:
275
275
276
276
277 In [1]: import sys
277 In [1]: import sys
278
278
279 In [2]: sys.stdout.write 'Hi!\n'
279 In [2]: sys.stdout.write 'Hi!\n'
280 ------> sys.stdout.write ('Hi!\n')
280 ------> sys.stdout.write ('Hi!\n')
281 Hi!
281 Hi!
282
282
283 In [3]: 3 + 4
283 In [3]: 3 + 4
284 Out[3]: 7
284 Out[3]: 7
285
285
286 gets converted to:
286 gets converted to:
287
287
288 >>> import sys
288 >>> import sys
289 >>> sys.stdout.write ('Hi!\n')
289 >>> sys.stdout.write ('Hi!\n')
290 Hi!
290 Hi!
291 >>> 3 + 4
291 >>> 3 + 4
292 7
292 7
293
293
294 "
294 "
295 (interactive "*r\n")
295 (interactive "*r\n")
296 ;(message (format "###DEBUG s:%de:%d" start end))
296 ;(message (format "###DEBUG s:%de:%d" start end))
297 (save-excursion
297 (save-excursion
298 (save-match-data
298 (save-match-data
299 ;; replace ``In [3]: bla`` with ``>>> bla`` and
299 ;; replace ``In [3]: bla`` with ``>>> bla`` and
300 ;; ``... : bla`` with ``... bla``
300 ;; ``... : bla`` with ``... bla``
301 (goto-char start)
301 (goto-char start)
302 (while (re-search-forward ipython-de-input-prompt-regexp end t)
302 (while (re-search-forward ipython-de-input-prompt-regexp end t)
303 ;(message "finding 1")
303 ;(message "finding 1")
304 (cond ((match-string 3) ;continued
304 (cond ((match-string 3) ;continued
305 (replace-match "... \\3" t nil))
305 (replace-match "... \\3" t nil))
306 (t
306 (t
307 (replace-match ">>> \\1\\2" t nil))))
307 (replace-match ">>> \\1\\2" t nil))))
308 ;; replace ``
308 ;; replace ``
309 (goto-char start)
309 (goto-char start)
310 (while (re-search-forward ipython-de-output-prompt-regexp end t)
310 (while (re-search-forward ipython-de-output-prompt-regexp end t)
311 (replace-match "" t nil)))))
311 (replace-match "" t nil)))))
312
312
313 (defvar ipython-completion-command-string
313 (defvar ipython-completion-command-string
314 "print(';'.join(__IP.Completer.all_completions('%s'))) #PYTHON-MODE SILENT\n"
314 "print(';'.join(get_ipython().Completer.all_completions('%s'))) #PYTHON-MODE SILENT\n"
315 "The string send to ipython to query for all possible completions")
315 "The string send to ipython to query for all possible completions")
316
316
317
317
318 ;; xemacs doesn't have `comint-preoutput-filter-functions' so we'll try the
318 ;; xemacs doesn't have `comint-preoutput-filter-functions' so we'll try the
319 ;; following wonderful hack to work around this case
319 ;; following wonderful hack to work around this case
320 (if (featurep 'xemacs)
320 (if (featurep 'xemacs)
321 ;;xemacs
321 ;;xemacs
322 (defun ipython-complete ()
322 (defun ipython-complete ()
323 "Try to complete the python symbol before point. Only knows about the stuff
323 "Try to complete the python symbol before point. Only knows about the stuff
324 in the current *Python* session."
324 in the current *Python* session."
325 (interactive)
325 (interactive)
326 (let* ((ugly-return nil)
326 (let* ((ugly-return nil)
327 (sep ";")
327 (sep ";")
328 (python-process (or (get-buffer-process (current-buffer))
328 (python-process (or (get-buffer-process (current-buffer))
329 ;XXX hack for .py buffers
329 ;XXX hack for .py buffers
330 (get-process py-which-bufname)))
330 (get-process py-which-bufname)))
331 ;; XXX currently we go backwards to find the beginning of an
331 ;; XXX currently we go backwards to find the beginning of an
332 ;; expression part; a more powerful approach in the future might be
332 ;; expression part; a more powerful approach in the future might be
333 ;; to let ipython have the complete line, so that context can be used
333 ;; to let ipython have the complete line, so that context can be used
334 ;; to do things like filename completion etc.
334 ;; to do things like filename completion etc.
335 (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_." (point-at-bol))
335 (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_." (point-at-bol))
336 (point)))
336 (point)))
337 (end (point))
337 (end (point))
338 (pattern (buffer-substring-no-properties beg end))
338 (pattern (buffer-substring-no-properties beg end))
339 (completions nil)
339 (completions nil)
340 (completion-table nil)
340 (completion-table nil)
341 completion
341 completion
342 (comint-output-filter-functions
342 (comint-output-filter-functions
343 (append comint-output-filter-functions
343 (append comint-output-filter-functions
344 '(ansi-color-filter-apply
344 '(ansi-color-filter-apply
345 (lambda (string)
345 (lambda (string)
346 ;(message (format "DEBUG filtering: %s" string))
346 ;(message (format "DEBUG filtering: %s" string))
347 (setq ugly-return (concat ugly-return string))
347 (setq ugly-return (concat ugly-return string))
348 (delete-region comint-last-output-start
348 (delete-region comint-last-output-start
349 (process-mark (get-buffer-process (current-buffer)))))))))
349 (process-mark (get-buffer-process (current-buffer)))))))))
350 ;(message (format "#DEBUG pattern: '%s'" pattern))
350 ;(message (format "#DEBUG pattern: '%s'" pattern))
351 (process-send-string python-process
351 (process-send-string python-process
352 (format ipython-completion-command-string pattern))
352 (format ipython-completion-command-string pattern))
353 (accept-process-output python-process)
353 (accept-process-output python-process)
354 ;(message (format "DEBUG return: %s" ugly-return))
354
355 ;(message (format "DEBUG return: %s" ugly-return))
355 (setq completions
356 (setq completions
356 (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
357 (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
357 (setq completion-table (loop for str in completions
358 (setq completion-table (loop for str in completions
358 collect (list str nil)))
359 collect (list str nil)))
359 (setq completion (try-completion pattern completion-table))
360 (setq completion (try-completion pattern completion-table))
360 (cond ((eq completion t))
361 (cond ((eq completion t))
361 ((null completion)
362 ((null completion)
362 (message "Can't find completion for \"%s\"" pattern)
363 (message "Can't find completion for \"%s\"" pattern)
363 (ding))
364 (ding))
364 ((not (string= pattern completion))
365 ((not (string= pattern completion))
365 (delete-region beg end)
366 (delete-region beg end)
366 (insert completion))
367 (insert completion))
367 (t
368 (t
368 (message "Making completion list...")
369 (message "Making completion list...")
369 (with-output-to-temp-buffer "*Python Completions*"
370 (with-output-to-temp-buffer "*Python Completions*"
370 (display-completion-list (all-completions pattern completion-table)))
371 (display-completion-list (all-completions pattern completion-table)))
371 (message "Making completion list...%s" "done")))))
372 (message "Making completion list...%s" "done")))))
372 ;; emacs
373 ;; emacs
373 (defun ipython-complete ()
374 (defun ipython-complete ()
374 "Try to complete the python symbol before point. Only knows about the stuff
375 "Try to complete the python symbol before point. Only knows about the stuff
375 in the current *Python* session."
376 in the current *Python* session."
376 (interactive)
377 (interactive)
377 (let* ((ugly-return nil)
378 (let* ((ugly-return nil)
378 (sep ";")
379 (sep ";")
379 (python-process (or (get-buffer-process (current-buffer))
380 (python-process (or (get-buffer-process (current-buffer))
380 ;XXX hack for .py buffers
381 ;XXX hack for .py buffers
381 (get-process py-which-bufname)))
382 (get-process py-which-bufname)))
382 ;; XXX currently we go backwards to find the beginning of an
383 ;; XXX currently we go backwards to find the beginning of an
383 ;; expression part; a more powerful approach in the future might be
384 ;; expression part; a more powerful approach in the future might be
384 ;; to let ipython have the complete line, so that context can be used
385 ;; to let ipython have the complete line, so that context can be used
385 ;; to do things like filename completion etc.
386 ;; to do things like filename completion etc.
386 (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_./" (point-at-bol))
387 (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_./" (point-at-bol))
387 (point)))
388 (point)))
388 (end (point))
389 (end (point))
389 (pattern (buffer-substring-no-properties beg end))
390 (pattern (buffer-substring-no-properties beg end))
390 (completions nil)
391 (completions nil)
391 (completion-table nil)
392 (completion-table nil)
392 completion
393 completion
393 (comint-preoutput-filter-functions
394 (comint-preoutput-filter-functions
394 (append comint-preoutput-filter-functions
395 (append comint-preoutput-filter-functions
395 '(ansi-color-filter-apply
396 '(ansi-color-filter-apply
396 (lambda (string)
397 (lambda (string)
397 (setq ugly-return (concat ugly-return string))
398 (setq ugly-return (concat ugly-return string))
398 "")))))
399 "")))))
399 (process-send-string python-process
400 (process-send-string python-process
400 (format ipython-completion-command-string pattern))
401 (format ipython-completion-command-string pattern))
401 (accept-process-output python-process)
402 (accept-process-output python-process)
402 (setq completions
403 (setq completions
403 (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
404 (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
404 ;(message (format "DEBUG completions: %S" completions))
405 ;(message (format "DEBUG completions: %S" completions))
405 (setq completion-table (loop for str in completions
406 (setq completion-table (loop for str in completions
406 collect (list str nil)))
407 collect (list str nil)))
407 (setq completion (try-completion pattern completion-table))
408 (setq completion (try-completion pattern completion-table))
408 (cond ((eq completion t))
409 (cond ((eq completion t))
409 ((null completion)
410 ((null completion)
410 (message "Can't find completion for \"%s\"" pattern)
411 (message "Can't find completion for \"%s\"" pattern)
411 (ding))
412 (ding))
412 ((not (string= pattern completion))
413 ((not (string= pattern completion))
413 (delete-region beg end)
414 (delete-region beg end)
414 (insert completion))
415 (insert completion))
415 (t
416 (t
416 (message "Making completion list...")
417 (message "Making completion list...")
417 (with-output-to-temp-buffer "*IPython Completions*"
418 (with-output-to-temp-buffer "*IPython Completions*"
418 (display-completion-list (all-completions pattern completion-table)))
419 (display-completion-list (all-completions pattern completion-table)))
419 (message "Making completion list...%s" "done")))))
420 (message "Making completion list...%s" "done")))))
420 )
421 )
421
422
422 ;;; autoindent support: patch sent in by Jin Liu <m.liu.jin@gmail.com>,
423 ;;; autoindent support: patch sent in by Jin Liu <m.liu.jin@gmail.com>,
423 ;;; originally written by doxgen@newsmth.net
424 ;;; originally written by doxgen@newsmth.net
424 ;;; Minor modifications by fperez for xemacs compatibility.
425 ;;; Minor modifications by fperez for xemacs compatibility.
425
426
426 (defvar ipython-autoindent t
427 (defvar ipython-autoindent t
427 "If non-nil, enable autoindent for IPython shell through python-mode.")
428 "If non-nil, enable autoindent for IPython shell through python-mode.")
428
429
429 (defvar ipython-indenting-buffer-name "*IPython Indentation Calculation*"
430 (defvar ipython-indenting-buffer-name "*IPython Indentation Calculation*"
430 "Temporary buffer for indenting multiline statement.")
431 "Temporary buffer for indenting multiline statement.")
431
432
432 (defun ipython-get-indenting-buffer ()
433 (defun ipython-get-indenting-buffer ()
433 "Return a temporary buffer set in python-mode. Create one if necessary."
434 "Return a temporary buffer set in python-mode. Create one if necessary."
434 (let ((buf (get-buffer-create ipython-indenting-buffer-name)))
435 (let ((buf (get-buffer-create ipython-indenting-buffer-name)))
435 (set-buffer buf)
436 (set-buffer buf)
436 (unless (eq major-mode 'python-mode)
437 (unless (eq major-mode 'python-mode)
437 (python-mode))
438 (python-mode))
438 buf))
439 buf))
439
440
440 (defvar ipython-indentation-string nil
441 (defvar ipython-indentation-string nil
441 "Indentation for the next line in a multiline statement.")
442 "Indentation for the next line in a multiline statement.")
442
443
443 (defun ipython-send-and-indent ()
444 (defun ipython-send-and-indent ()
444 "Send the current line to IPython, and calculate the indentation for
445 "Send the current line to IPython, and calculate the indentation for
445 the next line."
446 the next line."
446 (interactive)
447 (interactive)
447 (if ipython-autoindent
448 (if ipython-autoindent
448 (let ((line (buffer-substring (point-at-bol) (point)))
449 (let ((line (buffer-substring (point-at-bol) (point)))
449 (after-prompt1)
450 (after-prompt1)
450 (after-prompt2))
451 (after-prompt2))
451 (save-excursion
452 (save-excursion
452 (comint-bol t)
453 (comint-bol t)
453 (if (looking-at py-shell-input-prompt-1-regexp)
454 (if (looking-at py-shell-input-prompt-1-regexp)
454 (setq after-prompt1 t)
455 (setq after-prompt1 t)
455 (setq after-prompt2 (looking-at py-shell-input-prompt-2-regexp)))
456 (setq after-prompt2 (looking-at py-shell-input-prompt-2-regexp)))
456 (with-current-buffer (ipython-get-indenting-buffer)
457 (with-current-buffer (ipython-get-indenting-buffer)
457 (when after-prompt1
458 (when after-prompt1
458 (erase-buffer))
459 (erase-buffer))
459 (when (or after-prompt1 after-prompt2)
460 (when (or after-prompt1 after-prompt2)
460 (delete-region (point-at-bol) (point))
461 (delete-region (point-at-bol) (point))
461 (insert line)
462 (insert line)
462 (newline-and-indent))))))
463 (newline-and-indent))))))
463 ;; send input line to ipython interpreter
464 ;; send input line to ipython interpreter
464 (comint-send-input))
465 (comint-send-input))
465
466
466 (defun ipython-indentation-hook (string)
467 (defun ipython-indentation-hook (string)
467 "Insert indentation string if py-shell-input-prompt-2-regexp
468 "Insert indentation string if py-shell-input-prompt-2-regexp
468 matches last process output."
469 matches last process output."
469 (let* ((start-marker (or comint-last-output-start
470 (let* ((start-marker (or comint-last-output-start
470 (point-min-marker)))
471 (point-min-marker)))
471 (end-marker (process-mark (get-buffer-process (current-buffer))))
472 (end-marker (process-mark (get-buffer-process (current-buffer))))
472 (text (ansi-color-filter-apply (buffer-substring start-marker end-marker))))
473 (text (ansi-color-filter-apply (buffer-substring start-marker end-marker))))
473 ;; XXX if `text' matches both pattern, it MUST be the last prompt-2
474 ;; XXX if `text' matches both pattern, it MUST be the last prompt-2
474 (when (and (string-match py-shell-input-prompt-2-regexp text)
475 (when (and (string-match py-shell-input-prompt-2-regexp text)
475 (not (string-match "\n$" text)))
476 (not (string-match "\n$" text)))
476 (with-current-buffer (ipython-get-indenting-buffer)
477 (with-current-buffer (ipython-get-indenting-buffer)
477 (setq ipython-indentation-string
478 (setq ipython-indentation-string
478 (buffer-substring (point-at-bol) (point))))
479 (buffer-substring (point-at-bol) (point))))
479 (goto-char end-marker)
480 (goto-char end-marker)
480 (insert ipython-indentation-string)
481 (insert ipython-indentation-string)
481 (setq ipython-indentation-string nil))))
482 (setq ipython-indentation-string nil))))
482
483
483 (add-hook 'py-shell-hook
484 (add-hook 'py-shell-hook
484 (lambda ()
485 (lambda ()
485 (add-hook 'comint-output-filter-functions
486 (add-hook 'comint-output-filter-functions
486 'ipython-indentation-hook)))
487 'ipython-indentation-hook)))
487
488
488 (define-key py-shell-map (kbd "RET") 'ipython-send-and-indent)
489 (define-key py-shell-map (kbd "RET") 'ipython-send-and-indent)
489 ;;; / end autoindent support
490 ;;; / end autoindent support
490
491
491 (provide 'ipython)
492 (provide 'ipython)
General Comments 0
You need to be logged in to leave comments. Login now