如何将我的本地Emacs客户端用作通过TRAMP访问的远程计算机的$ EDITOR?


44

我经常使用TRAMP来管理多个远程服务器,用于编辑文件和在中运行远程shell shell-mode。但是,这在命令使用EDITOR变量来编辑文件时不起作用,例如,crontab -e特别是因为shell-mode它是“哑”终端,不支持在其中运行其他编辑器。

在本地,我通过适当的调用来做到这一点emacsclient,打开了一个新的缓冲区并使生活变得非常轻松。不幸的是,这在远程计算机上不起作用。

我想我可以用ed。(哈!)

如何设置一个遥控器EDITOR,该遥控器可以让我使用本地Emacs实例编辑文件?

Answers:


23

[注意]对该答案进行了大量编辑,以跟踪最新with-editor动态。大多数评论可能不再有意义。有一些新的评论确实有意义。


Magit包含一个名为https://github.com/magit/with-editor的with-editor可用库,该库允许您通过TRAMP在远程计算机上将本地Emacs用作$ EDITOR。

另一个选择是https://github.com/habnabit/remote-emacsclient,但它看起来更复杂且通用性较低。

最简单的安装方法with-editor是通过MELPA:

M-x package-install with-editor

否则,只需将https://github.com/magit/with-editor/blob/master/with-editor.el抓到加载路径的某个位置即可require(它也取决于破折号)。

然后,只需启动shelleshellansi-term执行以下操作:

M-x with-editor-export-editor

它会询问您您对哪个$ EDITOR感兴趣,只需按Enter键即可获取默认EDITOR变量。然后,您可以在外壳程序crontab -e内在emacs中键入和编辑crontab。按下C-c C-c以保存crontab或C-c C-k取消编辑。

如果您想要更永久的设置:

(add-hook 'shell-mode-hook  'with-editor-export-editor)
(add-hook 'term-mode-hook   'with-editor-export-editor)
(add-hook 'eshell-mode-hook 'with-editor-export-editor)

或者,您可以使用M-x with-editor-async-shell-command crontab -e RET快速命令。


您能否详细说明该with-editor库与问题的关系?听起来很有用
马拉巴巴2014年

@Silex:我是否需要将$EDITOR变量设置为远程计算机上的某个变量才能起作用?它只是迷上了emacsclient吗?
迪洪·杰维斯

但是,是的,这正是我想要的。我将不得不尝试一下—我假设它可以自己安装,而无需分支的其余部分?
迪洪·杰维斯

1
@TikhonJelvi:它当然可以自行安装,但现在只是的一部分git-modes。我正在密切关注这个lib,只是它的作者(@tarsius)忙于发布magit,但最终它将成为一个独立的软件包。关于$ EDITOR,您不需要自己将其设置为任何值,当您运行任何使用它的命令时,便会在需要时完成设置。Magit将此库与$ GIT_EDITOR一起使用。
Silex 2014年

1
请注意,这将从现有的shell-mode/ term-mode缓冲区内切换到远程后将停止工作。这可以通过一些其他配置来解决,请参阅emacs.stackexchange.com/questions/5589/…。如果您确实可以使用它,请在github.com/magit/magit/issues/1638中报告您的发现。
tarsius

1

免责声明:我还没有尝试过。

通过使用功能监视命令输出来使用TRAMP打开文件的命令,您可以得到部分帮助。安全孔?是。有功能吗?大概。

使用shell-mode钩子将钩子添加到after-change-hookshell-mode。该挂钩监视特定的顺序。例:

;; RemoteTRAMP token: <authentication token maybe?>
;; RemoteTRAMP edit: /path/to/my/file

然后,它tramp-find-file用于打开文件。这是相对安全的,因为遥控器只能做的事情是触发tramp-find-file。首先进行确认会很好,但可以选择。

编辑完成后,另一个挂钩可以触发伪程序的退出(例如,通过发送C-c)。

为了安全起见,最坏的情况是他们找到了运行任意代码的方法。如果您将缓冲区变量设置为始终评估,那么恶意攻击者可能会在您不知情的情况下覆盖重要的设置。他们还可能通过打开许多缓冲区来发起拒绝服务攻击。确认可能会阻止上述所有情况。

