Как я могу использовать свой локальный клиент Emacs в качестве $ EDITOR для удаленных машин, к которым я обращаюсь через TRAMP?


44

Я часто использую TRAMP для управления несколькими удаленными серверами, как для редактирования файлов, так и для запуска удаленных оболочек shell-mode. Однако это не работает, когда команда использует EDITORпеременную для редактирования файла, crontab -eособенно потому, что shell-modeэто «тупой» терминал, который не поддерживает запуск другого редактора внутри него.

Локально я делаю это с помощью соответствующего вызова, emacsclientкоторый открывает новый буфер и облегчает жизнь. К сожалению, это не работает с удаленной машины.

Я думаю, я мог бы использовать ed. (Ха!)

Как я могу настроить пульт EDITOR, который позволит мне редактировать файлы с моим локальным экземпляром Emacs?

Ответы:


23

[ПРИМЕЧАНИЕ] этот ответ был сильно отредактирован, чтобы следить за обновлениями with-editorсобытий. Большинство комментариев, скорее всего, больше не будут иметь смысла. Есть некоторые новые комментарии , которые делают смысл.


Magit содержит библиотеку с именем, with-editorдоступной по адресу https://github.com/magit/with-editor, которая позволяет вам использовать ваш локальный Emacs в качестве $ EDITOR на удаленных машинах через TRAMP.

Другой альтернативой является 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это (это также зависит от тире).

Затем просто начать shell, eshellили ansi-termи выполните следующие действия :

M-x with-editor-export-editor

Он спросит вас, какой $ EDITOR вас интересует, просто нажмите ввод для EDITORпеременной по умолчанию . Затем внутри оболочки вы можете напечатать crontab -eи отредактировать ваш crontab в emacs. Нажмите, 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библиотека относится к этому вопросу? Звучит полезно
Малабарба

@Silex: Нужно ли мне установить $EDITORпеременную на удаленном компьютере, чтобы это работало? Это просто зацепить emacsclient?
Тихон Джелвис

Но да, это выглядит именно то, что я хочу. Мне придется как-то попробовать - я предполагаю, что он может быть установлен сам, без остальной ветви?
Тихон Джелвис

1
@TikhonJelvi: он, конечно, будет устанавливаться сам по себе, но пока это только часть git-modes. Я внимательно слежу за этой библиотекой, и просто ее автор (@tarsius) занят выпуском magit, но в конечном итоге это будет собственный пакет. Что касается $ EDITOR, вам не нужно устанавливать его на что-либо самостоятельно, это делается при необходимости, когда вы запускаете любые команды, которые его используют. Magit использует эту библиотеку вместе с $ GIT_EDITOR.
Silex

1
Обратите внимание, что это перестанет работать после sshing на удаленный сервер из существующего shell-mode/ term-modeбуфера. Эту проблему можно решить с помощью дополнительной настройки, см. Emacs.stackexchange.com/questions/5589/… . Если вы все же заставите его работать, сообщите о своих результатах по адресу github.com/magit/magit/issues/1638 .
tarsius

1

Отказ от ответственности: я не пробовал это.

Вы могли бы пройти часть пути, выполнив вывод команды function для команды открыть файл с помощью TRAMP. Дыра в безопасности? Да. Функциональная? Вероятно.

Используйте shell-modeкрючок, чтобы добавить крюк after-change-hookв shell-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и +аргументы без изменений в emacsclient, в противном случае аргументы обрабатываются как файлы для открытия в вашем локальном Emacs. Каждый файл имеет префикс протокола TRAMP и хоста, поэтому Emacs знает, как его открыть. При ssh:желании вы можете перейти на другой протокол TRAMP.

Вы должны заменить zимя хоста вашей удаленной машины. Это используется локальными Emacs для подключения через TRAMP. (Вы можете использовать hostnameздесь для общности. Для краткости я предпочитаю использовать крошечные записи, например, zв моем локальном сообщении ssh_config, и пульт не имеет ни малейшего представления, что я это делаю. Попробуйте!)

Использование:

  • ec file в удаленной оболочке открывает файл в локальном Emacs и ждет
  • ec -n file в удаленной оболочке открывает файл в локальном 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
Вы имеете в виду ssh'ing обратно с удаленного сервера на клиент, где работает Emacs? Это часто невозможно.
Жиль "ТАК - перестань быть злым"

Ну, если вы не можете связаться с клиентом, на котором работает Emacs, вы ничего не сможете сделать.
Артаньон

2
Вы можете попросить ssh через ~ / .ssh / config всегда перенаправлять локального слушателя ssh на порт на удаленной машине. Возможно, вы также захотите переслать своего ssh-агента, хотя мнения о том, насколько это безопасно, различаются. Это позволит вам вернуться, выполнив команду EDITOR = "ssh $ user @ localhost: 1234 ..."
Бен Хайд,

Другой вариант, возможно, будет написать небольшую оболочку для вызова edit-server.el
stsquad

0

Гарольд Абнабит придумал такой подход 1 :

http://blog.habnab.it/blog/2013/06/25/emacsclient-and-tramp/

1 на основе более ранней статьи Райана Барретта (на которую он ссылается).

Также есть https://stackoverflow.com/q/5154224/324105, в котором Петри Лехтинен предложил https://gist.github.com/akheron/850795 . Я полагаю, что более сложные решения лучше, но очень простой подход все еще может представлять интерес.


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 tracking наверняка будет приветствоваться.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.