Mercurial > dotfiles
comparison .elisp/ipython.el @ 19:b5d75594b356
Add support for the ipython-mode stuff and remove vestigial pymacs code.
| author | Augie Fackler <durin42@gmail.com> |
|---|---|
| date | Mon, 08 Dec 2008 10:58:06 -0600 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 18:30467b2328cb | 19:b5d75594b356 |
|---|---|
| 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: 2275 $" | |
| 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 across 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 ;; To start an interactive ipython session run `py-shell' with ``M-x py-shell`` | |
| 32 ;; (or the default keybinding ``C-c C-!``). | |
| 33 ;; | |
| 34 ;; NOTE: This mode is currently somewhat alpha and although I hope that it | |
| 35 ;; will work fine for most cases, doing certain things (like the | |
| 36 ;; autocompletion and a decent scheme to switch between python interpreters) | |
| 37 ;; properly will also require changes to ipython that will likely have to wait | |
| 38 ;; for a larger rewrite scheduled some time in the future. | |
| 39 ;; | |
| 40 ;; Also note that you currently NEED THE CVS VERSION OF PYTHON.EL. | |
| 41 ;; | |
| 42 ;; Further note that I don't know whether this runs under windows or not and | |
| 43 ;; that if it doesn't I can't really help much, not being afflicted myself. | |
| 44 ;; | |
| 45 ;; | |
| 46 ;; Hints for effective usage | |
| 47 ;; ------------------------- | |
| 48 ;; | |
| 49 ;; - IMO the best feature by far of the ipython/emacs combo is how much easier it | |
| 50 ;; makes it to find and fix bugs thanks to the ``%pdb on``/ pdbtrack combo. Try | |
| 51 ;; it: first in the ipython to shell do ``%pdb on`` then do something that will | |
| 52 ;; raise an exception (FIXME nice example) -- and be amazed how easy it is to | |
| 53 ;; inspect the live objects in each stack frames and to jump to the | |
| 54 ;; corresponding sourcecode locations as you walk up and down the stack trace | |
| 55 ;; (even without ``%pdb on`` you can always use ``C-c -`` (`py-up-exception') | |
| 56 ;; to jump to the corresponding source code locations). | |
| 57 ;; | |
| 58 ;; - emacs gives you much more powerful commandline editing and output searching | |
| 59 ;; capabilities than ipython-standalone -- isearch is your friend if you | |
| 60 ;; quickly want to print 'DEBUG ...' to stdout out etc. | |
| 61 ;; | |
| 62 ;; - This is not really specific to ipython, but for more convenient history | |
| 63 ;; access you might want to add something like the following to *the beggining* | |
| 64 ;; of your ``.emacs`` (if you want behavior that's more similar to stand-alone | |
| 65 ;; ipython, you can change ``meta p`` etc. for ``control p``):: | |
| 66 ;; | |
| 67 ;; (require 'comint) | |
| 68 ;; (define-key comint-mode-map [(meta p)] | |
| 69 ;; 'comint-previous-matching-input-from-input) | |
| 70 ;; (define-key comint-mode-map [(meta n)] | |
| 71 ;; 'comint-next-matching-input-from-input) | |
| 72 ;; (define-key comint-mode-map [(control meta n)] | |
| 73 ;; 'comint-next-input) | |
| 74 ;; (define-key comint-mode-map [(control meta p)] | |
| 75 ;; 'comint-previous-input) | |
| 76 ;; | |
| 77 ;; - Be aware that if you customize py-python-command previously, this value | |
| 78 ;; will override what ipython.el does (because loading the customization | |
| 79 ;; variables comes later). | |
| 80 ;; | |
| 81 ;; Please send comments and feedback to the ipython-list | |
| 82 ;; (<ipython-user@scipy.net>) where I (a.s.) or someone else will try to | |
| 83 ;; answer them (it helps if you specify your emacs version, OS etc; | |
| 84 ;; familiarity with <http://www.catb.org/~esr/faqs/smart-questions.html> might | |
| 85 ;; speed up things further). | |
| 86 ;; | |
| 87 ;; Footnotes: | |
| 88 ;; | |
| 89 ;; [1] If you don't know what `load-path' is, C-h v load-path will tell | |
| 90 ;; you; if required you can also add a new directory. So assuming that | |
| 91 ;; ipython.el resides in ~/el/, put this in your emacs: | |
| 92 ;; | |
| 93 ;; | |
| 94 ;; (add-to-list 'load-path "~/el") | |
| 95 ;; (setq ipython-command "/some-path/ipython") | |
| 96 ;; (require 'ipython) | |
| 97 ;; | |
| 98 ;; | |
| 99 ;; | |
| 100 ;; | |
| 101 ;; TODO: | |
| 102 ;; - do autocompletion properly | |
| 103 ;; - implement a proper switching between python interpreters | |
| 104 ;; | |
| 105 ;; BUGS: | |
| 106 ;; - neither:: | |
| 107 ;; | |
| 108 ;; (py-shell "-c print 'FOOBAR'") | |
| 109 ;; | |
| 110 ;; nor:: | |
| 111 ;; | |
| 112 ;; (let ((py-python-command-args (append py-python-command-args | |
| 113 ;; '("-c" "print 'FOOBAR'")))) | |
| 114 ;; (py-shell)) | |
| 115 ;; | |
| 116 ;; seem to print anything as they should | |
| 117 ;; | |
| 118 ;; - look into init priority issues with `py-python-command' (if it's set | |
| 119 ;; via custom) | |
| 120 | |
| 121 | |
| 122 ;;; Code | |
| 123 (require 'cl) | |
| 124 (require 'shell) | |
| 125 (require 'executable) | |
| 126 (require 'ansi-color) | |
| 127 | |
| 128 (defcustom ipython-command "ipython" | |
| 129 "*Shell command used to start ipython." | |
| 130 :type 'string | |
| 131 :group 'python) | |
| 132 | |
| 133 ;; Users can set this to nil | |
| 134 (defvar py-shell-initial-switch-buffers t | |
| 135 "If nil, don't switch to the *Python* buffer on the first call to | |
| 136 `py-shell'.") | |
| 137 | |
| 138 (defvar ipython-backup-of-py-python-command nil | |
| 139 "HACK") | |
| 140 | |
| 141 | |
| 142 (defvar ipython-de-input-prompt-regexp "\\(?: | |
| 143 In \\[[0-9]+\\]: *.* | |
| 144 ----+> \\(.* | |
| 145 \\)[\n]?\\)\\|\\(?: | |
| 146 In \\[[0-9]+\\]: *\\(.* | |
| 147 \\)\\)\\|^[ ]\\{3\\}[.]\\{3,\\}: *\\(.* | |
| 148 \\)" | |
| 149 "A regular expression to match the IPython input prompt and the python | |
| 150 command after it. The first match group is for a command that is rewritten, | |
| 151 the second for a 'normal' command, and the third for a multiline command.") | |
| 152 (defvar ipython-de-output-prompt-regexp "^Out\\[[0-9]+\\]: " | |
| 153 "A regular expression to match the output prompt of IPython.") | |
| 154 | |
| 155 | |
| 156 (if (not (executable-find ipython-command)) | |
| 157 (message (format "Can't find executable %s - ipython.el *NOT* activated!!!" | |
| 158 ipython-command)) | |
| 159 ;; XXX load python-mode, so that we can screw around with its variables | |
| 160 ;; this has the disadvantage that python-mode is loaded even if no | |
| 161 ;; python-file is ever edited etc. but it means that `py-shell' works | |
| 162 ;; without loading a python-file first. Obviously screwing around with | |
| 163 ;; python-mode's variables like this is a mess, but well. | |
| 164 (require 'python-mode) | |
| 165 ;; turn on ansi colors for ipython and activate completion | |
| 166 (defun ipython-shell-hook () | |
| 167 ;; the following is to synchronize dir-changes | |
| 168 (make-local-variable 'shell-dirstack) | |
| 169 (setq shell-dirstack nil) | |
| 170 (make-local-variable 'shell-last-dir) | |
| 171 (setq shell-last-dir nil) | |
| 172 (make-local-variable 'shell-dirtrackp) | |
| 173 (setq shell-dirtrackp t) | |
| 174 (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t) | |
| 175 | |
| 176 (ansi-color-for-comint-mode-on) | |
| 177 (define-key py-shell-map [tab] 'ipython-complete) | |
| 178 ;; Add this so that tab-completion works both in X11 frames and inside | |
| 179 ;; terminals (such as when emacs is called with -nw). | |
| 180 (define-key py-shell-map "\t" 'ipython-complete) | |
| 181 ;;XXX this is really just a cheap hack, it only completes symbols in the | |
| 182 ;;interactive session -- useful nonetheless. | |
| 183 (define-key py-mode-map [(meta tab)] 'ipython-complete) | |
| 184 | |
| 185 ) | |
| 186 (add-hook 'py-shell-hook 'ipython-shell-hook) | |
| 187 ;; Regular expression that describes tracebacks for IPython in context and | |
| 188 ;; verbose mode. | |
| 189 | |
| 190 ;;Adapt python-mode settings for ipython. | |
| 191 ;; (this works for %xmode 'verbose' or 'context') | |
| 192 | |
| 193 ;; XXX putative regexps for syntax errors; unfortunately the | |
| 194 ;; current python-mode traceback-line-re scheme is too primitive, | |
| 195 ;; so it's either matching syntax errors, *or* everything else | |
| 196 ;; (XXX: should ask Fernando for a change) | |
| 197 ;;"^ File \"\\(.*?\\)\", line \\([0-9]+\\).*\n.*\n.*\nSyntaxError:" | |
| 198 ;;^ File \"\\(.*?\\)\", line \\([0-9]+\\)" | |
| 199 | |
| 200 (setq py-traceback-line-re | |
| 201 "\\(^[^\t >].+?\\.py\\).*\n +[0-9]+[^\00]*?\n-+> \\([0-9]+\\)+") | |
| 202 | |
| 203 | |
| 204 ;; Recognize the ipython pdb, whose prompt is 'ipdb>' or 'ipydb>' | |
| 205 ;;instead of '(Pdb)' | |
| 206 (setq py-pdbtrack-input-prompt "\n[(<]*[Ii]?[Pp]y?db[>)]+ ") | |
| 207 (setq pydb-pydbtrack-input-prompt "\n[(]*ipydb[>)]+ ") | |
| 208 | |
| 209 (setq py-shell-input-prompt-1-regexp "^In \\[[0-9]+\\]: *" | |
| 210 py-shell-input-prompt-2-regexp "^ [.][.][.]+: *" ) | |
| 211 ;; select a suitable color-scheme | |
| 212 (unless (member "-colors" py-python-command-args) | |
| 213 (setq py-python-command-args | |
| 214 (nconc py-python-command-args | |
| 215 (list "-colors" | |
| 216 (cond | |
| 217 ((eq frame-background-mode 'dark) | |
| 218 "Linux") | |
| 219 ((eq frame-background-mode 'light) | |
| 220 "LightBG") | |
| 221 (t ; default (backg-mode isn't always set by XEmacs) | |
| 222 "LightBG")))))) | |
| 223 (unless (equal ipython-backup-of-py-python-command py-python-command) | |
| 224 (setq ipython-backup-of-py-python-command py-python-command)) | |
| 225 (setq py-python-command ipython-command)) | |
| 226 | |
| 227 | |
| 228 ;; MODIFY py-shell so that it loads the editing history | |
| 229 (defadvice py-shell (around py-shell-with-history) | |
| 230 "Add persistent command-history support (in | |
| 231 $PYTHONHISTORY (or \"~/.ipython/history\", if we use IPython)). Also, if | |
| 232 `py-shell-initial-switch-buffers' is nil, it only switches to *Python* if that | |
| 233 buffer already exists." | |
| 234 (if (comint-check-proc "*Python*") | |
| 235 ad-do-it | |
| 236 (setq comint-input-ring-file-name | |
| 237 (if (string-equal py-python-command ipython-command) | |
| 238 (concat (or (getenv "IPYTHONDIR") "~/.ipython") "/history") | |
| 239 (or (getenv "PYTHONHISTORY") "~/.python-history.py"))) | |
| 240 (comint-read-input-ring t) | |
| 241 (let ((buf (current-buffer))) | |
| 242 ad-do-it | |
| 243 (unless py-shell-initial-switch-buffers | |
| 244 (switch-to-buffer-other-window buf))))) | |
| 245 (ad-activate 'py-shell) | |
| 246 ;; (defadvice py-execute-region (before py-execute-buffer-ensure-process) | |
| 247 ;; "HACK: test that ipython is already running before executing something. | |
| 248 ;; Doing this properly seems not worth the bother (unless people actually | |
| 249 ;; request it)." | |
| 250 ;; (unless (comint-check-proc "*Python*") | |
| 251 ;; (error "Sorry you have to first do M-x py-shell to send something to ipython."))) | |
| 252 ;; (ad-activate 'py-execute-region) | |
| 253 | |
| 254 (defadvice py-execute-region (around py-execute-buffer-ensure-process) | |
| 255 "HACK: if `py-shell' is not active or ASYNC is explicitly desired, fall back | |
| 256 to python instead of ipython." | |
| 257 (let ((py-which-shell (if (and (comint-check-proc "*Python*") (not async)) | |
| 258 py-python-command | |
| 259 ipython-backup-of-py-python-command))) | |
| 260 ad-do-it)) | |
| 261 (ad-activate 'py-execute-region) | |
| 262 | |
| 263 (defun ipython-to-doctest (start end) | |
| 264 "Transform a cut-and-pasted bit from an IPython session into something that | |
| 265 looks like it came from a normal interactive python session, so that it can | |
| 266 be used in doctests. Example: | |
| 267 | |
| 268 | |
| 269 In [1]: import sys | |
| 270 | |
| 271 In [2]: sys.stdout.write 'Hi!\n' | |
| 272 ------> sys.stdout.write ('Hi!\n') | |
| 273 Hi! | |
| 274 | |
| 275 In [3]: 3 + 4 | |
| 276 Out[3]: 7 | |
| 277 | |
| 278 gets converted to: | |
| 279 | |
| 280 >>> import sys | |
| 281 >>> sys.stdout.write ('Hi!\n') | |
| 282 Hi! | |
| 283 >>> 3 + 4 | |
| 284 7 | |
| 285 | |
| 286 " | |
| 287 (interactive "*r\n") | |
| 288 ;(message (format "###DEBUG s:%de:%d" start end)) | |
| 289 (save-excursion | |
| 290 (save-match-data | |
| 291 ;; replace ``In [3]: bla`` with ``>>> bla`` and | |
| 292 ;; ``... : bla`` with ``... bla`` | |
| 293 (goto-char start) | |
| 294 (while (re-search-forward ipython-de-input-prompt-regexp end t) | |
| 295 ;(message "finding 1") | |
| 296 (cond ((match-string 3) ;continued | |
| 297 (replace-match "... \\3" t nil)) | |
| 298 (t | |
| 299 (replace-match ">>> \\1\\2" t nil)))) | |
| 300 ;; replace `` | |
| 301 (goto-char start) | |
| 302 (while (re-search-forward ipython-de-output-prompt-regexp end t) | |
| 303 (replace-match "" t nil))))) | |
| 304 | |
| 305 (defvar ipython-completion-command-string | |
| 306 "print ';'.join(__IP.Completer.all_completions('%s')) #PYTHON-MODE SILENT\n" | |
| 307 "The string send to ipython to query for all possible completions") | |
| 308 | |
| 309 | |
| 310 ;; xemacs doesn't have `comint-preoutput-filter-functions' so we'll try the | |
| 311 ;; following wonderful hack to work around this case | |
| 312 (if (featurep 'xemacs) | |
| 313 ;;xemacs | |
| 314 (defun ipython-complete () | |
| 315 "Try to complete the python symbol before point. Only knows about the stuff | |
| 316 in the current *Python* session." | |
| 317 (interactive) | |
| 318 (let* ((ugly-return nil) | |
| 319 (sep ";") | |
| 320 (python-process (or (get-buffer-process (current-buffer)) | |
| 321 ;XXX hack for .py buffers | |
| 322 (get-process py-which-bufname))) | |
| 323 ;; XXX currently we go backwards to find the beginning of an | |
| 324 ;; expression part; a more powerful approach in the future might be | |
| 325 ;; to let ipython have the complete line, so that context can be used | |
| 326 ;; to do things like filename completion etc. | |
| 327 (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_." (point-at-bol)) | |
| 328 (point))) | |
| 329 (end (point)) | |
| 330 (pattern (buffer-substring-no-properties beg end)) | |
| 331 (completions nil) | |
| 332 (completion-table nil) | |
| 333 completion | |
| 334 (comint-output-filter-functions | |
| 335 (append comint-output-filter-functions | |
| 336 '(ansi-color-filter-apply | |
| 337 (lambda (string) | |
| 338 ;(message (format "DEBUG filtering: %s" string)) | |
| 339 (setq ugly-return (concat ugly-return string)) | |
| 340 (delete-region comint-last-output-start | |
| 341 (process-mark (get-buffer-process (current-buffer))))))))) | |
| 342 ;(message (format "#DEBUG pattern: '%s'" pattern)) | |
| 343 (process-send-string python-process | |
| 344 (format ipython-completion-command-string pattern)) | |
| 345 (accept-process-output python-process) | |
| 346 ;(message (format "DEBUG return: %s" ugly-return)) | |
| 347 (setq completions | |
| 348 (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep)) | |
| 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 "*Python Completions*" | |
| 362 (display-completion-list (all-completions pattern completion-table))) | |
| 363 (message "Making completion list...%s" "done"))))) | |
| 364 ;; emacs | |
| 365 (defun ipython-complete () | |
| 366 "Try to complete the python symbol before point. Only knows about the stuff | |
| 367 in the current *Python* session." | |
| 368 (interactive) | |
| 369 (let* ((ugly-return nil) | |
| 370 (sep ";") | |
| 371 (python-process (or (get-buffer-process (current-buffer)) | |
| 372 ;XXX hack for .py buffers | |
| 373 (get-process py-which-bufname))) | |
| 374 ;; XXX currently we go backwards to find the beginning of an | |
| 375 ;; expression part; a more powerful approach in the future might be | |
| 376 ;; to let ipython have the complete line, so that context can be used | |
| 377 ;; to do things like filename completion etc. | |
| 378 (beg (save-excursion (skip-chars-backward "a-z0-9A-Z_." (point-at-bol)) | |
| 379 (point))) | |
| 380 (end (point)) | |
| 381 (pattern (buffer-substring-no-properties beg end)) | |
| 382 (completions nil) | |
| 383 (completion-table nil) | |
| 384 completion | |
| 385 (comint-preoutput-filter-functions | |
| 386 (append comint-preoutput-filter-functions | |
| 387 '(ansi-color-filter-apply | |
| 388 (lambda (string) | |
| 389 (setq ugly-return (concat ugly-return string)) | |
| 390 ""))))) | |
| 391 (process-send-string python-process | |
| 392 (format ipython-completion-command-string pattern)) | |
| 393 (accept-process-output python-process) | |
| 394 (setq completions | |
| 395 (split-string (substring ugly-return 0 (position ?\n ugly-return)) sep)) | |
| 396 ;(message (format "DEBUG completions: %S" completions)) | |
| 397 (setq completion-table (loop for str in completions | |
| 398 collect (list str nil))) | |
| 399 (setq completion (try-completion pattern completion-table)) | |
| 400 (cond ((eq completion t)) | |
| 401 ((null completion) | |
| 402 (message "Can't find completion for \"%s\"" pattern) | |
| 403 (ding)) | |
| 404 ((not (string= pattern completion)) | |
| 405 (delete-region beg end) | |
| 406 (insert completion)) | |
| 407 (t | |
| 408 (message "Making completion list...") | |
| 409 (with-output-to-temp-buffer "*IPython Completions*" | |
| 410 (display-completion-list (all-completions pattern completion-table))) | |
| 411 (message "Making completion list...%s" "done"))))) | |
| 412 ) | |
| 413 | |
| 414 ;;; autoindent support: patch sent in by Jin Liu <m.liu.jin@gmail.com>, | |
| 415 ;;; originally written by doxgen@newsmth.net | |
| 416 ;;; Minor modifications by fperez for xemacs compatibility. | |
| 417 | |
| 418 (defvar ipython-autoindent t | |
| 419 "If non-nil, enable autoindent for IPython shell through python-mode.") | |
| 420 | |
| 421 (defvar ipython-indenting-buffer-name "*IPython Indentation Calculation*" | |
| 422 "Temporary buffer for indenting multiline statement.") | |
| 423 | |
| 424 (defun ipython-get-indenting-buffer () | |
| 425 "Return a temporary buffer set in python-mode. Create one if necessary." | |
| 426 (let ((buf (get-buffer-create ipython-indenting-buffer-name))) | |
| 427 (set-buffer buf) | |
| 428 (unless (eq major-mode 'python-mode) | |
| 429 (python-mode)) | |
| 430 buf)) | |
| 431 | |
| 432 (defvar ipython-indentation-string nil | |
| 433 "Indentation for the next line in a multiline statement.") | |
| 434 | |
| 435 (defun ipython-send-and-indent () | |
| 436 "Send the current line to IPython, and calculate the indentation for | |
| 437 the next line." | |
| 438 (interactive) | |
| 439 (if ipython-autoindent | |
| 440 (let ((line (buffer-substring (point-at-bol) (point))) | |
| 441 (after-prompt1) | |
| 442 (after-prompt2)) | |
| 443 (save-excursion | |
| 444 (comint-bol t) | |
| 445 (if (looking-at py-shell-input-prompt-1-regexp) | |
| 446 (setq after-prompt1 t) | |
| 447 (setq after-prompt2 (looking-at py-shell-input-prompt-2-regexp))) | |
| 448 (with-current-buffer (ipython-get-indenting-buffer) | |
| 449 (when after-prompt1 | |
| 450 (erase-buffer)) | |
| 451 (when (or after-prompt1 after-prompt2) | |
| 452 (delete-region (point-at-bol) (point)) | |
| 453 (insert line) | |
| 454 (newline-and-indent)))))) | |
| 455 ;; send input line to ipython interpreter | |
| 456 (comint-send-input)) | |
| 457 | |
| 458 (defun ipython-indentation-hook (string) | |
| 459 "Insert indentation string if py-shell-input-prompt-2-regexp | |
| 460 matches last process output." | |
| 461 (let* ((start-marker (or comint-last-output-start | |
| 462 (point-min-marker))) | |
| 463 (end-marker (process-mark (get-buffer-process (current-buffer)))) | |
| 464 (text (ansi-color-filter-apply (buffer-substring start-marker end-marker)))) | |
| 465 ;; XXX if `text' matches both pattern, it MUST be the last prompt-2 | |
| 466 (when (and (string-match py-shell-input-prompt-2-regexp text) | |
| 467 (not (string-match "\n$" text))) | |
| 468 (with-current-buffer (ipython-get-indenting-buffer) | |
| 469 (setq ipython-indentation-string | |
| 470 (buffer-substring (point-at-bol) (point)))) | |
| 471 (goto-char end-marker) | |
| 472 (insert ipython-indentation-string) | |
| 473 (setq ipython-indentation-string nil)))) | |
| 474 | |
| 475 (add-hook 'py-shell-hook | |
| 476 (lambda () | |
| 477 (add-hook 'comint-output-filter-functions | |
| 478 'ipython-indentation-hook))) | |
| 479 | |
| 480 (define-key py-shell-map (kbd "RET") 'ipython-send-and-indent) | |
| 481 ;;; / end autoindent support | |
| 482 | |
| 483 (provide 'ipython) |