遥控器上的程序可以用C(或任何其他语言)轻松实现。


1

https://stackoverflow.com/questions/2231902/originate-edit-of-remote-file-using-emacs-tramp-from-ssh-session有一个相当简单的可接受答案,相当于

(setq server-use-tcp t)
(setq server-host "name_of_local_machine")
(server-start)
;; Maybe also muck with `server-auth-dir`

然后使用

emacsclient -f ~/.emacs.d/server/server /`hostname`:/path/to/local/file

也有https://stackoverflow.com/questions/12546722/using-emacs-server-and-emacsclient-on-other-machines-as-other-users,它比较复杂,但答案也(大致)相似基地。


1

我的远程主机上的路径中有一个小脚本~/bin/ec,它是emacsclient的简写。

#!/bin/bash

params=()
for p in "$@"; do
  if [ "$p" == "-n" ]; then
    params+=( "$p" )
  elif [ "${p:0:1}" == "+" ]; then
    params+=( "$p" )
  else
    params+=( "/ssh:z:"$(readlink -f $p) )
  fi
done
emacsclient --server-file=$HOME/.emacs.d/server/server "${params[@]}"

该脚本将传递-n+args不变地传递给emacsclient,否则args被视为本地Emacs打开的文件。每个文件都以TRAMP协议和主机为前缀,因此Emacs知道如何打开它。ssh:如果愿意,您可以更改为其他TRAMP协议。

您必须替换z为远程计算机的主机名。本地Emacs使用它通过TRAMP连接。(您也许可以hostname在这里使用该标记符。为了简洁起见,我更喜欢z在本地使用一些微小的条目ssh_config,而遥控器不知道我正在这样做。尝试一下!)

用法:

  • ec file 在远程Shell中打开本地Emacs中的文件并等待
  • ec -n file 在远程Shell中打开本地Emacs中的文件并返回
  • export EDITOR=~/bin/ec在遥远的地方.bashrc使魔术发生

为了确保我的server文件是好的,我.emacs再次在本地使用小主机名将其保存在本地z

(setq server-use-tcp t
      server-port    9999)
(defun server-start-and-copy ()
  "Start server and copy server file to remote box."
  (interactive)
  (server-start)
  (copy-file "~/.emacs.d/server/server" "/z:.emacs.d/server/server" t)
  (chmod "/z:.emacs.d/server/server" (string-to-number "644" 8))
  )
(add-hook 'emacs-startup-hook 'server-start-and-copy)

端口9999是RemoteForward。我将其放在本地~/.ssh/ssh_config以自动化转发,并添加ControlMaster来提高速度。

Host z
HostName dev.example.com
User dev
ControlMaster auto
ControlPath ~/.ssh/z.sock
RemoteForward 9999 localhost:9999

最后,请确保TRAMP知道您ssh_config是否使用了它:

(require 'tramp)
(tramp-set-completion-function "ssh"
  '((tramp-parse-sconfig "~/.ssh/config")))

0

可能需要一些调整,但是这里是这个想法:

EDITOR="ssh artagnon@luneth \"emacsclient -n /`hostname`:$1\""

1
您是说要从远程服务器回退到运行Emacs的客户端吗?这通常是不可能的。
吉尔(Gilles)“所以,别再邪恶了”

好吧,如果您无法到达运行Emacs的客户端,则无法做任何事情。
artagnon 2014年

2
您可以通过它的〜/ .ssh / config要求ssh始终将本地ssh侦听器转发到远程计算机上的端口。您可能还希望转发ssh-agent,尽管对于安全性有不同的看法。这将使您可以通过执行EDITOR =“ ssh $ user @ localhost:1234 ...”回来
Ben Hyde

另一个选择可能是编写一个小的包装程序来调用edit-server.el
stsquad 2014年


0

真的很惊讶,没有人提到sshfs。这是我远程访问时通常要做的事情:

1) multi-term; sshfs user@host:/dir/i/want/ /mnt/point/on/my/machine
2) open whatever I want to edit in my local emacs
3) get-term; ssh user@host to launch executables etc

虽然multi-term不将本地工作目录与远程目录同步,但它击败了我长期尝试的所有其他解决方案。尽管dir跟踪肯定是受欢迎的功能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.