Pregunta

I'm using a local emacs instance (aquamacs) to run R processes on a remote server, and I'd like to automate the process of connecting to my server. The process is as follows:

[in emacs]

M-x shell

[in the resulting console]

TERM=xterm
ssh -Y -C <my remote server>
screen -rd [and/or] R

[in emacs]

M-x ess-remote
r

I discovered this general approach here: http://blog.nguyenvq.com/2010/07/11/using-r-ess-remote-with-screen-in-emacs/. The -Y -C options allow you use xterm to view plots. I don't know lisp and tho I've googled around a bit, I can't seem to piece together how to actually define a function to automate this (e.g., in .emacs.el). Has anyone implemented anything like this?

¿Fue útil?

Solución

Let's assume you just want to call shell in code. In Lisp, everything is prefix notation surrounded by parentheses. So we enter this into a buffer (say, the scratch buffer):

(shell)

Move your pointer to the end of the line after the close-paren, and type <C-x C-e> to execute the Lisp code. You should see that the shell function is called.

Now, let's make it a function, so we can add other things to it. The command to create a function is defun, and it takes the name of the function, the argument list (in parentheses), and then the body of the function:

(defun automate-connection ()
  (shell))

Move your cursor to the end of the code, hit <C-x C-e>, and the function will be defined. You can call it from Lisp by executing

(automate-connection)

Ok, now we just need to put some text into the shell buffer.

(defun automate-connection ()
  (shell)
  (insert "TERM=xterm"))

Now, when we run that, we get "TERM=xterm" put into the shell buffer. But it doesn't actually send the command. Let's try putting a newline.

(defun automate-connection ()
  (shell)
  (insert "TERM=xterm\n"))

That puts in a newline, but doesn't actually make the command run. Why not? Let's see what the enter key does. Go to your *shell* buffer, and type <C-h c>, then hit the return key. (<C-h c> runs describe-key-briefly, which prints the name of the function invoked by hitting the given key). That says that when you hit RET, it's not putting a newline, but actually calling comint-send-input. So let's do that:

(defun automate-connection ()
  (shell)
  (insert "TERM=xterm")
  (comint-send-input))

Now, when you run `(automate-connection) from any Lisp code, you should get the given thing sent. I leave it as an exercise to the reader to add your other commands.

But wait! We're not really done, are we? I assume you don't want to have to move to a Lisp scratch buffer, type in (automate-connection), then evaluate that code. You probably just want to type , and call it a day. You can't do that by default with the function we just created. Luckily, it's simple to allow that: just add a call to (interactive) in your function:

(defun automate-connection ()
  (interactive)
  (shell)
  (insert "TERM=xterm")
  (comint-send-input))

Now you can call it as you want, and it'll open the *shell* buffer, put in the text, and tell Emacs to tell the shell to run that text.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top