在远程主机上评估emacs python-mode中的缓冲区

时间:2010-12-16 21:39:03

标签: python emacs

我正在使用emacs23和tramp来修改远程主机上的python脚本。 我发现当我在emacs中启动python shell时它会启动 远程主机上的python。

我的问题是当我尝试通过C-c C-c调用python-send-buffer时会出现错误

  

追踪(最近一次通话):     文件“”,第1行,在?   ImportError:没有名为emacs的模块

     

追踪(最近一次通话):     文件“”,第1行,在?   NameError:名称'emacs'未定义

现在,我必须承认,我真的不知道这里发生了什么。有没有办法让我配置emacs,以便我可以评估远程主机上的缓冲区?

非常感谢。

编辑:我遵循了eichin的建议并重新实现了python-send-region。请参阅下面的答案。

2 个答案:

答案 0 :(得分:3)

我目前正试图将此未注册的问题与此帐户合并,之后我将能够接受eichin的回答并编辑我的帖子以包含我的解决方案。

我遵循了eichin的建议,将emacs2.py emacs3.py和emacs.py文件复制到远程主机,并将其目录添加到tramp-remote-process-environment变量中的PYTHONPATH。

然后我在.emacs

中重新实现了python-send-buffer函数
(require 'python)

(defun python-send-region (start end)
  "Send the region to the inferior Python process."

  (interactive "r")

  (let* ((loc_name)
     (f (if (file-remote-p default-directory)
        (let* ((con (tramp-dissect-file-name default-directory)))
          (setq loc_name (tramp-make-tramp-temp-file con))
          (concat "/"
              (tramp-file-name-method con) ":"
              (tramp-file-name-user con) "@"
              (tramp-file-name-host con) ":"
              loc_name
              ))
          (setq loc_name (make-temp-file "py"))))
     (command (format "emacs.eexecfile(%S)" loc_name))
     (orig-start (copy-marker start)))
    (save-excursion
      (let ((curbuf (current-buffer))
        (tempbuf (get-buffer-create "*python_temp*")))
    (set-buffer tempbuf)
    (delete-region (point-min) (point-max))
    (insert-buffer-substring curbuf start end)
    (python-mode)
    (when (save-excursion 
        (goto-char (point-min))
        (/= 0 (current-indentation)))
      (python-shift-left (point-min) (point-max)))
    (write-region nil nil f nil 'nomsg))

    (python-send-command command)
    (with-current-buffer (process-buffer (python-proc))
      ;; Tell compile.el to redirect error locations in file `f' to
      ;; positions past marker `orig-start'.  It has to be done *after*
      ;; `python-send-command''s call to `compilation-forget-errors'.
      (compilation-fake-loc orig-start f)))
))

我基本上将区域复制到新缓冲区,调整缩进然后将其写入临时文件,使用tramp-make-tramp-temp-file或make-temp-file创建,具体取决于访问文件是否为远程或本地。

我遇到了tramp-handle-write-region的一些问题,它似乎不接受字符串作为第一个参数,这就是为什么我首先在​​单独的缓冲区中完成所有格式化的原因。

如果代码仍有任何问题,请告诉我,但这是我第一次尝试elisp编码,所以请保持温和。

答案 1 :(得分:2)

简短的回答:不是没有写一些丢失的elisp代码。

长版:在python.el中,run-pythondata-directory(我的Ubuntu 10.10框中为/usr/share/emacs/23.1/etc/)添加到$PYTHONPATH,具体说明它可以找到emacs.py(由本地emacs发行版提供。)然后它执行(python-send-string "import emacs")并希望它能够正常工作......

看起来defadvice使用的tramp包装器实际上没有通过PYTHONPATH,所以即使您在远程系统上有匹配的emacs版本,这也不起作用。

如果你M-x customize-variable RET tramp-remote-process-environment RET 然后点击其中一个INS按钮并添加PYTHONPATH=/usr/share/emacs/23.1/etc然后点击STATE并将其设置为“当前会话”(仅用于测试它,或者“保存以备将来会话”,如果它适用于你的几乎工作 - 在任何情况下,投诉都会消失,因为远程python现在可以找到远程emacs.py。如果您现在回到原始问题,执行python-send-buffer,您只会遇到另一个错误:No such file or directory: '/tmp/py24574XdA'因为python-mode只是将内容填充到临时文件中并告诉python子进程加载。

您必须更改python-send-region(其他函数调用它),特别是它使用make-temp-file进行tramp-aware的方式 - 甚至可以构建tramp-make-tramp-temp-file根据。 (如果你这样做,请务必发布...)