mirror of https://github.com/djcb/mu.git
* mu4e(-main|-proc-|utils).el: refactoring, some cleanup/improvements
- move all mu4e startup functions to mu4e-utils - add `mu4e' function to mu4e.el that call these mu4e-utils function - now easy to start mu4e without showing ui - mu4e~proc-is-running moved to mu4e-proc - made mu4e-read-option a bit smarter - renamed some more functions from mu4e- => mu4e~ (i.e.., mark them private)
This commit is contained in:
parent
5ea06f1469
commit
084ecc71d2
|
@ -26,7 +26,7 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(require 'mu4e-utils) ;; utility functions
|
||||
|
||||
(defconst mu4e-main-buffer-name "*mu4e-main*"
|
||||
(defconst mu4e~main-buffer-name "*mu4e-main*"
|
||||
"*internal* Name of the mu4e main view buffer.")
|
||||
|
||||
(defvar mu4e-main-mode-map
|
||||
|
@ -40,7 +40,7 @@
|
|||
(define-key map "j" 'mu4e-jump-to-maildir)
|
||||
(define-key map "C" 'mu4e-compose-new)
|
||||
|
||||
(define-key map "m" 'mu4e-toggle-mail-sending-mode)
|
||||
(define-key map "m" 'mu4e~main-toggle-mail-sending-mode)
|
||||
(define-key map "f" 'smtpmail-send-queued-mail)
|
||||
(define-key map "U" 'mu4e-update-mail-show-window)
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
overwrite-mode 'overwrite-mode-binary))
|
||||
|
||||
|
||||
(defun mu4e-action-str (str &optional func-or-shortcut)
|
||||
(defun mu4e~main-action-str (str &optional func-or-shortcut)
|
||||
"Highlight the first occurence of [..] in STR. If
|
||||
FUNC-OR-SHORTCUT is non-nil and if it is a function, call it when
|
||||
STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is a
|
||||
|
@ -84,12 +84,12 @@ clicked."
|
|||
(define-key map (kbd "RET") func)
|
||||
(put-text-property 0 (length newstr) 'keymap map newstr)
|
||||
(put-text-property (string-match "\\w" newstr)
|
||||
(- (length newstr) 1) 'mouse-face 'highlight newstr)
|
||||
newstr))
|
||||
(- (length newstr) 1) 'mouse-face 'highlight newstr) newstr))
|
||||
|
||||
(defun mu4e-main-view()
|
||||
|
||||
(defun mu4e~main-view ()
|
||||
"Show the mu4e main view."
|
||||
(let ((buf (get-buffer-create mu4e-main-buffer-name))
|
||||
(let ((buf (get-buffer-create mu4e~main-buffer-name))
|
||||
(inhibit-read-only t))
|
||||
(with-current-buffer buf
|
||||
(erase-buffer)
|
||||
|
@ -99,70 +99,46 @@ clicked."
|
|||
(propertize mu4e-mu-version 'face 'mu4e-view-header-key-face)
|
||||
"\n\n"
|
||||
(propertize " Basics\n\n" 'face 'mu4e-title-face)
|
||||
(mu4e-action-str "\t* [j]ump to some maildir\n" 'mu4e-jump-to-maildir)
|
||||
(mu4e-action-str "\t* enter a [s]earch query\n" 'mu4e-search)
|
||||
(mu4e-action-str "\t* [C]ompose a new message\n" 'mu4e-compose-new)
|
||||
(mu4e~main-action-str "\t* [j]ump to some maildir\n" 'mu4e-jump-to-maildir)
|
||||
(mu4e~main-action-str "\t* enter a [s]earch query\n" 'mu4e-search)
|
||||
(mu4e~main-action-str "\t* [C]ompose a new message\n" 'mu4e-compose-new)
|
||||
"\n"
|
||||
(propertize " Bookmarks\n\n" 'face 'mu4e-title-face)
|
||||
;; TODO: it's a bit uncool to hard-code the "b" shortcut...
|
||||
(mapconcat
|
||||
(lambda (bm)
|
||||
(let* ((query (nth 0 bm)) (title (nth 1 bm)) (key (nth 2 bm)))
|
||||
(mu4e-action-str
|
||||
(mu4e~main-action-str
|
||||
(concat "\t* [b" (make-string 1 key) "] " title)
|
||||
(concat "b" (make-string 1 key)))))
|
||||
mu4e-bookmarks "\n")
|
||||
"\n"
|
||||
(propertize " Misc\n\n" 'face 'mu4e-title-face)
|
||||
|
||||
(mu4e-action-str "\t* [U]pdate email & database\n"
|
||||
(mu4e~main-action-str "\t* [U]pdate email & database\n"
|
||||
'mu4e-update-mail-show-window)
|
||||
|
||||
;; show the queue functions if `smtpmail-queue-dir' is defined
|
||||
(if (file-directory-p smtpmail-queue-dir)
|
||||
(concat
|
||||
(mu4e-action-str "\t* toggle [m]ail sending mode "
|
||||
'mu4e-toggle-mail-sending-mode)
|
||||
(mu4e~main-action-str "\t* toggle [m]ail sending mode "
|
||||
'mu4e~main-toggle-mail-sending-mode)
|
||||
"(" (propertize (if smtpmail-queue-mail "queued" "direct")
|
||||
'face 'mu4e-view-header-key-face) ")\n"
|
||||
(mu4e-action-str "\t* [f]lush queued mail\n"
|
||||
(mu4e~main-action-str "\t* [f]lush queued mail\n"
|
||||
'smtpmail-send-queued-mail))
|
||||
"")
|
||||
"\n"
|
||||
|
||||
(mu4e-action-str "\t* [H]elp\n" 'mu4e-display-manual)
|
||||
(mu4e-action-str "\t* [q]uit\n" 'mu4e-quit))
|
||||
(mu4e~main-action-str "\t* [H]elp\n" 'mu4e-display-manual)
|
||||
(mu4e~main-action-str "\t* [q]uit\n" 'mu4e-quit))
|
||||
(mu4e-main-mode)
|
||||
(switch-to-buffer buf)
|
||||
(delete-other-windows))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Interactive functions
|
||||
|
||||
(defconst mu4e-update-buffer-name "*mu4e-update*"
|
||||
"*internal* Name of the buffer for message retrieval / database
|
||||
updating.")
|
||||
|
||||
(defun mu4e-update-mail-show-window ()
|
||||
"Try to retrieve mail (using the user-provided shell command),
|
||||
and update the database afterwards, and show the progress in a
|
||||
split-window."
|
||||
(interactive)
|
||||
(unless mu4e-get-mail-command
|
||||
(error "`mu4e-get-mail-command' is not defined"))
|
||||
(let ((buf (get-buffer-create mu4e-update-buffer-name))
|
||||
(win
|
||||
(split-window (selected-window)
|
||||
(- (window-height (selected-window)) 8))))
|
||||
(with-selected-window win
|
||||
(switch-to-buffer buf)
|
||||
(set-window-dedicated-p win t)
|
||||
(erase-buffer)
|
||||
(insert "\n") ;; FIXME -- needed so output starts
|
||||
(mu4e-update-mail buf))))
|
||||
|
||||
|
||||
(defun mu4e-toggle-mail-sending-mode ()
|
||||
(defun mu4e~main-toggle-mail-sending-mode ()
|
||||
"Toggle sending mail mode, either queued or direct."
|
||||
(interactive)
|
||||
(unless (file-directory-p smtpmail-queue-dir)
|
||||
|
@ -171,6 +147,7 @@ split-window."
|
|||
(message
|
||||
(concat "Outgoing mail will now be "
|
||||
(if smtpmail-queue-mail "queued" "sent directly")))
|
||||
(mu4e-main-view))
|
||||
(mu4e~main-view))
|
||||
|
||||
|
||||
(provide 'mu4e-main)
|
||||
|
|
|
@ -72,6 +72,10 @@
|
|||
mu4e~proc-process nil
|
||||
mu4e~proc-buf nil))
|
||||
|
||||
(defun mu4e~proc-is-running ()
|
||||
"Whether the mu process is running."
|
||||
(and mu4e~proc-process (eq (process-status mu4e~proc-process) 'run)))
|
||||
|
||||
|
||||
(defun mu4e~proc-eat-sexp-from-buf ()
|
||||
"'Eat' the next s-expression from `mu4e~proc-buf'. `mu4e~proc-buf gets its
|
||||
|
@ -102,10 +106,10 @@ updated as well, with all processed sexp data removed."
|
|||
|
||||
(defun mu4e~proc-filter (proc str)
|
||||
"A process-filter for the 'mu server' output; it accumulates the
|
||||
strings into valid sexps by checking of the ';;eox' end-of-sexp
|
||||
marker, and then evaluating them.
|
||||
strings into valid sexps by checking of the ';;eox' end-of-sexp
|
||||
marker, and then evaluating them.
|
||||
|
||||
The server output is as follows:
|
||||
The server output is as follows:
|
||||
|
||||
1. an error
|
||||
(:error 2 :message \"unknown command\")
|
||||
|
@ -344,8 +348,10 @@ will receive (:info add :path <path> :docid <docid>)."
|
|||
|
||||
(defun mu4e~proc-sent (path maildir)
|
||||
"Add the message at PATH to the database, with MAILDIR set to the
|
||||
maildir this message resides in, e.g. '/drafts'; if this works, we
|
||||
will receive (:info add :path <path> :docid <docid>)."
|
||||
maildir this message resides in, e.g. '/drafts'.
|
||||
|
||||
if this works, we will receive (:info add :path <path> :docid
|
||||
<docid> :fcc <path>)."
|
||||
(mu4e~proc-send-command "sent path:\"%s\" maildir:\"%s\""
|
||||
path maildir))
|
||||
|
||||
|
|
|
@ -42,35 +42,60 @@ dir already existed, or has been created, nil otherwise."
|
|||
(t nil)))
|
||||
|
||||
|
||||
|
||||
(defun mu4e~read-option-normalize-list (options)
|
||||
"Turn a list OPTIONS into normal-form for `mu4e-read-option'."
|
||||
;; transform options into 'normal-form', so that in case an option has 'nil
|
||||
;; for CHAR, it's replaced by the first letter of OPTIONSTRING (and that char
|
||||
;; is eaten off OPTIONSTR. If RESULT is nil, replace it by CHAR
|
||||
(map 'list
|
||||
(lambda (option)
|
||||
(if (nth 1 option)
|
||||
(list
|
||||
(nth 0 option)
|
||||
(nth 1 option)
|
||||
(or (nth 2 option) (nth 1 option))) ;
|
||||
(list
|
||||
(substring (nth 0 option) 1) ;; chop off first char
|
||||
(string-to-char (nth 0 option)) ;; first char as shortcut
|
||||
(or (nth 2 option) (nth 1 option)))))
|
||||
options))
|
||||
|
||||
|
||||
(defun mu4e-read-option (prompt options)
|
||||
"Ask user for an option from a list on the input area. PROMPT
|
||||
describes a multiple-choice question to the user, OPTIONS describe
|
||||
the options, and is a list of cells describing particular
|
||||
options. Cells have the following structure:
|
||||
(OPTIONSTRING CHAR) where CHAR is a short-cut character for the
|
||||
|
||||
(OPTIONSTRING CHAR [RESULT])
|
||||
|
||||
where CHAR is a short-cut character for the
|
||||
option, and OPTIONSTRING is a non-empty string describing the
|
||||
option. If CHAR is nil or not-specified, the first character of the
|
||||
optionstring is used.
|
||||
|
||||
If RESULT is provide, this will be returned if the user presses the
|
||||
corresponding CHAR; otherwise, CHAR is returned.
|
||||
|
||||
The options are provided as a list for the user to choose from;
|
||||
user can then choose by typing CHAR.
|
||||
Example:
|
||||
user can then choose by typing CHAR. Example:
|
||||
(mu4e-read-option \"Choose an animal: \"
|
||||
'((\"Monkey\" ?m) (\"Gnu\" ?g) (\"platipus\")))
|
||||
User now will be presented with a list:
|
||||
\"Choose an animal: [m]Monkey, [g]Gnu, [p]latipus\"
|
||||
Function returns the CHAR typed."
|
||||
(let* ((optionkars)
|
||||
\"Choose an animal: [m]Monkey, [g]Gnu, [p]latipus\"."
|
||||
(let* ((options (mu4e~read-option-normalize-list options))
|
||||
(chosen)
|
||||
(optionsstr
|
||||
(mapconcat
|
||||
(lambda (option)
|
||||
(let* ((descr (car option))
|
||||
(lambda (option)
|
||||
(let* ((descr (car option))
|
||||
(kar (and (cdr option) (cadr option))))
|
||||
;; handle the empty kar case
|
||||
(unless kar
|
||||
(setq ;; eat first kar from descr; use it as kar
|
||||
kar (string-to-char descr)
|
||||
descr (substring descr 1)))
|
||||
(add-to-list 'optionkars kar)
|
||||
(concat
|
||||
"[" (propertize (make-string 1 kar)
|
||||
'face 'mu4e-highlight-face) "]"
|
||||
|
@ -79,14 +104,16 @@ Function returns the CHAR typed."
|
|||
(inhibit-quit nil)
|
||||
(okchar)
|
||||
(response))
|
||||
(while (not okchar)
|
||||
(while (not chosen)
|
||||
(message nil) ;; we need to clear the echo area first... why?!
|
||||
(setq response
|
||||
(read-char-exclusive
|
||||
(concat prompt optionsstr
|
||||
" [" (propertize "C-g" 'face 'mu4e-highlight-face) " to quit]")))
|
||||
(setq okchar (member response optionkars)))
|
||||
response))
|
||||
(setq chosen
|
||||
(find-if (lambda (option) (eq response (nth 1 option))) options)))
|
||||
(nth 2 chosen)))
|
||||
|
||||
|
||||
(defun mu4e~get-maildirs-1 (path &optional mdir)
|
||||
"Get maildirs under path, recursively, as a list of relative
|
||||
|
@ -328,40 +355,6 @@ function prefers the text part, but this can be changed by setting
|
|||
;; and finally, remove some crap from the remaining string.
|
||||
(replace-regexp-in-string "[
]" " " body nil nil nil)))
|
||||
|
||||
(defvar mu4e-update-timer nil
|
||||
"*internal* The mu4e update timer.")
|
||||
|
||||
(defconst mu4e-update-mail-name "*mu4e-update-mail*"
|
||||
"*internal* Name of the process to update mail")
|
||||
|
||||
(defun mu4e-update-mail (&optional buf)
|
||||
"Update mail (retrieve using `mu4e-get-mail-command' and update
|
||||
the database afterwards), with output going to BUF if not nil, or
|
||||
discarded if nil. After retrieving mail, update the database. Note,
|
||||
function is asynchronous, returns (almost) immediately, and all the
|
||||
processing takes part in the background, unless buf is non-nil."
|
||||
(unless mu4e-get-mail-command
|
||||
(error "`mu4e-get-mail-command' is not defined"))
|
||||
(let* ((process-connection-type t)
|
||||
(proc (start-process-shell-command
|
||||
mu4e-update-mail-name buf mu4e-get-mail-command)))
|
||||
(message "Retrieving mail...")
|
||||
(set-process-sentinel proc
|
||||
(lambda (proc msg)
|
||||
(let* ((status (process-status proc))
|
||||
(code (process-exit-status proc))
|
||||
;; sadly, fetchmail returns '1' when there is no mail; this is
|
||||
;; not really an error of course, but it's hard to distinguish
|
||||
;; from a genuine error
|
||||
(maybe-error (or (not (eq status 'exit)) (/= code 0))))
|
||||
(message nil)
|
||||
;; there may be an error, give the user up to 5 seconds to check
|
||||
(when maybe-error
|
||||
(sit-for 5))
|
||||
(mu4e~proc-index mu4e-maildir)
|
||||
(let ((buf (process-buffer proc)))
|
||||
(when (buffer-live-p buf)
|
||||
(kill-buffer buf))))))))
|
||||
|
||||
|
||||
(defun mu4e-display-manual ()
|
||||
|
@ -515,10 +508,38 @@ process."
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
(defconst mu4e-update-buffer-name "*mu4e-update*"
|
||||
"*internal* Name of the buffer for message retrieval / database
|
||||
updating.")
|
||||
|
||||
(defun mu4e-update-mail-show-window ()
|
||||
"Try to retrieve mail (using the user-provided shell command),
|
||||
and update the database afterwards, and show the progress in a
|
||||
split-window."
|
||||
(interactive)
|
||||
(unless mu4e-get-mail-command
|
||||
(error "`mu4e-get-mail-command' is not defined"))
|
||||
(let ((buf (get-buffer-create mu4e-update-buffer-name))
|
||||
(win
|
||||
(split-window (selected-window)
|
||||
(- (window-height (selected-window)) 8))))
|
||||
(with-selected-window win
|
||||
(switch-to-buffer buf)
|
||||
(set-window-dedicated-p win t)
|
||||
(erase-buffer)
|
||||
(insert "\n") ;; FIXME -- needed so output starts
|
||||
(mu4e-update-mail buf))))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; start and stopping
|
||||
(defun mu4e-check-requirements ()
|
||||
|
||||
(defun mu4e~check-requirements ()
|
||||
"Check for the settings required for running mu4e."
|
||||
(unless (and mu4e-mu-binary (file-executable-p mu4e-mu-binary))
|
||||
(error "Please set `mu4e-mu-binary' to the full path to the mu
|
||||
|
@ -542,49 +563,40 @@ process."
|
|||
(error "%S must start with a '/'" dir))
|
||||
(unless (mu4e-create-maildir-maybe path)
|
||||
(error "%s (%S) does not exist" path var)))))
|
||||
|
||||
|
||||
(defun mu4e~proc-is-running ()
|
||||
"Whether the mu process is running."
|
||||
(and mu4e~proc-process (eq (process-status mu4e~proc-process) 'run)))
|
||||
|
||||
|
||||
(defun* mu4e (&key (hide-ui nil))
|
||||
"Start mu4e . We do this by sending a 'ping' to the mu server
|
||||
process, and start the main view if the 'pong' we receive from the
|
||||
server has the expected values. If keyword argument :hide-ui is
|
||||
non-nil, don't show the UI."
|
||||
(interactive)
|
||||
(defun mu4e~start (&optional func)
|
||||
"If mu4e is already running, execute function FUNC (if non-nil). Otherwise,
|
||||
check various requirements, then start mu4e. When succesful, call
|
||||
FUNC (if non-nil) afterwards."
|
||||
;; if we're already running, simply go to the main view
|
||||
(if (mu4e~proc-is-running)
|
||||
(unless hide-ui
|
||||
(mu4e-main-view))
|
||||
(progn
|
||||
;; otherwise, check whether all is okay;
|
||||
(mu4e-check-requirements)
|
||||
(if (mu4e~proc-is-running) ;; already running?
|
||||
(when func
|
||||
(funcall func))) ;; yup!
|
||||
(progn ;; nope: check whether all is okay;
|
||||
(mu4e~check-requirements)
|
||||
;; explicit version checks are a bit questionable,
|
||||
;; better to check for specific features
|
||||
(if (< emacs-major-version 23)
|
||||
(error "Emacs >= 23.x is required for mu4e")
|
||||
(progn
|
||||
;; define the closure (when we receive the 'pong'
|
||||
(lexical-let ((hide-ui hide-ui))
|
||||
(setq mu4e-pong-func
|
||||
(lambda (version doccount)
|
||||
(unless (string= version mu4e-mu-version)
|
||||
(error "mu server has version %s, but we need %s"
|
||||
version mu4e-mu-version))
|
||||
(unless hide-ui
|
||||
(mu4e-main-view))
|
||||
(when (and mu4e-update-interval (null mu4e-update-timer))
|
||||
(setq mu4e-update-timer
|
||||
(run-at-time
|
||||
0 mu4e-update-interval 'mu4e-update-mail)))
|
||||
(message "Started mu4e with %d message%s in store"
|
||||
doccount (if (= doccount 1) "" "s")))))
|
||||
(unless (>= emacs-major-version 23)
|
||||
(error "Emacs >= 23.x is required for mu4e"))
|
||||
;; set up the 'pong' handler func
|
||||
(lexical-let ((func func))
|
||||
(setq mu4e-pong-func
|
||||
(lambda (version doccount)
|
||||
(unless (string= version mu4e-mu-version)
|
||||
(error "mu server has version %s, but we need %s"
|
||||
version mu4e-mu-version))
|
||||
(when func (funcall func))
|
||||
(when (and mu4e-update-interval (null mu4e-update-timer))
|
||||
(setq mu4e-update-timer
|
||||
(run-at-time
|
||||
0 mu4e-update-interval 'mu4e-update-mail)))
|
||||
(message "Started mu4e with %d message%s in store"
|
||||
doccount (if (= doccount 1) "" "s")))))
|
||||
;; send the ping
|
||||
(mu4e~proc-ping))))))
|
||||
(mu4e~proc-ping)))
|
||||
|
||||
(defun mu4e-quit()
|
||||
(defun mu4e~stop ()
|
||||
"Quit the mu4e session."
|
||||
(interactive)
|
||||
(when (y-or-n-p "Are you sure you want to quit? ")
|
||||
|
@ -594,7 +606,42 @@ non-nil, don't show the UI."
|
|||
(setq mu4e-update-timer nil))
|
||||
(mu4e~proc-kill)
|
||||
(kill-buffer)))
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defvar mu4e-update-timer nil
|
||||
"*internal* The mu4e update timer.")
|
||||
|
||||
(defconst mu4e-update-mail-name "*mu4e-update-mail*"
|
||||
"*internal* Name of the process to update mail")
|
||||
|
||||
(defun mu4e-update-mail (&optional buf)
|
||||
"Update mail (retrieve using `mu4e-get-mail-command' and update
|
||||
the database afterwards), with output going to BUF if not nil, or
|
||||
discarded if nil. After retrieving mail, update the database. Note,
|
||||
function is asynchronous, returns (almost) immediately, and all the
|
||||
processing takes part in the background, unless buf is non-nil."
|
||||
(unless mu4e-get-mail-command
|
||||
(error "`mu4e-get-mail-command' is not defined"))
|
||||
(let* ((process-connection-type t)
|
||||
(proc (start-process-shell-command
|
||||
mu4e-update-mail-name buf mu4e-get-mail-command)))
|
||||
(message "Retrieving mail...")
|
||||
(set-process-sentinel proc
|
||||
(lambda (proc msg)
|
||||
(let* ((status (process-status proc))
|
||||
(code (process-exit-status proc))
|
||||
;; sadly, fetchmail returns '1' when there is no mail; this is
|
||||
;; not really an error of course, but it's hard to distinguish
|
||||
;; from a genuine error
|
||||
(maybe-error (or (not (eq status 'exit)) (/= code 0))))
|
||||
(message nil)
|
||||
;; there may be an error, give the user up to 5 seconds to check
|
||||
(when maybe-error
|
||||
(sit-for 5))
|
||||
(mu4e~proc-index mu4e-maildir)
|
||||
(let ((buf (process-buffer proc)))
|
||||
(when (buffer-live-p buf)
|
||||
(kill-buffer buf))))))))
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -66,8 +66,25 @@
|
|||
|
||||
;; this one is defined in mu4e-view
|
||||
(setq mu4e-temp-func 'mu4e~view-temp-handler)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defun mu4e ()
|
||||
"Start mu4e."
|
||||
(interactive)
|
||||
;; start mu4e, then show the main view
|
||||
(mu4e~start 'mu4e~main-view))
|
||||
|
||||
(defun mu4e-quit()
|
||||
"Quit the mu4e session."
|
||||
(interactive)
|
||||
(when (y-or-n-p "Are you sure you want to quit? ")
|
||||
(mu4e~stop)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(provide 'mu4e)
|
||||
|
|
Loading…
Reference in New Issue