Attachment 'sage.el'
Download 1 ;;; ipython.el --- Adds support for IPython to python-mode.el
2
3 ;; Copyright (C) 2002, 2003, 2004, 2005 Alexander Schmolck
4 ;; Author: Alexander Schmolck
5 ;; Keywords: ipython python languages oop
6 ;; URL: http://ipython.scipy.org
7 ;; Compatibility: Emacs21, XEmacs21
8 ;; FIXME: #$@! INPUT RING
9 (defconst ipython-version "$Revision: 1.2 $"
10 "VC version number.")
11
12 ;;; Commentary
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
15 ;; persistent py-shell command history accross sessions (if you exit python
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
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
20 ;; line only needed if the default (``"ipython"``) is wrong)::
21 ;;
22 ;; (setq ipython-command "/SOME-PATH/ipython")
23 ;; (require 'ipython)
24 ;;
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>
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
29 ;; (i)python, so importing readline etc. will have 0 effect.
30 ;;
31 ;; NOTE: This mode is currently somewhat alpha and although I hope that it
32 ;; will work fine for most cases, doing certain things (like the
33 ;; autocompletion and a decent scheme to switch between python interpreters)
34 ;; properly will also require changes to ipython that will likely have to wait
35 ;; for a larger rewrite scheduled some time in the future.
36 ;;
37 ;; Also note that you currently NEED THE CVS VERSION OF PYTHON.EL.
38 ;;
39 ;; Further note that I don't know whether this runs under windows or not and
40 ;; that if it doesn't I can't really help much, not being a fellow sufferer.
41 ;;
42 ;; Please send comments and feedback to the ipython-list
43 ;; (<ipython-user@scipy.net>) where I (a.s.) or someone else will try to
44 ;; answer them (it helps if you specify your emacs version, OS etc;
45 ;; familiarity with <http://www.catb.org/~esr/faqs/smart-questions.html> might
46 ;; speed up things further).
47 ;;
48 ;; Footnotes:
49 ;;
50 ;; [1] If you don't know what `load-path' is, C-h v load-path will tell
51 ;; you; if required you can also add a new directory. So assuming that
52 ;; ipython.el resides in ~/el/, put this in your emacs:
53 ;;
54 ;;
55 ;; (add-to-list 'load-path "~/el")
56 ;; (setq ipython-command "/some-path/ipython")
57 ;; (require 'ipython)
58 ;;
59 ;;
60 ;;
61 ;;
62 ;; TODO:
63 ;; - do autocompletion properly
64 ;; - implement a proper switching between python interpreters
65 ;;
66 ;; BUGS:
67 ;; - neither::
68 ;;
69 ;; (py-shell "-c print 'FOOBAR'")
70 ;;
71 ;; nor::
72 ;;
73 ;; (let ((py-python-command-args (append py-python-command-args
74 ;; '("-c" "print 'FOOBAR'"))))
75 ;; (py-shell))
76 ;;
77 ;; seem to print anything as they should
78
79 ;;; Code
80 (require 'cl)
81 (require 'shell)
82 (require 'executable)
83 (require 'ansi-color)
84
85 (defcustom ipython-command "ipython"
86 "*Shell command used to start ipython."
87 :type 'string
88 :group 'python)
89
90 ;; Users can set this to nil
91 (defvar py-shell-initial-switch-buffers t
92 "If nil, don't switch to the *Python* buffer on the first call to
93 `py-shell'.")
94
95 (defvar ipython-backup-of-py-python-command nil
96 "HACK")
97
98
99 (defvar ipython-de-input-prompt-regexp "\\(?:
100 In \\[[0-9]+\\]: .*
101 ----+> \\(.*
102 \\)[\n]?\\)\\|\\(?:
103 In \\[[0-9]+\\]: \\(.*
104 \\)\\)\\|^[ ]\\{3\\}[.]\\{3,\\}: \\(.*
105 \\)"
106 "A regular expression to match the IPython input prompt and the python
107 command after it. The first match group is for a command that is rewritten,
108 the second for a 'normal' command, and the third for a multiline command.")
109 (defvar ipython-de-output-prompt-regexp "^Out\\[[0-9]+\\]: "
110 "A regular expression to match the output prompt of IPython.")
111
112 (defvar ipython-de-input-prompt-regexp "\\(?:
113 sage: .*
114 ----+> \\(.*
115 \\)[\n]?\\)\\|\\(?:
116 sage: \\(.*
117 \\)\\)\\|^[ ]\\{3\\}[.]\\{3,\\}: \\(.*
118 \\)"
119 "A regular expression to match the IPython input prompt and the python
120 command after it. The first match group is for a command that is rewritten,
121 the second for a 'normal' command, and the third for a multiline command.")
122 (defvar ipython-de-output-prompt-regexp " "
123 "A regular expression to match the output prompt of IPython.")
124
125 (if (not (executable-find ipython-command))
126 (message (format "Can't find executable %s - ipython.el *NOT* activated!!!"
127 ipython-command))
128 ;; XXX load python-mode, so that we can screw around with its variables
129 ;; this has the disadvantage that python-mode is loaded even if no
130 ;; python-file is ever edited etc. but it means that `py-shell' works
131 ;; without loading a python-file first. Obviously screwing around with
132 ;; python-mode's variables like this is a mess, but well.
133 (require 'python-mode)
134 ;; turn on ansi colors for ipython and activate completion
135 (defun ipython-shell-hook ()
136 ;; the following is to synchronize dir-changes
137 (make-local-variable 'shell-dirstack)
138 (setq shell-dirstack nil)
139 (make-local-variable 'shell-last-dir)
140 (setq shell-last-dir nil)
141 (make-local-variable 'shell-dirtrackp)
142 (setq shell-dirtrackp t)
143 (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t)
144
145 (ansi-color-for-comint-mode-on)
146 (define-key py-shell-map [tab] 'ipython-complete)
147 ;;XXX this is really just a cheap hack, it only completes symbols in the
148 ;;interactive session -- useful nonetheless.
149 (define-key py-mode-map [(meta tab)] 'ipython-complete))
150 (add-hook 'py-shell-hook 'ipython-shell-hook)
151 ;; Regular expression that describes tracebacks for IPython in context and
152 ;; verbose mode.
153
154 ;;Adapt python-mode settings for ipython.
155 ;; (this works for @xmode 'verbose' or 'context')
156
157 ;; XXX putative regexps for syntax errors; unfortunately the
158 ;; current python-mode traceback-line-re scheme is too primitive,
159 ;; so it's either matching syntax errors, *or* everything else
160 ;; (XXX: should ask Fernando for a change)
161 ;;"^ File \"\\(.*?\\)\", line \\([0-9]+\\).*\n.*\n.*\nSyntaxError:"
162 ;;^ File \"\\(.*?\\)\", line \\([0-9]+\\)"
163 (setq py-traceback-line-re
164 "\\(^[^\t ].+?\\.py\\).*\n +[0-9]+[^\00]*?\n-+> \\([0-9]+\\) +")
165
166 (setq py-shell-input-prompt-1-regexp "^In \\[[0-9]+\\]: "
167 py-shell-input-prompt-2-regexp "^ [.][.][.]+: " )
168 ;; select a suitable color-scheme
169 (unless (member "-colors" py-python-command-args)
170 (setq py-python-command-args
171 (nconc py-python-command-args
172 (list "-colors"
173 (cond
174 ((eq frame-background-mode 'dark)
175 "DarkBG")
176 ((eq frame-background-mode 'light)
177 "LightBG")
178 (t ; default (backg-mode isn't always set by XEmacs)
179 "LightBG"))))))
180 (setq ipython-backup-of-py-python-command py-python-command)
181 (setq py-python-command "sage"))
182
183
184 ;; MODIFY py-shell so that it loads the editing history
185 (defadvice py-shell (around py-shell-with-history)
186 "Add persistent command-history support (in
187 $PYTHONHISTORY (or \"~/.ipython/history\", if we use IPython)). Also, if
188 `py-shell-initial-switch-buffers' is nil, it only switches to *Python* if that
189 buffer already exists."
190 (if (comint-check-proc "*Python*")
191 ad-do-it
192 (setq comint-input-ring-file-name
193 (if (string-equal py-python-command "ipython")
194 (concat (or (getenv "IPYTHONDIR") "~/.ipython") "/history")
195 (or (getenv "PYTHONHISTORY") "~/.python-history.py")))
196 (comint-read-input-ring t)
197 (let ((buf (current-buffer)))
198 ad-do-it
199 (unless py-shell-initial-switch-buffers
200 (switch-to-buffer-other-window buf)))))
201 (ad-activate 'py-shell)
202 ;; (defadvice py-execute-region (before py-execute-buffer-ensure-process)
203 ;; "HACK: test that ipython is already running before executing something.
204 ;; Doing this properly seems not worth the bother (unless people actually
205 ;; request it)."
206 ;; (unless (comint-check-proc "*Python*")
207 ;; (error "Sorry you have to first do M-x py-shell to send something to ipython.")))
208 ;; (ad-activate 'py-execute-region)
209
210 (defadvice py-execute-region (around py-execute-buffer-ensure-process)
211 "HACK: if `py-shell' is not active or ASYNC is explicitly desired, fall back
212 to python instead of ipython."
213 (let ((py-python-command (if (or (comint-check-proc "*Python*") async)
214 py-python-command
215 ipython-backup-of-py-python-command)))
216 ad-do-it))
217 (ad-activate 'py-execute-region)
218
219 (defun ipython-to-doctest (start end)
220 "Transform a cut-and-pasted bit from an IPython session into something that
221 looks like it came from a normal interactive python session, so that it can
222 be used in doctests. Example:
223
224
225 In [1]: import sys
226
227 In [2]: sys.stdout.write 'Hi!\n'
228 ------> sys.stdout.write ('Hi!\n')
229 Hi!
230
231 In [3]: 3 + 4
232 Out[3]: 7
233
234 gets converted to:
235
236 >>> import sys
237 >>> sys.stdout.write ('Hi!\n')
238 Hi!
239 >>> 3 + 4
240 7
241
242 "
243 (interactive "*r\n")
244 ;(message (format "###DEBUG s:%de:%d" start end))
245 (save-excursion
246 (save-match-data
247 ;; replace ``In [3]: bla`` with ``>>> bla`` and
248 ;; ``... : bla`` with ``... bla``
249 (goto-char start)
250 (while (re-search-forward ipython-de-input-prompt-regexp end t)
251 ;(message "finding 1")
252 (cond ((match-string 3) ;continued
253 (replace-match "... \\3" t nil))
254 (t
255 (replace-match ">>> \\1\\2" t nil))))
256 ;; replace ``
257 (goto-char start)
258 (while (re-search-forward ipython-de-output-prompt-regexp end t)
259 (replace-match "" t nil)))))
260
261 (defvar ipython-completion-command-string
262 "print ';'.join(__IP.Completer.all_completions('%s')) #PYTHON-MODE SILENT\n"
263 "The string send to ipython to query for all possible completions")
264
265
266 ;; xemacs doesn't have `comint-preoutput-filter-functions' so we'll try the
267 ;; following wonderful hack to work around this case
268 (if (featurep 'xemacs)
269 ;;xemacs
270 (defun ipython-complete ()
271 "Try to complete the python symbol before point. Only knows about the stuff
272 in the current *Python* session."
273 (interactive)
274 (let* ((ugly-return nil)
275 (sep ";")
276 ;; XXX currently we go backwards to find the beginning of an
277 ;; expression part; a more powerful approach in the future might be
278 ;; to let ipython have the complete line, so that context can be used
279 ;; to do things like filename completion etc.
280 (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_." (point-at-bol))
281 (point)))
282 (end (point))
283 (pattern (buffer-substring-no-properties beg end))
284 (completions nil)
285 (completion-table nil)
286 completion
287 (comint-output-filter-functions
288 (append comint-output-filter-functions
289 '(ansi-color-filter-apply
290 (lambda (string)
291 ;(message (format "DEBUG filtering: %s" string))
292 (setq ugly-return (concat ugly-return string))
293 (delete-region comint-last-output-start
294 (process-mark (get-buffer-process (current-buffer)))))))))
295 ;(message (format "#DEBUG pattern: '%s'" pattern))
296 (process-send-string (or (get-buffer-process (current-buffer))
297 (get-process py-which-bufname)) ;XXX hack for .py buffers
298 (format ipython-completion-command-string pattern))
299 (accept-process-output (get-buffer-process (current-buffer)))
300 ;(message (format "DEBUG return: %s" ugly-return))
301 (setq completions
302 (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
303 (setq completion-table (loop for str in completions
304 collect (list str nil)))
305 (setq completion (try-completion pattern completion-table))
306 (cond ((eq completion t))
307 ((null completion)
308 (message "Can't find completion for \"%s\"" pattern)
309 (ding))
310 ((not (string= pattern completion))
311 (delete-region beg end)
312 (insert completion))
313 (t
314 (message "Making completion list...")
315 (with-output-to-temp-buffer "*Python Completions*"
316 (display-completion-list (all-completions pattern completion-table)))
317 (message "Making completion list...%s" "done")))))
318 ;; emacs
319 (defun ipython-complete ()
320 "Try to complete the python symbol before point. Only knows about the stuff
321 in the current *Python* session."
322 (interactive)
323 (let* ((ugly-return nil)
324 (sep ";")
325 ;; XXX currently we go backwards to find the beginning of an
326 ;; expression part; a more powerful approach in the future might be
327 ;; to let ipython have the complete line, so that context can be used
328 ;; to do things like filename completion etc.
329 (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_." (point-at-bol))
330 (point)))
331 (end (point))
332 (pattern (buffer-substring-no-properties beg end))
333 (completions nil)
334 (completion-table nil)
335 completion
336 (comint-preoutput-filter-functions
337 (append comint-preoutput-filter-functions
338 '(ansi-color-filter-apply
339 (lambda (string)
340 (setq ugly-return (concat ugly-return string))
341 "")))))
342 (process-send-string (or (get-buffer-process (current-buffer))
343 (get-process py-which-bufname)) ;XXX hack for .py buffers
344 (format ipython-completion-command-string pattern))
345 (accept-process-output (get-buffer-process (current-buffer)))
346 (setq completions
347 (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep))
348 ;(message (format "DEBUG completions: %S" completions))
349 (setq completion-table (loop for str in completions
350 collect (list str nil)))
351 (setq completion (try-completion pattern completion-table))
352 (cond ((eq completion t))
353 ((null completion)
354 (message "Can't find completion for \"%s\"" pattern)
355 (ding))
356 ((not (string= pattern completion))
357 (delete-region beg end)
358 (insert completion))
359 (t
360 (message "Making completion list...")
361 (with-output-to-temp-buffer "*IPython Completions*"
362 (display-completion-list (all-completions pattern completion-table)))
363 (message "Making completion list...%s" "done")))))
364 )
365
366 (provide 'ipython)
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.