mh-funcs.el 16.2 KB
Newer Older
Bill Wohler's avatar
Bill Wohler committed
1
;;; mh-funcs.el --- MH-E functions not everyone will use right away
Richard M. Stallman's avatar
Richard M. Stallman committed
2

Bill Wohler's avatar
Bill Wohler committed
3
;; Copyright (C) 1993, 1995,
4
;;  2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Bill Wohler's avatar
Bill Wohler committed
5 6 7 8 9

;; Author: Bill Wohler <wohler@newt.com>
;; Maintainer: Bill Wohler <wohler@newt.com>
;; Keywords: mail
;; See: mh-e.el
Richard M. Stallman's avatar
Richard M. Stallman committed
10

11
;; This file is part of GNU Emacs.
Richard M. Stallman's avatar
Richard M. Stallman committed
12

Karl Heuer's avatar
Karl Heuer committed
13
;; GNU Emacs is free software; you can redistribute it and/or modify
Richard M. Stallman's avatar
Richard M. Stallman committed
14 15 16 17
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

Karl Heuer's avatar
Karl Heuer committed
18
;; GNU Emacs is distributed in the hope that it will be useful,
Richard M. Stallman's avatar
Richard M. Stallman committed
19 20 21 22 23
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
Erik Naggum's avatar
Erik Naggum committed
24
;; along with GNU Emacs; see the file COPYING.  If not, write to the
Lute Kamstra's avatar
Lute Kamstra committed
25 26
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
Richard M. Stallman's avatar
Richard M. Stallman committed
27 28 29

;;; Commentary:

Bill Wohler's avatar
Bill Wohler committed
30 31
;; Internal support for MH-E package.
;; Putting these functions in a separate file lets MH-E start up faster,
Erik Naggum's avatar
Erik Naggum committed
32
;; since less Lisp code needs to be loaded all at once.
Richard M. Stallman's avatar
Richard M. Stallman committed
33

Karl Heuer's avatar
Karl Heuer committed
34 35
;;; Change Log:

Richard M. Stallman's avatar
Richard M. Stallman committed
36 37
;;; Code:

