Synch with Oort Gnus.
authoryamaoka <yamaoka>
Mon, 29 Jul 2002 00:12:21 +0000 (00:12 +0000)
committeryamaoka <yamaoka>
Mon, 29 Jul 2002 00:12:21 +0000 (00:12 +0000)
lisp/ChangeLog
lisp/flow-fill.el
lisp/gnus-sieve.el
lisp/nnweb.el
lisp/sieve-manage.el
lisp/sieve.el

index 50cb2d4..63bbdcb 100644 (file)
@@ -1,3 +1,34 @@
+2002-07-28  Kai Gro\e,b_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+       From Niklas Morberg <niklas.morberg@axis.com>.
+
+       * nnweb.el (nnweb-type, nnweb-type-definition)
+       (nnweb-gmane-create-mapping, nnweb-gmane-wash-article)
+       (nnweb-gmane-search, nnweb-gmane-identity): Added gmane
+       functionality.
+       * nnweb.el: Removed old non-functioning search engines.
+
+2002-07-27  Simon Josefsson  <jas@extundo.com>
+
+       * message.el (message-forward-make-body): Don't use
+       `message-forward-ignored-headers' when doing a "raw" followup (it
+       is important to preserve e.g. CTE).
+
+       * flow-fill.el (fill-flowed): Disable filladapt-mode.
+
+       * gnus-sieve.el (gnus-sieve-guess-rule-for-article): Don't
+       regexp-quote, Cyrus Sieve is fixed.
+
+       * sieve-manage.el (sieve-manage-deletescript): New function.
+
+       * sieve.el (sieve-manage-mode-map): Fix down-mouse-2 and down-mouse-3.  
+       (sieve-manage-mode): Fix menubar.
+       (sieve-activate): Change some messages.
+       (sieve-deactivate-all): New function.
+       (sieve-deactivate): New alias.
+       (sieve-remove): New function.
+       (sieve-help): Fix help.
+       All suggested by Ned Ludd.
+
 2002-07-24  Katsumi Yamaoka <yamaoka@jpl.org>
 
        * mm-decode.el (mm-inline-text-html-with-images): Doc fix.
index c72ad40..5dca163 100644 (file)
@@ -136,7 +136,8 @@ RFC 2646 suggests 66 characters for readability."
          (unless sig
            (condition-case nil
                (let ((fill-prefix (when quote (concat quote " ")))
-                     (fill-column (eval fill-flowed-display-column)))
+                     (fill-column (eval fill-flowed-display-column))
+                     filladapt-mode)
                  (fill-region (fill-flowed-point-at-bol)
                               (min (1+ (fill-flowed-point-at-eol)) (point-max))
                               'left 'nosqueeze))
index 18300ed..2fb82f9 100644 (file)
@@ -118,7 +118,7 @@ See the documentation for these variables and functions for details."
   "Guess a sieve rule based on RFC822 article in buffer.
 Return nil if no rule could be guessed."
   (when (message-fetch-field "sender")
-    `(sieve address "sender" ,(regexp-quote (message-fetch-field "sender")))))
+    `(sieve address "sender" ,(message-fetch-field "sender"))))
 
 ;;;###autoload
 (defun gnus-sieve-article-add-rule ()
index 921398b..ece9640 100644 (file)
@@ -50,7 +50,7 @@
 
 (defvoo nnweb-type 'google
   "What search engine type is being used.
-Valid types include `google', `dejanews', `reference', and `altavista'.")
+Valid types include `google', `dejanews', and `gmane'.")
 
 (defvar nnweb-type-definition
   '((google
@@ -62,33 +62,25 @@ Valid types include `google', `dejanews', `reference', and `altavista'.")
      (address . "http://groups.google.com/groups")
      (identifier . nnweb-google-identity))
     (dejanews ;; alias of google
-     ;;(article . nnweb-google-wash-article)
-     ;;(id . "http://groups.google.com/groups?as_umsgid=%s")
      (article . ignore)
      (id . "http://groups.google.com/groups?selm=%s&output=gplain")
-     ;;(reference . nnweb-google-reference)
      (reference . identity)
      (map . nnweb-google-create-mapping)
      (search . nnweb-google-search)
      (address . "http://groups.google.com/groups")
      (identifier . nnweb-google-identity))
-    (reference
-     (article . nnweb-reference-wash-article)
-     (map . nnweb-reference-create-mapping)
-     (search . nnweb-reference-search)
-     (address . "http://www.reference.com/cgi-bin/pn/go")
-     (identifier . identity))
-    (altavista
-     (article . nnweb-altavista-wash-article)
-     (map . nnweb-altavista-create-mapping)
-     (search . nnweb-altavista-search)
-     (address . "http://www.altavista.digital.com/cgi-bin/query")
-     (id . "/cgi-bin/news?id@%s")
-     (identifier . identity)))
+    (gmane
+     (article . nnweb-gmane-wash-article)
+     (id . "http://gmane.org/view.php?group=%s")
+     (reference . identity)
+     (map . nnweb-gmane-create-mapping)
+     (search . nnweb-gmane-search)
+     (address . "http://gmane.org/")
+     (identifier . nnweb-gmane-identity)))
   "Type-definition alist.")
 
 (defvoo nnweb-search nil
-  "Search string to feed to DejaNews.")
+  "Search string to feed to Google.")
 
 (defvoo nnweb-max-hits 999
   "Maximum number of hits to display.")
@@ -311,385 +303,6 @@ Valid types include `google', `dejanews', `reference', and `altavista'.")
                       nnweb-type nnweb-search server))
              (current-buffer))))))
 
