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
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:
Open an
ansi-termbuffer:M-x
ansi-termRET/usr/bin/ipythonRETOpen the buffer with the code you want to execute, and associate it to the interpreter buffer:
M-x
isend-associateRET*ansi-term*RETHit C-RET in the python buffer to send the current line to the interpreter in the
ansi-termbuffer.
8 Comments
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)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.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).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).(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
python-send-region saves current buffer's content to a temp file and send the command to load the temp file.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
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?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?