Bill Wohler's avatar
Bill Wohler committed
38 39
(eval-when-compile (require 'mh-acros))
(mh-require-cl)
Richard M. Stallman's avatar
Richard M. Stallman committed
40 41
(require 'mh-e)

Bill Wohler's avatar
Bill Wohler committed
42 43


Bill Wohler's avatar
Bill Wohler committed
44 45
;;; Scan Line Formats

Karl Heuer's avatar
Karl Heuer committed
46
(defvar mh-note-copied "C"
47
  "Messages that have been copied are marked by this character.")
Karl Heuer's avatar
Karl Heuer committed
48 49

(defvar mh-note-printed "P"
Bill Wohler's avatar
Bill Wohler committed
50
  "Messages that have been printed are marked by this character.")
Karl Heuer's avatar
Karl Heuer committed
51

Bill Wohler's avatar
Bill Wohler committed
52 53


Bill Wohler's avatar
Bill Wohler committed
54
;;; Functions
Karl Heuer's avatar
Karl Heuer committed
55

Bill Wohler's avatar
Bill Wohler committed
56
;;;###mh-autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
57
(defun mh-burst-digest ()
58 59
  "Break up digest into separate messages\\<mh-folder-mode-map>.

60 61 62 63 64 65 66 67 68 69 70 71 72
This command uses the MH command \"burst\" to break out each
message in the digest into its own message. Using this command,
you can quickly delete unwanted messages, like this: Once the
digest is split up, toggle out of MH-Folder Show mode with
\\[mh-toggle-showing] so that the scan lines fill the screen and
messages aren't displayed. Then use \\[mh-delete-msg] to quickly
delete messages that you don't want to read (based on the
\"Subject:\" header field). You can also burst the digest to
reply directly to the people who posted the messages in the
digest. One problem you may encounter is that the \"From:\"
header fields are preceded with a \">\" so that your reply can't
create the \"To:\" field correctly. In this case, you must
correct the \"To:\" field yourself."
Richard M. Stallman's avatar
Richard M. Stallman committed
73 74 75
  (interactive)
  (let ((digest (mh-get-msg-num t)))
    (mh-process-or-undo-commands mh-current-folder)
Bill Wohler's avatar
Bill Wohler committed
76
    (mh-set-folder-modified-p t)        ; lock folder while bursting
Richard M. Stallman's avatar
Richard M. Stallman committed
77 78
    (message "Bursting digest...")
    (mh-exec-cmd "burst" mh-current-folder digest "-inplace")
Karl Heuer's avatar
Karl Heuer committed
79 80 81 82 83
    (with-mh-folder-updating (t)
      (beginning-of-line)
      (delete-region (point) (point-max)))
    (mh-regenerate-headers (format "%d-last" digest) t)
    (mh-goto-cur-msg)
Richard M. Stallman's avatar
Richard M. Stallman committed
84 85
    (message "Bursting digest...done")))

Bill Wohler's avatar
Bill Wohler committed
86
;;;###mh-autoload
Bill Wohler's avatar
Bill Wohler committed
87
(defun mh-copy-msg (range folder)
88 89
  "Copy RANGE to FOLDER\\<mh-folder-mode-map>.

90
If you wish to copy a message to another folder, you can use this
91
command (see the \"-link\" argument to \"refile\"). Like the
92 93 94 95
command \\[mh-refile-msg], this command prompts you for the name
of the target folder and you can specify a range. Note that
unlike the command \\[mh-refile-msg], the copy takes place
immediately. The original copy remains in the current folder.
Bill Wohler's avatar
Bill Wohler committed
96

97 98
Check the documentation of `mh-interactive-range' to see how
RANGE is read in interactive use."
Bill Wohler's avatar
Bill Wohler committed
99
  (interactive (list (mh-interactive-range "Copy")
Bill Wohler's avatar
Bill Wohler committed
100
                     (mh-prompt-for-folder "Copy to" "" t)))
Bill Wohler's avatar
Bill Wohler committed
101
  (let ((msg-list (let ((result ()))
Bill Wohler's avatar
Bill Wohler committed
102
                    (mh-iterate-on-range msg range
Bill Wohler's avatar
Bill Wohler committed
103 104 105
                      (mh-notate nil mh-note-copied mh-cmd-note)
                      (push msg result))
                    result)))
Bill Wohler's avatar
Bill Wohler committed
106
    (mh-exec-cmd "refile" (mh-coalesce-msg-list msg-list)
Bill Wohler's avatar
Bill Wohler committed
107
                 "-link" "-src" mh-current-folder folder)))
Richard M. Stallman's avatar
Richard M. Stallman committed
108

Bill Wohler's avatar
Bill Wohler committed
109
;;;###mh-autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
110
(defun mh-kill-folder ()
111 112
  "Remove folder.

113 114
Remove all of the messages (files) within the current folder, and
then remove the folder (directory) itself.
115

116 117 118 119
Run the abnormal hook `mh-kill-folder-suppress-prompt-hooks'. The
hook functions are called with no arguments and should return a
non-nil value to suppress the normal prompt when you remove a
folder. This is useful for folders that are easily regenerated."
Richard M. Stallman's avatar
Richard M. Stallman committed
120
  (interactive)
Bill Wohler's avatar
Bill Wohler committed
121
  (if (or (run-hook-with-args-until-success
122
           'mh-kill-folder-suppress-prompt-hooks)
Bill Wohler's avatar
Bill Wohler committed
123
          (yes-or-no-p (format "Remove folder %s (and all included messages)? "
Bill Wohler's avatar
Bill Wohler committed
124 125 126
                               mh-current-folder)))
      (let ((folder mh-current-folder)
            (window-config mh-previous-window-config))
Bill Wohler's avatar
Bill Wohler committed
127
        (mh-set-folder-modified-p t)    ; lock folder to kill it
Bill Wohler's avatar
Bill Wohler committed
128
        (mh-exec-cmd-daemon "rmf" 'mh-rmf-daemon folder)
Bill Wohler's avatar
Bill Wohler committed
129 130
        (when (boundp 'mh-speed-folder-map)
          (mh-speed-invalidate-map folder))
Bill Wohler's avatar
Bill Wohler committed
131
        (mh-remove-from-sub-folders-cache folder)
Bill Wohler's avatar
Bill Wohler committed
132
        (mh-set-folder-modified-p nil)  ; so kill-buffer doesn't complain
Bill Wohler's avatar
Bill Wohler committed
133
        (if (and mh-show-buffer (get-buffer mh-show-buffer))
Bill Wohler's avatar
Bill Wohler committed
134 135
            (kill-buffer mh-show-buffer))
        (if (get-buffer folder)
Bill Wohler's avatar
Bill Wohler committed
136 137 138 139
            (kill-buffer folder))
        (when window-config
          (set-window-configuration window-config))
        (message "Folder %s removed" folder))
Bill Wohler's avatar
Bill Wohler committed
140
    (message "Folder not removed")))
Richard M. Stallman's avatar
Richard M. Stallman committed
141

Bill Wohler's avatar
Bill Wohler committed
142 143 144 145 146 147
(defun mh-rmf-daemon (process output)
  "The rmf PROCESS puts OUTPUT in temporary buffer.
Display the results only if something went wrong."
  (set-buffer (get-buffer-create mh-temp-buffer))
  (insert-before-markers output)
  (when (save-excursion
Bill Wohler's avatar
Bill Wohler committed
148
          (goto-char (point-min))
Bill Wohler's avatar
Bill Wohler committed
149 150 151
          (re-search-forward "^rmf: " (point-max) t))
    (display-buffer mh-temp-buffer)))

Bill Wohler's avatar
Bill Wohler committed
152 153
;; Avoid compiler warning...
(defvar view-exit-action)
Richard M. Stallman's avatar
Richard M. Stallman committed
154

Bill Wohler's avatar
Bill Wohler committed
155
;;;###mh-autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
156 157 158
(defun mh-list-folders ()
  "List mail folders."
  (interactive)
Bill Wohler's avatar
Bill Wohler committed
159
  (let ((temp-buffer mh-folders-buffer))
Bill Wohler's avatar
Bill Wohler committed
160 161
    (with-output-to-temp-buffer temp-buffer
      (save-excursion
Bill Wohler's avatar
Bill Wohler committed
162 163 164 165 166 167 168
        (set-buffer temp-buffer)
        (erase-buffer)
        (message "Listing folders...")
        (mh-exec-cmd-output "folders" t (if mh-recursive-folders-flag
                                            "-recurse"
                                          "-norecurse"))
        (goto-char (point-min))
Bill Wohler's avatar
Bill Wohler committed
169
        (view-mode-enter)
Bill Wohler's avatar
Bill Wohler committed
170 171 172 173
        (setq view-exit-action 'kill-buffer)
        (message "Listing folders...done")))))

;;;###mh-autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
174
(defun mh-pack-folder (range)
175 176
  "Pack folder\\<mh-folder-mode-map>.

177 178 179 180 181
This command packs the folder, removing gaps from the numbering
sequence. If you don't want to rescan the entire folder
afterward, this command will accept a RANGE. Check the
documentation of `mh-interactive-range' to see how RANGE is read
in interactive use.
182

183 184 185
This command will ask if you want to process refiles or deletes
first and then either run \\[mh-execute-commands] for you or undo
the pending refiles and deletes, which are lost."
Richard M. Stallman's avatar
Richard M. Stallman committed
186
  (interactive (list (if current-prefix-arg
Bill Wohler's avatar
Bill Wohler committed
187 188
                         (mh-read-range "Scan" mh-current-folder t nil t
                                        mh-interpret-number-as-range-flag)
Bill Wohler's avatar
Bill Wohler committed
189 190 191 192 193 194 195 196
                       '("all"))))
  (let ((threaded-flag (memq 'unthread mh-view-ops)))
    (mh-pack-folder-1 range)
    (mh-goto-cur-msg)
    (when mh-index-data
      (mh-index-update-maps mh-current-folder))
    (cond (threaded-flag (mh-toggle-threads))
          (mh-index-data (mh-index-insert-folder-headers))))
Richard M. Stallman's avatar
Richard M. Stallman committed
197 198 199
  (message "Packing folder...done"))

(defun mh-pack-folder-1 (range)
Bill Wohler's avatar
Bill Wohler committed
200
  "Close and pack the current folder.
201 202

Display RANGE after packing, or the entire folder if RANGE is nil."
Richard M. Stallman's avatar
Richard M. Stallman committed
203 204
  (mh-process-or-undo-commands mh-current-folder)
  (message "Packing folder...")
Bill Wohler's avatar
Bill Wohler committed
205
  (mh-set-folder-modified-p t)          ; lock folder while packing
Richard M. Stallman's avatar
Richard M. Stallman committed
206
  (save-excursion
Karl Heuer's avatar
Karl Heuer committed
207
    (mh-exec-cmd-quiet t "folder" mh-current-folder "-pack"
Bill Wohler's avatar
Bill Wohler committed
208
                       "-norecurse" "-fast"))
Bill Wohler's avatar
Bill Wohler committed
209
  (mh-reset-threads-and-narrowing)
Richard M. Stallman's avatar
Richard M. Stallman committed
210 211
  (mh-regenerate-headers range))

Bill Wohler's avatar
Bill Wohler committed
212
;;;###mh-autoload
213 214 215
(defun mh-pipe-msg (command include-header)
  "Pipe message through shell command COMMAND.

216 217 218 219
You are prompted for the Unix command through which you wish to
run your message. If you give an argument INCLUDE-HEADER to this
command, the message header is included in the text passed to the
command."
Richard M. Stallman's avatar
Richard M. Stallman committed
220 221
  (interactive
   (list (read-string "Shell command on message: ") current-prefix-arg))
Karl Heuer's avatar
Karl Heuer committed
222
  (let ((msg-file-to-pipe (mh-msg-filename (mh-get-msg-num t)))
Bill Wohler's avatar
Bill Wohler committed
223
        (message-directory default-directory))
Richard M. Stallman's avatar
Richard M. Stallman committed
224
    (save-excursion
Karl Heuer's avatar
Karl Heuer committed
225
      (set-buffer (get-buffer-create mh-temp-buffer))
Richard M. Stallman's avatar
Richard M. Stallman committed
226
      (erase-buffer)
Karl Heuer's avatar
Karl Heuer committed
227
      (insert-file-contents msg-file-to-pipe)
Richard M. Stallman's avatar
Richard M. Stallman committed
228
      (goto-char (point-min))
229
      (if (not include-header) (search-forward "\n\n"))
Karl Heuer's avatar
Karl Heuer committed
230
      (let ((default-directory message-directory))
Bill Wohler's avatar
Bill Wohler committed
231
        (shell-command-on-region (point) (point-max) command nil)))))
Richard M. Stallman's avatar
Richard M. Stallman committed
232

Bill Wohler's avatar
Bill Wohler committed
233
;;;###mh-autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
234
(defun mh-page-digest ()
235
  "Display next message in digest."
Richard M. Stallman's avatar
Richard M. Stallman committed
236 237 238 239 240 241 242
  (interactive)
  (mh-in-show-buffer (mh-show-buffer)
    ;; Go to top of screen (in case user moved point).
    (move-to-window-line 0)
    (let ((case-fold-search nil))
      ;; Search for blank line and then for From:
      (or (and (search-forward "\n\n" nil t)
Bill Wohler's avatar
Bill Wohler committed
243 244
               (re-search-forward "^From:" nil t))
          (error "No more messages in digest")))
Richard M. Stallman's avatar
Richard M. Stallman committed
245 246 247 248 249
    ;; Go back to previous blank line, then forward to the first non-blank.
    (search-backward "\n\n" nil t)
    (forward-line 2)
    (mh-recenter 0)))

Bill Wohler's avatar
Bill Wohler committed
250
;;;###mh-autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
251
(defun mh-page-digest-backwards ()
252
  "Display previous message in digest."
Richard M. Stallman's avatar
Richard M. Stallman committed
253 254 255 256 257 258 259
  (interactive)
  (mh-in-show-buffer (mh-show-buffer)
    ;; Go to top of screen (in case user moved point).
    (move-to-window-line 0)
    (let ((case-fold-search nil))
      (beginning-of-line)
      (or (and (search-backward "\n\n" nil t)
Bill Wohler's avatar
Bill Wohler committed
260 261
               (re-search-backward "^From:" nil t))
          (error "No previous message in digest")))
Richard M. Stallman's avatar
Richard M. Stallman committed
262 263
    ;; Go back to previous blank line, then forward to the first non-blank.
    (if (search-backward "\n\n" nil t)
Bill Wohler's avatar
Bill Wohler committed
264
        (forward-line 2))
Richard M. Stallman's avatar
Richard M. Stallman committed
265 266
    (mh-recenter 0)))

Bill Wohler's avatar
Bill Wohler committed
267
;;;###mh-autoload
Karl Heuer's avatar
Karl Heuer committed
268
(defun mh-sort-folder (&optional extra-args)
Richard M. Stallman's avatar
Richard M. Stallman committed
269
  "Sort the messages in the current folder by date.
270

Richard M. Stallman's avatar
Richard M. Stallman committed
271
Calls the MH program sortm to do the work.
272 273 274

The arguments in the list `mh-sortm-args' are passed to sortm if
the optional argument EXTRA-ARGS is given."
Richard M. Stallman's avatar
Richard M. Stallman committed
275 276 277
  (interactive "P")
  (mh-process-or-undo-commands mh-current-folder)
  (setq mh-next-direction 'forward)
Bill Wohler's avatar
Bill Wohler committed
278
  (mh-set-folder-modified-p t)          ; lock folder while sorting
Richard M. Stallman's avatar
Richard M. Stallman committed
279
  (message "Sorting folder...")
Bill Wohler's avatar
Bill Wohler committed
280 281 282 283 284 285 286 287 288 289
  (let ((threaded-flag (memq 'unthread mh-view-ops)))
    (mh-exec-cmd "sortm" mh-current-folder (if extra-args mh-sortm-args))
    (when mh-index-data
      (mh-index-update-maps mh-current-folder))
    (message "Sorting folder...done")
    (mh-scan-folder mh-current-folder "all")
    (cond (threaded-flag (mh-toggle-threads))
          (mh-index-data (mh-index-insert-folder-headers)))))

;;;###mh-autoload
Bill Wohler's avatar
Bill Wohler committed
290 291
(defun mh-undo-folder ()
  "Undo all pending deletes and refiles in current folder."
Richard M. Stallman's avatar
Richard M. Stallman committed
292
  (interactive)
Bill Wohler's avatar
Bill Wohler committed
293
  (cond ((or mh-do-not-confirm-flag
Bill Wohler's avatar
Bill Wohler committed
294 295 296 297 298 299
             (yes-or-no-p "Undo all commands in folder? "))
         (setq mh-delete-list nil
               mh-refile-list nil
               mh-seq-list nil
               mh-next-direction 'forward)
         (with-mh-folder-updating (nil)
Bill Wohler's avatar
Bill Wohler committed
300
           (mh-remove-all-notation)))
Bill Wohler's avatar
Bill Wohler committed
301
        (t
Bill Wohler's avatar
Bill Wohler committed
302
         (message "Commands not undone"))))
Bill Wohler's avatar
Bill Wohler committed
303 304

;;;###mh-autoload
Karl Heuer's avatar
Karl Heuer committed
305
(defun mh-store-msg (directory)
306
  "Unpack message created with \"uudecode\" or \"shar\".
307

308 309 310 311 312
The default DIRECTORY for extraction is the current directory;
however, you have a chance to specify a different extraction
directory. The next time you use this command, the default
directory is the last directory you used. If you would like to
change the initial default directory, customize the option
313
`mh-store-default-directory'."
Bill Wohler's avatar
Bill Wohler committed
314 315 316 317
  (interactive (list (let ((udir (or mh-store-default-directory
                                     default-directory)))
                       (read-file-name "Store message in directory: "
                                       udir udir nil))))
Karl Heuer's avatar
Karl Heuer committed
318
  (let ((msg-file-to-store (mh-msg-filename (mh-get-msg-num t))))
Richard M. Stallman's avatar
Richard M. Stallman committed
319
    (save-excursion
Karl Heuer's avatar
Karl Heuer committed
320
      (set-buffer (get-buffer-create mh-temp-buffer))
Richard M. Stallman's avatar
Richard M. Stallman committed
321
      (erase-buffer)
Karl Heuer's avatar
Karl Heuer committed
322 323
      (insert-file-contents msg-file-to-store)
      (mh-store-buffer directory))))
Richard M. Stallman's avatar
Richard M. Stallman committed
324

Bill Wohler's avatar
Bill Wohler committed
325
;;;###mh-autoload
Karl Heuer's avatar
Karl Heuer committed
326
(defun mh-store-buffer (directory)
Richard M. Stallman's avatar
Richard M. Stallman committed
327
  "Store the file(s) contained in the current buffer into DIRECTORY.
328

Richard M. Stallman's avatar
Richard M. Stallman committed
329
The buffer can contain a shar file or uuencoded file.
330 331 332

Default directory is the last directory used, or initially the
value of `mh-store-default-directory' or the current directory."
Bill Wohler's avatar
Bill Wohler committed
333
  (interactive (list (let ((udir (or mh-store-default-directory
Bill Wohler's avatar
Bill Wohler committed
334 335 336
                                     default-directory)))
                       (read-file-name "Store buffer in directory: "
                                       udir udir nil))))
Karl Heuer's avatar
Karl Heuer committed
337
  (let ((store-directory (expand-file-name directory))
Bill Wohler's avatar
Bill Wohler committed
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
        (sh-start (save-excursion
                    (goto-char (point-min))
                    (if (re-search-forward
                         "^#![ \t]*/bin/sh\\|^#\\|^: " nil t)
                        (progn
                          ;; The "cut here" pattern was removed from above
                          ;; because it seemed to hurt more than help.
                          ;; But keep this to make it easier to put it back.
                          (if (looking-at "^[^a-z0-9\"]*cut here\\b")
                              (forward-line 1))
                          (beginning-of-line)
                          (if (looking-at "^[#:]....+\n\\( ?\n\\)?end$")
                              nil       ;most likely end of a uuencode
                            (point))))))
        (command "sh")
Bill Wohler's avatar
Bill Wohler committed
353 354
        (uudecode-filename "(unknown filename)")
        log-begin)
Karl Heuer's avatar
Karl Heuer committed
355
    (if (not sh-start)
Bill Wohler's avatar
Bill Wohler committed
356 357 358 359 360 361
        (save-excursion
          (goto-char (point-min))
          (if (re-search-forward "^begin [0-7]+ " nil t)
              (setq uudecode-filename
                    (buffer-substring (point)
                                      (progn (end-of-line) (point)))))))
Richard M. Stallman's avatar
Richard M. Stallman committed
362
    (save-excursion
Bill Wohler's avatar
Bill Wohler committed
363 364
      (set-buffer (get-buffer-create mh-log-buffer))
      (setq log-begin (mh-truncate-log-buffer))
Richard M. Stallman's avatar
Richard M. Stallman committed
365
      (if (not (file-directory-p store-directory))
Bill Wohler's avatar
Bill Wohler committed
366 367
          (progn
            (insert "mkdir " directory "\n")
Bill Wohler's avatar
Bill Wohler committed
368
            (call-process "mkdir" nil mh-log-buffer t store-directory)))
Karl Heuer's avatar
Karl Heuer committed
369 370 371
      (insert "cd " directory "\n")
      (setq mh-store-default-directory directory)
      (if (not sh-start)
Bill Wohler's avatar
Bill Wohler committed
372 373 374
          (progn
            (setq command "uudecode")
            (insert uudecode-filename " being uudecoded...\n"))))
Bill Wohler's avatar
Bill Wohler committed
375 376 377 378 379 380 381 382 383
    (set-window-start (display-buffer mh-log-buffer) log-begin) ;watch progress
    (let ((default-directory (file-name-as-directory store-directory)))
      (if (equal (call-process-region sh-start (point-max) command
                                      nil mh-log-buffer t)
                 0)
          (save-excursion
            (set-buffer mh-log-buffer)
            (insert "\n(mh-store finished)\n"))
        (error "Error occurred during execution of %s" command)))))
Bill Wohler's avatar
Bill Wohler committed
384 385 386 387 388



;;; Help Functions

Bill Wohler's avatar
Bill Wohler committed
389
;;;###mh-autoload
Bill Wohler's avatar
Bill Wohler committed
390 391 392 393 394 395
(defun mh-ephem-message (string)
  "Display STRING in the minibuffer momentarily."
  (message "%s" string)
  (sit-for 5)
  (message ""))

Bill Wohler's avatar
Bill Wohler committed
396
;;;###mh-autoload
Bill Wohler's avatar
Bill Wohler committed
397
(defun mh-help ()
Bill Wohler's avatar
Bill Wohler committed
398
  "Display cheat sheet for the MH-E commands."
Bill Wohler's avatar
Bill Wohler committed
399
  (interactive)
Bill Wohler's avatar
Bill Wohler committed
400 401 402 403 404 405 406
  (with-electric-help
   (function
    (lambda ()
      (insert
       (substitute-command-keys
        (mapconcat 'identity (cdr (assoc nil mh-help-messages)) ""))))
    mh-help-buffer)))
407

Bill Wohler's avatar
Bill Wohler committed
408
;;;###mh-autoload
Bill Wohler's avatar
Bill Wohler committed
409 410 411
(defun mh-prefix-help ()
  "Display cheat sheet for the commands of the current prefix in minibuffer."
  (interactive)
412
  ;; We got here because the user pressed a "?", but he pressed a prefix key
Bill Wohler's avatar
Bill Wohler committed
413 414 415 416 417
  ;; before that. Since the the key vector starts at index 0, the index of the
  ;; last keystroke is length-1 and thus the second to last keystroke is at
  ;; length-2. We use that information to obtain a suitable prefix character
  ;; from the recent keys.
  (let* ((keys (recent-keys))
Bill Wohler's avatar
Bill Wohler committed
418
         (prefix-char (elt keys (- (length keys) 2))))
Bill Wohler's avatar
Bill Wohler committed
419 420 421 422 423 424 425 426
    (with-electric-help
     (function
      (lambda ()
        (insert
         (substitute-command-keys
          (mapconcat 'identity
                     (cdr (assoc prefix-char mh-help-messages)) "")))))
     mh-help-buffer)))
Bill Wohler's avatar
Bill Wohler committed
427 428 429

(provide 'mh-funcs)

Bill Wohler's avatar
Bill Wohler committed
430 431 432 433
;; Local Variables:
;; indent-tabs-mode: nil
;; sentence-end-double-space: nil
;; End:
Bill Wohler's avatar
Bill Wohler committed
434

Bill Wohler's avatar
Bill Wohler committed
435
;; arch-tag: 1936c4f1-4843-438e-bc4b-a63bb75a7762
436
;;; mh-funcs.el ends here