使用 swank/slime 在远程 Lisp 中加载本地文件

BnM*_*cGn 4 emacs common-lisp slime

假设我使用 swank/slime 连接到远程 Lisp。我的本地计算机上的磁盘上或者 emacs 缓冲区中可能有一个数据文件。我想使用远程 Lisp 处理这个文件。

显然,我可以退出 shell 并将文件 scp 到服务器,加载文件,处理它,关闭,删除文件,这样我就不会在服务器上弄乱。

我还可以将文件粘贴到 repl 中:

> (defparameter *my-file* "[paste file here]")
Run Code Online (Sandbox Code Playgroud)

但如果文本中有引号或者文件是二进制的,这就很糟糕了。

这两种选择都很麻烦。

有没有一种好的方法可以让本地 emacs 将文件通过隧道传输到远程 Lisp,以便远程 Lisp 可以将其作为流打开?

我正在想象这样的事情:

> (swank:with-open-client-file (s #p"/path/to/local/file") ... )
Run Code Online (Sandbox Code Playgroud)

编辑:这个例子感觉它可能会在我的本地文件系统中打开一些漏洞。可以在不造成严重安全问题的情况下完成吗?

cor*_*ump 5

设置的 Emacs 端可以启动一个 HTTP 服务器来限制发布哪些文件。看起来可以直接在 Emacs 中执行此操作(例如https://gist.github.com/TeMPOraL/f6f5333ae93de4ce9b5bd82cdad87d32)。

然后,远程部分可以使用drakma或获取流dexador

这不依赖于 Slime/swank。

或者,您可以调用eval-in-emacs执行 Emacs Lisp 表单,该表单将返回包含文件内容的字符串。您可以在 Emacs 中编写自定义函数来授予或不授予对文件的访问权限。

例如,不安全版本如下:

(defun get-file (filename)
  (with-temp-buffer
    (insert-file-contents filename)
      (buffer-string))))
Run Code Online (Sandbox Code Playgroud)

然后:

CL-USER> (swank:eval-in-emacs '(get-file "/etc/passwd"))
"......"
Run Code Online (Sandbox Code Playgroud)

以上需要配置 Slime 才能启用eval-in-emacs

一旦成功,您就可以编写一个辅助函数:

(defun call-with-open-client-file (function file)
  (with-input-from-string (stream (swank:eval-in-emacs `(get-file ,file)))
    (funcall function stream)))
Run Code Online (Sandbox Code Playgroud)

还有一个宏:

(defmacro with-open-client-file (var name &body body)
  `(call-with-open-client-file (lambda (,var) ,@body) ,name)
Run Code Online (Sandbox Code Playgroud)