[mew-int 00549] Re: Questions about dealing with CVS commit mail messages via Mew

sen_ml at example.com sen_ml at example.com
Tue Nov 6 10:25:52 JST 2001


From: Kazu Yamamoto (山本和彦) <kazu at example.com>
Subject: [mew-int 00548] Re: Questions about dealing with CVS commit mail messages via Mew
Date: Mon, 05 Nov 2001 17:39:50 +0900 (JST)

> How about doing this?
> 
> - "|" works as your previous command. (mew-int 00533)
> - "C-u|" works as you proposed here.

Some thoughts about this:

  -Doesn't "C-u|" already mean "pipe body of message to command"?
  I haven't personally used "C-u|" yet, so this wouldn't be a loss
  for me, but I don't know about anyone else ;-)

  -My naive guess for what "C-u|" might mean -- if it were supposed to
  be the "multiple message version" of "|" -- is different from what I
  wrote.  My naive guess for "C-u|" would be: "invoke a shell command
  which expects multiple messages to be piped to it in sequence" [1].

As far as the current code is concerned:

  I rewrote my earlier code for completing a shell command so that it
  doesn't use elisp code for comint or shell.  My personal feeling is
  that the code is simpler and easier to understand (not to mention
  maintain because it has less dependencies).  I confess that I have
  not tested it for anything other than Emacs 21.1.

  In the current code, in order to enter a space character in the
  minibuffer, the user must precede the space with C-q.  If this is a
  problem, I suspect it can be addressed through the construction of
  an appropriate keymap (e.g. one that lacks a keybinding for the
  space key) [2].

  Anyway, below are two sections of code.  One is a rewrite of my
  earlier code for `mew-summary-pipe-message' (as per mew-int 00533),
  and the other is the code for `mew-summary-multi-shell' (the command
  that makes multiple messages available to a shell command).

Any comments are welcome.

;; 3 functions to provide completion for shell command in
;; `mew-summary-pipe-message'

;; XXX: name of this command leaves a bit to be desired -- I'd like
;;      a shorter name that uses a verb as the word immediately followin
;;      `mew'
;;
;; This is a helper function for `mew-complete-command-name'
(defun mew-command-name-completions-table (string)
  "Make table of command names in `exec-path' that are completion candidates.
Returns table (alist) of command names."
  (let ((paths exec-path)
	table)
    (while paths
      (if (file-name-completion string (car paths)) ; can complete in cur dir?
	  (setq table
		(append table
			(mapcar
			 (lambda (x)
			   (cons x ""))
			 (file-name-all-completions string (car paths))))))
      (setq paths (cdr paths)))
    table))

;; XXX: need to disable the use of the space key for completion purposes?  
;;      or users learn to deal w/ using C-q before typing a space...
(defun mew-complete-command-name (prompt string default)
  "Complete command name by searching `exec-path'."
  (completing-read prompt 
		   (mew-command-name-completions-table string) 
		   nil 
		   nil 
		   nil 
		   nil 
		   default))

(defun mew-summary-pipe-message (prefix command)
  "Send current message via pipe.
This function supports completion of the shell command."
  (interactive 
   (list current-prefix-arg 
	 (mew-complete-command-name "Shell command on message: " 
				    "" 
				    mew-last-shell-command)))
  (mew-summary-display 'redisplay)
  (when (y-or-n-p "Send this message to pipe? ")
    (save-excursion
      (set-buffer (mew-buffer-message))
      (save-restriction
	(widen)
	(if (string= command "") (setq command mew-last-shell-command))
	(goto-char (point-min)) ; perhaps this line won't be necessary
	(if prefix (search-forward "\n\n"))
	(let ((max-mini-window-height 1))
	  (shell-command-on-region (point) (point-max) command nil))
	(setq mew-last-shell-command command)))))

;; 2 additional functions for handing multiple messages to a shell command

;; This is a helper function for `mew-summary-multi-shell'
(defun mew-expand-command-name (command)
  "Expand command name to an absolute name by searching `exec-path'."
  (let ((paths exec-path)
	full-path
	path)
    (while (and paths (not path))
      (setq path (file-name-completion command (car paths)))
      (if path
	  (setq full-path (concat (car paths) "/" command)))
      (setq paths (cdr paths)))
    full-path))

;; XXX: Buffer management was not thought through too well
(defun mew-summary-multi-shell (command)
  "Invoke `command' on messages marked with `@'.
`command' is invoked only once.  It is invoked with filenames corresponding 
to the messages marked with `@' as trailing arguments.  Thus, it is
important that `command' be written to comply with this interface."
  (interactive
   (list (mew-complete-command-name "Shell command on message: "
				    ""
				    mew-last-shell-command)))
  (mew-summary-multi-msgs
   (if (y-or-n-p (format "Execute %s for these messages? " command))
       (let ((buf (generate-new-buffer mew-buffer-prefix)))
	 (message "Executing %s..." command)
	 (set-buffer buf)
	 (mew-erase-buffer)
	 (apply (function call-process) 
		(mew-expand-command-name command)
		nil buf t FILES)
	 (display-buffer buf)
	 (message "Executing %s...done" command)))))

[1] Indeed, I first thought about how to write code to do this, but I
    didn't manage to think of a good design -- the issue I could not
    make clear to myself was how Emacs should communicate message
    boundaries to the shell command (without making a complicated
    scheme of escape sequences and/or prescanning message content to
    determine the safety of a string of characters to be used as a
    message boundary).  So, I ended up with the current design and
    code...

[2] I confess that I do not know of an easy way to remove a key from a
    keymap -- on the other hand, I imagine binding the space key to
    `self-insert-command' would achieve the desired effect.



More information about the Mew-int mailing list