From xemacs-m  Fri Sep 19 20:33:04 1997
Received: from jagor.srce.hr (hniksic@jagor.srce.hr [161.53.2.130])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id UAA17938
	for <xemacs-beta@xemacs.org>; Fri, 19 Sep 1997 20:32:59 -0500 (CDT)
Received: (from hniksic@localhost)
	by jagor.srce.hr (8.8.7/8.8.6) id DAA25180;
	Sat, 20 Sep 1997 03:32:57 +0200 (MET DST)
To: XEmacs Developers <xemacs-beta@xemacs.org>
Subject: [PATCH] Various
X-Attribution: Hrvoje
X-Face: Mie8:rOV<\c/~z{s.X4A{!?vY7{drJ([U]0O=W/<W*SMo/Mv:58:*_y~ki>xDi&N7XG
        KV^$k0m3Oe/)'e%3=$PCR&3ITUXH,cK>]bci&<qQ>Ff%x_>1`T(+M2Gg/fgndU%k*ft
        [(7._6e0n-V%|%'[c|q:;}td$#INd+;?!-V=c8Pqf}3J
From: Hrvoje Niksic <hniksic@srce.hr>
Date: 20 Sep 1997 03:32:55 +0200
Message-ID: <kigzpp8bwhk.fsf@jagor.srce.hr>
Lines: 491
X-Mailer: Quassia Gnus v0.5/XEmacs 20.3(beta22) - "Minsk"

I've done some 20.1 synching, including an implementation of
`scroll-conservatively'.  I'll try to look at implementing
`scroll-margin', but it looks hard.  `scroll-preserve-screen-position' 
is probably even harder.

Note that scroll-step + scroll-conservatively will look horribly on
TTYs because of our deficiency in that area.  Also, it won't be the
roses in X either, because this is one of the rare (X) cases that
scrolling *is* faster than redrawing everything.


The `C-x m' command now invokes `compose-mail', which is very useful.
In the same vein, `define-mail-user-agent' is now in simple.el, not in 
reporter.el.  However, compose-mail currently works only with builtin
mail, and (probably) with message.  It should be adapted to work
with VM and mh-e.

Lisp ChangeLog:

1997-09-20  Hrvoje Niksic  <hniksic@srce.hr>

	* modes/sendmail.el: Don't define keys to mail etc.

	* prim/keydefs.el: Add bindings to `compose-mail'.

	* prim/simple.el: Synch mail stuff with Emacs 20.

	* utils/reporter.el: Removed mail-user-agent stuff.

	* x11/x-menubar.el (default-menubar): Use new semantics for
 	`gnuserv-frame'.

	* prim/obsolete.el (string-to-sequence): Wouldn't work with TYPE
 	`vector'.


C ChangeLog:

1997-09-20  Hrvoje Niksic  <hniksic@srce.hr>

	* redisplay.c (scroll_conservatively): New variable.
	(redisplay_window): Use it.

--- etc/NEWS.orig	Sat Sep 20 02:32:04 1997
+++ etc/NEWS	Sat Sep 20 03:13:20 1997
@@ -185,6 +185,11 @@
 previous echo area contents is restored (in case the command prints
 something useful.)
 
+** If you set scroll-conservatively to a small number, then when you
+move point a short distance off the screen, XEmacs will scroll the
+screen just far enough to bring point back on screen, provided that
+does not exceed `scroll-conservatively' lines.
+
 ** Pending-delete changes.
 
 *** Pending-delete is now a minor mode, with the normal minor-mode
@@ -238,6 +243,16 @@
 ** The `M-x customize' command now automatically customizes `Emacs'
 group (top of the customize tree).  Use `M-x customize-group' to
 customize settings of a specific group.
+
+** The key C-x m no longer runs the `mail' command directly.
+Instead, it runs the command `compose-mail', which invokes the mail
+composition mechanism you have selected with the variable
+`mail-user-agent'.  The default choice of user agent is
+`sendmail-user-agent', which gives behavior compatible with the old
+behavior.
+
+C-x 4 m now runs compose-mail-other-window, and C-x 5 m runs
+compose-mail-other-frame.
 
 ** Gnuserv changes
 
--- lisp/prim/obsolete.el.orig	Fri Sep 19 23:22:09 1997
+++ lisp/prim/obsolete.el	Fri Sep 19 23:22:40 1997
@@ -634,12 +634,11 @@
   "Convert STRING to a sequence of TYPE which contains characters in STRING.
 TYPE should be `list' or `vector'.
 Multibyte characters are concerned."
-  (cond ((eq type 'list)
-	 (mapcar #'identity string))
-	((eq type 'vector)
-	 (mapcar #'identity string))
-	(t
-	 (error "Type must be `list' or `vector'"))))
+  (ecase type
+    (list
+     (mapcar #'identity string))
+    (vector
+     (mapvector #'identity string))))
 
 (defun string-to-list (string)
   "Return a list of characters in STRING."
--- lisp/prim/simple.el.orig	Sat Sep 20 01:43:31 1997
+++ lisp/prim/simple.el	Sat Sep 20 02:31:36 1997
@@ -2927,6 +2927,152 @@
       (setq alist (cdr alist)))
     element))
 
+
+(defcustom mail-user-agent 'sendmail-user-agent
+  "*Your preference for a mail composition package.
+Various Emacs Lisp packages (e.g. reporter) require you to compose an
+outgoing email message.  This variable lets you specify which
+mail-sending package you prefer.
+
+Valid values include:
+
+    sendmail-user-agent -- use the default Emacs Mail package
+    mh-e-user-agent     -- use the Emacs interface to the MH mail system
+    message-user-agent  -- use the GNUS mail sending package
+
+Additional valid symbols may be available; check with the author of
+your package for details."
+  :type '(radio (function-item :tag "Default Emacs mail"
+			       :format "%t\n"
+			       sendmail-user-agent)
+		(function-item :tag "Gnus mail sending package"
+			       :format "%t\n"
+			       message-user-agent)
+		(function :tag "Other"))
+  :group 'mail)
+
+(defun define-mail-user-agent (symbol composefunc sendfunc
+				      &optional abortfunc hookvar)
+  "Define a symbol to identify a mail-sending package for `mail-user-agent'.
+
+SYMBOL can be any Lisp symbol.  Its function definition and/or
+value as a variable do not matter for this usage; we use only certain
+properties on its property list, to encode the rest of the arguments.
+
+COMPOSEFUNC is program callable function that composes an outgoing
+mail message buffer.  This function should set up the basics of the
+buffer without requiring user interaction.  It should populate the
+standard mail headers, leaving the `to:' and `subject:' headers blank
+by default.
+
+COMPOSEFUNC should accept several optional arguments--the same
+arguments that `compose-mail' takes.  See that function's documentation.
+
+SENDFUNC is the command a user would run to send the message.
+
+Optional ABORTFUNC is the command a user would run to abort the
+message.  For mail packages that don't have a separate abort function,
+this can be `kill-buffer' (the equivalent of omitting this argument).
+
+Optional HOOKVAR is a hook variable that gets run before the message
+is actually sent.  Callers that use the `mail-user-agent' may
+install a hook function temporarily on this hook variable.
+If HOOKVAR is nil, `mail-send-hook' is used.
+
+The properties used on SYMBOL are `composefunc', `sendfunc',
+`abortfunc', and `hookvar'."
+  (put symbol 'composefunc composefunc)
+  (put symbol 'sendfunc sendfunc)
+  (put symbol 'abortfunc (or abortfunc 'kill-buffer))
+  (put symbol 'hookvar (or hookvar 'mail-send-hook)))
+
+(define-mail-user-agent 'sendmail-user-agent
+  'sendmail-user-agent-compose 'mail-send-and-exit)
+
+(define-mail-user-agent 'message-user-agent
+  'message-mail 'message-send-and-exit
+  'message-kill-buffer 'message-send-hook)
+
+(defun sendmail-user-agent-compose (&optional to subject other-headers continue
+					      switch-function yank-action
+					      send-actions)
+  (if switch-function
+      (let ((special-display-buffer-names nil)
+	    (special-display-regexps nil)
+	    (same-window-buffer-names nil)
+	    (same-window-regexps nil))
+	(funcall switch-function "*mail*")))
+  (let ((cc (cdr (assoc-ignore-case "cc" other-headers)))
+	(in-reply-to (cdr (assoc-ignore-case "in-reply-to" other-headers))))
+    (or (mail continue to subject in-reply-to cc yank-action send-actions)
+	continue
+	(error "Message aborted"))
+    (save-excursion
+      (goto-char (point-min))
+      (search-forward mail-header-separator)
+      (beginning-of-line)
+      (while other-headers
+	(if (not (member (car (car other-headers)) '("in-reply-to" "cc")))
+	    (insert (car (car other-headers)) ": "
+		    (cdr (car other-headers)) "\n"))
+	(setq other-headers (cdr other-headers)))
+      t)))
+
+(define-mail-user-agent 'mh-e-user-agent
+  'mh-smail-batch 'mh-send-letter 'mh-fully-kill-draft
+  'mh-before-send-letter-hook)
+
+(defun compose-mail (&optional to subject other-headers continue
+			       switch-function yank-action send-actions)
+  "Start composing a mail message to send.
+This uses the user's chosen mail composition package
+as selected with the variable `mail-user-agent'.
+The optional arguments TO and SUBJECT specify recipients
+and the initial Subject field, respectively.
+
+OTHER-HEADERS is an alist specifying additional
+header fields.  Elements look like (HEADER . VALUE) where both
+HEADER and VALUE are strings.
+
+CONTINUE, if non-nil, says to continue editing a message already
+being composed.
+
+SWITCH-FUNCTION, if non-nil, is a function to use to
+switch to and display the buffer used for mail composition.
+
+YANK-ACTION, if non-nil, is an action to perform, if and when necessary,
+to insert the raw text of the message being replied to.
+It has the form (FUNCTION . ARGS).  The user agent will apply
+FUNCTION to ARGS, to insert the raw text of the original message.
+\(The user agent will also run `mail-citation-hook', *after* the
+original text has been inserted in this way.)
+
+SEND-ACTIONS is a list of actions to call when the message is sent.
+Each action has the form (FUNCTION . ARGS)."
+  (interactive
+   (list nil nil nil current-prefix-arg))
+  (let ((function (get mail-user-agent 'composefunc)))
+    (funcall function to subject other-headers continue
+	     switch-function yank-action send-actions)))
+
+(defun compose-mail-other-window (&optional to subject other-headers continue
+					    yank-action send-actions)
+  "Like \\[compose-mail], but edit the outgoing message in another window."
+  (interactive
+   (list nil nil nil current-prefix-arg))
+  (compose-mail to subject other-headers continue
+		'switch-to-buffer-other-window yank-action send-actions))
+
+
+(defun compose-mail-other-frame (&optional to subject other-headers continue
+					    yank-action send-actions)
+  "Like \\[compose-mail], but edit the outgoing message in another frame."
+  (interactive
+   (list nil nil nil current-prefix-arg))
+  (compose-mail to subject other-headers continue
+		'switch-to-buffer-other-frame yank-action send-actions))
+
+
 (defun set-variable (var val)
   "Set VARIABLE to VALUE.  VALUE is a Lisp object.
 When using this interactively, supply a Lisp expression for VALUE.
--- lisp/modes/sendmail.el.orig	Sat Sep 20 02:07:43 1997
+++ lisp/modes/sendmail.el	Sat Sep 20 02:08:14 1997
@@ -1268,12 +1268,6 @@
     (pop-to-buffer "*mail*"))
   (mail noerase to subject in-reply-to cc replybuffer sendactions))
 
-;;; Do not execute these when sendmail.el is loaded,
-;;; only in loaddefs.el.
-;;;###autoload (define-key ctl-x-map "m" 'mail)
-;;;###autoload (define-key ctl-x-4-map "m" 'mail-other-window)
-;;;###autoload (define-key ctl-x-5-map "m" 'mail-other-frame)
-
 ;;;###autoload (add-hook 'same-window-buffer-names "*mail*")
 
 ;;; Do not add anything but external entries on this page.
--- lisp/utils/reporter.el.orig	Sat Sep 20 01:48:12 1997
+++ lisp/utils/reporter.el	Sat Sep 20 01:50:53 1997
@@ -92,24 +92,6 @@
 ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 ;; End user interface
 
-;; XEmacs -- don't autoload
-(defvar mail-user-agent 'sendmail-user-agent
-  "*Your preference for a mail composition package.
-Various Emacs Lisp packages (e.g. reporter) require you to compose an
-outgoing email message.  As there are several such packages available
-for Emacs, you can indicate your preference by setting this variable.
-
-Valid values currently are:
-
-    'sendmail-user-agent -- use Emacs built-in Mail package
-    'vm-user-agent       -- use Kyle Jones' VM package
-    'mh-e-user-agent     -- use the Emacs interface to the MH mail system
-
-Additional valid symbols may be available; check with the author of
-your package for details.")
-
-
-
 ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 ;; Package author interface variables
 
@@ -469,47 +451,6 @@
       )))
 
 
-;; paradigm definitions
-(defun define-mail-user-agent (symbol composefunc sendfunc
-				      &optional abortfunc hookvar)
-  "Define a symbol appropriate for `mail-user-agent'.
-
-SYMBOL can be any meaningful lisp symbol.  It need not have a function
-or variable definition, as it is only used for its property list.
-The property names are equivalent to the formal argument described
-below (but in lower case).  Additional properties can be placed on the
-symbol.
-
-COMPOSEFUNC is program callable function that composes an outgoing
-mail message buffer.  This function should set up the basics of the
-buffer without requiring user interaction.  It should populate the
-standard mail headers, leaving the `to:' and `subject:' headers blank.
-
-SENDFUNC is the command a user would type to send the message.
-
-Optional ABORTFUNC is the command a user would type to abort the
-message.  For mail packages that don't have a separate abort function,
-this can be `kill-buffer' (the equivalent of omitting this argument).
-
-Optional HOOKVAR is a hook variable that gets run before the message
-is actually sent.  Reporter will install `reporter-bug-hook' onto this
-hook so that empty bug reports can be suppressed by raising an error.
-If not supplied, `mail-send-hook' will be used."
-  (put symbol 'composefunc composefunc)
-  (put symbol 'sendfunc sendfunc)
-  (put symbol 'abortfunc (or abortfunc 'kill-buffer))
-  (put symbol 'hookvar (or hookvar 'mail-send-hook)))
-
-(define-mail-user-agent 'sendmail-user-agent
-  'reporter-mail 'mail-send-and-exit)
-
-(define-mail-user-agent 'vm-user-agent
-  'vm-mail 'vm-mail-send-and-exit)
-
-(define-mail-user-agent 'mh-e-user-agent
-  'mh-smail-batch 'mh-send-letter 'mh-fully-kill-draft
-  'mh-before-send-letter-hook)
 
-
 (provide 'reporter)
 ;;; reporter.el ends here
--- lisp/packages/font-lock.el.orig	Sat Sep 20 01:36:37 1997
+++ lisp/packages/font-lock.el	Sat Sep 20 01:36:40 1997
@@ -109,9 +109,8 @@
 ;; Further comments from the FSF:
 
 ;; Nasty regexps of the form "bar\\(\\|lo\\)\\|f\\(oo\\|u\\(\\|bar\\)\\)\\|lo"
-;; are made thusly: (make-regexp '("foo" "fu" "fubar" "bar" "barlo" "lo")) for
-;; efficiency.  See /pub/gnu/emacs/elisp-archive/functions/make-regexp.el.Z on
-;; archive.cis.ohio-state.edu for this and other functions.
+;; are made thusly: (regexp-opt '("foo" "fu" "fubar" "bar" "barlo" "lo")) for
+;; efficiency.
 
 ;; What is fontification for?  You might say, "It's to make my code look nice."
 ;; I think it should be for adding information in the form of cues.  These cues
@@ -1612,28 +1611,30 @@
     ;;
     ;; Control structures.  ELisp and CLisp combined.
     ;;
-    ;;(make-regexp
-    ;;  '("cond" "if" "while" "let\\*?" "prog[nv12*]?" "catch" "throw"
-    ;;    "save-restriction" "save-excursion" "save-window-excursion"
+    ;;(regexp-opt
+    ;;  '("cond" "if" "while" "let" "let*" "prog" "progn" "prog1"
+    ;;    "prog2" "progv" "catch" "throw" "save-restriction"
+    ;;    "save-excursion" "save-window-excursion"
     ;;    "save-current-buffer" "with-current-buffer"
-    ;;    "with-temp-file" "with-output-to-.+"
+    ;;    "with-temp-file" "with-temp-buffer" "with-output-to-string"
+    ;;    "with-string-as-buffer-contents"
     ;;    "save-selected-window" "save-match-data" "unwind-protect"
     ;;    "condition-case" "track-mouse" "autoload"
     ;;    "eval-after-load" "eval-and-compile" "eval-when-compile"
-    ;;    "when" "unless" "do" "flet" "labels" "lambda"
-    ;;    "return" "return-from"))
-    ;;
+    ;;    "when" "unless" "do" "dolist" "dotimes" "flet" "labels"
+    ;;    "lambda" "return" "return-from"))
     (cons
      (concat
       "(\\("
-      "autoload\\|c\\(atch\\|ond\\(\\|ition-case\\)\\)\\|do\\|"
-      "eval-\\(a\\(fter-load\\|nd-compile\\)\\|when-compile\\)\\|"
-      "flet\\|if\\|l\\(a\\(bels\\|mbda\\)\\|et\\*?\\)\\|prog[nv12*]?\\|"
-      "return\\(\\|-from\\)\\|save-\\(current-buffer\\|excursion\\|"
-      "match-data\\|restriction\\|selected-window\\|window-excursion\\)\\|"
-      "t\\(hrow\\|rack-mouse\\)\\|un\\(less\\|wind-protect\\)\\|"
-      "w\\(h\\(en\\|ile\\)\\|ith-\\(current-buffer\\|output-to-.+\\|"
-      "temp-file\\)\\)"
+      "autoload\\|c\\(atch\\|ond\\(ition-case\\)?\\)\\|do\\(list\\|"
+      "times\\)?\\|eval-\\(a\\(fter-load\\|nd-compile\\)\\|when-compile\\)\\|"
+      "flet\\|if\\|l\\(a\\(bels\\|mbda\\)\\|et\\*?\\)\\|"
+      "prog[nv12\\*]?\\|return\\(-from\\)?\\|save-\\(current-buffer\\|"
+      "excursion\\|match-data\\|restriction\\|selected-window\\|"
+      "window-excursion\\)\\|t\\(hrow\\|rack-mouse\\)\\|un\\(less\\|"
+      "wind-protect\\)\\|w\\(h\\(en\\|ile\\)\\|ith-\\(current-buffer\\|"
+      "output-to-string\\|string-as-buffer-contents\\|temp-\\(buffer\\|"
+      "file\\)\\)\\)"
       "\\)\\>") 1)
     ;;
     ;; Words inside \\[] tend to be for `substitute-command-keys'.
@@ -1721,7 +1722,7 @@
 	       nil t))
      ;;
      ;; Control structures.
-;(make-regexp '("begin" "call-with-current-continuation" "call/cc"
+;(regexp-opt '("begin" "call-with-current-continuation" "call/cc"
 ;	       "call-with-input-file" "call-with-output-file" "case" "cond"
 ;	       "do" "else" "for-each" "if" "lambda"
 ;	       "let\\*?" "let-syntax" "letrec" "letrec-syntax"
--- lisp/prim/keydefs.el.orig	Sat Sep 20 01:38:59 1997
+++ lisp/prim/keydefs.el	Sat Sep 20 02:11:44 1997
@@ -141,8 +141,6 @@
 (define-key global-map "\C-x52" 'make-frame)
 (define-key global-map "\C-x50" 'delete-frame)
 (define-key global-map "\C-x5o" 'other-frame)
-;; XEmacs addition:
-(define-key global-map "\C-x5m" 'mail-other-frame)
 
 ;; FSFmacs help.el
 
@@ -462,9 +460,9 @@
 
 (define-key global-map "\M-$" 'ispell-word)
 
-(define-key global-map "\C-x4m" 'mail-other-window)
-
-(define-key global-map "\C-xm" 'mail)
+(define-key global-map "\C-xm" 'compose-mail)
+(define-key global-map "\C-x4m" 'compose-mail-other-window)
+(define-key global-map "\C-x5m" 'compose-mail-other-frame)
 
 (define-key global-map "\M-." 'find-tag)
 
--- src/redisplay.c.orig	Sat Sep 20 02:52:57 1997
+++ src/redisplay.c	Sat Sep 20 03:05:27 1997
@@ -454,11 +454,13 @@
 
 Lisp_Object Vglobal_mode_string;
 
-/* The number of lines to try scrolling a
-  window by when point leaves the window; if
+/* The number of lines scroll a window by when point leaves the window; if
   it is <=0 then point is centered in the window */
 int scroll_step;
 
+/* Scroll up to this many lines, to bring point back on screen. */
+int scroll_conservatively;
+
 /* Marker for where to display an arrow on top of the buffer text.  */
 Lisp_Object Voverlay_arrow_position;
 /* String to display for the arrow.  */
@@ -5190,12 +5192,16 @@
      back onto the screen. */
   if (scroll_step)
     {
-      startp = vmotion (w, startp,
-			(pointm < startp) ? -scroll_step : scroll_step, 0);
-      regenerate_window (w, startp, pointm, DESIRED_DISP);
+      int scrolled = scroll_conservatively;
+      for (; scrolled >= 0; scrolled -= scroll_step)
+	{
+	  startp = vmotion (w, startp,
+			    (pointm < startp) ? -scroll_step : scroll_step, 0);
+	  regenerate_window (w, startp, pointm, DESIRED_DISP);
 
-      if (point_visible (w, pointm, DESIRED_DISP))
-	goto regeneration_done;
+	  if (point_visible (w, pointm, DESIRED_DISP))
+	    goto regeneration_done;
+	}
     }
 
   /* We still haven't managed to get the screen drawn with point on
@@ -8205,6 +8211,12 @@
 If that fails to bring point back on frame, point is centered instead.
 If this is zero, point is always centered after it moves off screen.
 */ );
+  scroll_step = 0;
+
+  DEFVAR_INT ("scroll-conservatively", &scroll_conservatively /*
+*Scroll up to this many lines, to bring point back on screen.
+*/ );
+  scroll_conservatively = 0;
 
   DEFVAR_BOOL_MAGIC ("truncate-partial-width-windows",
 		     &truncate_partial_width_windows /*


-- 
Hrvoje Niksic <hniksic@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
I'm sure they'll listen to reason! -- Neal Stevenson, _Snow Crash_

