[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: How to pass messages between emacs and a Python program? (goal: tryi
From: |
Alexis Roda |
Subject: |
Re: How to pass messages between emacs and a Python program? (goal: trying to use emacs as a UI) |
Date: |
Fri, 26 Aug 2016 13:51:09 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 |
El 26/08/16 a les 00:18, Brian Merchant ha escrit:
I don't want the Python program to be constantly polling the file for
changes (using a `while` loop), and I probably don't want emacs to be
constantly polling the file for updates (which I know how to do using the
`auto-revert` command).
Hi,
not sure what you mean by "polling", for me it means:
while True:
if file_changed():
do_something()
sleep(some_time)
pynofify (https://github.com/seb-m/pyinotify/wiki) can help with that.
It's event driven, it monitors a set of files and reacts to changes on
them. Unfortunately, AFAIK, it's not portable, it only works on linux.
Anyway, depending on your use case, this may not be the right approach.
Maybe I press some key combination, and then that sends a message to a
Python script that its time to read the file and make updates and then the
Python script would message emacs and ask it to update what it is
displaying in its buffer.
Could this be done?
Yes, but you'll need to learn some emacs lisp.
The simplest solution I can think of that does not require a lot of
emacs lisp is pymacs (https://github.com/pinard/Pymacs). In short, it
starts a python interpreter in the background and exposes a set of
python functions to emacs so that you can use them as if they where
native emacs functions. From memory:
mymodule.py:
def do_something(path):
# do something on file 'path'
return changed # return True or False
emacs:
(require 'pymacs)
(pymacs-load "mymodule.py" "mm")
From now on you can call functions defined in mymodule.py prefixing
them with "mm-":
(mm-do-something "/path/to/buffer")
Pymacs will take care of "encoding" the function call, pass it to
python, get back the return value and "decode" it.
If required you can define a command that operates on the current buffer:
(defun do-something-on-current-buffer ()
"call do_something on current buffer"
(interactive)
;; TODO: check if buffer has changes not saved to disk and
;; prompt the user to save them.
(if (mm-do-something (buffer-file-name))
;; if content changed reload buffer contents
(revert-buffer t t)))
and bind it to a key:
(global-set-key (kbd "<f12>") 'do-something-on-current-buffer)
The pros are that you do all your coding in python and write a little
bit of elisp glue code, the cons are that it's seem unmaintained and I'm
not sure if it will work with python 3.
Packages like elpy or jedi start an RPC server. The idea is pretty much
the same as pymacs, take care of forwarding function calls to python and
getting back the result, but using a different communication
channel/protocol.
HTH