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.
  • [get | view] (2008-06-29 22:37:57, 34.1 KB) [[attachment:doctest-mode.el]]
  • [get | view] (2008-06-29 22:38:05, 0.4 KB) [[attachment:pyrex-mode.el]]
  • [get | view] (2008-06-29 22:38:13, 2.4 KB) [[attachment:pyrex-mode.elc]]
  • [get | view] (2008-06-29 22:41:02, 141.2 KB) [[attachment:python-mode.el]]
  • [get | view] (2008-06-29 22:41:13, 108.9 KB) [[attachment:python-mode.elc]]
  • [get | view] (2008-06-29 22:38:19, 15.3 KB) [[attachment:sage.el]]
  • [get | view] (2008-06-29 22:38:23, 7.9 KB) [[attachment:sage.elc]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.