X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=emacs%2Fnotmuch-tag.el;h=959778819617f9cd23498818b2344103fb008c12;hb=e191d3c574e91199e524acbf6d7199bd58fd73d5;hp=98064a3b6f64378679689840d435ffc10b6cf657;hpb=0cf457b73b4b666314d1a09ac3e31bd0fa2346a6;p=notmuch
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 98064a3b..95977881 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -1,4 +1,4 @@
-;;; notmuch-tag.el --- tag messages within emacs
+;;; notmuch-tag.el --- tag messages within emacs -*- lexical-binding: t -*-
;;
;; Copyright © Damien Cassou
;; Copyright © Carl Worth
@@ -16,20 +16,76 @@
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see .
+;; along with Notmuch. If not, see .
;;
;; Authors: Carl Worth
;; Damien Cassou
-;;
+
;;; Code:
-;;
-(require 'cl)
(require 'crm)
+
(require 'notmuch-lib)
+(declare-function notmuch-search-tag "notmuch"
+ (tag-changes &optional beg end only-matched))
+(declare-function notmuch-show-tag "notmuch-show" (tag-changes))
+(declare-function notmuch-tree-tag "notmuch-tree" (tag-changes))
+(declare-function notmuch-jump "notmuch-jump" (action-map prompt))
+
+;;; Keys
+
+(define-widget 'notmuch-tag-key-type 'list
+ "A single key tagging binding."
+ :format "%v"
+ :args '((list :inline t
+ :format "%v"
+ (key-sequence :tag "Key")
+ (radio :tag "Tag operations"
+ (repeat :tag "Tag list"
+ (string :format "%v" :tag "change"))
+ (variable :tag "Tag variable"))
+ (string :tag "Name"))))
+
+(defcustom notmuch-tagging-keys
+ `((,(kbd "a") notmuch-archive-tags "Archive")
+ (,(kbd "u") notmuch-show-mark-read-tags "Mark read")
+ (,(kbd "f") ("+flagged") "Flag")
+ (,(kbd "s") ("+spam" "-inbox") "Mark as spam")
+ (,(kbd "d") ("+deleted" "-inbox") "Delete"))
+ "A list of keys and corresponding tagging operations.
+
+For each key (or key sequence) you can specify a sequence of
+tagging operations to apply, or a variable which contains a list
+of tagging operations such as `notmuch-archive-tags'. The final
+element is a name for this tagging operation. If the name is
+omitted or empty then the list of tag changes, or the variable
+name is used as the name.
+
+The key `notmuch-tag-jump-reverse-key' (k by default) should not
+be used (either as a key, or as the start of a key sequence) as
+it is already bound: it switches the menu to a menu of the
+reverse tagging operations. The reverse of a tagging operation is
+the same list of individual tag-ops but with `+tag' replaced by
+`-tag' and vice versa.
+
+If setting this variable outside of customize then it should be a
+list of triples (lists of three elements). Each triple should be
+of the form (key-binding tagging-operations name). KEY-BINDING
+can be a single character or a key sequence; TAGGING-OPERATIONS
+should either be a list of individual tag operations each of the
+form `+tag' or `-tag', or the variable name of a variable that is
+a list of tagging operations; NAME should be a name for the
+tagging operation, if omitted or empty than then name is taken
+from TAGGING-OPERATIONS."
+ :tag "List of tagging bindings"
+ :type '(repeat notmuch-tag-key-type)
+ :group 'notmuch-tag)
+
+;;; Faces and Formats
+
(define-widget 'notmuch-tag-format-type 'lazy
- "Customize widget for notmuch-tag-format and friends"
+ "Customize widget for notmuch-tag-format and friends."
:type '(alist :key-type (regexp :tag "Tag")
:extra-offset -3
:value-type
@@ -56,26 +112,48 @@
(string :tag "Custom")))
(sexp :tag "Custom")))))
+(defface notmuch-tag-unread
+ '((t :foreground "red"))
+ "Default face used for the unread tag.
+
+Used in the default value of `notmuch-tag-formats'."
+ :group 'notmuch-faces)
+
+(defface notmuch-tag-flagged
+ '((((class color)
+ (background dark))
+ (:foreground "LightBlue1"))
+ (((class color)
+ (background light))
+ (:foreground "blue")))
+ "Face used for the flagged tag.
+
+Used in the default value of `notmuch-tag-formats'."
+ :group 'notmuch-faces)
+
(defcustom notmuch-tag-formats
- '(("unread" (propertize tag 'face '(:foreground "red")))
- ("flagged" (propertize tag 'face '(:foreground "blue"))
+ '(("unread" (propertize tag 'face 'notmuch-tag-unread))
+ ("flagged" (propertize tag 'face 'notmuch-tag-flagged)
(notmuch-tag-format-image-data tag (notmuch-tag-star-icon))))
"Custom formats for individual tags.
-This is an association list that maps from tag name regexps to
-lists of formatting expressions. The first entry whose car
-regexp-matches a tag will be used to format that tag. The regexp
-is implicitly anchored, so to match a literal tag name, just use
-that tag name (if it contains special regexp characters like
-\".\" or \"*\", these have to be escaped). The cdr of the
-matching entry gives a list of Elisp expressions that modify the
-tag. If the list is empty, the tag will simply be hidden.
-Otherwise, each expression will be evaluated in order: for the
-first expression, the variable `tag' will be bound to the tag
-name; for each later expression, the variable `tag' will be bound
-to the result of the previous expression. In this way, each
+This is an association list of the form ((MATCH EXPR...)...),
+mapping tag name regexps to lists of formatting expressions.
+
+The first entry whose MATCH regexp-matches a tag is used to
+format that tag. The regexp is implicitly anchored, so to match
+a literal tag name, just use that tag name (if it contains
+special regexp characters like \".\" or \"*\", these have to be
+escaped).
+
+The cdr of the matching entry gives a list of Elisp expressions
+that modify the tag. If the list is empty, the tag is simply
+hidden. Otherwise, each expression EXPR is evaluated in order:
+for the first expression, the variable `tag' is bound to the tag
+name; for each later expression, the variable `tag' is bound to
+the result of the previous expression. In this way, each
expression can build on the formatting performed by the previous
-expression. The result of the last expression will displayed in
+expression. The result of the last expression is displayed in
place of the tag.
For example, to replace a tag with another string, simply use
@@ -90,18 +168,20 @@ with images."
:group 'notmuch-faces
:type 'notmuch-tag-format-type)
+(defface notmuch-tag-deleted
+ '((((class color) (supports :strike-through "red")) :strike-through "red")
+ (t :inverse-video t))
+ "Face used to display deleted tags.
+
+Used in the default value of `notmuch-tag-deleted-formats'."
+ :group 'notmuch-faces)
+
(defcustom notmuch-tag-deleted-formats
- '(("unread" (notmuch-apply-face bare-tag
- (if (display-supports-face-attributes-p '(:strike-through "red"))
- '(:strike-through "red")
- '(:inverse-video t))))
- (".*" (notmuch-apply-face tag
- (if (display-supports-face-attributes-p '(:strike-through "red"))
- '(:strike-through "red")
- '(:inverse-video t)))))
+ '(("unread" (notmuch-apply-face bare-tag `notmuch-tag-deleted))
+ (".*" (notmuch-apply-face tag `notmuch-tag-deleted)))
"Custom formats for tags when deleted.
-For deleted tags the formats in `notmuch-tag-formats` are applied
+For deleted tags the formats in `notmuch-tag-formats' are applied
first and then these formats are applied on top; that is `tag'
passed to the function is the tag with all these previous
formattings applied. The formatted can access the original
@@ -118,11 +198,18 @@ See `notmuch-tag-formats' for full documentation."
:group 'notmuch-faces
:type 'notmuch-tag-format-type)
+(defface notmuch-tag-added
+ '((t :underline "green"))
+ "Default face used for added tags.
+
+Used in the default value for `notmuch-tag-added-formats'."
+ :group 'notmuch-faces)
+
(defcustom notmuch-tag-added-formats
- '((".*" (notmuch-apply-face tag '(:underline "green"))))
+ '((".*" (notmuch-apply-face tag 'notmuch-tag-added)))
"Custom formats for tags when added.
-For added tags the formats in `notmuch-tag-formats` are applied
+For added tags the formats in `notmuch-tag-formats' are applied
first and then these formats are applied on top.
To disable special formatting of added tags, set this variable to
@@ -133,6 +220,8 @@ See `notmuch-tag-formats' for full documentation."
:group 'notmuch-faces
:type 'notmuch-tag-format-type)
+;;; Icons
+
(defun notmuch-tag-format-image-data (tag data)
"Replace TAG with image DATA, if available.
@@ -151,8 +240,8 @@ DATA is the content of an SVG picture (e.g., as returned by
(defun notmuch-tag-star-icon ()
"Return SVG data representing a star icon.
This can be used with `notmuch-tag-format-image-data'."
-"
-