Say that I am connected to a remote Lisp using swank/slime. I have a data file on my local machine on disk or, perhaps, in an emacs buffer. I want to process this file using the remote Lisp.
I can obviously drop out to a shell and scp the file to the server, load the file, process it, close, delete the file so that I don't make a mess on the server.
I can also paste the file into the repl:
> (defparameter *my-file* "[paste file here]")
But this is nasty if the text has quotes in it or the file is binary.
Both options are cumbersome.
Is there a nice way to get the local emacs to tunnel a file to the remote Lisp so that the remote Lisp can open it as a stream?
I'm picturing something like:
> (swank:with-open-client-file (s #p"/path/to/local/file") ... )
Edit: This example feels like it could open some holes in my local file system. Could it be done without causing serious security problems?
The Emacs-side of the setup could start an HTTP server that restricts which files are published. It looks like it is possible to do it in Emacs directly (e.g. https://gist.github.com/TeMPOraL/f6f5333ae93de4ce9b5bd82cdad87d32).
The remote part could then obtain streams with drakma
or dexador
.
This does not rely on Slime/swank.
Alternatively, you can call eval-in-emacs
to execute an Emacs Lisp form that would return a string containing the content of the file. You can write a custom function in Emacs to grant access or not to the files.
For example, an unsafe version is as follows:
(defun get-file (filename)
(with-temp-buffer
(insert-file-contents filename)
(buffer-string))))
Then:
CL-USER> (swank:eval-in-emacs '(get-file "/etc/passwd"))
"......"
The above requires Slime to be configured so that eval-in-emacs
is enabled.
Once this works, you can write a helper function:
(defun call-with-open-client-file (function file)
(with-input-from-string (stream (swank:eval-in-emacs `(get-file ,file)))
(funcall function stream)))
And a macro:
(defmacro with-open-client-file (var name &body body)
`(call-with-open-client-file (lambda (,var) ,@body) ,name)