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