2019-08-19 12:41:33 +02:00
|
|
|
|
;;; mu4e-view.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
|
2020-02-11 12:23:40 +01:00
|
|
|
|
|
2021-03-04 21:10:28 +01:00
|
|
|
|
;; Copyright (C) 2021 Dirk-Jan C. Binnema
|
2011-09-18 13:39:36 +02:00
|
|
|
|
|
|
|
|
|
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
|
|
|
|
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
|
|
|
|
|
|
|
|
|
;; This file is not part of GNU Emacs.
|
2020-02-11 12:23:40 +01:00
|
|
|
|
|
2011-09-18 13:39:36 +02:00
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; 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
|
|
|
|
|
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
2012-03-31 16:20:03 +02:00
|
|
|
|
;; In this file we define mu4e-view-mode (+ helper functions), which is used for
|
|
|
|
|
;; viewing e-mail messages
|
2011-09-18 13:39:36 +02:00
|
|
|
|
|
|
|
|
|
;;; Code:
|
2020-02-11 15:10:35 +01:00
|
|
|
|
|
|
|
|
|
;;; Options
|
|
|
|
|
|
2012-04-24 17:13:12 +02:00
|
|
|
|
(defgroup mu4e-view nil
|
|
|
|
|
"Settings for the message view."
|
|
|
|
|
:group 'mu4e)
|
|
|
|
|
|
2021-03-07 16:35:30 +01:00
|
|
|
|
(defcustom mu4e-view-use-gnus t
|
2021-03-04 21:10:28 +01:00
|
|
|
|
"If non-nil, use the new Gnus-based viewer.
|
|
|
|
|
Otherwise, use the old viewer."
|
2018-04-24 13:21:15 +02:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'mu4e-view)
|
|
|
|
|
|
2012-10-17 11:07:57 +02:00
|
|
|
|
(defcustom mu4e-view-scroll-to-next t
|
2018-12-01 11:29:07 +01:00
|
|
|
|
"Move to the next message when calling
|
|
|
|
|
`mu4e-view-scroll-up-or-next' (typically bound to SPC) when at
|
|
|
|
|
the end of a message. Otherwise, don't move to the next message."
|
2017-09-02 14:37:35 +02:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'mu4e-view)
|
2021-03-07 21:03:36 +01:00
|
|
|
|
|
|
|
|
|
(defcustom mu4e-view-fields
|
|
|
|
|
'(:from :to :cc :subject :flags :date :maildir :mailing-list :tags
|
|
|
|
|
:attachments :signature :decryption)
|
|
|
|
|
"Header fields to display in the message view buffer.
|
|
|
|
|
For the complete list of available headers, see `mu4e-header-info'."
|
|
|
|
|
:type (list 'symbol)
|
|
|
|
|
:group 'mu4e-view)
|
2012-10-17 11:07:57 +02:00
|
|
|
|
|
2019-12-31 17:20:15 +01:00
|
|
|
|
(defcustom mu4e-view-actions
|
2015-11-07 06:36:31 +01:00
|
|
|
|
'( ("capture message" . mu4e-action-capture-message)
|
|
|
|
|
("view as pdf" . mu4e-action-view-as-pdf)
|
|
|
|
|
("show this thread" . mu4e-action-show-thread))
|
2012-11-10 14:01:17 +01:00
|
|
|
|
"List of actions to perform on messages in view mode.
|
2017-11-04 14:06:45 +01:00
|
|
|
|
The actions are cons-cells of the form:
|
|
|
|
|
(NAME . FUNC)
|
2012-04-24 17:13:12 +02:00
|
|
|
|
where:
|
|
|
|
|
* NAME is the name of the action (e.g. \"Count lines\")
|
2012-07-10 10:51:54 +02:00
|
|
|
|
* FUNC is a function which receives a message plist as an argument.
|
|
|
|
|
|
2019-12-31 17:20:15 +01:00
|
|
|
|
The first letter of NAME is used as a shortcut character."
|
|
|
|
|
:group 'mu4e-view
|
|
|
|
|
:type '(alist :key-type string :value-type function))
|
2012-04-28 12:47:13 +02:00
|
|
|
|
|
2020-02-11 15:10:35 +01:00
|
|
|
|
|
2014-04-27 10:54:15 +02:00
|
|
|
|
|
2017-05-18 03:42:52 +02:00
|
|
|
|
(defun mu4e-view (msg)
|
2011-09-18 13:39:36 +02:00
|
|
|
|
"Display the message MSG in a new buffer, and keep in sync with HDRSBUF.
|
|
|
|
|
'In sync' here means that moving to the next/previous message in
|
2012-04-29 21:03:27 +02:00
|
|
|
|
the the message view affects HDRSBUF, as does marking etc.
|
2014-10-10 17:34:57 +02:00
|
|
|
|
|
2011-09-18 13:39:36 +02:00
|
|
|
|
As a side-effect, a message that is being viewed loses its 'unread'
|
2018-04-24 13:21:15 +02:00
|
|
|
|
marking if it still had that.
|
|
|
|
|
|
|
|
|
|
Depending on the value of `mu4e-view-use-gnus', either use mu4e's
|
2020-03-06 13:23:30 +01:00
|
|
|
|
internal display mode, or a display mode based on Gnus'
|
2018-04-24 13:21:15 +02:00
|
|
|
|
article-mode."
|
2020-06-10 16:36:38 +02:00
|
|
|
|
(mu4e~headers-update-handler msg nil nil);; update headers, if necessary.
|
|
|
|
|
|
2021-03-04 21:10:28 +01:00
|
|
|
|
;; sanity check; only one can be active.
|
2020-06-10 16:36:38 +02:00
|
|
|
|
(if mu4e-view-use-gnus
|
2021-03-04 21:10:28 +01:00
|
|
|
|
(progn
|
|
|
|
|
(when (featurep 'mu4e-view-old)
|
|
|
|
|
(mu4e-error "Cannot load gnus-based view with old one loaded. Restart emacs"))
|
|
|
|
|
(require 'mu4e-view-gnus)
|
|
|
|
|
(mu4e~view-gnus msg))
|
|
|
|
|
(progn
|
|
|
|
|
(when (featurep 'mu4e-view-gnus)
|
|
|
|
|
(mu4e-error "Cannot load old view with gnus-based view loaded. Restart emacs"))
|
|
|
|
|
(require 'mu4e-view-old)
|
|
|
|
|
(mu4e~view-old msg))))
|
2012-07-18 16:53:04 +02:00
|
|
|
|
|
2014-10-19 02:20:21 +02:00
|
|
|
|
|
2012-09-19 15:56:13 +02:00
|
|
|
|
|
2021-03-04 21:10:28 +01:00
|
|
|
|
(defun mu4e~view-quit-buffer ()
|
|
|
|
|
"Quit the mu4e-view buffer.
|
|
|
|
|
This is a rather complex function, to ensure we don't disturb
|
|
|
|
|
other windows."
|
2014-02-06 09:01:13 +01:00
|
|
|
|
(interactive)
|
2021-03-04 21:10:28 +01:00
|
|
|
|
(if (eq mu4e-split-view 'single-window)
|
|
|
|
|
(when (buffer-live-p (mu4e-get-view-buffer))
|
|
|
|
|
(kill-buffer (mu4e-get-view-buffer)))
|
|
|
|
|
(unless (eq major-mode 'mu4e-view-mode)
|
|
|
|
|
(mu4e-error "Must be in mu4e-view-mode (%S)" major-mode))
|
|
|
|
|
(let ((curbuf (current-buffer))
|
|
|
|
|
(curwin (selected-window))
|
|
|
|
|
(headers-win))
|
|
|
|
|
(walk-windows
|
|
|
|
|
(lambda (win)
|
|
|
|
|
;; check whether the headers buffer window is visible
|
|
|
|
|
(when (eq (mu4e-get-headers-buffer) (window-buffer win))
|
|
|
|
|
(setq headers-win win))
|
|
|
|
|
;; and kill any _other_ (non-selected) window that shows the current
|
|
|
|
|
;; buffer
|
|
|
|
|
(when
|
|
|
|
|
(and
|
|
|
|
|
(eq curbuf (window-buffer win)) ;; does win show curbuf?
|
|
|
|
|
(not (eq curwin win)) ;; but it's not the curwin?
|
|
|
|
|
(not (one-window-p))) ;; and not the last one on the frame?
|
|
|
|
|
(delete-window win)))) ;; delete it!
|
|
|
|
|
;; now, all *other* windows should be gone.
|
|
|
|
|
;; if the headers view is also visible, kill ourselves + window; otherwise
|
|
|
|
|
;; switch to the headers view
|
|
|
|
|
(if (window-live-p headers-win)
|
|
|
|
|
;; headers are visible
|
|
|
|
|
(progn
|
|
|
|
|
(kill-buffer-and-window) ;; kill the view win
|
|
|
|
|
(setq mu4e~headers-view-win nil)
|
|
|
|
|
(select-window headers-win)) ;; and switch to the headers win...
|
|
|
|
|
;; headers are not visible...
|
|
|
|
|
(progn
|
|
|
|
|
(kill-buffer)
|
|
|
|
|
(setq mu4e~headers-view-win nil)
|
|
|
|
|
(when (buffer-live-p (mu4e-get-headers-buffer))
|
|
|
|
|
(switch-to-buffer (mu4e-get-headers-buffer))))))))
|
2012-11-25 17:33:03 +01:00
|
|
|
|
|
2018-04-24 13:21:15 +02:00
|
|
|
|
|
2021-03-04 21:10:28 +01:00
|
|
|
|
(defconst mu4e~view-raw-buffer-name " *mu4e-raw-view*"
|
|
|
|
|
"Name for the raw message view buffer.")
|
2012-06-26 21:49:34 +02:00
|
|
|
|
|
2021-03-04 21:10:28 +01:00
|
|
|
|
(defun mu4e-view-raw-message ()
|
|
|
|
|
"Display the raw contents of message at point in a new buffer."
|
2014-02-06 09:01:13 +01:00
|
|
|
|
(interactive)
|
2021-03-04 21:10:28 +01:00
|
|
|
|
(let ((path (mu4e-message-field-at-point :path))
|
|
|
|
|
(buf (get-buffer-create mu4e~view-raw-buffer-name)))
|
|
|
|
|
(unless (and path (file-readable-p path))
|
|
|
|
|
(mu4e-error "Not a readable file: %S" path))
|
|
|
|
|
(with-current-buffer buf
|
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(insert-file-contents path)
|
|
|
|
|
(view-mode)
|
|
|
|
|
(goto-char (point-min))))
|
|
|
|
|
(switch-to-buffer buf)))
|
2012-05-20 18:59:57 +02:00
|
|
|
|
|
2021-03-04 21:10:28 +01:00
|
|
|
|
(defun mu4e-view-pipe (cmd)
|
|
|
|
|
"Pipe the message at point through shell command CMD.
|
|
|
|
|
Then, display the results."
|
|
|
|
|
(interactive "sShell command: ")
|
|
|
|
|
(let ((path (mu4e-message-field (mu4e-message-at-point) :path)))
|
|
|
|
|
(mu4e-process-file-through-pipe path cmd)))
|
2015-03-21 09:28:01 +01:00
|
|
|
|
|
2012-01-06 11:31:28 +01:00
|
|
|
|
|
2012-04-23 19:35:14 +02:00
|
|
|
|
|
2012-05-06 15:57:11 +02:00
|
|
|
|
(defmacro mu4e~view-in-headers-context (&rest body)
|
2013-06-08 16:36:29 +02:00
|
|
|
|
"Evaluate BODY in the context of the headers buffer connected to
|
|
|
|
|
this view."
|
2012-05-06 15:57:11 +02:00
|
|
|
|
`(progn
|
2017-05-18 03:42:52 +02:00
|
|
|
|
(unless (buffer-live-p (mu4e-get-headers-buffer))
|
|
|
|
|
(mu4e-error "no headers buffer connected"))
|
2012-09-26 16:28:30 +02:00
|
|
|
|
(let* ((msg (mu4e-message-at-point))
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(docid (mu4e-message-field msg :docid)))
|
2012-09-21 11:35:53 +02:00
|
|
|
|
(unless docid
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(mu4e-error "message without docid: action is not possible."))
|
2017-05-18 03:42:52 +02:00
|
|
|
|
(with-current-buffer (mu4e-get-headers-buffer)
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(unless (eq mu4e-split-view 'single-window)
|
|
|
|
|
(when (get-buffer-window)
|
|
|
|
|
(select-window (get-buffer-window))))
|
|
|
|
|
(if (mu4e~headers-goto-docid docid)
|
|
|
|
|
,@body
|
|
|
|
|
(mu4e-error "cannot find message in headers buffer."))))))
|
2012-04-23 19:35:14 +02:00
|
|
|
|
|
2014-11-28 07:54:08 +01:00
|
|
|
|
(defun mu4e-view-headers-next (&optional n)
|
2012-05-06 10:00:56 +02:00
|
|
|
|
"Move point to the next message header in the headers buffer
|
|
|
|
|
connected with this message view. If this succeeds, return the new
|
|
|
|
|
docid. Otherwise, return nil. Optionally, takes an integer
|
|
|
|
|
N (prefix argument), to the Nth next header."
|
|
|
|
|
(interactive "P")
|
2012-05-06 15:57:11 +02:00
|
|
|
|
(mu4e~view-in-headers-context
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(mu4e~headers-move (or n 1))))
|
2012-05-06 10:00:56 +02:00
|
|
|
|
|
2014-11-28 07:54:08 +01:00
|
|
|
|
(defun mu4e-view-headers-prev (&optional n)
|
2012-05-06 10:00:56 +02:00
|
|
|
|
"Move point to the previous message header in the headers buffer
|
|
|
|
|
connected with this message view. If this succeeds, return the new
|
|
|
|
|
docid. Otherwise, return nil. Optionally, takes an integer
|
|
|
|
|
N (prefix argument), to the Nth previous header."
|
|
|
|
|
(interactive "P")
|
2012-05-06 15:57:11 +02:00
|
|
|
|
(mu4e~view-in-headers-context
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(mu4e~headers-move (- (or n 1)))))
|
2012-04-20 17:23:47 +02:00
|
|
|
|
|
2015-11-22 22:32:05 +01:00
|
|
|
|
(defun mu4e~view-prev-or-next-unread (backwards)
|
2014-11-28 07:54:08 +01:00
|
|
|
|
"Move point to the next or previous (when BACKWARDS is non-`nil')
|
|
|
|
|
unread message header in the headers buffer connected with this
|
|
|
|
|
message view. If this succeeds, return the new docid. Otherwise,
|
|
|
|
|
return nil."
|
2017-02-12 10:11:16 +01:00
|
|
|
|
(mu4e~view-in-headers-context
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(mu4e~headers-prev-or-next-unread backwards))
|
2017-05-18 03:42:52 +02:00
|
|
|
|
(if (eq mu4e-split-view 'single-window)
|
|
|
|
|
(when (eq (window-buffer) (mu4e-get-view-buffer))
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(with-current-buffer (mu4e-get-headers-buffer)
|
|
|
|
|
(mu4e-headers-view-message)))
|
2017-05-18 03:42:52 +02:00
|
|
|
|
(mu4e-select-other-view)
|
|
|
|
|
(mu4e-headers-view-message)))
|
2014-11-28 07:54:08 +01:00
|
|
|
|
|
2015-11-22 22:32:05 +01:00
|
|
|
|
(defun mu4e-view-headers-prev-unread ()
|
2020-02-11 12:00:46 +01:00
|
|
|
|
"Move point to the previous unread message header in the headers
|
2015-11-22 22:32:05 +01:00
|
|
|
|
buffer connected with this message view. If this succeeds, return
|
|
|
|
|
the new docid. Otherwise, return nil."
|
|
|
|
|
(interactive)
|
|
|
|
|
(mu4e~view-prev-or-next-unread t))
|
|
|
|
|
|
|
|
|
|
(defun mu4e-view-headers-next-unread ()
|
|
|
|
|
"Move point to the next unread message header in the headers
|
|
|
|
|
buffer connected with this message view. If this succeeds, return
|
|
|
|
|
the new docid. Otherwise, return nil."
|
|
|
|
|
(interactive)
|
|
|
|
|
(mu4e~view-prev-or-next-unread nil))
|
2014-11-28 07:54:08 +01:00
|
|
|
|
|
2012-09-19 15:56:13 +02:00
|
|
|
|
|
2020-02-11 15:10:35 +01:00
|
|
|
|
;;; Interactive functions
|
2012-04-20 17:23:47 +02:00
|
|
|
|
(defun mu4e-view-action (&optional msg)
|
2012-11-10 14:01:17 +01:00
|
|
|
|
"Ask user for some action to apply on MSG, then do it.
|
|
|
|
|
If MSG is nil apply action to message returned
|
|
|
|
|
bymessage-at-point. The actions are specified in
|
2012-04-20 17:23:47 +02:00
|
|
|
|
`mu4e-view-actions'."
|
|
|
|
|
(interactive)
|
2012-09-26 16:28:30 +02:00
|
|
|
|
(let* ((msg (or msg (mu4e-message-at-point)))
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(actionfunc (mu4e-read-option "Action: " mu4e-view-actions)))
|
2012-04-20 17:23:47 +02:00
|
|
|
|
(funcall actionfunc msg)))
|
|
|
|
|
|
2012-05-10 08:55:28 +02:00
|
|
|
|
(defun mu4e-view-mark-pattern ()
|
2020-02-11 12:00:46 +01:00
|
|
|
|
"Ask user for a kind of mark (move, delete etc.), a field to
|
2012-04-24 21:37:42 +02:00
|
|
|
|
match and a regular expression to match with. Then, mark all
|
|
|
|
|
matching messages with that mark."
|
|
|
|
|
(interactive)
|
2012-09-30 19:12:24 +02:00
|
|
|
|
(mu4e~view-in-headers-context (mu4e-headers-mark-pattern)))
|
2012-04-26 21:42:53 +02:00
|
|
|
|
|
2015-11-23 12:33:50 +01:00
|
|
|
|
(defun mu4e-view-mark-thread (&optional markpair)
|
|
|
|
|
"Ask user for a kind of mark (move, delete etc.), and apply it
|
|
|
|
|
to all messages in the thread at point in the headers view. The
|
|
|
|
|
optional MARKPAIR can also be used to provide the mark
|
|
|
|
|
selection."
|
2012-04-26 21:42:53 +02:00
|
|
|
|
(interactive)
|
2015-11-23 12:33:50 +01:00
|
|
|
|
(mu4e~view-in-headers-context
|
|
|
|
|
(if markpair (mu4e-headers-mark-thread nil markpair)
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(call-interactively 'mu4e-headers-mark-thread))))
|
2015-11-23 12:33:50 +01:00
|
|
|
|
|
|
|
|
|
(defun mu4e-view-mark-subthread (&optional markpair)
|
|
|
|
|
"Ask user for a kind of mark (move, delete etc.), and apply it
|
|
|
|
|
to all messages in the subthread at point in the headers view.
|
|
|
|
|
The optional MARKPAIR can also be used to provide the mark
|
|
|
|
|
selection."
|
2012-04-26 21:42:53 +02:00
|
|
|
|
(interactive)
|
2015-11-23 12:33:50 +01:00
|
|
|
|
(mu4e~view-in-headers-context
|
|
|
|
|
(if markpair (mu4e-headers-mark-subthread markpair)
|
|
|
|
|
(mu4e-headers-mark-subthread))))
|
2012-04-26 21:42:53 +02:00
|
|
|
|
|
2012-06-10 12:24:41 +02:00
|
|
|
|
(defun mu4e-view-search-narrow ()
|
2012-05-06 15:57:11 +02:00
|
|
|
|
"Run `mu4e-headers-search-narrow' in the headers buffer."
|
2012-06-10 12:24:41 +02:00
|
|
|
|
(interactive)
|
2016-01-10 12:08:18 +01:00
|
|
|
|
(mu4e~view-in-headers-context
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(call-interactively 'mu4e-headers-search-narrow)))
|
2012-05-06 15:57:11 +02:00
|
|
|
|
|
2012-06-10 12:24:41 +02:00
|
|
|
|
(defun mu4e-view-search-edit ()
|
2012-05-06 15:57:11 +02:00
|
|
|
|
"Run `mu4e-headers-search-edit' in the headers buffer."
|
2012-06-10 12:24:41 +02:00
|
|
|
|
(interactive)
|
2012-09-30 19:12:24 +02:00
|
|
|
|
(mu4e~view-in-headers-context (mu4e-headers-search-edit)))
|
2012-04-26 21:42:53 +02:00
|
|
|
|
|
2014-03-24 09:17:25 +01:00
|
|
|
|
(defun mu4e-mark-region-code ()
|
2014-03-24 09:22:39 +01:00
|
|
|
|
"Highlight region marked with `message-mark-inserted-region'.
|
|
|
|
|
Add this function to `mu4e-view-mode-hook' to enable this feature."
|
2014-03-24 09:17:25 +01:00
|
|
|
|
(require 'message)
|
|
|
|
|
(let (beg end ov-beg ov-end ov-inv)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(while (re-search-forward
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(concat "^" message-mark-insert-begin) nil t)
|
|
|
|
|
(setq ov-beg (match-beginning 0)
|
|
|
|
|
ov-end (match-end 0)
|
|
|
|
|
ov-inv (make-overlay ov-beg ov-end)
|
|
|
|
|
beg ov-end)
|
|
|
|
|
(overlay-put ov-inv 'invisible t)
|
|
|
|
|
(when (re-search-forward
|
|
|
|
|
(concat "^" message-mark-insert-end) nil t)
|
|
|
|
|
(setq ov-beg (match-beginning 0)
|
|
|
|
|
ov-end (match-end 0)
|
|
|
|
|
ov-inv (make-overlay ov-beg ov-end)
|
|
|
|
|
end ov-beg)
|
|
|
|
|
(overlay-put ov-inv 'invisible t))
|
|
|
|
|
(when (and beg end)
|
|
|
|
|
(let ((ov (make-overlay beg end)))
|
|
|
|
|
(overlay-put ov 'face 'mu4e-region-code))
|
|
|
|
|
(setq beg nil end nil))))))
|
2014-03-24 09:17:25 +01:00
|
|
|
|
|
2020-02-18 22:39:30 +01:00
|
|
|
|
;;; View Utilities
|
2012-10-01 20:17:05 +02:00
|
|
|
|
|
|
|
|
|
(defun mu4e-view-mark-custom ()
|
2012-06-14 20:54:24 +02:00
|
|
|
|
"Run some custom mark function."
|
|
|
|
|
(mu4e~view-in-headers-context
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(mu4e-headers-mark-custom)))
|
2012-04-23 18:07:20 +02:00
|
|
|
|
|
2012-10-01 20:17:05 +02:00
|
|
|
|
(defun mu4e~view-split-view-p ()
|
2012-04-09 10:51:24 +02:00
|
|
|
|
"Return t if we're in split-view, nil otherwise."
|
|
|
|
|
(member mu4e-split-view '(horizontal vertical)))
|
2012-10-03 11:53:16 +02:00
|
|
|
|
|
2020-02-11 15:10:35 +01:00
|
|
|
|
;;; Scroll commands
|
|
|
|
|
|
2012-10-17 11:07:57 +02:00
|
|
|
|
(defun mu4e-view-scroll-up-or-next ()
|
2012-11-10 14:01:17 +01:00
|
|
|
|
"Scroll-up the current message.
|
|
|
|
|
If `mu4e-view-scroll-to-next' is non-nil, and we can't scroll-up
|
|
|
|
|
anymore, go the next message."
|
2012-10-17 11:07:57 +02:00
|
|
|
|
(interactive)
|
2012-10-17 11:26:11 +02:00
|
|
|
|
(condition-case nil
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(scroll-up)
|
2012-10-17 11:26:11 +02:00
|
|
|
|
(error
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(when mu4e-view-scroll-to-next
|
|
|
|
|
(mu4e-view-headers-next)))))
|
2012-10-22 22:52:50 +02:00
|
|
|
|
|
2012-11-11 14:27:10 +01:00
|
|
|
|
(defun mu4e-scroll-up ()
|
|
|
|
|
"Scroll text of selected window up one line."
|
|
|
|
|
(interactive)
|
|
|
|
|
(scroll-up 1))
|
|
|
|
|
|
|
|
|
|
(defun mu4e-scroll-down ()
|
|
|
|
|
"Scroll text of selected window down one line."
|
|
|
|
|
(interactive)
|
|
|
|
|
(scroll-down 1))
|
|
|
|
|
|
2020-02-11 15:10:35 +01:00
|
|
|
|
;;; Mark commands
|
|
|
|
|
|
2012-04-09 10:51:24 +02:00
|
|
|
|
(defun mu4e-view-unmark-all ()
|
2012-11-10 14:01:17 +01:00
|
|
|
|
"If we're in split-view, unmark all messages.
|
|
|
|
|
Otherwise, warn user that unmarking only works in the header
|
|
|
|
|
list."
|
2011-09-18 13:39:36 +02:00
|
|
|
|
(interactive)
|
2012-10-01 20:17:05 +02:00
|
|
|
|
(if (mu4e~view-split-view-p)
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(mu4e~view-in-headers-context (mu4e-mark-unmark-all))
|
2012-05-02 16:26:57 +02:00
|
|
|
|
(mu4e-message "Unmarking needs to be done in the header list view")))
|
2011-09-18 13:39:36 +02:00
|
|
|
|
|
2012-04-09 10:51:24 +02:00
|
|
|
|
(defun mu4e-view-unmark ()
|
2012-11-10 14:01:17 +01:00
|
|
|
|
"If we're in split-view, unmark message at point.
|
|
|
|
|
Otherwise, warn user that unmarking only works in the header
|
|
|
|
|
list."
|
2012-04-09 10:51:24 +02:00
|
|
|
|
(interactive)
|
2012-10-01 20:17:05 +02:00
|
|
|
|
(if (mu4e~view-split-view-p)
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(mu4e-view-mark-for-unmark)
|
2012-05-02 16:26:57 +02:00
|
|
|
|
(mu4e-message "Unmarking needs to be done in the header list view")))
|
2011-09-18 13:39:36 +02:00
|
|
|
|
|
2012-09-27 20:53:21 +02:00
|
|
|
|
(defmacro mu4e~view-defun-mark-for (mark)
|
|
|
|
|
"Define a function mu4e-view-mark-for-MARK."
|
2012-11-11 14:39:02 +01:00
|
|
|
|
(let ((funcname (intern (format "mu4e-view-mark-for-%s" mark)))
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(docstring (format "Mark the current message for %s." mark)))
|
2012-11-11 14:39:02 +01:00
|
|
|
|
`(progn
|
|
|
|
|
(defun ,funcname () ,docstring
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(interactive)
|
|
|
|
|
(mu4e~view-in-headers-context
|
|
|
|
|
(mu4e-headers-mark-and-next ',mark)))
|
2012-11-11 14:39:02 +01:00
|
|
|
|
(put ',funcname 'definition-name ',mark))))
|
2012-09-27 20:53:21 +02:00
|
|
|
|
|
|
|
|
|
(mu4e~view-defun-mark-for move)
|
|
|
|
|
(mu4e~view-defun-mark-for refile)
|
|
|
|
|
(mu4e~view-defun-mark-for delete)
|
|
|
|
|
(mu4e~view-defun-mark-for flag)
|
|
|
|
|
(mu4e~view-defun-mark-for unflag)
|
|
|
|
|
(mu4e~view-defun-mark-for unmark)
|
2013-02-11 22:49:39 +01:00
|
|
|
|
(mu4e~view-defun-mark-for something)
|
2014-11-30 10:49:41 +01:00
|
|
|
|
(mu4e~view-defun-mark-for read)
|
|
|
|
|
(mu4e~view-defun-mark-for unread)
|
2020-05-18 17:51:25 +02:00
|
|
|
|
(mu4e~view-defun-mark-for trash)
|
2017-06-17 10:59:16 +02:00
|
|
|
|
(mu4e~view-defun-mark-for untrash)
|
2012-06-14 18:10:02 +02:00
|
|
|
|
|
2013-05-04 13:15:35 +02:00
|
|
|
|
(defun mu4e-view-marked-execute ()
|
2018-12-01 11:29:07 +01:00
|
|
|
|
"Execute the marked actions."
|
2011-09-18 13:39:36 +02:00
|
|
|
|
(interactive)
|
2012-05-06 15:57:11 +02:00
|
|
|
|
(mu4e~view-in-headers-context
|
2020-02-11 12:00:46 +01:00
|
|
|
|
(mu4e-mark-execute-all)))
|
2011-09-18 13:39:36 +02:00
|
|
|
|
|
2020-02-11 15:10:35 +01:00
|
|
|
|
|
2011-12-13 08:07:38 +01:00
|
|
|
|
(provide 'mu4e-view)
|
2020-02-11 12:38:01 +01:00
|
|
|
|
;;; mu4e-view.el ends here
|