mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-23 03:18:08 +01:00
Merge branch 'upstream' into debian
This commit is contained in:
commit
518c8c0d3f
4 changed files with 68 additions and 59 deletions
16
TODO
16
TODO
|
@ -8,6 +8,12 @@ Fix the things that are causing the most pain to new users
|
||||||
|
|
||||||
Emacs interface (notmuch.el)
|
Emacs interface (notmuch.el)
|
||||||
----------------------------
|
----------------------------
|
||||||
|
Enhance '+' and '-' in the search view to operate on an entire region
|
||||||
|
if set.
|
||||||
|
|
||||||
|
Fix '*' to work by simply calling '+' or '-' on a region consisting of
|
||||||
|
the entire buffer.
|
||||||
|
|
||||||
Add a global keybinding table for notmuch, and then view-specific
|
Add a global keybinding table for notmuch, and then view-specific
|
||||||
tables that add to it.
|
tables that add to it.
|
||||||
|
|
||||||
|
@ -44,6 +50,10 @@ and *then* --max-threads), and also complete value for --sort=
|
||||||
|
|
||||||
notmuch command-line tool
|
notmuch command-line tool
|
||||||
-------------------------
|
-------------------------
|
||||||
|
Implement "notmuch search --exclude-threads=<search-terms>" to allow
|
||||||
|
for excluding muted threads, (and any other negative, thread-based
|
||||||
|
filtering that the user wants to do).
|
||||||
|
|
||||||
Fix "notmuch show" so that the UI doesn't fail to show a thread that
|
Fix "notmuch show" so that the UI doesn't fail to show a thread that
|
||||||
is visible in a search buffer, but happens to no longer match the
|
is visible in a search buffer, but happens to no longer match the
|
||||||
current search. (Perhaps add a --matching=<secondary-search-terms>
|
current search. (Perhaps add a --matching=<secondary-search-terms>
|
||||||
|
@ -130,6 +140,12 @@ Add support for configuring "virtual tags" which are a tuple of
|
||||||
(tag-name, search-specification). The database is responsible for
|
(tag-name, search-specification). The database is responsible for
|
||||||
ensuring that the virtual tag is always consistent.
|
ensuring that the virtual tag is always consistent.
|
||||||
|
|
||||||
|
Indicate to the user if two files with the same message ID have
|
||||||
|
content that is actually different in some interesting way. Perhaps
|
||||||
|
notmuch initially sees all changes as interesting, and quickly learns
|
||||||
|
from the user which changes are not interesting (such as the very
|
||||||
|
common mailing-list footer).
|
||||||
|
|
||||||
General
|
General
|
||||||
-------
|
-------
|
||||||
Audit everything for dealing with out-of-memory (and drop xutil.c).
|
Audit everything for dealing with out-of-memory (and drop xutil.c).
|
||||||
|
|
|
@ -855,12 +855,11 @@ _notmuch_database_link_message_to_children (notmuch_database_t *notmuch,
|
||||||
*
|
*
|
||||||
* We first look at 'message_file' and its link-relevant headers
|
* We first look at 'message_file' and its link-relevant headers
|
||||||
* (References and In-Reply-To) for message IDs. We also look in the
|
* (References and In-Reply-To) for message IDs. We also look in the
|
||||||
* database for existing message that reference 'message'.p
|
* database for existing message that reference 'message'.
|
||||||
*
|
*
|
||||||
* The end result is to call _notmuch_message_add_thread_id with one
|
* The end result is to call _notmuch_message_ensure_thread_id which
|
||||||
* or more thread IDs to which this message belongs, (including
|
* generates a new thread ID if the message doesn't connect to any
|
||||||
* generating a new thread ID if necessary if the message doesn't
|
* existing threads.
|
||||||
* connect to any existing threads).
|
|
||||||
*/
|
*/
|
||||||
static notmuch_status_t
|
static notmuch_status_t
|
||||||
_notmuch_database_link_message (notmuch_database_t *notmuch,
|
_notmuch_database_link_message (notmuch_database_t *notmuch,
|
||||||
|
|
|
@ -193,10 +193,6 @@ void
|
||||||
_notmuch_message_set_filename (notmuch_message_t *message,
|
_notmuch_message_set_filename (notmuch_message_t *message,
|
||||||
const char *filename);
|
const char *filename);
|
||||||
|
|
||||||
void
|
|
||||||
_notmuch_message_add_thread_id (notmuch_message_t *message,
|
|
||||||
const char *thread_id);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_notmuch_message_ensure_thread_id (notmuch_message_t *message);
|
_notmuch_message_ensure_thread_id (notmuch_message_t *message);
|
||||||
|
|
||||||
|
|
96
notmuch.el
96
notmuch.el
|
@ -322,7 +322,9 @@ buffer."
|
||||||
(lambda (p)
|
(lambda (p)
|
||||||
(let ((disposition (mm-handle-disposition p)))
|
(let ((disposition (mm-handle-disposition p)))
|
||||||
(and (listp disposition)
|
(and (listp disposition)
|
||||||
(equal (car disposition) "attachment")
|
(or (equal (car disposition) "attachment")
|
||||||
|
(and (equal (car disposition) "inline")
|
||||||
|
(assq 'filename disposition)))
|
||||||
(incf count))))
|
(incf count))))
|
||||||
mm-handle)
|
mm-handle)
|
||||||
count))
|
count))
|
||||||
|
@ -332,7 +334,9 @@ buffer."
|
||||||
(lambda (p)
|
(lambda (p)
|
||||||
(let ((disposition (mm-handle-disposition p)))
|
(let ((disposition (mm-handle-disposition p)))
|
||||||
(and (listp disposition)
|
(and (listp disposition)
|
||||||
(equal (car disposition) "attachment")
|
(or (equal (car disposition) "attachment")
|
||||||
|
(and (equal (car disposition) "inline")
|
||||||
|
(assq 'filename disposition)))
|
||||||
(or (not queryp)
|
(or (not queryp)
|
||||||
(y-or-n-p
|
(y-or-n-p
|
||||||
(concat "Save '" (cdr (assq 'filename disposition)) "' ")))
|
(concat "Save '" (cdr (assq 'filename disposition)) "' ")))
|
||||||
|
@ -595,26 +599,27 @@ which this thread was originally shown."
|
||||||
(while (< (point) end)
|
(while (< (point) end)
|
||||||
(let ((beg-sub (point-marker))
|
(let ((beg-sub (point-marker))
|
||||||
(indent (make-string depth ? ))
|
(indent (make-string depth ? ))
|
||||||
(citation "[[:space:]]*>"))
|
(citation ">"))
|
||||||
|
(move-to-column depth)
|
||||||
(if (looking-at citation)
|
(if (looking-at citation)
|
||||||
(progn
|
(progn
|
||||||
(while (looking-at citation)
|
(while (looking-at citation)
|
||||||
(forward-line))
|
(forward-line)
|
||||||
|
(move-to-column depth))
|
||||||
(let ((overlay (make-overlay beg-sub (point)))
|
(let ((overlay (make-overlay beg-sub (point)))
|
||||||
(invis-spec (make-symbol "notmuch-citation-region")))
|
(invis-spec (make-symbol "notmuch-citation-region")))
|
||||||
(add-to-invisibility-spec invis-spec)
|
(add-to-invisibility-spec invis-spec)
|
||||||
(overlay-put overlay 'invisible invis-spec)
|
(overlay-put overlay 'invisible invis-spec)
|
||||||
(let ((p (point))
|
(let ((p (point-marker))
|
||||||
(cite-button-text
|
(cite-button-text
|
||||||
(concat "[" (number-to-string (count-lines beg-sub (point)))
|
(concat "[" (number-to-string (count-lines beg-sub (point)))
|
||||||
"-line citation.]")))
|
"-line citation. Click/Enter to show.]")))
|
||||||
(goto-char (- beg-sub 1))
|
(goto-char (- beg-sub 1))
|
||||||
(insert (concat "\n" indent))
|
(insert (concat "\n" indent))
|
||||||
(insert-button cite-button-text
|
(insert-button cite-button-text
|
||||||
'invisibility-spec invis-spec
|
'invisibility-spec invis-spec
|
||||||
:type 'notmuch-button-citation-toggle-type)
|
:type 'notmuch-button-citation-toggle-type)
|
||||||
(insert "\n")
|
(forward-line)
|
||||||
(goto-char (+ (length cite-button-text) p))
|
|
||||||
))))
|
))))
|
||||||
(move-to-column depth)
|
(move-to-column depth)
|
||||||
(if (looking-at notmuch-show-signature-regexp)
|
(if (looking-at notmuch-show-signature-regexp)
|
||||||
|
@ -629,7 +634,7 @@ which this thread was originally shown."
|
||||||
(goto-char (- beg-sub 1))
|
(goto-char (- beg-sub 1))
|
||||||
(insert (concat "\n" indent))
|
(insert (concat "\n" indent))
|
||||||
(let ((sig-button-text (concat "[" (number-to-string sig-lines)
|
(let ((sig-button-text (concat "[" (number-to-string sig-lines)
|
||||||
"-line signature.]")))
|
"-line signature. Click/Enter to show.]")))
|
||||||
(insert-button sig-button-text 'invisibility-spec invis-spec
|
(insert-button sig-button-text 'invisibility-spec invis-spec
|
||||||
:type 'notmuch-button-signature-toggle-type)
|
:type 'notmuch-button-signature-toggle-type)
|
||||||
)
|
)
|
||||||
|
@ -637,52 +642,29 @@ which this thread was originally shown."
|
||||||
(goto-char end))))))
|
(goto-char end))))))
|
||||||
(forward-line))))
|
(forward-line))))
|
||||||
|
|
||||||
(defun notmuch-show-markup-part (beg end depth mime-message)
|
(defun notmuch-show-markup-part (beg end depth)
|
||||||
(if (re-search-forward notmuch-show-part-begin-regexp nil t)
|
(if (re-search-forward notmuch-show-part-begin-regexp nil t)
|
||||||
(progn
|
(progn
|
||||||
(if (eq mime-message nil)
|
|
||||||
(let ((filename (notmuch-show-get-filename)))
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-file-contents filename nil nil nil t)
|
|
||||||
(setq mime-message (mm-dissect-buffer)))))
|
|
||||||
(forward-line)
|
(forward-line)
|
||||||
(let ((part-beg (point-marker)))
|
(let ((beg (point-marker)))
|
||||||
(re-search-forward notmuch-show-part-end-regexp)
|
(re-search-forward notmuch-show-part-end-regexp)
|
||||||
|
(let ((end (copy-marker (match-beginning 0))))
|
||||||
(let ((part-end (copy-marker (match-beginning 0))))
|
(goto-char end)
|
||||||
(goto-char part-end)
|
|
||||||
(if (not (bolp))
|
(if (not (bolp))
|
||||||
(insert "\n"))
|
(insert "\n"))
|
||||||
(indent-rigidly part-beg part-end depth)
|
(indent-rigidly beg end depth)
|
||||||
(save-excursion
|
(notmuch-show-markup-citations-region beg end depth)
|
||||||
(goto-char part-beg)
|
|
||||||
(forward-line -1)
|
|
||||||
(beginning-of-line)
|
|
||||||
(let ((handle-type (mm-handle-type mime-message))
|
|
||||||
mime-type)
|
|
||||||
(if (sequencep (car handle-type))
|
|
||||||
(setq mime-type (car handle-type))
|
|
||||||
(setq mime-type (car (car (cdr handle-type))))
|
|
||||||
)
|
|
||||||
(if (equal mime-type "text/html")
|
|
||||||
(mm-display-part mime-message))))
|
|
||||||
|
|
||||||
(notmuch-show-markup-citations-region part-beg part-end depth)
|
|
||||||
; Advance to the next part (if any) (so the outer loop can
|
; Advance to the next part (if any) (so the outer loop can
|
||||||
; determine whether we've left the current message.
|
; determine whether we've left the current message.
|
||||||
(if (re-search-forward notmuch-show-part-begin-regexp nil t)
|
(if (re-search-forward notmuch-show-part-begin-regexp nil t)
|
||||||
(beginning-of-line)))))
|
(beginning-of-line)))))
|
||||||
(goto-char end))
|
(goto-char end)))
|
||||||
mime-message)
|
|
||||||
|
|
||||||
(defun notmuch-show-markup-parts-region (beg end depth)
|
(defun notmuch-show-markup-parts-region (beg end depth)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char beg)
|
(goto-char beg)
|
||||||
(let (mime-message)
|
|
||||||
(while (< (point) end)
|
(while (< (point) end)
|
||||||
(setq mime-message
|
(notmuch-show-markup-part beg end depth))))
|
||||||
(notmuch-show-markup-part
|
|
||||||
beg end depth mime-message))))))
|
|
||||||
|
|
||||||
(defun notmuch-show-markup-body (depth match btn)
|
(defun notmuch-show-markup-body (depth match btn)
|
||||||
"Markup a message body, (indenting, buttonizing citations,
|
"Markup a message body, (indenting, buttonizing citations,
|
||||||
|
@ -949,15 +931,17 @@ All currently available key bindings:
|
||||||
(lambda()
|
(lambda()
|
||||||
(hl-line-mode 1) ))
|
(hl-line-mode 1) ))
|
||||||
|
|
||||||
(defun notmuch-show (thread-id &optional parent-buffer)
|
(defun notmuch-show (thread-id &optional parent-buffer query-context)
|
||||||
"Run \"notmuch show\" with the given thread ID and display results.
|
"Run \"notmuch show\" with the given thread ID and display results.
|
||||||
|
|
||||||
The optional PARENT-BUFFER is the notmuch-search buffer from
|
The optional PARENT-BUFFER is the notmuch-search buffer from
|
||||||
which this notmuch-show command was executed, (so that the next
|
which this notmuch-show command was executed, (so that the next
|
||||||
thread from that buffer can be show when done with this one)."
|
thread from that buffer can be show when done with this one).
|
||||||
|
|
||||||
|
The optional QUERY-CONTEXT is a notmuch search term. Only messages from the thread
|
||||||
|
matching this search term are shown if non-nil. "
|
||||||
(interactive "sNotmuch show: ")
|
(interactive "sNotmuch show: ")
|
||||||
(let ((query notmuch-search-query-string)
|
(let ((buffer (get-buffer-create (concat "*notmuch-show-" thread-id "*"))))
|
||||||
(buffer (get-buffer-create (concat "*notmuch-show-" thread-id "*"))))
|
|
||||||
(switch-to-buffer buffer)
|
(switch-to-buffer buffer)
|
||||||
(notmuch-show-mode)
|
(notmuch-show-mode)
|
||||||
(set (make-local-variable 'notmuch-show-parent-buffer) parent-buffer)
|
(set (make-local-variable 'notmuch-show-parent-buffer) parent-buffer)
|
||||||
|
@ -969,7 +953,11 @@ thread from that buffer can be show when done with this one)."
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(call-process notmuch-command nil t nil "show" "--entire-thread" thread-id "and (" query ")")
|
(let* ((basic-args (list notmuch-command nil t nil "show" "--entire-thread" thread-id))
|
||||||
|
(args (if query-context (append basic-args (list "and (" query-context ")")) basic-args)))
|
||||||
|
(apply 'call-process args)
|
||||||
|
(when (and (eq (buffer-size) 0) query-context)
|
||||||
|
(apply 'call-process basic-args)))
|
||||||
(notmuch-show-markup-messages)
|
(notmuch-show-markup-messages)
|
||||||
)
|
)
|
||||||
(run-hooks 'notmuch-show-hook)
|
(run-hooks 'notmuch-show-hook)
|
||||||
|
@ -1133,12 +1121,20 @@ Complete list of currently available key bindings:
|
||||||
"Return the thread for the current thread"
|
"Return the thread for the current thread"
|
||||||
(get-text-property (point) 'notmuch-search-thread-id))
|
(get-text-property (point) 'notmuch-search-thread-id))
|
||||||
|
|
||||||
|
(defun notmuch-search-find-authors ()
|
||||||
|
"Return the authors for the current thread"
|
||||||
|
(get-text-property (point) 'notmuch-search-authors))
|
||||||
|
|
||||||
|
(defun notmuch-search-find-subject ()
|
||||||
|
"Return the subject for the current thread"
|
||||||
|
(get-text-property (point) 'notmuch-search-subject))
|
||||||
|
|
||||||
(defun notmuch-search-show-thread ()
|
(defun notmuch-search-show-thread ()
|
||||||
"Display the currently selected thread."
|
"Display the currently selected thread."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((thread-id (notmuch-search-find-thread-id)))
|
(let ((thread-id (notmuch-search-find-thread-id)))
|
||||||
(if (> (length thread-id) 0)
|
(if (> (length thread-id) 0)
|
||||||
(notmuch-show thread-id (current-buffer))
|
(notmuch-show thread-id (current-buffer) notmuch-search-query-string)
|
||||||
(error "End of search results"))))
|
(error "End of search results"))))
|
||||||
|
|
||||||
(defun notmuch-search-reply-to-thread ()
|
(defun notmuch-search-reply-to-thread ()
|
||||||
|
@ -1193,7 +1189,7 @@ The tag is added to messages in the currently selected thread
|
||||||
which match the current search terms."
|
which match the current search terms."
|
||||||
(interactive
|
(interactive
|
||||||
(list (notmuch-select-tag-with-completion "Tag to add: ")))
|
(list (notmuch-select-tag-with-completion "Tag to add: ")))
|
||||||
(notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id) " and " notmuch-search-query-string)
|
(notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id))
|
||||||
(notmuch-search-set-tags (delete-dups (sort (cons tag (notmuch-search-get-tags)) 'string<))))
|
(notmuch-search-set-tags (delete-dups (sort (cons tag (notmuch-search-get-tags)) 'string<))))
|
||||||
|
|
||||||
(defun notmuch-search-remove-tag (tag)
|
(defun notmuch-search-remove-tag (tag)
|
||||||
|
@ -1203,7 +1199,7 @@ The tag is removed from messages in the currently selected thread
|
||||||
which match the current search terms."
|
which match the current search terms."
|
||||||
(interactive
|
(interactive
|
||||||
(list (notmuch-select-tag-with-completion "Tag to remove: " (notmuch-search-find-thread-id))))
|
(list (notmuch-select-tag-with-completion "Tag to remove: " (notmuch-search-find-thread-id))))
|
||||||
(notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id) " and " notmuch-search-query-string)
|
(notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id))
|
||||||
(notmuch-search-set-tags (delete tag (notmuch-search-get-tags))))
|
(notmuch-search-set-tags (delete tag (notmuch-search-get-tags))))
|
||||||
|
|
||||||
(defun notmuch-search-archive-thread ()
|
(defun notmuch-search-archive-thread ()
|
||||||
|
@ -1257,7 +1253,9 @@ This function advances the next thread when finished."
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(let ((beg (point-marker)))
|
(let ((beg (point-marker)))
|
||||||
(insert (format "%s %-7s %-40s %s (%s)\n" date count authors subject tags))
|
(insert (format "%s %-7s %-40s %s (%s)\n" date count authors subject tags))
|
||||||
(put-text-property beg (point-marker) 'notmuch-search-thread-id thread-id))
|
(put-text-property beg (point-marker) 'notmuch-search-thread-id thread-id)
|
||||||
|
(put-text-property beg (point-marker) 'notmuch-search-authors authors)
|
||||||
|
(put-text-property beg (point-marker) 'notmuch-search-subject subject))
|
||||||
(set 'line (match-end 0)))
|
(set 'line (match-end 0)))
|
||||||
(set 'more nil))))))
|
(set 'more nil))))))
|
||||||
(delete-process proc))))
|
(delete-process proc))))
|
||||||
|
|
Loading…
Reference in a new issue