[23665] in Source-Commits

home help back first fref pref prev next nref lref last post

/svn/athena r23280 - in trunk/athena/bin/discuss: debian edsc

daemon@ATHENA.MIT.EDU (broder@MIT.EDU)
Fri Jan 9 21:34:16 2009

Date: Fri, 9 Jan 2009 21:33:46 -0500 (EST)
From: broder@MIT.EDU
Message-Id: <200901100233.VAA07970@drugstore.mit.edu>
To: source-commits@MIT.EDU
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: broder
Date: 2009-01-09 21:33:45 -0500 (Fri, 09 Jan 2009)
New Revision: 23280

Added:
   trunk/athena/bin/discuss/edsc/discuss.el.in
Removed:
   trunk/athena/bin/discuss/edsc/discuss.el
Modified:
   trunk/athena/bin/discuss/debian/changelog
   trunk/athena/bin/discuss/edsc/Makefile.in
Log:
Remove hard-coded paths from Emacs discuss-mode, in favor if
retrieving them from autoconf.


Modified: trunk/athena/bin/discuss/debian/changelog
===================================================================
--- trunk/athena/bin/discuss/debian/changelog	2009-01-10 00:59:14 UTC (rev 23279)
+++ trunk/athena/bin/discuss/debian/changelog	2009-01-10 02:33:45 UTC (rev 23280)
@@ -2,8 +2,10 @@
 
   * Revert a small part of the OS X com_err patch from 10.0.6 in favor of
     changes to aclocal.m4
+  * Remove hard-coded paths from discuss-mode, in favor of getting them
+    from autoconf.
 
- -- Evan Broder <broder@mit.edu>  Fri, 09 Jan 2009 19:23:15 -0500
+ -- Evan Broder <broder@mit.edu>  Fri, 09 Jan 2009 21:32:25 -0500
 
 debathena-discuss (10.0.6-0debathena1) unstable; urgency=low
 

Modified: trunk/athena/bin/discuss/edsc/Makefile.in
===================================================================
--- trunk/athena/bin/discuss/edsc/Makefile.in	2009-01-10 00:59:14 UTC (rev 23279)
+++ trunk/athena/bin/discuss/edsc/Makefile.in	2009-01-10 02:33:45 UTC (rev 23280)
@@ -37,7 +37,7 @@
 all: edsc
 
 clean:
-	rm -f edsc *.o version.h
+	rm -f edsc *.o version.h discuss.el
 
 depend:
 
@@ -54,6 +54,9 @@
 version.h: ${SRCS} newvers.sh
 	sh newvers.sh
 
+discuss.el: discuss.el.in Makefile
+	sed -e 's|#libexecdir#|${libexecdir}|' $< > $@
+
 edsc: $(OBJS)
 	${CC} ${LDFLAGS} -o edsc ${OBJS} ${LIBS}
 

Deleted: trunk/athena/bin/discuss/edsc/discuss.el

