diff lisp/packages/gnuserv.el @ 193:f53b5ca2e663 r20-3b23

Import from CVS: tag r20-3b23
author cvs
date Mon, 13 Aug 2007 09:58:30 +0200
parents e121b013d1f0
children a2f645c6b9f8
line wrap: on
line diff
--- a/lisp/packages/gnuserv.el	Mon Aug 13 09:57:40 2007 +0200
+++ b/lisp/packages/gnuserv.el	Mon Aug 13 09:58:30 2007 +0200
@@ -1,9 +1,9 @@
 ;;; gnuserv.el --- Lisp interface code between Emacs and gnuserv
 ;; Copyright (C) 1989-1997 Free Software Foundation, Inc.
 
-;; Version: 3.9
+;; Version: 3.10
 ;; Author: Andy Norman (ange@hplb.hpl.hp.com), originally based on server.el
-;;         Hrvoje Niksic <hniksic@srce.hr>
+;;         Hrvoje Niksic <hniksic@srce.hr>, rewritten from scratch in May 1997
 ;; Maintainer: Jan Vroonhof <vroonhof@math.ethz.ch>,
 ;;             Hrvoje Niksic <hniksic@srce.hr>
 ;; Keywords: environment, processes, terminals
@@ -63,12 +63,6 @@
 ;; Mukherjee, Ben Wing and Jan Vroonhof.  It was completely rewritten
 ;; (labeled as version 3) by Hrvoje Niksic in May 1997.
 
-;; Jan Vroonhof <vroonhof@math.ethz.ch> July/1996
-;; ported the server-temp-file-regexp feature from server.el
-;; ported server hooks from server.el
-;; ported kill-*-query functions from server.el (and made it optional)
-;; synced other behaviour with server.el
-;;
 ;; Jan Vroonhof
 ;;     Customized.
 ;;
@@ -78,6 +72,9 @@
 ;;
 ;; Mike Scheidler <c23mts@eng.delcoelect.com> July, 1997
 ;;     Added 'Done' button to the menubar.
+;;
+;; Hrvoje Niksic <hniksic@srce.hr> Sep/1997
+;;     More pervasive changes.
 
 
 ;;; Code:
@@ -92,7 +89,8 @@
 ;; Provide the old variables as aliases, to avoid breaking .emacs
 ;; files.  However, they are obsolete and should be converted to the
 ;; new forms.  This ugly crock must be before the variable