-;; (defun nnweb-fetch-url (url)
-;;   (let (buf)
-;;     (save-excursion
-;;       (if (not nnheader-callback-function)
-;;       (progn
-;;         (with-temp-buffer
-;;           (mm-enable-multibyte)
-;;           (let ((coding-system-for-read 'binary)
-;;                 (coding-system-for-write 'binary)
-;;                 (input-coding-system 'binary)
-;;                 (output-coding-system 'binary)
-;;                 (default-process-coding-system 'binary))
-;;             (nnweb-insert url))
-;;           (setq buf (buffer-string)))
-;;         (erase-buffer)
-;;         (insert buf)
-;;         t)
-;;     (nnweb-url-retrieve-asynch
-;;      url 'nnweb-callback (current-buffer) nnheader-callback-function)
-;;     t))))
-
-;; (defun nnweb-callback (buffer callback)
-;;   (when (gnus-buffer-live-p url-working-buffer)
-;;     (save-excursion
-;;       (set-buffer url-working-buffer)
-;;       (funcall (nnweb-definition 'article))
-;;       (nnweb-decode-entities)
-;;       (set-buffer buffer)
-;;       (goto-char (point-max))
-;;       (insert-buffer-substring url-working-buffer))
-;;     (funcall callback t)
-;;     (gnus-kill-buffer url-working-buffer)))
-
-;; (defun nnweb-url-retrieve-asynch (url callback &rest data)
-;;   (let ((url-request-method "GET")
-;;     (old-asynch url-be-asynchronous)
-;;     (url-request-data nil)
-;;     (url-request-extra-headers nil)
-;;     (url-working-buffer (generate-new-buffer-name " *nnweb*")))
-;;     (setq-default url-be-asynchronous t)
-;;     (save-excursion
-;;       (set-buffer (get-buffer-create url-working-buffer))
-;;       (setq url-current-callback-data data
-;;         url-be-asynchronous t
-;;         url-current-callback-func callback)
-;;       (url-retrieve url nil))
-;;     (setq-default url-be-asynchronous old-asynch)))
-
-;; (if (fboundp 'url-retrieve-synchronously)
-;;     (defun nnweb-url-retrieve-asynch (url callback &rest data)
-;;       (url-retrieve url callback data)))
-
-;;;
-;;; DejaNews functions.
-;;;
-
-(defun nnweb-dejanews-create-mapping ()
-  "Perform the search and create an number-to-url alist."
-  (save-excursion
-    (set-buffer nnweb-buffer)
-    (erase-buffer)
-    (when (funcall (nnweb-definition 'search) nnweb-search)
-      (let ((i 0)
-           (more t)
-           (case-fold-search t)
-           (active (or (cadr (assoc nnweb-group nnweb-group-alist))
-                       (cons 1 0)))
-           subject date from
-           map url parse a table group text)
-       (while more
-         ;; Go through all the article hits on this page.
-         (goto-char (point-min))
-         (setq parse (w3-parse-buffer (current-buffer))
-               table (nth 1 (nnweb-parse-find-all 'table parse)))
-         (dolist (row (nth 2 (car (nth 2 table))))
-           (setq a (nnweb-parse-find 'a row)
-                 url (cdr (assq 'href (nth 1 a)))
-                 text (nreverse (nnweb-text row)))
-           (when a
-             (setq subject (nth 4 text)
-                   group (nth 2 text)
-                   date (nth 1 text)
-                   from (nth 0 text))
-             (if (string-match "\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)" date)
-                 (setq date (format "%s %s 00:00:00 %s"
-                                    (car (rassq (string-to-number
-                                                 (match-string 2 date))
-                                                parse-time-months))
-                                    (match-string 3 date)
-                                    (match-string 1 date)))
-               (setq date "Jan 1 00:00:00 0000"))
-             (incf i)
-             (setq url (concat url "&fmt=text"))
-             (when (string-match "&context=[^&]+" url)
-               (setq url (replace-match "" t t url)))
-             (unless (nnweb-get-hashtb url)
-               (push
-                (list
-                 (incf (cdr active))
-                 (make-full-mail-header
-                  (cdr active) (concat subject " (" group ")") from date
-                  (concat "<" (nnweb-identifier url) "@dejanews>")
-                  nil 0 0 url))
-                map)
-               (nnweb-set-hashtb (cadar map) (car map)))))
-         ;; See whether there is a "Get next 20 hits" button here.
-         (goto-char (point-min))
-         (if (or (not (re-search-forward
-                       "HREF=\"\\([^\"]+\\)\"[<>b]+Next result" nil t))
-                 (>= i nnweb-max-hits))
-             (setq more nil)
-           ;; Yup -- fetch it.
-           (setq more (match-string 1))
-           (erase-buffer)
-           (mm-url-insert more)))
-       ;; Return the articles in the right order.
-       (setq nnweb-articles
-             (sort (nconc nnweb-articles map) 'car-less-than-car))))))
-
-(defun nnweb-dejanews-search (search)
-  (mm-url-insert
-   (concat
-    (nnweb-definition 'address)
-    "?"
-    (mm-url-encode-www-form-urlencoded
-     `(("ST" . "PS")
-       ("svcclass" . "dnyr")
-       ("QRY" . ,search)
-       ("defaultOp" . "AND")
-       ("DBS" . "1")
-       ("OP" . "dnquery.xp")
-       ("LNG" . "ALL")
-       ("maxhits" . "100")
-       ("threaded" . "0")
-       ("format" . "verbose2")
-       ("showsort" . "date")
-       ("agesign" . "1")
-       ("ageweight" . "1")))))
-  t)
-
-;; (defun nnweb-dejanewsold-search (search)
-;;   (nnweb-fetch-form
-;;    (nnweb-definition 'address)
-;;    `(("query" . ,search)
-;;      ("defaultOp" . "AND")
-;;      ("svcclass" . "dnold")
-;;      ("maxhits" . "100")
-;;      ("format" . "verbose2")
-;;      ("threaded" . "0")
-;;      ("showsort" . "date")
-;;      ("agesign" . "1")
-;;      ("ageweight" . "1")))
-;;   t)
-
-(defun nnweb-dejanews-identity (url)
-  "Return an unique identifier based on URL."
-  (if (string-match "AN=\\([0-9]+\\)" url)
-      (match-string 1 url)
-    url))
-
-;;;
-;;; InReference
-;;;
-
-(defun nnweb-reference-create-mapping ()
-  "Perform the search and create an number-to-url alist."
-  (save-excursion
-    (set-buffer nnweb-buffer)
-    (erase-buffer)
-    (when (funcall (nnweb-definition 'search) nnweb-search)
-      (let ((i 0)
-           (more t)
-           (case-fold-search t)
-           (active (or (cadr (assoc nnweb-group nnweb-group-alist))
-                       (cons 1 0)))
-           Subject Score Date Newsgroups From Message-ID
-           map url)
-       (while more
-         ;; Go through all the article hits on this page.
-         (goto-char (point-min))
-         (search-forward "</pre><hr>" nil t)
-         (delete-region (point-min) (point))
-         (goto-char (point-min))
-         (while (re-search-forward "^ +[0-9]+\\." nil t)
-           (narrow-to-region
-            (point)
-            (if (re-search-forward "^$" nil t)
-                (match-beginning 0)
-              (point-max)))
-           (goto-char (point-min))
-           (when (looking-at ".*href=\"\\([^\"]+\\)\"")
-             (setq url (match-string 1)))
-           (mm-url-remove-markup)
-           (goto-char (point-min))
-           (while (search-forward "\t" nil t)
-             (replace-match " "))
-           (goto-char (point-min))
-           (while (re-search-forward "^\\([^:]+\\): \\(.*\\)$" nil t)
-             (set (intern (match-string 1)) (match-string 2)))
-           (widen)
-           (search-forward "</pre>" nil t)
-           (incf i)
-           (unless (nnweb-get-hashtb url)
-             (push
-              (list
-               (incf (cdr active))
-               (make-full-mail-header
-                (cdr active) (concat  "(" Newsgroups ") " Subject) From Date
-                Message-ID
-                nil 0 (string-to-int Score) url))
-              map)
-             (nnweb-set-hashtb (cadar map) (car map))))
-         (setq more nil))
-       ;; Return the articles in the right order.
-       (setq nnweb-articles
-             (sort (nconc nnweb-articles map) 'car-less-than-car))))))
-
-(defun nnweb-reference-wash-article ()
-  (let ((case-fold-search t))
-    (goto-char (point-min))
-    (re-search-forward "^</center><hr>" nil t)
-    (delete-region (point-min) (point))
-    (search-forward "<pre>" nil t)
-    (forward-line -1)
-    (let ((body (point-marker)))
-      (search-forward "</pre>" nil t)
-      (delete-region (point) (point-max))
-      (mm-url-remove-markup)
-      (goto-char (point-min))
-      (while (looking-at " *$")
-       (gnus-delete-line))
-      (narrow-to-region (point-min) body)
-      (while (and (re-search-forward "^$" nil t)
-                 (not (eobp)))
-       (gnus-delete-line))
-      (goto-char (point-min))
-      (while (looking-at "\\(^[^ ]+:\\) *")
-       (replace-match "\\1 " t)
-       (forward-line 1))
-      (goto-char (point-min))
-      (when (re-search-forward "^References:" nil t)
-       (narrow-to-region
-        (point) (if (re-search-forward "^$\\|^[^:]+:" nil t)
-                    (match-beginning 0)
-                  (point-max)))
-       (goto-char (point-min))
-       (while (not (eobp))
-         (unless (looking-at "References")
-           (insert "\t")
-           (forward-line 1)))
-       (goto-char (point-min))
-       (while (search-forward "," nil t)
-         (replace-match " " t t)))
-      (widen)
-      (mm-url-decode-entities)
-      (set-marker body nil))))
-
-(defun nnweb-reference-search (search)
-  (mm-url-insert
-   (concat
-    (nnweb-definition 'address)
-    "?"
-    (mm-url-encode-www-form-urlencoded
-     `(("search" . "advanced")
-       ("querytext" . ,search)
-       ("subj" . "")
-       ("name" . "")
-       ("login" . "")
-       ("host" . "")
-       ("organization" . "")
-       ("groups" . "")
-       ("keywords" . "")
-       ("choice" . "Search")
-       ("startmonth" . "Jul")
-       ("startday" . "25")
-       ("startyear" . "1996")
-       ("endmonth" . "Aug")
-       ("endday" . "24")
-       ("endyear" . "1996")
-       ("mode" . "Quick")
-       ("verbosity" . "Verbose")
-       ("ranking" . "Relevance")
-       ("first" . "1")
-       ("last" . "25")
-       ("score" . "50")))))
-  (setq buffer-file-name nil)
-  t)
-
-;;;
-;;; Alta Vista
-;;;
-
-(defun nnweb-altavista-create-mapping ()
-  "Perform the search and create an number-to-url alist."
-  (save-excursion
-    (set-buffer nnweb-buffer)
-    (erase-buffer)
-    (let ((part 0))
-      (when (funcall (nnweb-definition 'search) nnweb-search part)
-       (let ((i 0)
-             (more t)
-             (case-fold-search t)
-             (active (or (cadr (assoc nnweb-group nnweb-group-alist))
-                         (cons 1 0)))
-             subject date from id group
-             map url)
-         (while more
-           ;; Go through all the article hits on this page.
-           (goto-char (point-min))
-           (search-forward "<dt>" nil t)
-           (delete-region (point-min) (match-beginning 0))
-           (goto-char (point-min))
-           (while (search-forward "<dt>" nil t)
-             (replace-match "\n<blubb>"))
-           (mm-url-decode-entities)
-           (goto-char (point-min))
-           (while (re-search-forward "<blubb>.*href=\"\\([^\"]+\\)\"><strong>\\([^>]*\\)</strong></a><dd>\\([^-]+\\)- <b>\\([^<]+\\)<.*href=\"news:\\([^\"]+\\)\">.*\">\\(.+\\)</a><P>"
-                                     nil t)
-             (setq url (match-string 1)
-                   subject (match-string 2)
-                   date (match-string 3)
-                   group (match-string 4)
-                   id (concat "<" (match-string 5) ">")
-                   from (match-string 6))
-             (incf i)
-             (unless (nnweb-get-hashtb url)
-               (push
-                (list
-                 (incf (cdr active))
-                 (make-full-mail-header
-                  (cdr active) (concat  "(" group ") " subject) from date
-                  id nil 0 0 url))
-                map)
-               (nnweb-set-hashtb (cadar map) (car map))))
-           ;; See if we want more.
-           (when (or (not nnweb-articles)
-                     (>= i nnweb-max-hits)
-                     (not (funcall (nnweb-definition 'search)
-                                   nnweb-search (incf part))))
-             (setq more nil)))
-         ;; Return the articles in the right order.
-         (setq nnweb-articles
-               (sort (nconc nnweb-articles map) 'car-less-than-car)))))))
-
-(defun nnweb-altavista-wash-article ()
-  (goto-char (point-min))
-  (let ((case-fold-search t))
-    (when (re-search-forward "^<strong>" nil t)
-      (delete-region (point-min) (match-beginning 0)))
-    (goto-char (point-min))
-    (while (looking-at "<strong>\\([^ ]+\\) +</strong> +\\(.*\\)$")
-      (replace-match "\\1: \\2" t)
-      (forward-line 1))
-    (when (re-search-backward "^References:" nil t)
-      (narrow-to-region (point) (progn (forward-line 1) (point)))
-      (goto-char (point-min))
-      (while (re-search-forward "<A.*\\?id@\\([^\"]+\\)\">[0-9]+</A>" nil t)
-       (replace-match "&lt;\\1&gt; " t)))
-    (widen)
-    (mm-url-remove-markup)
-    (mm-url-decode-entities)))
-
-(defun nnweb-altavista-search (search &optional part)
-  (mm-url-insert
-   (concat
-    (nnweb-definition 'address)
-    "?"
-    (mm-url-encode-www-form-urlencoded
-     `(("pg" . "aq")
-       ("what" . "news")
-       ,@(when part `(("stq" . ,(int-to-string (* part 30)))))
-       ("fmt" . "d")
-       ("q" . ,search)
-       ("r" . "")
-       ("d0" . "")
-       ("d1" . "")))))
-  (setq buffer-file-name nil)
-  t)
-
 ;;;
 ;;; Deja bought by google.com
 ;;;
@@ -838,6 +451,71 @@ Valid types include `google', `dejanews', `reference', and `altavista'.")
     url))
 
 ;;;
+;;; gmane.org
+;;;
+(defun nnweb-gmane-create-mapping ()
+  "Perform the search and create a number-to-url alist."
+  (save-excursion
+    (set-buffer nnweb-buffer)
+    (erase-buffer)
+    (when (funcall (nnweb-definition 'search) nnweb-search)
+      (let ((more t)
+           (case-fold-search t)
+           (active (or (cadr (assoc nnweb-group nnweb-group-alist))
+                       (cons 1 0)))
+           subject group url
+           map)
+         ;; Remove stuff from the beginning of results
+       (goto-char (point-min))
+       (search-forward "Search Results</h1><ul>" nil t)
+       (delete-region (point-min) (point))
+       (goto-char (point-min))
+       ;; Iterate over the actual hits
+       (while (re-search-forward ".*href=\"\\([^\"]+\\)\">\\(.*\\)" nil t)
+           (setq url (concat "http://gmane.org/" (match-string 1)))
+           (setq subject (match-string 2))
+         (unless (nnweb-get-hashtb url)
+           (push
+            (list
+             (incf (cdr active))
+             (make-full-mail-header
+              (cdr active) (concat  "(" group ") " subject) nil nil
+              nil nil 0 0 url))
+            map)
+           (nnweb-set-hashtb (cadar map) (car map))))
+       ;; Return the articles in the right order.
+       (setq nnweb-articles
+             (sort (nconc nnweb-articles map) 'car-less-than-car))))))
+
+(defun nnweb-gmane-wash-article ()
+  (let ((case-fold-search t))
+    (goto-char (point-min))
+    (re-search-forward "<!--X-Head-of-Message-->" nil t)
+    (delete-region (point-min) (point))
+    (goto-char (point-min))
+    (while (looking-at "^<li><em>\\([^ ]+\\)</em>.*</li>")
+      (replace-match "\\1\\2" t)
+      (forward-line 1))
+    (mm-url-remove-markup)))
+
+(defun nnweb-gmane-search (search)
+  (mm-url-insert
+   (concat
+    (nnweb-definition 'address)
+    "?"
+    (mm-url-encode-www-form-urlencoded
+     `(("query" . ,search)))))
+  (setq buffer-file-name nil)
+  t)
+
+
+(defun nnweb-gmane-identity (url)
+  "Return a unique identifier based on URL."
+  (if (string-match "group=\\(.+\\)" url)
+      (match-string 1 url)
+    url))
+
+;;;
 ;;; General web/w3 interface utility functions
 ;;;
 
index 6f91f5b..967c721 100644 (file)
@@ -42,6 +42,8 @@
 ;;
 ;; `sieve-manage-authenticate'
 ;; `sieve-manage-listscripts'
+;; `sieve-manage-deletescript'
+;; `sieve-manage-getscript'
 ;; performs managesieve protocol actions
 ;;
 ;; and that's it.  Example of a managesieve session in *scratch*:
@@ -64,6 +66,7 @@
 ;; Release history:
 ;;
 ;; 2001-10-31 Committed to Oort Gnus.
+;; 2002-07-27 Added DELETESCRIPT.  Suggested by Ned Ludd.
 
 ;;; Code:
 
@@ -501,6 +504,11 @@ password is remembered in the buffer."
                               sieve-manage-client-eol content))
     (sieve-manage-parse-okno)))
 
+(defun sieve-manage-deletescript (name &optional buffer)
+  (with-current-buffer (or buffer (current-buffer))
+    (sieve-manage-send (format "DELETESCRIPT \"%s\"" name))
+    (sieve-manage-parse-okno)))
+
 (defun sieve-manage-getscript (name output-buffer &optional buffer)
   (with-current-buffer (or buffer (current-buffer))
     (sieve-manage-send (format "GETSCRIPT \"%s\"" name))
index bb78008..f41fa7c 100644 (file)
 ;; Release history:
 ;;
 ;; 2001-10-31 Committed to Oort Gnus.
+;; 2002-07-27 Fix down-mouse-2 and down-mouse-3 in manage-mode.  Fix menubar
+;;            in manage-mode.  Change some messages.  Added sieve-deactivate*,
+;;            sieve-remove.  Fixed help text in manage-mode.  Suggested by
+;;            Ned Ludd.
 ;;
 ;; Todo:
 ;;
@@ -124,14 +128,15 @@ require \"fileinto\";
   (define-key sieve-manage-mode-map "f" 'sieve-edit-script)
   (define-key sieve-manage-mode-map "o" 'sieve-edit-script-other-window)
   (define-key sieve-manage-mode-map "r" 'sieve-remove)
-  (define-key sieve-manage-mode-map [mouse-2] 'sieve-edit-script)
-  (define-key sieve-manage-mode-map [(down-mouse-3)] 'sieve-menu))
+  (define-key sieve-manage-mode-map [(down-mouse-2)] 'sieve-edit-script)
+  (define-key sieve-manage-mode-map [(down-mouse-3)] 'sieve-manage-mode-menu))
 
 (define-derived-mode sieve-manage-mode fundamental-mode "SIEVE"
   "Mode used for sieve script management."
   (setq mode-name "SIEVE")
   (buffer-disable-undo (current-buffer))
-  (setq truncate-lines t))
+  (setq truncate-lines t)
+  (easy-menu-add-item nil nil sieve-manage-mode-menu))
 
 (put 'sieve-manage-mode 'mode-class 'special)
 
@@ -151,13 +156,38 @@ require \"fileinto\";
 (defun sieve-activate (&optional pos)
   (interactive "d")
   (let ((name (sieve-script-at-point)) err)
-    (unless name
+    (when (or (null name) (string-equal name sieve-new-script))
       (error "No sieve script at point"))
+    (message "Activating script %s..." name)
     (setq err (sieve-manage-setactive name sieve-manage-buffer))
+    (sieve-refresh-scriptlist)
+    (if (sieve-manage-ok-p err)
+       (message "Activating script %s...done" name)
+      (message "Activating script %s...failed: %s" name (nth 2 err)))))
+
+(defun sieve-deactivate-all (&optional pos)
+  (interactive "d")
+  (let ((name (sieve-script-at-point)) err)
+    (message "Deactivating scripts...")
+    (setq err (sieve-manage-setactive "" sieve-manage-buffer))
+    (sieve-refresh-scriptlist)
     (if (sieve-manage-ok-p err)
-       (message "Script %s activated." name)
-      (message "Failed to activate script %s: %s" name (nth 2 err)))
-    (sieve-refresh-scriptlist)))
+       (message "Deactivating scripts...done")
+      (message "Deactivating scripts...failed" (nth 2 err)))))
+
+(defalias 'sieve-deactivate 'sieve-deactivate-all)
+
+(defun sieve-remove (&optional pos)
+  (interactive "d")
+  (let ((name (sieve-script-at-point)) err)
+    (when (or (null name) (string-equal name sieve-new-script))
+      (error "No sieve script at point"))
+    (message "Removing sieve script %s..." name)
+    (setq err (sieve-manage-deletescript name sieve-manage-buffer))
+    (unless (sieve-manage-ok-p err)
+      (error "Removing sieve script %s...failed: " err))
+    (sieve-refresh-scriptlist)
+    (message "Removing sieve script %s...done" name)))
 
 (defun sieve-edit-script (&optional pos)
   (interactive "d")
@@ -214,7 +244,7 @@ Used to bracket operations which move point in the sieve-buffer."
       ;; would need minor-mode for log-edit-mode
       (describe-function 'sieve-mode)
     (message (substitute-command-keys
-             "`\\[sieve-help]':help `\\[cvs-mode-add]':add `\\[sieve-remove]':remove"))))
+             "`\\[sieve-edit-script]':edit `\\[sieve-activate]':activate `\\[sieve-deactivate]':deactivate `\\[sieve-remove]':remove"))))
 
 (defun sieve-bury-buffer (buf &optional mainbuf)
   "Hide the buffer BUF that was temporarily popped up.