Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is there a non-buffer output version of vm-pipe-message-to-command

0 views
Skip to first unread message

blueman

unread,
Dec 19, 2007, 3:17:12 PM12/19/07
to
I am looking for a function that pipes a message to a command but just
returns the standard output result in a string rather than writing to
a buffer as vm-pipe-message-to-command does.

This would be the analog of the general elisp command
shell-command-to-string vs. shell-command.

This would be easy for me to hack based on the existing function but
before I do, I just want to make sure it doesn't already exist
somewhere by another name...

Chris McMahan

unread,
Dec 19, 2007, 6:00:46 PM12/19/07
to
I was looking for the same capability just today, to run the
spamassassin sa-learn script and avoid the output buffer hiding the
message window.

- Chris

blueman <NOS...@nospam.com> writes:

--
(. .)
=ooO=(_)=Ooo=====================================
Chris McMahan | first_init...@one.dot.net
=================================================

blueman

unread,
Dec 19, 2007, 7:33:18 PM12/19/07
to
Chris McMahan <first_init...@one.dot.net> writes:
> I was looking for the same capability just today, to run the
> spamassassin sa-learn script and avoid the output buffer hiding the
> message window.
>
> - Chris

:) That is the reason I was asking too! (since I was the one who asked
the spamassassin question)

It seems like an obvious building block function.

Robert Marshall

unread,
Dec 20, 2007, 2:24:27 PM12/20/07
to

Yes I was - after your message - experimenting with

(defun rajm:vm-pipe-hack ()
(interactive)
(let ((buffer (get-buffer-create "*Shell Command Output*"))
res)
(save-window-excursion
(vm-pipe-message-to-command "sa-learn --spam " 0)
(set-buffer buffer)
(setq res (buffer-substring (point-min) (point-max))))
(kill-buffer buffer)
; (message "%s" res)
; (sit-for 3)
res))

or something - last night

But it would be nicer if there were something there already.

I have one version with a
(vm-pipe-message-to-command "spamassassin -t" 0)
in that case I do want to see the output!

Robert
--
La grenouille songe..dans son château d'eau
Links and things http://rmstar.blogspot.com/

blueman

unread,
Dec 20, 2007, 8:35:04 PM12/20/07
to
> La grenouille songe..dans son chāteau d'eau

> Links and things http://rmstar.blogspot.com/

I like the fact that vm-pipe-message-to-command can operate on batches
of marked messages. In addition to the obvious benefits of using
marks, it also allows you to do the 'sync' portion just once at the
end rather than (implicitly) with each sa-learn. This is a big time
saver.

The functions I am using so far include this modification. However, it
still uses vm-pipe-message-to-command with the undesirable shell
output.

(defun vm-learn-spam ()
"Learn current message (or marked message if previous command was vm-next-command-uses-marks) as *spam* using sa-learn/spamassassin (JJK)."
(interactive)
(let
((sa-learn (vm-locate-executable-file "sa-learn")))
(cond
(sa-learn
(message "Learning spam. This may take a while...")
(vm-pipe-message-to-command
(concat sa-learn " --spam --no-sync"))
; no sync here because possibly multiple messages
(message (concat "Done: "
(shell-command-to-string
(concat sa-learn " --sync")))))
; sync after all messages parsed
(nil (error "Error: sa-learn function not found")))
))

(defun vm-learn-ham ()
"Learn current message (or marked message if previous command was vm-next-command-uses-marks) as *ham* using sa-learn/spamassassin (JJK)."
(interactive)
(let
((sa-learn (vm-locate-executable-file "sa-learn")))
(and sa-learn
(message "Learning ham. This may take a while...")
(vm-pipe-message-to-command
(concat sa-learn " --ham --no-sync"))
; no sync here because possibly multiple messages
(message (concat "Done: "
(shell-command-to-string
(concat sa-learn " --sync")))))
; sync after all messages parsed
))

An even *faster* approach would be to write a function that extracts
and concatenates the messages together and then pipes the
concatenation onto a single process call to sa-learn.

So, in summary, I think it would be great to have the following
building block functions in addition to vm-pipe-message-to-command.
vm-pipe-message-to-command-string
Analogous to vm-pipe-message-to-command but with
output to string rather than buffer. This is what I
would substitute in the above functions

vm-copy-messages-to-buffer
This would allow you to copy marked messages (if using
marks) or the current message to a buffer.
(Then I could write a short script to run sa-learn on
that buffer and avoid having to launch multiple
sa-learn processes)

If you don't want to first write to a buffer it may also be
nice to have the following two functions.

vm-pipe-concatenated-messages-to-command
Analogous to vm-pipe-messags-to-command but
concatenate marked messages.

vm-pipe-concatenated-messages-to-command-string
Analogous to vm-pipe-messags-to-command-string
but concatenate marked messages first.

Finally, I have written other functions that also allow you to
delete/save messages to a previously defined spam folder. The reason I
wrote this rather than using vm-save-message is that first of all you
don't have to keep typing the name of your spam folder and second of
all it doesn't overwrite the variable vm-last-save-folder which can be
a PITA.

(define-key vm-mode-map "ls" vm-save-and-learn-spam)

(defvar vm-spam-folder "~/mail/spam-certain"
"Mail folder for storing mail that is confirmed to be spam (JJK).")

(defun vm-save-and-learn-spam (&optional no-learn)
"Label message (or marked messages) as read and save to folder 'vm-spam-folder'. Also, unless prefix or optional variable NO-LEARN is non-nil, learn as spam via sa-learn/spamassassin (JJK)."
(interactive "P")
(let ((vm-last-save-folder-old ; Protect the last-save-folder variable
(save-excursion
(vm-select-folder-buffer)
vm-last-save-folder)))
(or no-learn (vm-learn-spam))
(vm-set-message-attributes "read" 1)
(vm-save-message vm-spam-folder)
(save-excursion ; Restore the last-save-folder variable
(vm-select-folder-buffer)
(setq vm-last-save-folder vm-last-save-folder-old))
))

blueman

unread,
Dec 20, 2007, 11:56:45 PM12/20/07
to
blueman <NOS...@nospam.com> writes:
> So, in summary, I think it would be great to have the following
> building block functions in addition to vm-pipe-message-to-command.
> vm-pipe-message-to-command-string
> Analogous to vm-pipe-message-to-command but with
> output to string rather than buffer. This is what I
> would substitute in the above functions
>
> vm-copy-messages-to-buffer
> This would allow you to copy marked messages (if using
> marks) or the current message to a buffer.
> (Then I could write a short script to run sa-learn on
> that buffer and avoid having to launch multiple
> sa-learn processes)
>

Another advantage of having the building block "vm-copy-messages-to-buffer"
is that it would also allow you to create an asynchronous process
which may be very desirable when running sa-learn on a long list of
marked messages.

0 new messages