-;; declaration, or the scheme fails.
+;; declaration, or the scheme fails.  I'd prefer if we could junk this
+;; sh*t, but I guess the users will appreciate compatibility.  Uh...
 
 (define-obsolete-variable-alias 'server-frame 'gnuserv-frame)
 (define-obsolete-variable-alias 'server-done-function
@@ -109,29 +107,50 @@
   'gnuserv-done-hook)
 (define-obsolete-variable-alias 'server-kill-quietly
   'gnuserv-kill-quietly)
-(define-obsolete-variable-alias 'server-temp-file-regexp
-  'gnuserv-temp-file-regexp)
-(define-obsolete-variable-alias 'server-make-temp-file-backup
-  'gnuserv-make-temp-file-backup)
 
 ;;;###autoload
-(defcustom gnuserv-frame nil
-  "*The frame to be used to display all edited files.
-If nil, then a new frame is created for each file edited.
-If t, then the currently selected frame will be used.
-If a function, then this will be called with a symbol `x' or `tty' as the
-only argument, and its return value will be interpreted as above."
+(defcustom gnuserv-frame 'new
+  "*Determines what frame will be used to display all edited files.
+Legal values are:
+ `new'     -- a new frame will be created for each file edited;
+ `current' -- the currently selected frame will be used;
+ `main'    -- \"main\" Emacs frame will be used;
+ `visible' -- a visible frame will be used, or a new one created;
+ `special' -- a special Gnuserv frame will be created, and used for
+              all gnuserv-edited files;
+ frame     -- that particular frame will be used.
+
+If gnuclient is called using the `-nw' method (from a TTY device), the
+ behaviour will be as if gnuserv-frame were `new'.
+This variable is read by `gnuserv-frame-default-function'.  If you
+ change `gnuserv-frame-function' to anything else, this variable will
+ have no effect."
   :tag "Gnuserv Frame"
-  :type '(radio (const :tag "Create new frame each time" nil)
-		(const :tag "Use selected frame" t)
-	        (function-item :tag "Use main Emacs frame"
-			       gnuserv-main-frame-function)
-		(function-item :tag "Use visible frame, otherwise create new"
-			       gnuserv-visible-frame-function)
-		(function-item :tag "Create special Gnuserv frame and use it"
-			       gnuserv-special-frame-function)
-		(function :tag "Other"))
-   :group 'gnuserv)
+  ;; Compatibility
+  :type '(radio (const :tag "Create new frame each time" new)
+		(const :tag "Use currently selected frame" current)
+		(const :tag "Use main Emacs frame" main)
+		(const :tag "Use visible frame, otherwise create new" visible)
+		(const :tag "Create special Gnuserv frame and use it" special))
+  :group 'gnuserv)
+
+(defcustom gnuserv-frame-properties nil
+  "*Properties of the frame in which gnuclient buffers are displayed.
+Note that this is in effect only for frames created by
+`gnuserv-frame-default-function'."
+  :type '(repeat (group :inline t
+			(symbol :tag "Property")
+			(sexp :tag "Value")))
+  :group 'gnuserv)
+
+(defcustom gnuserv-frame-function 'gnuserv-frame-default-function
+  "*Function to return the appropriate frame for use by gnuclient.
+The function will be called with two arguments: the first one as
+ described by `gnuserv-frame', and the second one as the device to
+ create the frame on.
+The function must return a valid frame object."
+  :type 'function
+  :group 'gnuserv)
 
 (defcustom gnuserv-done-function 'kill-buffer 
   "*Function used to remove a buffer after editing.
@@ -142,15 +161,6 @@
 		(function :tag "Other"))
   :group 'gnuserv)
 
-(defcustom gnuserv-done-temp-file-function 'kill-buffer
-  "*Function used to remove a temporary buffer after editing.
-It is called with one BUFFER argument.  Functions such as `kill-buffer' and
-`bury-buffer' are good values. See also `gnuserv-done-temp-file-function'."
-  :type '(radio (function-item kill-buffer)
-		(function-item bury-buffer)
-		(function :tag "Other"))
-  :group 'gnuserv)
-
 (defcustom gnuserv-find-file-function 'find-file
   "*Function to visit a file with.
 It takes one argument, a file name to visit."
@@ -197,17 +207,6 @@
   :type 'boolean
   :group 'gnuserv)
 
-(defcustom gnuserv-temp-file-regexp "^/tmp/Re\\|/draft$"
-  "*Regexp which should match filenames of temporary files deleted
-and reused by the programs that invoke the Emacs server."
-  :type 'regexp
-  :group 'gnuserv)
-
-(defcustom gnuserv-make-temp-file-backup nil
-  "*Non-nil makes the server backup temporary files also."
-  :type 'boolean
-  :group 'gnuserv)
-
 
 ;;; Internal variables:
 
@@ -230,7 +229,7 @@
   (device nil)
   (frame nil))
 
-(defvar gnuserv-process nil 
+(defvar gnuserv-process nil
   "The current gnuserv process.")
 
 (defvar gnuserv-string ""
@@ -246,43 +245,53 @@
 (defvar gnuserv-devices nil
   "List of devices created by clients.")
 
+;; We want the client-infested buffers to have some modeline
+;; identification, so we'll make a "minor mode".  We don't use
+;; `add-minor-mode', as we don't want it to be togglable.
+(defvar gnuserv-minor-mode nil)
+
+(make-variable-buffer-local 'gnuserv-mode)
+(pushnew '(gnuserv-minor-mode " Server") minor-mode-alist :test 'equal)
+
 (defvar gnuserv-special-frame nil
   "Frame created specially for Server.")
 
-;; We want the client-infested buffers to have some modeline
-;; identification, so we'll make a "minor mode".
-(defvar gnuserv-minor-mode nil)
-(make-variable-buffer-local 'gnuserv-mode)
-(pushnew '(gnuserv-minor-mode " Server") minor-mode-alist
-	  :test 'equal)
-
 
-;; Sample gnuserv-frame functions
-
-(defun gnuserv-main-frame-function (type)
-  "Returns a sensible value for the main Emacs frame."
-  (if (eq type 'x)
-      (car (frame-list))
-    nil))
+;; Creating gnuserv frame.
 
-(defun gnuserv-visible-frame-function (type)
-  "Returns a frame if there is a frame that is truly visible, nil otherwise.
-This is meant in the X sense, so it will not return frames that are on another
-visual screen.  Totally visible frames are preferred.  If none found, return nil."
-  (if (eq type 'x)
-      (cond ((car (filtered-frame-list 'frame-totally-visible-p
-				       (selected-device))))
-	    ((car (filtered-frame-list (lambda (frame)
-					 ;; eq t as in not 'hidden
-					 (eq t (frame-visible-p frame)))
-				       (selected-device)))))
-    nil))
-
-(defun gnuserv-special-frame-function (type)
-  "Creates a special frame for Gnuserv and returns it on later invocations."
-  (unless (frame-live-p gnuserv-special-frame)
-    (setq gnuserv-special-frame (make-frame)))
-  gnuserv-special-frame)
+(defun gnuserv-frame-default-function (arg device)
+  "Default function to create Gnuserv frames.
+See the documentation of `gnuserv-frame' for instructions how to
+customize it."
+  ;; If we are on TTY, act as if `new' was given.
+  (if (not (device-on-window-system-p))
+      (gnuserv-frame-default-function 'new device)
+    (cond
+      ((or (eq arg 'new)
+	   ;; nil for back-compat
+	   (eq arg nil))
+       (make-frame gnuserv-frame-properties device))
+      ((or (eq arg 'current)
+	   ;; t for back-compat
+	   (eq arg t))
+       (selected-frame))
+      ((eq arg 'main)
+       (car (frame-list)))
+      ((eq arg 'visible)
+       (cond ((car (filtered-frame-list 'frame-totally-visible-p device)))
+	     ((car (filtered-frame-list (lambda (frame)
+					  ;; eq t as in not 'hidden
+					  (eq (frame-visible-p frame) t))
+					device)))
+	     (t (make-frame gnuserv-frame-properties device))))
+      ((eq arg 'special)
+       (unless (frame-live-p gnuserv-special-frame)
+	 (setq gnuserv-special-frame
+	       (make-frame gnuserv-frame-properties device))))
+      ((frame-live-p arg)
+       arg)
+      (t
+       (error "Invalid argument %s" arg)))))
 
 
 ;;; Communication functions
@@ -402,29 +411,17 @@
 	      (t     (error "Invalid flag %s" flag))))
 	  flags)
     (let* ((old-device-num (length (device-list)))
-	   (new-frame nil)
-	   (dest-frame (if (functionp gnuserv-frame)
-			   (funcall gnuserv-frame (car type))
-			 gnuserv-frame))
-	   ;; The gnuserv-frame dependencies are ugly.
-	   (device (cond ((frame-live-p dest-frame)
-			  (frame-device dest-frame))
-			 ((null dest-frame)
-			  (case (car type)
+	   (old-frame-num  (length (frame-list)))
+	   (device (case (car type)
 			    (tty (apply 'make-tty-device (cdr type)))
 			    (x   (make-x-device (cadr type)))
 			    (t   (error "Invalid device type"))))
-			 (t
-			  (selected-device))))
-	   (frame (cond ((frame-live-p dest-frame)
-			 dest-frame)
-			((null dest-frame)
-			 (setq new-frame (make-frame nil device))
-			 new-frame)
-			(t (selected-frame))))
+	   (frame (funcall gnuserv-frame-function gnuserv-frame device))
 	   (client (make-gnuclient :id gnuserv-current-client
 				   :device device
-				   :frame new-frame)))
+				   :frame (if (= (length (frame-list))
+						 old-frame-num)
+					      nil frame))))
       (setq gnuserv-current-client nil)
       ;; If the device was created by this client, push it to the list.
       (and (/= old-device-num (length (device-list)))
@@ -435,6 +432,7 @@
       (while list
 	(let ((line (caar list)) (path (cdar list)))
 	  (select-frame frame)
+	  (raise-frame frame)
 	  ;; Visit the file.
 	  (funcall (if view
 		       gnuserv-view-file-function
@@ -446,10 +444,9 @@
 	    (pushnew (current-buffer) (gnuclient-buffers client))
 	    (setq gnuserv-minor-mode t)
 	    ;; Add the "Done" button to the menubar, only in this buffer.
-	    (if (boundp 'current-menubar)
-	      (progn (set-buffer-menubar current-menubar)
-	      (add-menu-button nil ["Done" gnuserv-edit t]))
-	      ))
+	    (when (boundp 'current-menubar)
+	      (set-buffer-menubar current-menubar)
+	      (add-menu-button nil ["Done" gnuserv-edit t])))
 	  (run-hooks 'gnuserv-visit-hook)
 	  (pop list)))
       (cond
@@ -463,19 +460,19 @@
        (t
 	;; Else, the client gets a vote.
 	(push client gnuserv-clients)
-	;; Explain buffer exit options.  If dest-frame is nil, the
-	;; user can exit via `delete-frame'.  OTOH, if FLAGS are nil
-	;; and there are some buffers, the user can exit via
+	;; Explain buffer exit options.  If client-frame is non-nil,
+	;; the user can exit via `delete-frame'.  OTOH, if FLAGS are
+	;; nil and there are some buffers, the user can exit via
 	;; `gnuserv-edit'.
 	(if (and (not (or quick view))
 		 (gnuclient-buffers client))
 	    (message "%s"
 		     (substitute-command-keys
 		      "Type `\\[gnuserv-edit]' to finish editing"))
-	  (or dest-frame
-	      (message "%s"
-		       (substitute-command-keys
-			"Type `\\[delete-frame]' to finish editing")))))))))
+	  (and (gnuclient-frame client)
+	       (message "%s"
+			(substitute-command-keys
+			 "Type `\\[delete-frame]' to finish editing")))))))))
 
 
 ;;; Functions that hook into Emacs in various way to enable operation
