[Mew-dist 1312] pack and sort in background

UMEMURA Akihiro akihiro at example.com
1997年 7月 24日 (木) 18:51:46 JST


こんにちは。
人によって Mew の使い方も違うのでしょうが、
私は pack をしばしば使います。

このことに関して、今まで
 (1) pack している間何もできないのと、
 (2) pack 後の scan (imls) が、update と指定しても結局
     folder 全部を scan してしまう
のが、どうも使いにくく思っていました。

(2)については、もし、impack の方から「どの番号から pack を
始めたか」を教えてもらえれば、そこから scan を始めればよいので
す。

というわけで、(1)と(2)の問題に一応の解決を与えたものを
作ってみました。sort についても同様の処理ができるので
一緒に作ってみました。いかがでしょうか?

なお、細かい仕様の決め方はかなりいいかげんですので、いろいろ
直していただいた方がいいような気もします。
例えば impack と imsort に --diff という option を与えると
ちょっと diff っぽい出力を返すようにした(この出力を拾って
scan に使う)のですが、これなどは --no-harm に合わせた方が
いいのかもしれません。また英語のメッセージも変かもしれません。

さらに UNIX 系以外の OS の場合は動くのかどうかはちょっと解りません。

とまあ、いろいろ改良は必要かもしれませんが、本体に採用する方
向で検討していただければ幸いです。

pick についても同様に backgroud 化することはできると思います
が、まだやってはいません。

(以下の part は mew-1.86 と im-46 に対応する patch です。
何か私の diff の使い方は変な気がします。どなたか正しい
patch の作り方を教えてください。)
*****************************************************************
  NTT基礎研究所情報科学研究部  0462-40-3663 (厚木市森の里若宮)
           梅村晃広               akihiro at example.com
-------------- next part --------------
--- impack.org	Tue Jul 22 12:57:20 1997
+++ impack	Wed Jul 23 15:17:50 1997
@@ -44,6 +44,7 @@
    'src;F;;'    => "Set source folder.",
    'noharm;b;;' => "No packing. Show what will happen.",
    'help;b;;'   => "Show this message.",
+   'diff;b;;' => "Show packing diff.",	     
     );
 
 ##
@@ -80,10 +81,15 @@
     print "packing messages in $opt_src ... " unless $opt_noharm;
     flush(STDOUT) unless $opt_noharm;
 
+    if ($opt_diff){ printf("\n");}
     foreach (@paths) {
 	$dst = $_;
 	$dst =~ s|[^/]+$|$msg++|e;
 	if ($_ ne $dst){
+	    if ($opt_diff){
+		printf("-%s\n", $_);
+		printf("+%s\n", $dst);
+	    }
 	    im_rename($_, $dst) || die $@;   # XXX
 	}
     }
-------------- next part --------------
--- imsort.org	Tue Jul 22 12:57:20 1997
+++ imsort	Wed Jul 23 13:07:58 1997
@@ -45,6 +45,7 @@
     'noharm;b;;'   => "Display the commands but do not actually execute them.",
     'src;F;;'      => "Set source folder.",
     'help;b;;'     => "Show this message.",
+    'diff;b;;'     => "Show sorting diff.",
     );
 
 ##
@@ -137,6 +138,10 @@
 	    }
 	    $sorted_index[$to] = -1;
 
+	    if ($opt_diff){
+		printf("-%s\n", $msg_paths[$from]);
+		printf("+%s\n", $msg_paths[$to]);
+	    }
 	    im_rename($msg_paths[$from], $msg_paths[$to]) || die;
 	} while ($to = $from) != $tmp;
 
-------------- next part --------------
--- mew-summary.el.org	Thu Jul 24 15:09:01 1997
+++ mew-summary.el	Thu Jul 24 17:13:24 1997
@@ -1504,6 +1504,29 @@
 ;;; Sorting and Packing
 ;;;
 
