Come posso usare il mio client Emacs locale come $ EDITOR per macchine remote a cui accedo tramite TRAMP?


44

Uso spesso TRAMP per gestire diversi server remoti, sia per modificare file sia per eseguire shell remote shell-mode. Tuttavia, questo non funziona quando un comando utilizza la EDITORvariabile per modificare un file, ad esempio crontab -eperché shell-modeè un terminale "stupido" che non supporta l'esecuzione di un altro editor al suo interno.

A livello locale, lo faccio con una chiamata appropriata a emacsclientcui si apre un nuovo buffer e rende la vita molto facile. Sfortunatamente, questo non funziona dal computer remoto.

Immagino di poter usare ed. (Hah!)

Come posso configurare un telecomando EDITORche mi consenta di modificare i file con la mia istanza Emacs locale?

Risposte:


23

[NOTA] questa risposta è stata pesantemente modificata per seguire gli aggiornamenti degli with-editorsviluppi. La maggior parte dei commenti probabilmente non avrà più molto senso. Ci sono alcuni nuovi commenti che fanno senso.


Magit contiene una libreria chiamata with-editordisponibile su https://github.com/magit/with-editor che ti consente di utilizzare Emacs locale come $ EDITOR su macchine remote tramite TRAMP.

Un'altra alternativa è https://github.com/habnabit/remote-emacsclient , ma sembra più complicato e meno generico.

Il modo più semplice per l'installazione with-editorè tramite MELPA:

M-x package-install with-editor

Altrimenti, basta prendere https://github.com/magit/with-editor/blob/master/with-editor.el da qualche parte sul percorso di caricamento e requirequesto (dipende anche dal trattino).

Quindi, è sufficiente avviare shell, eshello ansi-terme procedere come segue:

M-x with-editor-export-editor

Ti chiederà a quale $ EDITOR sei interessato, premi Invio per la EDITORvariabile predefinita . Quindi all'interno della shell puoi digitare crontab -ee modificare il tuo crontab all'interno di emacs. Premere C-c C-cper salvare il crontab o C-c C-kper annullare la modifica.

Se vuoi una configurazione più permanente:

(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)

In alternativa, è possibile utilizzare M-x with-editor-async-shell-command crontab -e RETper comandi rapidi.


Potresti approfondire come questa with-editorbiblioteca si collega alla domanda? Sembra utile
Malabarba

@Silex: avrei bisogno di impostare la $EDITORvariabile su qualcosa sul computer remoto per farlo funzionare? Si aggancia e basta emacsclient?
Tikhon Jelvis,

Ma sì, sembra esattamente quello che voglio. Dovrò provarlo in qualche modo: suppongo che possa essere installato da solo, senza il resto del ramo?
Tikhon Jelvis,

1
@TikhonJelvi: certamente sarà essere installabile di per sé, ma per ora è solo una parte di git-modes. Sto seguendo da vicino questa lib ed è solo che il suo autore (@tarsius) è impegnato a rilasciare magit, ma alla fine sarebbe un pacchetto tutto suo. A proposito di $ EDITOR, non è necessario impostarlo su nulla da soli, viene eseguito quando necessario quando si esegue qualsiasi comando lo utilizza. Magit usa questa lib con $ GIT_EDITOR.
Silex,

1
Si noti che questo smetterà di funzionare dopo essere stato inviato a un telecomando dall'interno di un shell-mode/ term-modebuffer esistente . Questo può essere risolto con qualche configurazione aggiuntiva, vedi emacs.stackexchange.com/questions/5589/… . Se riesci a farlo funzionare, ti preghiamo di segnalare i tuoi risultati su github.com/magit/magit/issues/1638 .
Tarsius,

1

Disclaimer: non ho provato questo.

È possibile ottenere una parte del percorso facendo in modo che l'output di un comando watch watch per un comando apra il file usando TRAMP. Buca di sicurezza? Sì. Funzionale? Probabilmente.

Utilizzare un shell-modehook per aggiungere un hook a after-change-hookin shell-mode. Questo gancio cerca una sequenza specifica. Esempio:

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