@@ -489,10 +486,9 @@
 (defun gnuserv-buffer-clients (buffer)
   "Returns a list of clients to which BUFFER belongs."
   (let (res)
-    (dolist (client gnuserv-clients)
+    (dolist (client gnuserv-clients res)
       (when (memq buffer (gnuclient-buffers client))
-	(push client res)))
-    res))
+	(push client res)))))
 
 ;; Like `gnuserv-buffer-clients', but returns a boolean; doesn't
 ;; collect a list.
@@ -553,16 +549,6 @@
 
 (add-hook 'delete-device-hook 'gnuserv-check-device)
 
-(defun gnuserv-temp-file-p (buffer)
-  "Return non-nil if BUFFER contains a file considered temporary.
-These are files whose names suggest they are repeatedly
-reused to pass information to another program.
-
-The variable `gnuserv-temp-file-regexp' controls which filenames
-are considered temporary."
-  (and (buffer-file-name buffer)
-       (string-match gnuserv-temp-file-regexp (buffer-file-name buffer))))
-
 (defun gnuserv-kill-client (client &optional leave-frame)
   "Kill the gnuclient CLIENT.
 This will do away with all the associated buffers.  If LEAVE-FRAME,
@@ -608,10 +594,7 @@
     ;; Delete the menu button.
     (if (boundp 'current-menubar)
       (delete-menu-item '("Done")))
-    (funcall (if (gnuserv-temp-file-p buffer)
-		 gnuserv-done-temp-file-function
-	       gnuserv-done-function)
-	     buffer)))
+    (funcall gnuserv-done-function buffer)))
 
 
 ;;; Higher-level functions