+;;(defun mew-summary-sort ()    
+;;  (interactive)
+;;  (let ((folder (buffer-name)))
+;;    (if (not (mew-summary-exclusive-p))
+;;	(message "Try later")
+;;      (mew-mark-clean-up)
+;;      (if (not (mew-y-or-n-p "Sort %s ? " folder))
+;;	  ()
+;;	(setq mew-summary-buffer-process t)
+;;	(message "Sorting %s ... " folder)
+;;	(call-process mew-prog-imsort nil nil nil 
+;;		      (concat "--src=" folder))
+;;	(message "Sorting %s ... done" folder)
+;;	(setq mew-summary-buffer-process nil)
+;;	(let ((buffer-read-only nil)) (erase-buffer))  ;; for update
+;;	(mew-summary-scan-body mew-prog-imls
+;;			       'mew-summary-mode
+;;			       folder
+;;			       mew-cs-scan
+;;			       (mew-input-range folder))
+;;	))
+;;    ))
+
 (defun mew-summary-sort ()    
   (interactive)
   (let ((folder (buffer-name)))
@@ -1512,22 +1535,36 @@
       (mew-mark-clean-up)
       (if (not (mew-y-or-n-p "Sort %s ? " folder))
 	  ()
-	(setq mew-summary-buffer-process t)
-	(message "Sorting %s ... " folder)
-	(call-process mew-prog-imsort nil nil nil 
-		      (concat "--src=" folder))
-	(message "Sorting %s ... done" folder)
-	(setq mew-summary-buffer-process nil)
-	(let ((buffer-read-only nil)) (erase-buffer))  ;; for update
-	(mew-summary-scan-body mew-prog-imls
+	(mew-summary-scan-diff mew-prog-imsort
 			       'mew-summary-mode
 			       folder
-			       mew-cs-scan
-			       (mew-input-range folder))
+			       mew-cs-scan)
 	))
-    ))
+      ))
+
+;;(defun mew-summary-pack ()    
+;;  (interactive)
+;;  (let ((folder (buffer-name)))
+;;    (if (not (mew-summary-exclusive-p))
+;;	(message "Try later")
+;;      (mew-mark-clean-up)
+;;      (if (not (mew-y-or-n-p "Pack %s? " folder))
+;;	  ()
+;;	(setq mew-summary-buffer-process t)
+;;	(message "Packing %s ... " folder)
+;;	(call-process mew-prog-impack nil nil nil (format "--src=%s" folder))
+;;	(message "Packing %s ... done" folder)
+;;	(setq mew-summary-buffer-process nil)
+;;	(let ((buffer-read-only nil)) (erase-buffer)) ;; for update
+;;	(mew-summary-scan-body mew-prog-imls
+;;			       'mew-summary-mode
+;;			       folder
+;;			       mew-cs-scan
+;;			       (mew-input-range folder))
+;;	))
+;;    ))
 
