Send emacs buffer to arbitrary Python process

1.3k views Asked by At

I like the python-send-buffer command, however I very often use Python embedded in applications, or launch Python via a custom package management system (to launch Python with certain dependencies).. In other words, I can't just run "python" and get a useful Python instance (something that python-send-buffer relies on)

What I would like to achieve is:

  • in any Python interpreter (or application that allows you to evaluate Python code), import a magic_emacs_python_server.py module (appending to sys.path as necessary)
  • In emacs, run magic-emacs-python-send-buffer

This would evaluate the buffer in the remote Python instance.

Seems like it should be pretty simple - the Python module listens on a socket, in a thread. It evaluates in the main thread, and returns the repr() of the result (or maybe captures the stdout/stderr, or maybe both). The emacs module would just send text to the socket, waits for a string in response, and displays it in a buffer.

Sounds so simple something like this must exist already... IPython has ipy_vimserver, but this is the wrong way around. There is also swank, while it seems very Lisp-specific, there is a Javascript backend which looks very like what I want... but searching finds almost nothing, other than some vague (possibly true) claims that SLIME doesn't work nicely with non-Lisp languages

In short:

  • Does a project exist to send code from an emacs buffer to an existing Python process?
  • If not, how would you recommend I write such a thing (not being very familiar with elisp) - SWANK? IPython's server code? Simple TCP server from scratch?
2

There are 2 answers

0
dbr On BEST ANSWER

comint provides most of the infrastructure for stuff like this. There's a bunch of good examples, like this or this

It allows you to run a command, provides things comint-send-string to easily implement send-region type commands.

dbr/remoterepl on Github is a crude proof-of-concept of what I described in the question.

It lacks any kind of polish, but it mostly works - you import the replify.py module in the target interpreter, then evaluate the emacs-remote-repl.el after fixing the stupid hardcoded path to client.py

1
Matt Harrison On

Doesn't shell-command give you what you are looking for? You could write a wrapper script or adjust the #! and sys.path appropriately.