How can I automate these emacs ESS (ess-remote) commands?
elisp, emacs, ess, r
Solution
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.
Problem
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?