-(defun mew-summary-pack ()    
+(defun mew-summary-pack ()
   (interactive)
   (let ((folder (buffer-name)))
     (if (not (mew-summary-exclusive-p))
@@ -1535,19 +1572,133 @@
       (mew-mark-clean-up)
       (if (not (mew-y-or-n-p "Pack %s? " folder))
 	  ()
-	(setq mew-summary-buffer-process t)
-	(message "Packing %s ... " folder)
-	(call-process mew-prog-impack nil nil nil (format "--src=%s" folder))
-	(message "Packing %s ... done" folder)
-	(setq mew-summary-buffer-process nil)
-	(let ((buffer-read-only nil)) (erase-buffer)) ;; for update
-	(mew-summary-scan-body mew-prog-imls
+	(mew-summary-scan-diff mew-prog-impack
 			       'mew-summary-mode
 			       folder
-			       mew-cs-scan
-			       (mew-input-range folder))
+			       mew-cs-scan)
 	))
-    ))
+      ))
+
+;;;
+;;; scan diff
+;;;
+(defun mew-summary-scan-diff (prog mode folder read)
+  (save-excursion
+    (set-buffer (get-buffer-create folder))
+    (buffer-disable-undo (current-buffer))
+    (if (not (equal major-mode mode)) (funcall mode))
+    (mew-window-configure (current-buffer) 'summary)
+    (mew-current-set 'message nil)
+    (mew-current-set 'part nil)
+    (mew-current-set 'cache nil)
+    (setq mew-summary-buffer-direction 'down)
+    (mew-decode-syntax-delete)
+    (if (not (mew-summary-exclusive-p))
+	()
+      (condition-case nil
+	  (let ((process-connection-type mew-connection-type1))
+	    (cond
+	     ((string-match mew-prog-imsort prog)
+	      (message "Sorting %s in background ..." folder))
+	     ((string-match mew-prog-impack prog)
+	      (message "Packing %s in background ..." folder))
+	     )
+	    (setq mew-summary-buffer-start-point (point))
+	    (setq mew-summary-buffer-string "") ; Sorry, I use this
+						; variable to keep 
+					        ; non-string value.
+	    (setq mew-summary-buffer-process
+		  (apply (function start-process) 
+			 prog;; name
+			 (current-buffer) 
+			 prog;; program
+			 (list (concat "--src=" folder) "--diff")
+			 ))
+	    (mew-set-process-cs mew-summary-buffer-process read mew-cs-noconv)
+	    (set-process-filter mew-summary-buffer-process
+				'mew-summary-scan-diff-filter)
+	    (set-process-sentinel mew-summary-buffer-process
+				  'mew-summary-scan-diff-sentinel)
+	    (process-kill-without-query mew-summary-buffer-process)
+	    )
+	(quit
+	 (set-process-sentinel mew-summary-buffer-process nil)
+	 (setq mew-summary-buffer-start-point nil)
+	 (setq mew-summary-buffer-process nil)
+	 (setq mew-summary-buffer-string nil)
+	 ))
+      )))
+
+(defun mew-summary-scan-diff-filter (process string)
+  (save-excursion
+    (set-buffer (process-buffer process)) ;; just in case
+    (if (stringp mew-summary-buffer-string)
+	(progn
+	  (setq mew-summary-buffer-string 
+		(concat mew-summary-buffer-string string)) ;; nil can concat
+	  (cond
+	   ;; just for imls
+	   ((string-match mew-prog-impack (process-name process))
+	    ;; Skip greeting...
+	    (if (string-match "^packing messages in .*\n"
+			      mew-summary-buffer-string)
+		(setq mew-summary-buffer-string
+		      (substring mew-summary-buffer-string (match-end 0)))))
+	   )
+	  (if (string-match "^-\\(.*\\)\n\\+\\(.*\\)\n"
+			    mew-summary-buffer-string)
+	      (let* ((pre (file-name-nondirectory 
+			   (mew-match 1 mew-summary-buffer-string)))
+		     (now (file-name-nondirectory 
+			   (mew-match 2 mew-summary-buffer-string)))
+		     (pre-num (string-to-int pre))
+		     (now-num (string-to-int now)))
+		(setq mew-summary-buffer-string (min pre-num now-num))
+		))))))
+
+(defun mew-summary-scan-diff-sentinel (process event)
+  (save-excursion
+    ;; xxx if killed, we can't clear sentinel
+    ;;(set-process-sentinel mew-summary-buffer-process nil)
+    (setq mew-summary-buffer-start-point nil)
+    (setq mew-summary-buffer-process nil)
+    ;;
+    (set-buffer (process-buffer process)) ;; just in case
+    (let ((prog (process-name process))
+	  (folder (buffer-name))
+	  (msg nil))
+      (if (not (string= event "finished\n"))
+	  (message "Some error may be occured.")
+	(cond
+	 ((string-match mew-prog-impack prog)
+	  (setq msg (format "Packing %s in background ... done" folder)))
+	 ((string-match mew-prog-imsort prog)
+	  (setq msg (format "Sorting %s in background ... done" folder)))
+	 )
+	(if (numberp mew-summary-buffer-string)
+	    (let ((buffer-read-only nil))
+	      (goto-char (point-min))
+;;	      (keep-lines (concat mew-summary-message-regex))
+	      (while (< (string-to-int (mew-summary-message-number))
+			mew-summary-buffer-string)
+		(forward-line 1))
+	      (beginning-of-line)
+	      (delete-region (point) (point-max))
+;;	      ;; save cache only when success
+;;	      (if mew-summary-cache-use (mew-summary-folder-cache-save))
+	      (if msg (message msg))
+	      ;; summary buffer
+	      (set-buffer-modified-p nil)
+	      (setq mew-summary-buffer-string nil)
+	      (mew-summary-scan-body mew-prog-imls
+				     'mew-summary-mode
+				     folder
+				     mew-cs-scan
+				     (mew-input-range folder))
+	      )
+	  (message "Folder %s is not changed." folder)
+	  (setq mew-summary-buffer-string nil)
+	  )))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;


Mew-dist メーリングリストの案内