Rename "notmuch cat" to "notmuch show --format=raw"

This is part of an effort to avoid proliferation of excessive
top-level notmuch commands. Also, "raw" better captures the
functionality here, (as opposed to "cat" which is a fairly oblique
reference to a bad Unix abbreviation whose metaphor doesn't work here
since "notmuch cat" operates only on a single message and hence cannot
"con'cat'enate" anything).
This commit is contained in:
Carl Worth 2010-11-06 12:03:51 -07:00
parent 581ea7c8d3
commit 81d3bd3670
6 changed files with 124 additions and 137 deletions

View file

@ -88,7 +88,7 @@ any given message."
(let ((id (notmuch-show-get-message-id)))
(let ((buf (generate-new-buffer (concat "*notmuch-msg-" id "*"))))
(with-current-buffer buf
(call-process notmuch-command nil t nil "cat" id)
(call-process notmuch-command nil t nil "show" "--format=raw" id)
,@body)
(kill-buffer buf)))))
@ -921,7 +921,7 @@ any effects from previous calls to
(let ((buf (get-buffer-create (concat "*notmuch-raw-" id "*"))))
(switch-to-buffer buf)
(save-excursion
(call-process notmuch-command nil t nil "cat" id)))))
(call-process notmuch-command nil t nil "show" "--format=raw" id)))))
(defun notmuch-show-pipe-message (entire-thread command)
"Pipe the contents of the current message (or thread) to the given command.
@ -942,7 +942,7 @@ than only the current message."
(mapconcat 'identity (notmuch-show-get-message-ids-for-open-messages) " OR "))
" | " command))
(setq shell-command
(concat "notmuch cat " (shell-quote-argument (notmuch-show-get-message-id)) " | " command)))
(concat "notmuch show --format=raw " (shell-quote-argument (notmuch-show-get-message-id)) " | " command)))
(start-process-shell-command "notmuch-pipe-command" "*notmuch-pipe*" shell-command)))
(defun notmuch-show-add-tags-worker (current-tags add-tags)

View file

@ -528,21 +528,105 @@ show_messages (void *ctx, const show_format_t *format, notmuch_messages_t *messa
fputs (format->message_set_end, stdout);
}
/* Support for --format=raw */
static int
do_show_raw (unused(void *ctx), notmuch_query_t *query)
{
notmuch_messages_t *messages;
notmuch_message_t *message;
const char *filename;
FILE *file;
size_t size;
char buf[4096];
if (notmuch_query_count_messages (query) != 1) {
fprintf (stderr, "Error: search term did not match precisely one message.\n");
return 1;
}
messages = notmuch_query_search_messages (query);
message = notmuch_messages_get (messages);
if (message == NULL) {
fprintf (stderr, "Error: Cannot find matching message.\n");
return 1;
}
filename = notmuch_message_get_filename (message);
if (filename == NULL) {
fprintf (stderr, "Error: Cannot message filename.\n");
return 1;
}
file = fopen (filename, "r");
if (file == NULL) {
fprintf (stderr, "Error: Cannot open file %s: %s\n", filename, strerror (errno));
return 1;
}
while (!feof (file)) {
size = fread (buf, 1, sizeof (buf), file);
fwrite (buf, size, 1, stdout);
}
fclose (file);
return 0;
}
/* Support for --format=text|json|mbox */
static int
do_show (void *ctx,
notmuch_query_t *query,
const show_format_t *format,
int entire_thread)
{
notmuch_threads_t *threads;
notmuch_thread_t *thread;
notmuch_messages_t *messages;
int first_toplevel = 1;
fputs (format->message_set_start, stdout);
for (threads = notmuch_query_search_threads (query);
notmuch_threads_valid (threads);
notmuch_threads_move_to_next (threads))
{
thread = notmuch_threads_get (threads);
messages = notmuch_thread_get_toplevel_messages (thread);
if (messages == NULL)
INTERNAL_ERROR ("Thread %s has no toplevel messages.\n",
notmuch_thread_get_thread_id (thread));
if (!first_toplevel)
fputs (format->message_set_sep, stdout);
first_toplevel = 0;
show_messages (ctx, format, messages, 0, entire_thread);
notmuch_thread_destroy (thread);
}
fputs (format->message_set_end, stdout);
return 0;
}
int
notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
{
notmuch_config_t *config;
notmuch_database_t *notmuch;
notmuch_query_t *query;
notmuch_threads_t *threads;
notmuch_thread_t *thread;
notmuch_messages_t *messages;
char *query_string;
char *opt;
const show_format_t *format = &format_text;
int entire_thread = 0;
int i;
int first_toplevel = 1;
int raw = 0;
for (i = 0; i < argc && argv[i][0] == '-'; i++) {
if (strcmp (argv[i], "--") == 0) {
@ -558,6 +642,8 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
entire_thread = 1;
} else if (strcmp (opt, "mbox") == 0) {
format = &format_mbox;
} else if (strcmp (opt, "raw") == 0) {
raw = 1;
} else {
fprintf (stderr, "Invalid value for --format: %s\n", opt);
return 1;
@ -599,115 +685,11 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
return 1;
}
fputs (format->message_set_start, stdout);
if (raw)
return do_show_raw (ctx, query);
else
return do_show (ctx, query, format, entire_thread);
for (threads = notmuch_query_search_threads (query);
notmuch_threads_valid (threads);
notmuch_threads_move_to_next (threads))
{
thread = notmuch_threads_get (threads);
messages = notmuch_thread_get_toplevel_messages (thread);
if (messages == NULL)
INTERNAL_ERROR ("Thread %s has no toplevel messages.\n",
notmuch_thread_get_thread_id (thread));
if (!first_toplevel)
fputs (format->message_set_sep, stdout);
first_toplevel = 0;
show_messages (ctx, format, messages, 0, entire_thread);
notmuch_thread_destroy (thread);
}
fputs (format->message_set_end, stdout);
notmuch_query_destroy (query);
notmuch_database_close (notmuch);
return 0;
}
int
notmuch_cat_command (void *ctx, unused (int argc), unused (char *argv[]))
{
notmuch_config_t *config;
notmuch_database_t *notmuch;
notmuch_query_t *query;
notmuch_messages_t *messages;
notmuch_message_t *message;
char *query_string;
int i;
const char *filename;
FILE *file;
size_t size;
char buf[4096];
for (i = 0; i < argc && argv[i][0] == '-'; i++) {
fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
return 1;
}
config = notmuch_config_open (ctx, NULL, NULL);
if (config == NULL)
return 1;
query_string = query_string_from_args (ctx, argc, argv);
if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
return 1;
}
if (*query_string == '\0') {
fprintf (stderr, "Error: notmuch cat requires at least one search term.\n");
return 1;
}
notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_ONLY);
if (notmuch == NULL)
return 1;
query = notmuch_query_create (notmuch, query_string);
if (query == NULL) {
fprintf (stderr, "Error: Out of memory\n");
return 1;
}
if (notmuch_query_count_messages (query) != 1) {
fprintf (stderr, "Error: search term did not match precisely one message.\n");
return 1;
}
messages = notmuch_query_search_messages (query);
message = notmuch_messages_get (messages);
if (message == NULL) {
fprintf (stderr, "Error: Cannot find matching message.\n");
return 1;
}
filename = notmuch_message_get_filename (message);
if (filename == NULL) {
fprintf (stderr, "Error: Cannot message filename.\n");
return 1;
}
file = fopen (filename, "r");
if (file == NULL) {
fprintf (stderr, "Error: Cannot open file %s: %s\n", filename, strerror (errno));
return 1;
}
while (!feof (file)) {
size = fread (buf, 1, sizeof (buf), file);
fwrite (buf, size, 1, stdout);
}
fclose (file);
notmuch_query_destroy (query);
notmuch_database_close (notmuch);

View file

@ -248,7 +248,7 @@ matched message will be displayed.
.RS 4
.TP 4
.B \-\-format=(text|json|mbox)
.B \-\-format=(text|json|mbox|raw)
.RS 4
.TP 4
@ -286,6 +286,16 @@ beginning with "From " (preceded by zero or more '>' characters) have
an additional '>' character added. This reversible escaping
is termed "mboxrd" format and described in detail here:
http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/mail-mbox-formats.html
.RE
.RS 4
.TP 4
.B raw
The original, raw content of the email message is displayed.
Consumers of this format should expect to implement MIME decoding and
similar functions. This format must only be used with search terms
matching a single message.
.RE
A common use of
.B notmuch show
@ -300,10 +310,6 @@ See the
section below for details of the supported syntax for <search-terms>.
.RE
.TP
.BR cat " <search-term>..."
Output raw content of a single message matched by the search term.
.TP
.BR count " <search-term>..."
Count messages matching the search terms.

View file

@ -222,7 +222,7 @@ command_t commands[] = {
"\t\tall messages in the same thread as any matched\n"
"\t\tmessage will be displayed.\n"
"\n"
"\t--format=(text|json|mbox)\n"
"\t--format=(text|json|mbox|raw)\n"
"\n"
"\t\ttext (default)\n"
"\n"
@ -254,6 +254,13 @@ command_t commands[] = {
"\n"
"\t\thttp://homepage.ntlworld.com/jonathan.deboynepollard/FGA/mail-mbox-formats.html\n"
"\n"
"\t\traw\n"
"\n"
"\t\tThe original, raw content of the email message is displayed.\n"
"\t\tConsumers of this format should expect to implement MIME\n"
"\t\tdecoding and similar functions. This format must only\n"
"\t\tbe used with search terms matching a single message.\n"
"\n"
"\tA common use of \"notmuch show\" is to display a single\n"
"\tthread of email messages. For this, use a search term of\n"
"\t\"thread:<thread-id>\" as can be seen in the first column\n"
@ -343,10 +350,6 @@ command_t commands[] = {
"\tcontain tags only from messages that match the search-term(s).\n"
"\n"
"\tIn both cases the list will be alphabetically sorted." },
{ "cat", notmuch_cat_command,
"<search-terms>",
"Output raw content of a single message matched by the search term.",
"" },
{ "part", notmuch_part_command,
"--part=<num> <search-terms>",
"Output a single MIME part of a message.",

View file

@ -16,7 +16,7 @@ fi
cd $(dirname "$0")
TESTS="basic new search json thread-naming reply cat dump-restore uuencode thread-order author-order from-guessing long-id encoding emacs"
TESTS="basic new search json thread-naming raw reply dump-restore uuencode thread-order author-order from-guessing long-id encoding emacs"
# Clean up any results from a previous run
rm -r test-results >/dev/null 2>/dev/null

View file

@ -1,6 +1,6 @@
#!/bin/bash
test_description='notmuch cat'
test_description='notmuch show --format=raw'
. ./test-lib.sh
test_begin_subtest "Generate some messages"
@ -9,16 +9,12 @@ generate_message
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "Added 2 new messages to the database."
test_begin_subtest "Without arguments"
output=$(notmuch cat 2>&1)
test_expect_equal "$output" "Error: notmuch cat requires at least one search term."
test_begin_subtest "Attempt to cat multiple messages"
output=$(notmuch cat "*" 2>&1)
test_begin_subtest "Attempt to show multiple raw messages"
output=$(notmuch show --format=raw "*" 2>&1)
test_expect_equal "$output" "Error: search term did not match precisely one message."
test_begin_subtest "Cat a message"
output=$(notmuch cat id:msg-001@notmuch-test-suite)
test_begin_subtest "Show a raw message"
output=$(notmuch show --format=raw id:msg-001@notmuch-test-suite)
test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
To: Notmuch Test Suite <test_suite@notmuchmail.org>
Message-Id: <msg-001@notmuch-test-suite>
@ -27,8 +23,8 @@ Date: Tue, 05 Jan 2001 15:43:57 -0000
This is just a test message (#1)"
test_begin_subtest "Cat another message"
output=$(notmuch cat id:msg-002@notmuch-test-suite)
test_begin_subtest "Show another raw message"
output=$(notmuch show --format=raw id:msg-002@notmuch-test-suite)
test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
To: Notmuch Test Suite <test_suite@notmuchmail.org>
Message-Id: <msg-002@notmuch-test-suite>