Implement and document `server-eval-at'.
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Mon, 2 May 2011 02:06:53 +0000 (04:06 +0200)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Mon, 2 May 2011 02:06:53 +0000 (04:06 +0200)
doc/emacs/ChangeLog
doc/emacs/misc.texi
lisp/ChangeLog
lisp/server.el

index 92cd765..efe031d 100644 (file)
@@ -1,3 +1,7 @@
+2011-05-02  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * misc.texi (Emacs Server): Document `server-eval-at'.
+
 2011-04-24  Chong Yidong  <cyd@stupidchicken.com>
 
        * maintaining.texi (List Tags): Document next-file.  Suggested by
index 1299895..0626785 100644 (file)
@@ -1495,6 +1495,15 @@ server-name @key{RET} foo @key{RET}} sets the server name to
 @samp{foo}.  The @code{emacsclient} program can specify a server by
 name, using the @samp{-s} option (@pxref{emacsclient Options}).
 
+@findex server-eval-at
+  If you have defined a server by a unique server name, you can
+connect to this server from other Emacs instances and evaluate forms
+on it by using the @code{server-eval-at} function.
+
+@code{(server-eval-at "foo" '(+ 1 2))} gives the result @code{3}, if
+there's a server with that name that is listening.  If not, an error
+will be signaled.
+
 @menu
 * Invoking emacsclient:: Connecting to the Emacs server.
 * emacsclient Options::  Emacs client startup options.
index a111f30..f303f5d 100644 (file)
@@ -1,3 +1,7 @@
+2011-05-02  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * server.el (server-eval-at): New function.
+
 2011-05-01  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
        * net/network-stream.el (open-network-stream): Take a :nowait
index ce14f13..ab7dd40 100644 (file)
@@ -1484,6 +1484,41 @@ only these files will be asked to be saved."
   ;; continue standard unloading
   nil)
 
+(defun server-eval-at (server form)
+  "Eval FORM on Emacs Server SERVER."
+  (let ((auth-file (expand-file-name server server-auth-dir))
+       ;;(coding-system-for-read 'binary)
+       ;;(coding-system-for-write 'binary)
+       address port secret process)
+    (unless (file-exists-p auth-file)
+      (error "No such server definition: %s" auth-file))
+    (with-temp-buffer
+      (insert-file-contents auth-file)
+      (unless (looking-at "\\([0-9.]+\\):\\([0-9]+\\)")
+       (error "Invalid auth file"))
+      (setq address (match-string 1)
+           port (string-to-number (match-string 2)))
+      (forward-line 1)
+      (setq secret (buffer-substring (point) (line-end-position)))
+      (erase-buffer)
+      (unless (setq process (open-network-stream "eval-at" (current-buffer)
+                                                address port))
+       (error "Unable to contact the server"))
+      (set-process-query-on-exit-flag process nil)
+      (process-send-string
+       process
+       (concat "-auth " secret " -eval "
+              (replace-regexp-in-string
+               " " "&_" (format "%S" form))
+              "\n"))
+      (while (memq (process-status process) '(open run))
+       (accept-process-output process 0 10))
+      (goto-char (point-min))
+      ;; If the result is nil, there's nothing in the buffer.  If the
+      ;; result is non-nil, it's after "-print ".
+      (and (search-forward "\n-print" nil t)
+          (read (current-buffer))))))
+
 \f
 (provide 'server)