Copied: trunk/athena/bin/discuss/edsc/discuss.el.in (from rev 23276, trunk/athena/bin/discuss/edsc/discuss.el)
===================================================================
--- trunk/athena/bin/discuss/edsc/discuss.el	2009-01-09 21:11:46 UTC (rev 23276)
+++ trunk/athena/bin/discuss/edsc/discuss.el.in	2009-01-10 02:33:45 UTC (rev 23280)
@@ -0,0 +1,1224 @@
+;;; Emacs lisp code to remote control a "discuss" shell process to
+;;; provide an emacs-based interface to the discuss conferencing system.
+;;;
+;;; Copyright (C) 1989, 1993 by the Massachusetts Institute of Technology
+;;; Developed by the MIT Student Information Processing Board (SIPB).
+;;; Written by Stan Zanarotti, Bill Sommerfeld and Theodore Ts'o.
+;;; For copying information, see the file mit-copyright.h in this release.
+;;;
+;;; $Id: discuss.el,v 1.41 1999-06-04 14:11:13 danw Exp $
+;;;
+
+;;
+;; WARNING --- change discuss-source-dir when installing this file!
+;;
+
+(provide 'discuss)
+
+(defvar discuss-source-dir nil
+  "Source directory from which this version of discuss is loaded, including
+the trailing `/'.  It must end with `/', since it will be directly
+concatenated to other file names.  Setting this to nil or an empty string
+will cause load-path to be used.")
+
+(defvar discuss-pathname "#libexecdir#/edsc"
+  "*Name of program to run as slave process for discuss.")
+
+(defvar discuss-DWIM nil
+  "If true, enable Do_What_I_Mean mode.  Allows the user to read discuss by
+repeatedly hitting the space bar.  For the truly lazy user.")
+
+(defvar discuss-safe-delete nil
+  "If true, discuss asks for confirmation before deleting a transaction with
+discuss-delete-trn.")
+
+(defvar discuss-reply-by-mail-with-message-id nil
+  "If true, use the Message-Id field in a message for generating the
+In-Reply-To field, rather than using the discuss convention of
+In-Reply-To: [###] in Meeting.")
+
+(defvar discuss-auto-reply-to-alist nil
+  "Association list of discuss meeting names (long forms) and default
+Reply-To addresses that should be inserted into replies by mail (to help
+ensure that people don't drop the CC to the discuss meeting.)")
+
+(defvar discuss-font-lock-keywords '(("^\\(From: .*\\)" 1 'bold t)
+				     ("^\\(Subject: .*\\)" 1 'bold t))
+  "Keywords to highlight in transactions if using font-lock mode.
+(Add (add-hook 'discuss-show-trn-hooks 'font-lock-mode) to your
+.emacs to enable discuss font-lock mode.)")
+
+(defvar discuss-visible-headers nil
+  "If non-nil, a regexp matching the mail headers to display in discuss
+meetings fed by mailing lists. If nil, the value of discuss-invisible-headers
+is used instead.")
+
+(defvar discuss-invisible-headers "^From \\|^Received:"
+  "If discuss-visible-headers is nil, discuss-invisible-headers is a regexp
+matching the mail headers to be not shown by default in discuss meetings
+fed by mailing lists.")
+
+(defvar discuss-keep-discuss-ls nil
+  "If nil, windows containing *discuss-ls* buffers will be deleted when
+leaving transaction mode.")
+
+(defvar discuss-use-short-meeting-name nil
+  "If nil, transaction mode buffers will use the full name of the discuss
+meeting. If non-nil, they will use the short name.")
+
+(defvar discuss-mtgs-mode-map nil
+  "Keymap used by the meetings-list mode of the discuss subsystem.")
+
+(defvar discuss-list-mode-map nil
+  "Keymap used by the transaction-list mode of the discuss subsystem.")
+
+(defvar discuss-trn-mode-map nil
+  "Keymap used by the transaction mode of the discuss subsystem.")
+
+(defvar discuss-main-buffer "*meetings*"
+  "Name of main buffer for discuss, which holds a list of the current
+meetings.")
+
+(defvar discuss-version nil "Version of discuss code loaded.")
+(defun discuss-version nil (interactive) (message discuss-version))
+
+(defvar discuss-process nil
+  "Structure discribing the slave discuss subprocess.")
+
+(defvar discuss-cont nil
+  "Internal hook to call when discuss subprocess is done.")
+
+(defvar discuss-unwind nil
+  "Internal hook to call when discuss subprocess returns an error.")
+
+(defvar discuss-in-progress nil
+  "t if a request to the slave subprocess is outstanding.")
+
+(defvar discuss-form nil
+  "Lisp form returned by the subprocess.")
+
+(defvar discuss-meeting-list nil
+  "Meeting list.")
+
+(defvar discuss-meeting-completion-list nil
+  "Meeting list changed into the right format for completion-read.")
+
+(defvar discuss-show-num 0
+  "Current discuss transaction number.")
+
+(defvar discuss-show-headers nil
+  "Whether or not all headers are being displayed on the current transaction.")
+
+(defvar discuss-meeting nil
+  "Buffer-local variable containing the name of the meeting of a discuss
+transaction buffer.  Nil means this buffer is not a discuss-transaction
+buffer.")
+
+(defvar discuss-meeting-info nil
+  "Buffer-local variable containing the info struction for the discuss
+transaction buffer.")
+
+(defvar discuss-cur-mtg-buf nil
+  "Name of buffer for current Discuss meeting.")
+
+(defvar discuss-cur-direction 0
+  "Current discuss direction.")
+
+(defvar discuss-async t
+  "*Run discuss commands asynchronously.
+
+Currently ignored (always async).")
+
+(defvar discuss-in-show-trn nil)
+
+(defvar discuss-error nil
+  "Contains error message returned by edsc process.  If nil, means last
+request completed successfully.")
+
+
+;;; Major modes defined by this package.
+
+;;; List of all meetings.
+
+(defun discuss-mtgs-mode ()
+  "Major mode for providing an emacs discuss subsystem.
+This looks a lot like RMAIL.  This works by using ``edsc'' as a subjob.
+
+The following commands are available:
+\\[describe-mode]	List available commands.
+\\[discuss-forward-meeting]	Go to next meeting that has unread transactions.
+\\[discuss-prev-meeting]	Go to previous meeting has unread transactions.
+\\[discuss-lsm]	List meetings.
+\\[discuss-goto]	Go to meeting listed on line.
+\\[discuss-add-mtg]	Add meeting.
+\\[discuss-del-mtg]	Delete meeting listed on line.
+\\[discuss-catchup]	Mark a meeting as read (catch up).
+\\[discuss-quit]	Quit Discuss."
+  (interactive)
+  (kill-all-local-variables)
+  (setq major-mode 'discuss-mtgs-mode)
+  (setq mode-name "Discuss (meetings)")
+  (use-local-map discuss-mtgs-mode-map)
+  (setq buffer-read-only t)
+  (run-hooks 'discuss-mode-hooks))
+
+;;; Meeting list mode.
+
+(defun discuss-list-mode ()
+  "Major mode for looking at listings of a meeting under the
+discuss subsystem."
+  (interactive)
+  (kill-all-local-variables)
+  (setq major-mode 'discuss-list-mode)
+  (setq mode-name "Discuss (list)")
+  (use-local-map discuss-list-mode-map)
+  (setq buffer-read-only t)
+  (make-local-variable 'trans-buffer)
+  (setq trans-buffer nil)
+  (make-local-variable 'meeting-name)
+  (setq meeting-name nil)
+  (run-hooks 'discuss-list-hooks))
+
+;;; Transaction mode.
+
+(defun discuss-trn-mode ()
+"Major mode for looking at transactions of a meeting under the
+discuss subsystem.
+All normal editing commands are turned off.
+Instead, these commands are available:
+
+\\[describe-mode]	List available commands.
+\\[discuss-scroll-up]	Scroll to next screen of this transaction.
+\\[scroll-down]	Scroll to previous screen of this transaction.
+\\[discuss-ls]	List headers of remaining transactions.
+\\[discuss-next-trn]	Move to Next transaction.
+\\[discuss-prev-trn]	Move to Previous transaction.
+\\[discuss-last-trn]	Move to Last transaction in meeting.
+\\[discuss-first-trn]	Move to First transaction in meeting.
+\\[discuss-nref]	Move to Next transaction in chain.
+\\[discuss-pref]	Move to Previous transaction in chain.
+\\[discuss-fref]	Move to First transaction in chain.
+\\[discuss-lref]	Move to Last transaction in chain.
+\\[discuss-show-trn]	Goto a specific transaction.
+\\[discuss-delete-trn]	Delete transaction (and move forwards).
+\\[discuss-delete-trn-backwards]	Delete transaction (and move backwards).
+\\[discuss-retrieve-trn]	Retrieve (undelete) a deleted transaction.
+\\[discuss-update]	Redisplay this transaction from the top.
+\\[discuss-show-trn-with-headers]	Redisplay this transaction with full mail headers.
+\\[discuss-reply]	Reply to this transaction (via discuss.)
+\\[discuss-reply-by-mail]	Reply to this transaction (via mail.)
+\\[discuss-forward]	Forward this transaction via mail.
+\\[discuss-trn-output]	Append this transaction to a UNIX file.
+\\[discuss-talk]	Talk.  Enter a new transaction.
+\\[discuss-toggle-trn-flag]	Toggle the flag on this transaction.
+\\[discuss-set-seen-and-leave-mtg]	Mark transaction as highest-seen and leave meeting.
+\\[discuss-catchup]	Catch up.  Mark all of the transactions in this meeting as read.
+\\[discuss-add-mtg]	Add meeting (if this transaction is a meeting annoucement).
+\\[discuss-leave-mtg]	Quit (leave) meeting."
+  (interactive)
+  (kill-all-local-variables)
+  (setq major-mode 'discuss-trn-mode)
+  (setq mode-name "Discuss (transaction)")
+  (use-local-map discuss-trn-mode-map)
+  (setq buffer-read-only t)
+  (make-local-variable 'discuss-current-transaction)
+  (setq discuss-current-transaction 0)
+  (make-local-variable 'discuss-highest-seen)
+  (setq discuss-highest-seen 0)
+  (make-local-variable 'discuss-output-last-file)
+  (make-local-variable 'discuss-meeting)
+  (make-local-variable 'discuss-meeting-info)
+  (setq discuss-output-last-file nil)
+  (run-hooks 'discuss-trn-hooks))
+
+
+;;; Main entry point:  Start up a slave process and listen for requests.
+
+(defun discuss (&optional arg)
+  "Enter discuss mode for emacs and list meetings."
+  (interactive "P")
+  (message "Starting discuss....")
+  (if (not (and (get-buffer discuss-main-buffer)
+		(buffer-name (get-buffer discuss-main-buffer))
+		(> (length discuss-meeting-list) 0)))
+      (progn
+	(switch-to-buffer (get-buffer-create discuss-main-buffer))
+	(discuss-mtgs-mode)
+	(setq discuss-meeting-list nil)
+	(if arg
+	    (message "Hit `g' and enter a meeting name.")	
+	  (discuss-lsm)))
+    (switch-to-buffer discuss-main-buffer)))
+
+;;; Entry points typically entered through key sequences.
+
+(defun discuss-list-meetings ()
+  "List discuss meetings."
+  (interactive)
+  (message "Listing meetings..."
+  (switch-to-buffer (get-buffer discuss-main-buffer))
+  (let ((buffer-read-only nil))
+    (erase-buffer))
+  (discuss-send-cmd "(gml)\n" 'discuss-end-of-lsm 'discuss-read-form)))
+
+(fset 'discuss-lsm (symbol-function 'discuss-list-meetings))
+
+;;(defmacro cadr (x)
+;;  (list 'car (list 'cdr x)))
+(defun cadr (x) (car (cdr x)))
+
+;;(defmacro caddr (x)
+;;  (` (car (cdr (cdr (, x))))))
+(defun caddr (x) (car (cdr (cdr x))))
+
+;;(defmacro cddr (x)
+;;  (` (cdr (cdr (, x)))))
+(defun cddr (x) (cdr (cdr x)))
+
+(defun discuss-lsm-1 (entry)
+  (insert (cond ((eq (car entry) 1)
+		 " c       ")
+		((stringp (car entry))
+		 "   X     ")
+		(t
+		 "         "))
+	  (cadr entry))
+  (cond ((stringp (car entry))
+	 (insert " (" (car entry) ")"))
+	((cddr entry)
+	 (mapcar 'discuss-lsm-2 (cddr entry))))
+  (insert "\n"))
+
+(defun discuss-lsm-2 (name)
+  (insert ", " name))
+
+;; Compliments of jik
+(defun flatten (list)
+  (if (eq nil list) '())
+  (let* ((newlist (copy-list (car list)))
+        (restoflist (cdr list))
+        (pointer newlist))
+    (while (not (eq nil restoflist))
+      (while (not (eq nil (cdr pointer)))
+        (setq pointer (cdr pointer)))
+      (setcdr pointer (copy-list (car restoflist)))
+      (setq restoflist (cdr restoflist)))
+    newlist))
+
+(defun copy-list (list)
+  (if (eq nil list)
+      '()
+    (cons (car list) (copy-list (cdr list)))))
+
+(defun discuss-end-of-lsm ()
+  (message "Listing meetings...")
+  (let ((orig-buffer (current-buffer)))
+    (set-buffer discuss-main-buffer)
+    (setq discuss-meeting-list (apply 'vector discuss-form))
+    (setq discuss-meeting-completion-list
+	  (mapcar (function (lambda (x) (cons x 0)))
+		  (flatten (mapcar 'cdr discuss-form))))
+    (let ((buffer-read-only nil))
+      (erase-buffer)
+      (goto-char (point-min))
+      (insert " Flags   Meeting name\n"
+	      " -----   ------------\n")
+      (mapcar 'discuss-lsm-1 discuss-form)
+      (goto-char (point-max))
+      (backward-delete-char 1))
+    (goto-char (point-min))
+    (forward-line 2)
+    (set-buffer orig-buffer))
+  (message "Listing meetings...done."))
+
+(defun discuss-find-meeting (meeting)
+  (let ((i 0)
+	(eol (length discuss-meeting-list)))
+    (while (and (< i eol)
+		(not (member meeting (aref discuss-meeting-list i))))
+	(setq i (1+ i)))
+    (if (< i eol)
+	(aref discuss-meeting-list i)
+      nil)))
+
+
+(defun discuss-quit ()
+  "Exits Discuss mode."
+  (interactive)
+  (if discuss-cur-mtg-buf
+      (discuss-leave-mtg))
+  (discuss-restart)
+  (switch-to-buffer (other-buffer))
+  (bury-buffer discuss-main-buffer))
+
+(defun discuss-goto (&optional meeting)
+  "Go to a meeting."
+  (interactive (list (if (or current-prefix-arg
+			     (not (equal (buffer-name) discuss-main-buffer))
+			     (= (point) 1))
+			 (completing-read "Meeting name:  "
+					  discuss-meeting-completion-list
+					  nil t ""))))
+  (if (not meeting)
+      (let ((curline (- (count-lines 1 (min (1+ (point)) (point-max))) 3)))
+	(if (< curline 0)
+	    (error "Not looking at a meeting."))
+	(setq meeting (cadr (aref discuss-meeting-list
+				  curline)))))
+  (if (not (and discuss-cur-mtg-buf
+	       (buffer-name discuss-cur-mtg-buf)
+	       (equal discuss-current-meeting meeting)))
+      (progn
+	(if discuss-cur-mtg-buf
+	    (discuss-leave-mtg))
+	(setq discuss-cur-mtg-buf
+	      (get-buffer-create (if discuss-use-short-meeting-name
+				     (caddr (discuss-find-meeting meeting))
+				   (concat "*" meeting " meeting*"))))
+	(switch-to-buffer discuss-cur-mtg-buf)
+	(discuss-trn-mode))
+    (progn
+      (set-buffer discuss-cur-mtg-buf)
+      (discuss-send-cmd (format "(ss %d %s)\n"
+				discuss-highest-seen
+				discuss-meeting)
+			nil
+			(if discuss-old-ss nil 'discuss-read-form))))
+  (switch-to-buffer discuss-cur-mtg-buf)
+  (setq discuss-meeting meeting)
+  (setq discuss-current-meeting meeting)   ;;; denigrated
+  (setq discuss-output-last-file (concat discuss-meeting ".trans"))
+  (discuss-send-cmd (format "(gmi %s)\n" meeting)
+		    'discuss-end-of-goto 'discuss-read-form
+		    'discuss-goto-error))
+
+(defun discuss-goto-error ()
+  "Called to back out when there's an error in going to a meeting."
+  (kill-buffer (buffer-name discuss-cur-mtg-buf))
+  (setq discuss-cur-mtg-buf nil)
+  (setq discuss-current-meeting nil)
+  (switch-to-buffer discuss-main-buffer))
+
+(defun discuss-end-of-goto ()
+  (let ((last (nth 4 discuss-form)))
+    ;
+    ; To have gotten this far, we must have had status access....
+    ;
+    (if (not (string-match "r" (nth 10 discuss-form)))
+	(progn
+	  (discuss-goto-error)
+	  (error "Insufficient access to read transactions in %s"
+		 (nth 1 discuss-current-meeting-info))))
+    (setq discuss-highest-seen (nth 11 discuss-form))
+    (if (> discuss-highest-seen last)
+	(progn
+	  (beep)
+	  (message "Warning!  Last seen transaction higher than last transaction")
+	  (sit-for 1)
+	  (setq discuss-highest-seen last)))
+    (message "%s meeting: %d new, %d last."
+	     (cadr discuss-form)
+	     (- last discuss-highest-seen)
+	     last)
+    (set-buffer discuss-cur-mtg-buf)
+    (setq discuss-current-meeting-info discuss-form)
+    (cond ((not (zerop discuss-current-transaction)) nil)
+	  ((zerop (nth 3 discuss-form)) (error "Empty meeting."))
+	  ((or (zerop discuss-highest-seen) (>= discuss-highest-seen last))
+	   (discuss-show-trn last))
+	  (t (discuss-send-cmd (format "(nut %d %s)\n"
+				       discuss-highest-seen
+				       discuss-meeting)
+;			       'discuss-next-goto
+			       '(lambda () (progn (discuss-show-trn
+						   (car discuss-form))))
+			       'discuss-read-form)))))
+
+;(defun discuss-next-goto ()
+;  (discuss-show-trn (car discuss-form)))
+
+;;;
+;;; This is broken --- only works in transaction buffer.  Of course, this is
+;;; is the only place that you'd really want to use it.  Actually, it
+;;; sort of works in meetings-mode too, but only barely so.
+;;; This should be cleaned up.  -- TYT
+;;;
+(defun discuss-stat (&optional meeting)
+  "Go to a meeting."
+  (interactive (list (if (eq (current-buffer) discuss-cur-mtg-buf)
+			 discuss-meeting
+		       (if (or current-prefix-arg
+			       (not (equal (buffer-name) discuss-main-buffer))
+			       (= (point) 1))
+			 (completing-read "Meeting name:  "
+					  discuss-meeting-completion-list
+					  nil t "")))))
+  (if (not meeting)
+      (let ((curline (- (count-lines 1 (min (1+ (point)) (point-max))) 3)))
+	(if (< curline 0)
+	    (error "Not looking at a meeting."))
+	(setq meeting (cadr (aref discuss-meeting-list
+				  curline)))))
+  (discuss-send-cmd (format "(gmi %s)\n" meeting)
+		    'discuss-end-of-stat 'discuss-read-form))
+
+(defun discuss-end-of-stat ()
+  (setq discuss-current-meeting-info discuss-form)
+  (setq discuss-meeting-info discuss-form)
+  (let ((last (nth 4 discuss-form))
+	(highest-seen (nth 11 discuss-form)))
+    (if (and (equal (cadr discuss-form) discuss-current-meeting)
+	     (not (= discuss-highest-seen 0)))
+	(setq highest-seen discuss-highest-seen))    ;; This is wrong...
+    (message "%s meeting: %d new, %d last."
+	     (cadr discuss-form)
+	     (- last highest-seen)
+	     last)))
+
+(defun discuss-show-trn-with-headers ()
+  "Show transaction with full headers."
+  (interactive)
+  (discuss-show-trn discuss-current-transaction t))
+
+(defun discuss-show-trn (trn-num &optional show-headers)
+  "Show transaction number N (prefix argument)."
+  (interactive
+   (list (if (not (numberp current-prefix-arg))
+	     (string-to-int (read-string "Transaction number: "))
+	   current-prefix-arg)))
+  (if (and trn-num (numberp trn-num))
+      (progn
+	(setq discuss-show-num trn-num)
+	(setq discuss-show-headers show-headers)
+	(discuss-send-cmd (format "(gtfc %d %d %s)\n"
+				  discuss-cur-direction
+				  trn-num
+				  discuss-current-meeting)
+			  'discuss-end-show-trn
+			  'discuss-read-form))))
+
+(defun discuss-end-show-trn ()
+  (let ((transaction-file (car discuss-form)))
+    (set-buffer discuss-cur-mtg-buf)
+    (setq discuss-current-transaction-info (cdr discuss-form))
+    (setq discuss-current-transaction discuss-show-num)
+    (setq discuss-highest-seen (max discuss-highest-seen
+				    discuss-current-transaction))
+    (if (>= discuss-current-transaction
+	    (nth 4 discuss-current-meeting-info))
+	(let ((discuss-in-show-trn t))
+	  (discuss-update)
+	  (discuss-block-til-ready nil)))
+
+    (setq mode-line-process (format " %d/%d"
+				    discuss-current-transaction
+				    (nth 4 discuss-current-meeting-info)))
+    (let ((buffer-read-only nil))
+      (erase-buffer)
+      (insert-file-contents transaction-file)
+      (if (not discuss-show-headers)
+	  (discuss-clean-msg-header))
+      (goto-char (point-min)))
+    (if (= (caddr discuss-current-transaction-info) 0)
+	(progn
+	  (message "Last transaction in %s" discuss-meeting)
+	  (discuss-mark-read-meeting discuss-meeting)
+	  (discuss-next-meeting t)))
+    (make-local-variable 'font-lock-defaults)
+    (setq font-lock-defaults '(discuss-font-lock-keywords t))
+    (run-hooks 'discuss-show-trn-hooks)))
+
+(defun discuss-clean-msg-header ()
+  (save-excursion
+    (goto-char (point-min))
+    (next-line 2)	; skip title and subject
+    (if (looking-at "From \\|[^ ]+:")
+	(let ((start (point)))
+	  (save-restriction
+	    (if (search-forward "\n\n" nil 'move)
+		(backward-char 1))
+	    (narrow-to-region start (point))
+	    (goto-char (point-min))
+	    (condition-case nil
+		(if discuss-visible-headers
+		    (while (< (point) (point-max))
+		      (cond ((looking-at discuss-visible-headers)
+			     (re-search-forward "\n[^ \t]"))
+			    (t
+			     (delete-region (point)
+					    (progn (re-search-forward "\n[^ \t]")
+						   (- (point) 1))))))
+		  (while (re-search-forward discuss-invisible-headers nil t)
+		    (beginning-of-line)
+		    (delete-region (point) (progn (re-search-forward "\n[^ \t]")
+						  (- (point) 1)))
+		    (beginning-of-line)))
+	      (error nil)))))))
+
+(defun discuss-update ()
+  "Update Discuss display to show new transactions."
+  (interactive)
+  (discuss-send-cmd (format "(gmi %s)\n" discuss-meeting)
+		    'discuss-end-of-update 'discuss-read-form))
+
+(defun discuss-end-of-update ()
+  (setq discuss-current-meeting-info discuss-form)
+  (save-excursion
+    (set-buffer discuss-cur-mtg-buf)
+    (if (not discuss-in-show-trn)
+	(discuss-show-trn discuss-current-transaction))))
+
+(defun discuss-next-trn ()
+  "Show next transaction."
+  (interactive)
+  (if (or (not discuss-current-transaction)
+	  (= discuss-current-transaction 0))
+      (error "Not looking at transactions")
+    (let ((next (caddr discuss-current-transaction-info)))
+      (if (= next 0)
+	  (progn
+	    (discuss-send-cmd (format "(gti %d %s)\n"
+				      discuss-current-transaction
+				      discuss-current-meeting)
+			      nil 'discuss-read-form)
+	    (discuss-block-til-ready nil)
+	    (setq discuss-current-transaction-info discuss-form)
+	    (if (= 0 (caddr discuss-current-transaction-info))
+		(if discuss-DWIM
+		    (discuss-leave-mtg)
+		  (error "No next transaction."))
+	      (progn
+		(setq discuss-cur-direction 1)
+		(discuss-send-cmd (format "(im %s)\n" discuss-current-meeting)
+				  nil 'discuss-read-form)
+		(discuss-next-trn))))
+	(progn
+	  (setq discuss-cur-direction 1)
+	  (discuss-show-trn next))))))
+
+(defun discuss-prev-trn ()
+  "Show previous transaction."
+  (interactive)
+  (if (or (not discuss-current-transaction)
+	  (= discuss-current-transaction 0))
+      (error "Not looking at transactions")
+    (let ((prev (cadr discuss-current-transaction-info)))
+      (if (= prev 0)
+	  (error "No previous transaction.")
+	(progn
+	  (setq discuss-cur-direction 2)
+	  (discuss-show-trn prev))))))
+
+
+(defun discuss-nref ()
+  "Show next transaction in chain."
+  (interactive)
+  (if (or (not discuss-current-transaction)
+	  (= discuss-current-transaction 0))
+      (error "Not looking at transactions")
+    (let ((nref (nth 4 discuss-current-transaction-info)))
+      (if (= nref 0)
+	  (error "No next reference.")
+	(progn
+	  (setq discuss-cur-direction 3)
+	  (discuss-show-trn nref))))))
+
+(defun discuss-pref ()
+  "Show previous transaction in chain."
+  (interactive)
+  (if (or (not discuss-current-transaction)
+	  (= discuss-current-transaction 0))
+      (error "Not looking at transactions")
+    (let ((pref (nth 3 discuss-current-transaction-info)))
+      (if (= pref 0)
+	  (error "No previous reference.")
+	(progn
+	  (setq discuss-cur-direction 4)
+	  (discuss-show-trn pref))))))
+
+(defun discuss-lref ()
+  "Show last transaction in chain."
+  (interactive)
+  (if (or (not discuss-current-transaction)
+	  (= discuss-current-transaction 0))
+      (error "Not looking at transactions")
+    (let ((lref (nth 6 discuss-current-transaction-info)))
+      (if (= lref 0)
+	  (error "No last reference.")
+	(progn
+	  (setq discuss-cur-direction 4)
+	  (discuss-show-trn lref))))))
+
+(defun discuss-fref ()
+  "Show first transaction in chain."
+  (interactive)
+  (if (or (not discuss-current-transaction)
+	  (= discuss-current-transaction 0))
+      (error "Not looking at transactions")
+    (let ((fref (nth 5 discuss-current-transaction-info)))
+      (if (= fref 0)
+	  (error "No first reference.")
+	(progn
+	  (setq discuss-cur-direction 3)
+	  (discuss-show-trn fref))))))
+
+(defun discuss-first-trn ()
+  "Show first transaction of meeting."
+  (interactive)
+  (let ((first (nth 3 discuss-current-meeting-info)))
+    (setq discuss-cur-direction 1)
+    (discuss-show-trn first)))
+
+(defun discuss-last-trn ()
+  "Show last transaction of meeting."
+  (interactive)
+  (let ((last (nth 4 discuss-current-meeting-info)))
+    (setq discuss-cur-direction 2)
+    (discuss-show-trn last)))
+
+(defun discuss-toggle-trn-flag ()
+  "Toggle the per-transaction flag."
+  (interactive)
+  (let ((old-flag (nth 13 discuss-current-transaction-info)))
+    (if old-flag
+	(progn
+	  (discuss-send-cmd (format "(it %d %s)\n"
+				    discuss-current-transaction
+				    discuss-meeting)
+			    'nil 'discuss-read-form)
+	  (message "Toggling the transaction flag....")
+	  (discuss-send-cmd (format "(sfl %d %d %s)\n"
+				    (logxor old-flag 2)
+				    discuss-current-transaction
+				    discuss-meeting)
+			    'discuss-end-of-toggle 'discuss-read-form)))))
+
+(defun discuss-end-of-toggle ()
+  (discuss-show-trn discuss-current-transaction)
+  (message ""))
+
+(defun discuss-set-seen-and-leave-mtg (arg)
+  "Sets the highest transaction number seen in the current meeting to
+the argument or the current transaction and leaves the meeting."
+  (interactive "p")
+  (if (not discuss-cur-mtg-buf)
+      (error "Not looking at a meeting.")
+    (if current-prefix-arg
+	(setq discuss-highest-seen arg)
+      (setq discuss-highest-seen discuss-current-transaction))
+    (discuss-next-meeting t t)
+    (discuss-mark-unread-meeting discuss-current-meeting)
+    (discuss-leave-mtg)))
+
+(defun discuss-leave-mtg ()
+  "Leave the current discuss meeting."
+  (interactive)
+  (if (buffer-name discuss-cur-mtg-buf)
+      (progn
+	(set-buffer discuss-cur-mtg-buf)
+	(if (not (= discuss-highest-seen 0))
+	    (discuss-send-cmd (format "(ss %d %s)\n"
+				      discuss-highest-seen
+				      discuss-meeting)
+			      nil
+			      (if discuss-old-ss nil 'discuss-read-form)))
+	(kill-buffer (buffer-name discuss-cur-mtg-buf))
+	(setq discuss-cur-mtg-buf nil)
+	(setq discuss-current-meeting nil)
+	(if (and (not discuss-keep-discuss-ls) (get-buffer "*discuss-ls*"))
+	    (progn
+	      (delete-windows-on (get-buffer "*discuss-ls*"))
+	      (bury-buffer (get-buffer "*discuss-ls*"))))
+	(switch-to-buffer discuss-main-buffer))))
+
+(defun discuss-catchup (&optional meeting)
+  "Mark all messages in the current meeting as read."
+  (interactive
+   (list (or discuss-cur-mtg-buf
+	     (if (or current-prefix-arg (= (point) 1))
+		 (completing-read "Meeting name:  "
+				  discuss-meeting-completion-list
+				  nil t "")))))
+
+  ;; If meeting is nil or a string, we are in the *meetings* buffer.  Use the
+  ;; meeting on the current line.
+  (if (or (not meeting) (stringp meeting))
+      (let ((curline (- (count-lines 1 (min (1+ (point)) (point-max))) 3)))
+	(if meeting
+	    nil
+	  (if (< curline 0)
+	      (error "Not looking at a meeting."))
+	  (setq meeting (cadr (aref discuss-meeting-list curline))))
+	(message "Catching up in %s" meeting)
+	(discuss-send-cmd (format "(gmi %s)\n" meeting)
+			  'discuss-end-of-catchup 'discuss-read-form))
+    ;; Otherwise just set discuss-highest-seen.
+    (setq discuss-highest-seen (nth 6 discuss-current-meeting-info))
+    (discuss-mark-read-meeting (nth 1 discuss-current-meeting-info))
+    (discuss-next-meeting t)
+    (discuss-leave-mtg)
+    ))
+
+(defun discuss-end-of-catchup ()
+  (let ((meeting (nth 1 discuss-form))
+	(highest (nth 6 discuss-form)))
+    (discuss-send-cmd (format "(ss %d %s)\n" highest meeting)
+		      nil
+		      (if discuss-old-ss nil 'discuss-read-form))
+    (discuss-mark-read-meeting meeting)
+    (discuss-next-meeting t)
+    (message "Done.")
+    ))
+
+(defun discuss-delete-trn-backwards (trn-num)
+  (interactive
+   (cond (current-prefix-arg
+	  (if discuss-cur-mtg-buf
+	      (list (string-to-int (read-input "Transaction to delete: ")))
+	    (error "Not currently visiting a meeting.")))
+	 ((eq (current-buffer) discuss-cur-mtg-buf)
+	  (list discuss-current-transaction))
+	 (t
+	  (if discuss-cur-mtg-buf
+	      (list (string-to-int (read-input "Transaction to delete: ")))
+	    (error "Not currently visiting a meeting.")))
+	 ))
+  (discuss-delete-trn trn-num t))
+
+(defun discuss-delete-trn (trn-num &optional backwards)
+  (interactive
+   (cond (current-prefix-arg
+	  (if discuss-cur-mtg-buf
+	      (list (string-to-int (read-input "Transaction to delete: ")))
+	    (error "Not currently visiting a meeting.")))
+	 ((eq (current-buffer) discuss-cur-mtg-buf)
+	  (list discuss-current-transaction))
+	 (t
+	  (if discuss-cur-mtg-buf
+	      (list (string-to-int (read-input "Transaction to delete: ")))
+	    (error "Not currently visiting a meeting.")))
+	 ))
+  ;; Probably we should make sure the transaction can be deleted before
+  ;; asking this question, but the cache code is too confusing...
+  (if (and discuss-safe-delete
+	   (not (yes-or-no-p (format "Delete transaction %d? " trn-num))))
+      nil
+    (let ((info discuss-current-transaction-info)
+	  other)
+      (if (and info
+	       (= discuss-current-transaction trn-num))
+	  (progn
+	    (if backwards
+		(setq discuss-current-transaction (cadr info)
+		      other (caddr info))
+	      (setq discuss-current-transaction (caddr info)
+		    other (cadr info)))
+	    (if (= discuss-current-transaction 0)
+		(setq discuss-current-transaction other))
+	    (if (= discuss-current-transaction 0)
+		(progn
+		  (message "No more transactions in meeting!")
+		  (beep)))
+	    ))
+      (discuss-send-cmd (format "(itn %d %s)\n"
+				trn-num
+				discuss-meeting)
+			'nil 'discuss-read-form)
+      (message "Deleting %d...." trn-num)
+      (discuss-send-cmd (format "(dt %d %s)\n" trn-num discuss-meeting)
+			'discuss-end-del-trn 'discuss-read-form))))
+
+(defun discuss-end-del-trn ()
+  (message "Done.")
+  (discuss-show-trn discuss-current-transaction))
+
+(defun discuss-retrieve-trn (trn-num)
+  "Retrieve a deleted transaction."
+  (interactive "nTransaction to retrieve: ")
+  (setq discuss-current-transaction trn-num)
+  (message "Retrieving %d...." trn-num)
+  (discuss-send-cmd (format "(rt %d %s)\n" trn-num discuss-meeting)
+		    'discuss-end-rt-trn 'discuss-read-form))
+
+(defun discuss-end-rt-trn ()
+  (message "Done.")
+  (discuss-send-cmd (format "(itn %d %s)\n"
+			    discuss-current-transaction
+			    discuss-meeting)
+		    'nil 'discuss-read-form)
+  (discuss-show-trn discuss-current-transaction))
+
+(defun discuss-la-invalidate-relatives (trn-num)
+  (discuss-send-cmd (format "(itn %d %s)\n"
+			    trn-num
+			    discuss-meeting)
+		    'nil 'discuss-read-form)
+  )
+
+(defun discuss-format-trn-num (num)
+  (format "[%s%d]"
+	  (cond ((<= num 9) "000")
+		((<= num 99) "00")
+		((<= num 999) "0")
+		(t ""))
+	  num))
+
+;;; Discuss DWIM
+(defun discuss-scroll-up ()
+  (interactive)
+  (condition-case err
+      (scroll-up nil)
+    (error
+     (if (and discuss-DWIM
+	      (equal err '(end-of-buffer)))
+	 (if (equal discuss-current-transaction
+		    (nth 4 discuss-current-meeting-info))
+	     (discuss-leave-mtg)
+	   (discuss-next-trn))
+       (signal (car err) (cdr err))))))
+
+
+;;; Routines for communicating with slave process.  Since things are
+;;; asynchronous when communicating with the process, we may have to
+;;; spin on a flag if something else is in progress.
+;;;
+;;; The optional arguments to discuss-send-cmd are a function to be
+;;; called by the filter-func when the end-of-operation is seen and a
+;;; function to be used as a filter (it gets called with the process and
+;;; a string when the process outputs something.
+;;;
+;;; It is possible that if discuss-in-progress gets set to true
+;;; accidentally that things could get deadlocked; I think that can be
+;;; avoided in the purely, but I'm not sure.. (knowing how easily elisp
+;;; breaks unexpectedly, I should put in a lock timeout and a function to
+;;; unlock things).
+
+(defun discuss-restart ()
+  "Used to save the world when edsc gets hung or dies...
+
+Flushes the discuss cache and destroys the edsc process."
+  (interactive)
+  (if (and discuss-process
+	   (equal (process-status discuss-process) 'run))
+      (send-string discuss-process "(quit)\n"))
+  (setq discuss-process nil
+	discuss-in-progress nil))
+
+(defun discuss-send-cmd (cmd &optional end-func filter-func unwind-func)
+  "Send an command to the edsc process."
+  (if (not discuss-process)
+      (let ((process-connection-type nil))
+	(if (not (file-exists-p discuss-pathname))
+	    (error "%s does not exist!" discuss-pathname))
+	(setq discuss-process (start-process "discuss-shell"
+					     nil
+					     discuss-pathname))
+	(set-process-sentinel discuss-process 'discuss-edsc-sentinel)
+	(discuss-send-cmd "(gpv)\n" nil 'discuss-read-form)
+	(discuss-block-til-ready t)
+	(let* ((discuss-vers (cond (discuss-form
+				    (car discuss-form))
+				   ((equal discuss-error
+					  "Unimplemented operation")
+				    10)
+				   (t
+				    (error "Edsc returned error: %s"
+					   discuss-error))))
+	       (ver-string
+		(format "%d.%d"
+			(/ discuss-vers 10)
+			(- discuss-vers (* (/ discuss-vers 10) 10)))))
+	  (if (> 23 discuss-vers)
+	      (setq discuss-version-string "")
+	    (setq discuss-version-string (cadr discuss-form)))
+	  (setq discuss-old-ss (= 23 discuss-vers))
+	  (if (> 25 discuss-vers)
+	      (progn
+		(discuss-restart)
+		(error
+		 "Bad version of edsc (%s) --- you need at least version 2.5."
+		 ver-string))
+	    (progn
+	      (message "Started edsc process.... version %s %s)"
+		       ver-string discuss-version-string)
+	      (sit-for 1))))))
+
+  ;; block until we have control over things..
+  (discuss-block-til-ready t)
+  (if filter-func
+      (setq discuss-in-progress t))
+  (save-excursion
+    (setq discuss-debug-cmd cmd)
+    (setq discuss-reading-string "")
+    (setq discuss-cont end-func)
+    (setq discuss-unwind unwind-func)
+    (if filter-func (set-process-filter discuss-process filter-func))
+    (send-string discuss-process cmd)))
+
+(defun discuss-block-til-ready (verbose)
+  "Block, waiting until the previous operation for discuss finished.
+If VERBOSE is non-nil, then print a message that we're waiting for the
+discuss server while we spin-block."
+  (if discuss-in-progress
+      (progn
+	(while discuss-in-progress
+	  (if verbose
+	      (message "waiting for discuss..."))
+	  (sit-for 1)
+	  (accept-process-output))
+	(message ""))))
+
+;;;
+;;; This gets called when something nasty has happened to our edsc.
+;;;
+(defun discuss-edsc-sentinel (process signal)
+  (let ((buffer (process-buffer process))
+	(status (process-status process)))
+    (cond
+     ((eq status 'exit)
+      (discuss-restart))
+     ((eq status 'signal)
+      (ding)
+      (message "discuss-shell: %s."
+	       (substring signal 0 -1))
+      (discuss-restart))
+     )))
+
+;;; Routines to filter the output from discuss.
+;;; These are pretty simplistic
+
+(defun discuss-read-form (process string)
+  (setq discuss-reading-string (concat discuss-reading-string string))
+  (let* ((end-of-line (string-match "\n" discuss-reading-string)))
+    (if end-of-line
+	(let ((flag-char (substring discuss-reading-string 0 1))
+	      (first-line (substring discuss-reading-string 1
+				     end-of-line)))
+	  (setq discuss-error nil)
+	  (cond ((equal flag-char "-") ; warning
+		 (message first-line)
+		 (setq discuss-reading-string
+		       (substring discuss-reading-string (1+ end-of-line)))
+		 (discuss-read-form process ""))
+                ((equal flag-char "l") ; Sun os ld.so warning crock
+                 (message "l" first-line)
+                 (setq discuss-reading-string
+                       (substring discuss-reading-string (1+ end-of-line)))
+                 (discuss-read-form process ""))
+		((equal flag-char ";") ; error
+		 (setq discuss-error first-line)
+		 (message discuss-error)
+		 (ding)
+		 (setq discuss-reading-string
+		       (substring discuss-reading-string (1+ end-of-line)))
+		 (setq discuss-in-progress nil)
+		 (setq discuss-form nil)
+		 (if discuss-unwind
+		     (apply discuss-unwind nil)))
+		(t
+		 (setq discuss-form
+		       (car (read-from-string (concat "(" first-line))))
+		 (setq discuss-in-progress nil)
+		 (if discuss-cont
+		     (apply discuss-cont nil))))))))
+
+
+; run this at each load
+(defun discuss-initialize nil
+  (setq discuss-version
+	"$Id: discuss.el,v 1.41 1999-06-04 14:11:13 danw Exp $")
+
+;;;
+;;; Lots of autoload stuff....
+;;;
+
+(autoload 'discuss-talk (concat discuss-source-dir "discuss-enter")
+	  "Enter a new discuss transaction." t)
+
+(autoload 'discuss-reply (concat discuss-source-dir "discuss-enter")
+	  "Reply to an existing discuss transaction." t)
+
+(autoload 'discuss-randrp (concat discuss-source-dir "discuss-enter")
+	  "Random reply in a meeting." t)
+
+(autoload 'discuss-ls (concat discuss-source-dir "discuss-ls")
+	  "List the headings of the transactions in a meeting." t)
+
+(autoload 'discuss-list-acl (concat discuss-source-dir "discuss-acl")
+	  "List the ACL of a meeting." t)
+
+(autoload 'discuss-forward (concat discuss-source-dir "discuss-misc")
+	  "Forward a transaction via mail." t)
+
+(autoload 'discuss-forward-to-meeting
+	  (concat discuss-source-dir "discuss-misc")
+	  "Forward a transaction to another discuss meeting." t)
+
+(autoload 'discuss-reply-by-mail (concat discuss-source-dir "discuss-misc")
+	  "Forward a transaction via mail." t)
+
+(autoload 'discuss-add-mtg (concat discuss-source-dir "discuss-misc")
+	  "Add a discuss meeting" t)
+
+(autoload 'discuss-del-mtg (concat discuss-source-dir "discuss-misc")
+	  "Delete a discuss meeting" t)
+
+;;; Keymaps, here at the end, where the trash belongs..
+
+(if discuss-mtgs-mode-map
+    nil
+  (setq discuss-mtgs-mode-map (make-keymap))
+  (suppress-keymap discuss-mtgs-mode-map)
+  (define-key discuss-mtgs-mode-map "a" 'discuss-add-mtg)
+  (define-key discuss-mtgs-mode-map "d" 'discuss-del-mtg)
+  (define-key discuss-mtgs-mode-map "n" 'discuss-forward-meeting)
+  (define-key discuss-mtgs-mode-map "p" 'discuss-prev-meeting)
+  (define-key discuss-mtgs-mode-map " " 'discuss-next-meeting)
+  (define-key discuss-mtgs-mode-map "\177" 'discuss-prev-meeting)
+  (define-key discuss-mtgs-mode-map "l" 'discuss-lsm)
+  (define-key discuss-mtgs-mode-map "g" 'discuss-goto)
+  (define-key discuss-mtgs-mode-map "q" 'discuss-quit)
+  (define-key discuss-mtgs-mode-map "s" 'discuss-stat)
+  (define-key discuss-mtgs-mode-map "c" 'discuss-catchup)
+  (define-key discuss-mtgs-mode-map "?" 'describe-mode))
+
+(if discuss-trn-mode-map
+    nil
+  (setq discuss-trn-mode-map (make-keymap))
+  (suppress-keymap discuss-trn-mode-map)
+  (define-key discuss-trn-mode-map "." 'discuss-update)
+  (define-key discuss-trn-mode-map "," 'discuss-show-trn-with-headers)
+  (define-key discuss-trn-mode-map " " 'discuss-scroll-up)
+  (define-key discuss-trn-mode-map "\177" 'scroll-down)
+  (define-key discuss-trn-mode-map "n" 'discuss-next-trn)
+  (define-key discuss-trn-mode-map "p" 'discuss-prev-trn)
+  (define-key discuss-trn-mode-map "d" 'discuss-delete-trn)
+  (define-key discuss-trn-mode-map "R" 'discuss-retrieve-trn)
+  (define-key discuss-trn-mode-map "\M-n" 'discuss-nref)
+  (define-key discuss-trn-mode-map "\M-p" 'discuss-pref)
+  (define-key discuss-trn-mode-map "g" 'discuss-show-trn)
+  (define-key discuss-trn-mode-map "<" 'discuss-first-trn)
+  (define-key discuss-trn-mode-map ">" 'discuss-last-trn)
+  (define-key discuss-trn-mode-map "f" 'discuss-forward)
+  (define-key discuss-trn-mode-map "F" 'discuss-toggle-trn-flag)
+  (define-key discuss-trn-mode-map "h" 'discuss-trn-summary)
+  (define-key discuss-trn-mode-map "\e\C-h" 'discuss-trn-summary)
+  (define-key discuss-trn-mode-map "t" 'discuss-talk)
+  (define-key discuss-trn-mode-map "r" 'discuss-reply)
+  (define-key discuss-trn-mode-map "\C-c\C-r" 'discuss-randrp)
+  (define-key discuss-trn-mode-map "\M-r" 'discuss-reply-by-mail)
+  (define-key discuss-trn-mode-map "\C-o" 'discuss-trn-output)
+  (define-key discuss-trn-mode-map "i" 'discuss-trn-input)
+  (define-key discuss-trn-mode-map "q" 'discuss-leave-mtg)
+  (define-key discuss-trn-mode-map "?" 'describe-mode)
+  (define-key discuss-trn-mode-map "s" 'discuss-stat)
+  (define-key discuss-trn-mode-map "a" 'discuss-add-mtg)
+  (define-key discuss-trn-mode-map "\C-d" 'discuss-delete-trn-backwards)
+  (define-key discuss-trn-mode-map "\M-f" 'discuss-fref)
+  (define-key discuss-trn-mode-map "\M-l" 'discuss-lref)
+  (define-key discuss-trn-mode-map "=" 'discuss-ls)
+  (define-key discuss-trn-mode-map "c" 'discuss-catchup)
+  (define-key discuss-trn-mode-map "l" 'discuss-set-seen-and-leave-mtg)
+)
+
+
+  (fmakunbound 'discuss-initialize)
+  )					;end of discuss-initialize
+(discuss-initialize)
+
+;;; discuss-trn-output mostly stolen from rmail-output...
+;;; converted by [eichin:19881026.1505EST]
+;(defvar discuss-output-last-file nil
+;  "*Default file for discuss saves")
+
+(defun discuss-trn-output (file-name)
+  "Append this message to file named FILE-NAME."
+  (interactive
+   (list
+    (read-file-name
+     (concat "Append to: (default "
+	     (file-name-nondirectory discuss-output-last-file)
+	     ") ")
+     (file-name-directory discuss-output-last-file)
+     discuss-output-last-file)))
+  (setq file-name (expand-file-name file-name))
+  (setq discuss-output-last-file file-name)
+  (let ((discuss-trn-buf (current-buffer))
+	(tembuf (get-buffer-create " discuss-trn-output"))
+	(case-fold-search t))
+    (save-excursion
+      (set-buffer tembuf)
+      (erase-buffer)
+      (insert-buffer-substring discuss-trn-buf)
+      (goto-char (point-max))
+      (insert "\n")			;other modifying here as well
+      (append-to-file (point-min) (point-max) file-name))
+    (kill-buffer tembuf)))
+
+;;;
+;;; this is just a quick hack, but I don't see an `better' way to do it...
+;;;
+(defun discuss-next-meeting (&optional quiet dontgo)
+  "Find the next changed meeting in the discuss *meetings* buffer, or wrap."
+  (interactive)
+  (let ((buffer (current-buffer)))
+    (set-buffer discuss-main-buffer)
+    ;; If we're in DWIM mode, and we're currently looking at a changed
+    ;; meeting, go to it.
+    (if (and discuss-DWIM
+	     (not dontgo)
+	     (re-search-backward "^ c" (save-excursion (beginning-of-line)
+						       (point))
+				 t))
+	(discuss-goto)
+      (if (not (re-search-forward "^ c " nil t))
+	  (progn
+	    (goto-char (point-min))
+	    (if (not (re-search-forward "^ c " nil t))
+		(if (not quiet)
+		    (message "No new meetings, try discuss-lsm instead."))
+	      ))))
+    (set-buffer buffer)))
+
+(defun discuss-forward-meeting (&optional quiet)
+  "Find the next changed meeting in the discuss *meetings* buffer, or wrap."
+  (interactive)
+  (let ((discuss-DWIM nil))
+    (discuss-next-meeting quiet)))
+
+(defun discuss-prev-meeting ()
+  "Find the previous changed meeting in the discuss *meetings* buffer, or wrap."
+  (interactive)
+  (beginning-of-line)
+  (if (not (re-search-backward "^ c " nil t))
+      (progn
+	(goto-char (point-max))
+	(if (not (re-search-backward "^ c " nil t))
+	    (message "No new meetings, try discuss-lsm instead.")
+	  )))
+  (forward-char 3))
+
+(defun discuss-mark-read-meeting (meeting &optional inschar)
+  "Mark a meeting as read on the discuss-mode listing.  An optional
+argument means insert that character instead of a space before the
+meeting (usually a c)."
+  (setq inschar (or inschar ?\ ))
+  (save-excursion
+    (set-buffer discuss-main-buffer)
+    (goto-char (point-min))
+    (if (not (re-search-forward (concat " " (regexp-quote meeting)
+					"\\(,\\|$\\)")
+			     nil t))
+	(progn
+	  (ding)
+	  (message "Couldn't update changed flag for meeting %s." meeting))
+      (beginning-of-line)
+      (forward-char 1)
+      (let ((buffer-read-only nil))
+	(insert-char inschar 1)
+	(delete-char 1)
+	))))
+
+(defun discuss-mark-unread-meeting (meeting)
+  "Mark a meeting as unread on the discuss-mode listing."
+  (discuss-mark-read-meeting meeting ?c))


Property changes on: trunk/athena/bin/discuss/edsc/discuss.el.in
___________________________________________________________________
Name: svn:mergeinfo
   + 


home help back first fref pref prev next nref lref last post