3

Say I open a terminal emulator in Emacs with M-x ansi-term. This opens a buffer in Emacs with the shell of my choice. Say I then run ipython from this shell. Can I send code to this ipython session from another buffer with Python code in Emacs? If so how?

3 Answers 3

5

I have a minor mode for this purpose (except it is not IPython-specific and I mostly use it for shell scripts): isend-mode.

Here is how you would use it:

  1. Open an ansi-term buffer:

    M-xansi-termRET/usr/bin/ipythonRET

  2. Open the buffer with the code you want to execute, and associate it to the interpreter buffer:

    M-xisend-associateRET*ansi-term*RET

  3. Hit C-RET in the python buffer to send the current line to the interpreter in the ansi-term buffer.

Sign up to request clarification or add additional context in comments.

8 Comments

This is awesome Francesco. Does it only support sending the current line? (i.e. as opposed to sending a region, or a full buffer).
If the region is active, it will send it instead of sending the current line (actually, it will send all lines spanned by the region, i.e no line will be only partially sent). To send the whole buffer, I use C-x h C-RET (but I very seldom use this since my main usage is to interpret scripts line by line or part by part)
Thanks @Francesco, the only thing I noticed is that isend does not cope well with code snippets that have code blocks with indentation in them. E.g. if I select code that has an if block or a for loop with some other unindented code, isend will not send the indentation the way IPython expects it. Wouldn't it be better to send the code selected to the shell by calling %paste in IPython? (i.e. you would have isend copy the code to the Emacs clipboard and then have it call %paste in the IPython buffer). This will allow isend to cope with arbitrarily complex code snipetts.
I think your problem was related to the fact that interactive IPython interpreters expect empty lines at the end of loops or other indented constructs. By default, isend ignores such lines, but I've uploaded a new version which can be told to send empty lines using (setq isend-skip-empty-lines nil).
Thanks Francesco. I tried the new version but problems persist. The reason is that indentation has meaning in Python (and IPython), so if I select code that comes, say, from inside a loop, IPython complains with unexpected indent because the code is indented. The only way to solve the problem with isend would be if you remove any extra indentation from the code block (but keeping the relative indentation between lines) before sending it to the buffer. I think this would be an elegant solution, and it should work with other shells as well (other shells are not picky about indentation).
|
3
(defun send-buffer-to-ipython ()
  "Send current buffer to the running ipython process."
  (interactive)
  (let* ((ipython-buffer "*ansi-term*") ; the buffer name of your running terminal
         (proc (get-buffer-process ipython-buffer)))
    (unless proc
      (error "no process found"))
    (save-buffer)
    (process-send-string proc
                         (format "execfile(\"%s\")\n" (buffer-file-name)))
    (pop-to-buffer ipython-buffer)      ; show ipython and select it
    ;; (display-buffer ipython-buffer)  ; show ipython but don't select it
    ))

Then bind command send-buffer-to-ipython to any key you like. I bind it to C-c C-c

(define-key python-mode-map [?\C-c ?\C-c] 'send-buffer-to-ipython)

1 Comment

When text is large, I think sending a command to load and execute current file is better. This is also the way how python.el implements it, except that in python.el python-send-region saves current buffer's content to a temp file and send the command to load the temp file.
2

with python-mode.el

M-x customize-variable RET py-shell-name RET ansi-term

M-x ansi-term RET ipython RET

C-c C-c from Python-buffer than executes in IPython shell

Caveat: a shebang precedes default py-shell-name

https://launchpad.net/python-mode/trunk/6.0.12/+download/python-mode.el-6.0.12.tar.gz

3 Comments

Thanks Andreas. What do you mean with Caveat: a shebang precedes default py-shell-name. Do you mean that if I have a shebang in the script from which I want to send my code, the shebang would take precedence over the value of my py-shell-name?
yes. AFAIS executing through ansi-term only works if no shebang is set - which is a bug.
Andreas, how would I set this up if I have multiple ansi_term buffers? Can I just rename the Emacs buffer running IPython to something else and pass this as an argument to py-shell-name? Or how should we cope with multiple ansi-terms?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.