Quindi utilizza tramp-find-fileper aprire il file. Questo è relativamente sicuro perché l'UNICA COSA che il telecomando può fare è innescare a tramp-find-file. Una conferma prima sarebbe buona ma facoltativa.

Al termine della modifica, un altro hook può attivare l'uscita del programma fittizio (ad es. Inviando C-c).

Il caso peggiore (per sicurezza) è che trovano un modo per eseguire codice arbitrario. Se hai variabili buffer impostate per valutare sempre, un utente malintenzionato potrebbe sovrascrivere impostazioni importanti a tua insaputa. Potrebbero anche lanciare un attacco denial of service causando l'apertura di molti buffer. Le conferme potrebbero probabilmente impedire tutto quanto sopra.

Il programma sul telecomando potrebbe essere banalmente implementato in C (o in qualsiasi altra lingua).


1

https://stackoverflow.com/questions/2231902/originate-edit-of-remote-file-using-emacs-tramp-from-ssh-session ha una risposta accettata abbastanza semplice che equivale a

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

e quindi usare

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

C'è anche https://stackoverflow.com/questions/12546722/using-emacs-server-and-emacsclient-on-other-machines-as-other-users che è più complesso ma in cui le risposte toccano (approssimativamente) anche simili basi.


1

Ho un piccolo script nel mio percorso sull'host remoto su ~/bin/ec, stenografia per 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[@]}"

Questo script passa -ne gli +argomenti sono invariati rispetto a emacsclient, altrimenti gli argomenti vengono trattati come file per l'apertura di Emacs locale. Ogni file è preceduto dal protocollo TRAMP e dall'host in modo che Emacs sappia come aprirlo. ssh:Se lo desideri, potresti essere in grado di passare a un protocollo TRAMP diverso.

È necessario sostituire zcon il nome host del computer remoto. Viene utilizzato da Emacs locale per connettersi tramite TRAMP. (Potresti essere in grado di utilizzare hostnamequi per generalità. Preferisco usare piccole voci come znel mio locale ssh_configper brevità, e il telecomando non ha idea che lo stia facendo. Provalo!)

Uso:

  • ec file nella shell remota apre il file in Emacs locale e attende
  • ec -n file nella shell remota apre il file in Emacs locale e ritorna
  • export EDITOR=~/bin/ecin remoto .bashrcfa accadere la magia

Per essere sicuro che il mio serverfile sia buono, lo ho nel mio locale .emacs, usando di nuovo il piccolo nome host 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)

La porta 9999 è RemoteForward. L'ho messo nel mio locale ~/.ssh/ssh_configper automatizzare l'inoltro, più le cose ControlMaster per la velocità.

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

Infine, assicurati che TRAMP sia a conoscenza del tuo ssh_configse lo usi:

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

0

Potrebbe richiedere un po 'di modifiche, ma ecco l'idea:

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

1
Vuoi dire che stai tornando dal server remoto al client su cui è in esecuzione Emacs? Questo spesso non è possibile.
Gilles 'SO- smetti di essere cattivo' il

Bene, se non riesci a raggiungere il client su cui è in esecuzione Emacs, è impossibile fare qualsiasi cosa.
artagnon,

2
Puoi chiedere a ssh, tramite ~ / .ssh / config di inoltrare sempre il listener ssh locale a una porta sul computer remoto. Probabilmente vorrai inoltrare anche il tuo agente ssh, anche se le opinioni variano su quanto sia sicuro. Questo ti permetterà di tornare indietro facendo EDITOR = "ssh $ user @ localhost: 1234 ..."
Ben Hyde

Un'altra opzione potrebbe essere quella di scrivere un piccolo wrapper per chiamare edit-server.el
stsquad


0

Davvero sorpreso, nessuno ha sshfsancora parlato . Questo è ciò che faccio di solito quando vado a distanza:

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

Anche multi-termse non sincronizza la directory di lavoro locale con la directory remota, batte tutte le altre soluzioni che ho provato a lungo. Anche se il tracciamento di dir sarebbe sicuramente una funzionalità benvenuta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.