关于远程文件编辑的方式选择

网上搜了下,发现大致提到两种方式:

1.emacs client 和 emacs server模式 2.emacs tramp mode

不知是否有人在服务器端进行emacs配置,然后通过ssh连接执行emacs -nw,这样做有什么坏处吗? 采用这种方法,目前发现的问题:复制本地机器上的内容,无法直接粘贴到服务端使用emacs打开的 文件中但可以直接复制到服务端使用vim打开的文件中。

1 个赞

这个问题也属于月经贴了,论坛里过往很多:https://emacs-china.org/search?q=emacs%20远程%20编辑

你说的 server/client 模式,其实是间接的 tramp。所以两种方案应该是:

  1. ssh 登录远程,运行远程电脑上的 emacs
  2. tramp 2.1 直接 tramp 打开远程文件 2.2 在本地启动 emacs-server,然后远程运行 emacs-client, 穿透回来

无意说哪一种方案更好,如果让我决定,我会考虑:

  • 如果编辑少量并且是小文件,例如配置文件,或者明确知道要修改什么,一锤子买卖这种,就直接 tramp。 至于远程 emacs-client,并没有实质不同,而且配置略麻烦一些。

  • 如果是一个完整的工程,长期编辑,必须在远程配置 emacs 了,因为 tramp 只会把你编辑过的文件传到本地,这些文件是孤立的,想要自动补全、静态分析…这些就很困难了。

速度方面:

  • tramp 比较慢,因为哪怕你该懂一个字符,也需要同步整个文件(所以大文件慎用 tramp),但是有个好处,你可以很方便拷贝整个 buffer 的内容,有些人比较需要这个;
  • 运行远程 emacs 速度无疑快很多,因为它只传输屏幕内容到你本地,相应的,要拷贝整个 buffer 就不容易了。
3 个赞

运行远程 emacs 速度无疑快很多,因为它只传输屏幕内容到你本地,相应的,要拷贝整个 buffer 就不容易了。

那在这种工作模式下,应该如何在远程emacs和本地主机之间进行数据拷贝。毕竟在本地上网copy代码到远程emacs的需求是大量存在的 - -

从本地贴代码到远程,直接 C-v 就可以了吧(至少 macOS 到 Linux 是可以的),也许不同的终端表现不一样。

想要完整的支持双向共享剪贴板,可以看看:

好的,多谢,看来是终端的问题。:sweat:

你用的什么终端,从本地到远程只要按输入(粘贴)的方法做就好了,一般是从远程到本地比较麻烦

gnome 诶,最近发现在gnome上跑emacs终端有好些问题。没办法复制本地到远程(鼠标中键粘贴),远程到本地也没解决。

先理一理你是怎么运行 emacs 的,我越看越乱了。

感觉你是 ssh 到服务器上, 然后服务器上直接开 emacs ? 这样肯定是 cli 的emacs,确认一下你的输入模式?原生emacs还是evil? 如果是evil有没有切换到 insert? ctrl+shift+v 可以粘贴嘛?我记得 gnome-terminal 应该是可以的。还不行换个 terminal 试试?

另外如果还是不行推荐把服务器上的emacs 版本和配置发一下。

我是ssh到服务器上,服务器上运行 emacs -nw,使用的是原生emacs(Steve Purcell的配置),终端是gnome-terminal。复制粘贴是通过鼠标选中,然后鼠标中键进行粘贴操作。

xterm下使用Ctrl+v可粘贴,但是会把emacs的快捷键Ctrl-v覆盖了。

那我推荐一下 guake :grin:

看了楼上这些说法,我怎么还是一头雾水,

直接 tramp, 穿透回来

以前都没有直接编辑远程文件的经验, 这些词让我不明觉厉. 可不可说说下面这个具体的例子,让我开开窍:

我的资源:

  1. 一台远程服务器. 公网IP是 47.47.47.47, 用户名root
  2. 本地电脑装好了Emacs (我用的spacemacs, 默认已经有 tramp了,但我从来没有配置过它).

现在我想通过本地电脑的 spacemacs 打开远程服务器上的 /root/flask_py3/app.py 文件. 我用(参考链接)
C-x C-f /ssh:[email protected]:/root/flask_py3/app.py RET
并没有成功!
Message Buffer 中可以看到错误信息:

Error running timer: (error “In ‘Find Files’ source: ‘helm-find-files-get-candidates’ (wrong-type-argument arrayp (tramp-file-name “ssh” “root” nil “47.47.47.47” nil “” nil))”)

难道我需要怎么配置一下吗? 但是我看 Tramp User Manual 似乎除了Selecting a default method,没有什么要配的呀! 而这句命令 /ssh:[email protected] method, user 都已经指明了,所以就不用配置什么了吧?

另外, 好几处都说到了ssh回本地,

这些都是说的一个意思吗? 我不太理解, 我登录远程时是用:

ssh 用户名@公网IP ssh端口

但是我本地电脑并没有公网IP,ssh怎么能回来呢?

关于穿透前面 2.2.2 已经说得很明白了,就是

  1. 本地运行 emacs-server,启动监听;
  2. ssh 登录到远程,运行 emacs-client,透过已经建立的 ssh 隧道反向穿透回来,本地无需公网 ip。

操作一遍就明白了,前提是本地/远程配置正确。

关于这种方式的优缺点前面也提到。

之所以没有成功应该是因为 helm 。

这个快捷键调用了 (spacemacs/helm-find-files ARG) (我用的是spacemacs)。 我怀疑这是一个Helm的Bug,当然,跟我的配置也有很大关系。于是我不用快捷键,直接使用 M-x find-file, 调用函数 (find-file FILENAME &optional WILDCARDS),这样就可以打开远程文件了。

不知道你 helm-find-file 的时候, /ssh:[email protected]:/root/flask_py3/app.py 这一串是怎么输入的。如果是一个字一个字输入,helm 会逐步展开当前路径,应该在候选窗口能看到 app.py 文件。

如果是输入太快/黏贴没等 helm 反应就回车,可能会出现问题。不过你这个出错信息倒是有点像你的 package 更新了但 byte-code 没有重新编译。

确保路径是对的,通过代码 (helm-find-files-1 "/ssh:your-vps:/root/your-file") 试试。

我是一个字一个字输入的。

另外,当我已经在编辑远程文件时, spc f j 同样出错,我不得不用 M-x find-file:

In ‘Find Files’ source: ‘helm-find-files-get-candidates’ (wrong-type-argument arrayp (tramp-file-name “ssh” “pi” nil “192.168.21.101” nil “” nil))

我这里 helm 是正常的。

错误信息看不太明白,array 应该不是传递给 helm-find-files-get-candidates 的,这函数只有一个布尔参数。

请发完整的 backtrace 。

还是老实用终端emacs吧

似乎没有少什么呀,我是从Message Buffer里看的信息:

先用 M-x find-file ssh 的方式连上 [email protected], 然后 Spc f f:

Tramp: Opening connection for [email protected] using ssh...
Tramp: Sending command ‘exec ssh -l pi  -o ControlMaster=auto -o ControlPath='tramp.%C' -o ControlPersist=no -e none 192.168.21.102’
Tramp: Waiting for prompts from remote shell...done
Tramp: Found remote shell prompt on ‘192.168.21.102’
Tramp: Opening connection for [email protected] using ssh...done
In ‘Find Files’ source: ‘helm-find-files-get-candidates’ 
 (wrong-type-argument arrayp (tramp-file-name "ssh" "pi" nil "192.168.21.102" nil "" nil))

其实我觉得现在就比终端好用。

我指要用 toggle-debug-mode-on,这样会给出更详细的错误信息。