@@ -650,15 +633,9 @@
   (unless (gnuserv-buffer-p buffer)
     (error "%s does not belong to a gnuserv client" buffer))
   ;; Backup/ask query.
-  (if (gnuserv-temp-file-p buffer)
-      ;; For a temp file, save, and do NOT make a non-numeric backup
-      ;; Why does server.el explicitly back up temporary files?
-      (let ((version-control nil)
-	    (buffer-backed-up (not gnuserv-make-temp-file-backup)))
-	(save-buffer))
-    (if (and (buffer-modified-p)
-	     (y-or-n-p (concat "Save file " buffer-file-name "? ")))
-	(save-buffer buffer)))
+  (if (and (buffer-modified-p)
+	   (y-or-n-p (concat "Save file " buffer-file-name "? ")))
+      (save-buffer buffer))
   (gnuserv-buffer-done-1 buffer))
 
 ;; Called by `gnuserv-start-1' to clean everything.  Hooked into
@@ -715,10 +692,9 @@
 ;;;###autoload
 (defun gnuserv-start (&optional leave-dead)
   "Allow this Emacs process to be a server for client processes.
-This starts a gnuserv communications subprocess through which
-client \"editors\" (gnuclient and gnudoit) can send editing commands to 
-this Emacs job.  See the gnuserv(1) manual page for more details.
-
+ This starts a gnuserv communications subprocess through which
+ client \"editors\" (gnuclient and gnudoit) can send editing commands to 
+ this Emacs job.  See the gnuserv(1) manual page for more details.
 Prefix arg means just kill any existing server communications subprocess."
   (interactive "P")
   (and gnuserv-process
@@ -727,21 +703,14 @@
   (gnuserv-start-1 leave-dead))
 
 (defun gnuserv-edit (&optional count)
-  "Mark the current gnuserv editing buffer as \"done\", and switch to next one.
-
+  "Mark the current gnuserv buffer as \"done\", and switch to next one.
 Run with a numeric prefix argument, repeat the operation that number
-of times.  If given a universal prefix argument, close all the buffers
-of this buffer's clients.
-
-The `gnuserv-done-function' (bound to `kill-buffer' by default) is
-called to dispose of the buffer after marking it as done.
-
-Files that match `gnuserv-temp-file-regexp' are considered temporary and
-are saved unconditionally and backed up if `gnuserv-make-temp-file-backup'
-is non-nil.  They are disposed of using `gnuserv-done-temp-file-function'
-(also bound to `kill-buffer' by default).
-
-When all of a client's buffers are marked as \"done\", the client is notified."
+ of times.  If given a universal prefix argument, close all the buffers
+ of this buffer's clients.
+The `gnuserv-done-function' (`kill-buffer' by default) is called to
+ dispose of the buffer after marking it as done.
+When all of a client's buffers are marked as \"done\", the client is
+ notified."
   (interactive "P")
   (when (null count)
     (setq count 1))