Rename "notmuch cat" to "notmuch show --format=raw"
authorCarl Worth <cworth@cworth.org>
Sat, 6 Nov 2010 19:03:51 +0000 (12:03 -0700)
committerCarl Worth <cworth@cworth.org>
Sat, 6 Nov 2010 19:03:51 +0000 (12:03 -0700)
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).

emacs/notmuch-show.el
notmuch-show.c
notmuch.1
notmuch.c
test/cat [deleted file]
test/notmuch-test
test/raw [new file with mode: 0755]

index 9b3841fffbbbf21233190950b9c11104d762e28a..3daa8685a46f3df1f283acba947dc819c8e69a0b 100644 (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)
index f46e0c8218785efb77957fffa048c0d1c0956f87..ef421ec7cc382ea6e3dbe188c50d1140423b6f30 100644 (file)
@@ -528,77 +528,64 @@ show_messages (void *ctx, const show_format_t *format, notmuch_messages_t *messa
     fputs (format->message_set_end, stdout);
 }
 
-int
-notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
+/* Support for --format=raw */
+static int
+do_show_raw (unused(void *ctx), notmuch_query_t *query)
 {
-    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;
+    notmuch_message_t *message;
+    const char *filename;
+    FILE *file;
+    size_t size;
+    char buf[4096];
 
-    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-       if (strcmp (argv[i], "--") == 0) {
-           i++;
-           break;
-       }
-       if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
-           opt = argv[i] + sizeof ("--format=") - 1;
-           if (strcmp (opt, "text") == 0) {
-               format = &format_text;
-           } else if (strcmp (opt, "json") == 0) {
-               format = &format_json;
-               entire_thread = 1;
-           } else if (strcmp (opt, "mbox") == 0) {
-               format = &format_mbox;
-           } else {
-               fprintf (stderr, "Invalid value for --format: %s\n", opt);
-               return 1;
-           }
-       } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
-           entire_thread = 1;
-       } else {
-           fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
-           return 1;
-       }
+    if (notmuch_query_count_messages (query) != 1) {
+       fprintf (stderr, "Error: search term did not match precisely one message.\n");
+       return 1;
     }
 
-    argc -= i;
-    argv += i;
-
-    config = notmuch_config_open (ctx, NULL, NULL);
-    if (config == NULL)
-       return 1;
+    messages = notmuch_query_search_messages (query);
+    message = notmuch_messages_get (messages);
 
-    query_string = query_string_from_args (ctx, argc, argv);
-    if (query_string == NULL) {
-       fprintf (stderr, "Out of memory\n");
+    if (message == NULL) {
+       fprintf (stderr, "Error: Cannot find matching message.\n");
        return 1;
     }
 
-    if (*query_string == '\0') {
-       fprintf (stderr, "Error: notmuch show requires at least one search term.\n");
+    filename = notmuch_message_get_filename (message);
+    if (filename == NULL) {
+       fprintf (stderr, "Error: Cannot message filename.\n");
        return 1;
     }
 
-    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
-                                    NOTMUCH_DATABASE_MODE_READ_ONLY);
-    if (notmuch == NULL)
+    file = fopen (filename, "r");
+    if (file == NULL) {
+       fprintf (stderr, "Error: Cannot open file %s: %s\n", filename, strerror (errno));
        return 1;
+    }
 
-    query = notmuch_query_create (notmuch, query_string);
-    if (query == NULL) {
-       fprintf (stderr, "Out of memory\n");
-       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);
@@ -625,32 +612,53 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 
     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_show_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;
+    char *opt;
+    const show_format_t *format = &format_text;
+    int entire_thread = 0;
     int i;
-    const char *filename;
-    FILE *file;
-    size_t size;
-    char buf[4096];
+    int raw = 0;
 
     for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-       fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
-       return 1;
+       if (strcmp (argv[i], "--") == 0) {
+           i++;
+           break;
+       }
+       if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
+           opt = argv[i] + sizeof ("--format=") - 1;
+           if (strcmp (opt, "text") == 0) {
+               format = &format_text;
+           } else if (strcmp (opt, "json") == 0) {
+               format = &format_json;
+               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;
+           }
+       } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
+           entire_thread = 1;
+       } else {
+           fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+           return 1;
+       }
     }
 
+    argc -= i;
+    argv += i;
+
     config = notmuch_config_open (ctx, NULL, NULL);
     if (config == NULL)
        return 1;
@@ -662,7 +670,7 @@ notmuch_cat_command (void *ctx, unused (int argc), unused (char *argv[]))
     }
 
     if (*query_string == '\0') {
-       fprintf (stderr, "Error: notmuch cat requires at least one search term.\n");
+       fprintf (stderr, "Error: notmuch show requires at least one search term.\n");
        return 1;
     }
 
@@ -673,41 +681,15 @@ notmuch_cat_command (void *ctx, unused (int argc), unused (char *argv[]))
 
     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));
+       fprintf (stderr, "Out of memory\n");
        return 1;
     }
 
-    while (!feof (file)) {
-       size = fread (buf, 1, sizeof (buf), file);
-       fwrite (buf, size, 1, stdout);
-    }
+    if (raw)
+       return do_show_raw (ctx, query);
+    else
+       return do_show (ctx, query, format, entire_thread);
 
-    fclose (file);
     notmuch_query_destroy (query);
     notmuch_database_close (notmuch);
 
index 853b5eafab31cac83959e074713174f528d6475a..3878a040cbcf1e10f1bdf3b568b0cb8affeb2a2e 100644 (file)
--- a/notmuch.1
+++ b/notmuch.1
@@ -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.
index 0eba89a38e30f48d20c67ef0d6b6ef8ba104ac20..9ba0ec0308ae2b172b8410405a653e6f643e4840 100644 (file)
--- a/notmuch.c
+++ b/notmuch.c
@@ -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.",
diff --git a/test/cat b/test/cat
deleted file mode 100755 (executable)
index c2cfedb..0000000
--- a/test/cat
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/bash
-
-test_description='notmuch cat'
-. ./test-lib.sh
-
-test_begin_subtest "Generate some messages"
-generate_message
-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_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_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>
-Subject: Test message #1
-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_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>
-Subject: Test message #2
-Date: Tue, 05 Jan 2001 15:43:57 -0000
-
-This is just a test message (#2)"
-
-test_done
index 6b89409060c3f80d0deeaecacc4701019e694414..9a3c698396a57e9ce3969f26fdb0e749b2cfbe8c 100755 (executable)
@@ -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
diff --git a/test/raw b/test/raw
new file mode 100755 (executable)
index 0000000..4ed237c
--- /dev/null
+++ b/test/raw
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+test_description='notmuch show --format=raw'
+. ./test-lib.sh
+
+test_begin_subtest "Generate some messages"
+generate_message
+generate_message
+output=$(NOTMUCH_NEW)
+test_expect_equal "$output" "Added 2 new messages to the database."
+
+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 "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>
+Subject: Test message #1
+Date: Tue, 05 Jan 2001 15:43:57 -0000
+
+This is just a test message (#1)"
+
+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>
+Subject: Test message #2
+Date: Tue, 05 Jan 2001 15:43:57 -0000
+
+This is just a test message (#2)"
+
+test_done