]> git.notmuchmail.org Git - notmuch/blobdiff - notmuch.c
Add a simple configure script.
[notmuch] / notmuch.c
index 4ac5531ae42a14c8216e3977cfc7dc8a495fbb29..4158cc5f098bf13429168a389393beb1c42614dd 100644 (file)
--- a/notmuch.c
+++ b/notmuch.c
@@ -60,7 +60,7 @@
 
 #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
 
-typedef int (*command_function_t) (int argc, char *argv[]);
+typedef int (*command_function_t) (void *ctx, int argc, char *argv[]);
 
 typedef struct command {
     const char *name;
@@ -471,7 +471,7 @@ count_files (const char *path, int *count)
 }
 
 static int
-setup_command (unused (int argc), unused (char *argv[]))
+setup_command (unused (void *ctx), unused (int argc), unused (char *argv[]))
 {
     notmuch_database_t *notmuch = NULL;
     char *default_path, *mail_directory = NULL;
@@ -629,7 +629,7 @@ tag_inbox_and_unread (notmuch_message_t *message)
 }
 
 static int
-new_command (unused (int argc), unused (char *argv[]))
+new_command (unused (void *ctx), unused (int argc), unused (char *argv[]))
 {
     notmuch_database_t *notmuch;
     const char *mail_directory;
@@ -733,16 +733,91 @@ query_string_from_args (void *ctx, int argc, char *argv[])
     return query_string;
 }
 
+/* Format a nice representation of 'time' relative to the current time.
+ *
+ * Examples include:
+ *
+ *     5 minutes ago   (For times less than 60 minutes ago)
+ *     12:30           (For times >60 minutes but still today)
+ *     Yesterday
+ *     Monday          (Before yesterday but fewer than 7 days ago)
+ *     Oct. 12         (Between 7 and 180 days ago (about 6 months))
+ *     2008-06-30      (More than 180 days ago)
+ */
+#define MINUTE (60)
+#define HOUR (60 * MINUTE)
+#define DAY (24 * HOUR)
+#define RELATIVE_DATE_MAX 20
+static const char *
+_format_relative_date (void *ctx, time_t then)
+{
+    struct tm tm_now, tm_then;
+    time_t now = time(NULL);
+    time_t delta;
+    char *result;
+
+    localtime_r (&now, &tm_now);
+    localtime_r (&then, &tm_then);
+
+    result = talloc_zero_size (ctx, RELATIVE_DATE_MAX);
+    if (result == NULL)
+       return "when?";
+
+    if (then > now)
+       return "the future";
+
+    delta = now - then;
+
+    if (delta > 180 * DAY) {
+       strftime (result, RELATIVE_DATE_MAX,
+                 "%F", &tm_then); /* 2008-06-30 */
+       return result;
+    }
+
+    if (delta < 3600) {
+       snprintf (result, RELATIVE_DATE_MAX,
+                 "%d minutes ago", (int) (delta / 60));
+       return result;
+    }
+
+    if (delta <= 7 * DAY) {
+       if (tm_then.tm_wday == tm_now.tm_wday &&
+           delta < DAY)
+       {
+           strftime (result, RELATIVE_DATE_MAX,
+                     "%R", &tm_then); /* 12:30 */
+           return result;
+       } else if ((tm_now.tm_wday + 7 - tm_then.tm_wday) % 7 == 1) {
+           return "Yesterday";
+       } else {
+           if (tm_then.tm_wday != tm_now.tm_wday) {
+               strftime (result, RELATIVE_DATE_MAX,
+                         "%A", &tm_then); /* Monday */
+               return result;
+           }
+       }
+    }
+
+    strftime (result, RELATIVE_DATE_MAX,
+             "%b %d", &tm_then); /* Oct. 12 */
+    return result;
+}
+#undef MINUTE
+#undef HOUR
+#undef DAY
+
 static int
-search_command (int argc, char *argv[])
+search_command (void *ctx, int argc, char *argv[])
 {
-    void *local = talloc_new (NULL);
+    void *local = talloc_new (ctx);
     notmuch_database_t *notmuch = NULL;
     notmuch_query_t *query;
-    notmuch_thread_results_t *results;
+    notmuch_threads_t *threads;
     notmuch_thread_t *thread;
     notmuch_tags_t *tags;
     char *query_str;
+    const char *relative_date;
+    time_t date;
     notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
 
     notmuch = notmuch_database_open (NULL);
@@ -760,16 +835,20 @@ search_command (int argc, char *argv[])
        goto DONE;
     }
 
-    for (results = notmuch_query_search_threads (query);
-        notmuch_thread_results_has_more (results);
-        notmuch_thread_results_advance (results))
+    for (threads = notmuch_query_search_threads (query);
+        notmuch_threads_has_more (threads);
+        notmuch_threads_advance (threads))
     {
        int first = 1;
 
-       thread = notmuch_thread_results_get (results);
+       thread = notmuch_threads_get (threads);
 
-       printf ("%s %s",
+       date = notmuch_thread_get_oldest_date (thread);
+       relative_date = _format_relative_date (local, date);
+
+       printf ("%s (%s) %s",
                notmuch_thread_get_thread_id (thread),
+               relative_date,
                notmuch_thread_get_subject (thread));
 
        printf (" (");
@@ -797,14 +876,34 @@ search_command (int argc, char *argv[])
     return ret;
 }
 
+/* Get a nice, single-line summary of message. */
+static const char *
+_get_one_line_summary (void *ctx, notmuch_message_t *message)
+{
+    const char *from;
+    time_t date;
+    const char *relative_date;
+    const char *subject;
+
+    from = notmuch_message_get_header (message, "from");
+
+    date = notmuch_message_get_date (message);
+    relative_date = _format_relative_date (ctx, date);
+
+    subject = notmuch_message_get_header (message, "subject");
+
+    return talloc_asprintf (ctx, "%s (%s) %s",
+                           from, relative_date, subject);
+}
+
 static int
-show_command (unused (int argc), unused (char *argv[]))
+show_command (void *ctx, unused (int argc), unused (char *argv[]))
 {
-    void *local = talloc_new (NULL);
+    void *local = talloc_new (ctx);
     char *query_string;
     notmuch_database_t *notmuch = NULL;
     notmuch_query_t *query = NULL;
-    notmuch_message_results_t *messages;
+    notmuch_messages_t *messages;
     notmuch_message_t *message;
     const char *filename;
     FILE *file;
@@ -844,15 +943,17 @@ show_command (unused (int argc), unused (char *argv[]))
     }
 
     for (messages = notmuch_query_search_messages (query);
-        notmuch_message_results_has_more (messages);
-        notmuch_message_results_advance (messages))
+        notmuch_messages_has_more (messages);
+        notmuch_messages_advance (messages))
     {
-       message = notmuch_message_results_get (messages);
+       message = notmuch_messages_get (messages);
 
        printf ("%%message{\n");
 
        printf ("%%header{\n");
 
+       printf ("%s\n", _get_one_line_summary (local, message));
+
        for (i = 0; i < ARRAY_SIZE (headers); i++) {
            name = headers[i];
            value = notmuch_message_get_header (message, name);
@@ -896,7 +997,7 @@ show_command (unused (int argc), unused (char *argv[]))
 }
 
 static int
-tag_command (unused (int argc), unused (char *argv[]))
+tag_command (void *ctx, unused (int argc), unused (char *argv[]))
 {
     void *local;
     int *add_tags, *remove_tags;
@@ -905,12 +1006,12 @@ tag_command (unused (int argc), unused (char *argv[]))
     char *query_string;
     notmuch_database_t *notmuch = NULL;
     notmuch_query_t *query;
-    notmuch_message_results_t *results;
+    notmuch_messages_t *messages;
     notmuch_message_t *message;
     int ret = 0;
     int i;
 
-    local = talloc_new (NULL);
+    local = talloc_new (ctx);
     if (local == NULL) {
        ret = 1;
        goto DONE;
@@ -969,11 +1070,11 @@ tag_command (unused (int argc), unused (char *argv[]))
        goto DONE;
     }
 
-    for (results = notmuch_query_search_messages (query);
-        notmuch_message_results_has_more (results);
-        notmuch_message_results_advance (results))
+    for (messages = notmuch_query_search_messages (query);
+        notmuch_messages_has_more (messages);
+        notmuch_messages_advance (messages))
     {
-       message = notmuch_message_results_get (results);
+       message = notmuch_messages_get (messages);
 
        notmuch_message_freeze (message);
 
@@ -1001,12 +1102,12 @@ tag_command (unused (int argc), unused (char *argv[]))
 }
 
 static int
-dump_command (int argc, char *argv[])
+dump_command (unused (void *ctx), int argc, char *argv[])
 {
     FILE *output = NULL;
     notmuch_database_t *notmuch = NULL;
     notmuch_query_t *query;
-    notmuch_message_results_t *results;
+    notmuch_messages_t *messages;
     notmuch_message_t *message;
     notmuch_tags_t *tags;
     int ret = 0;
@@ -1038,12 +1139,12 @@ dump_command (int argc, char *argv[])
 
     notmuch_query_set_sort (query, NOTMUCH_SORT_MESSAGE_ID);
 
-    for (results = notmuch_query_search_messages (query);
-        notmuch_message_results_has_more (results);
-        notmuch_message_results_advance (results))
+    for (messages = notmuch_query_search_messages (query);
+        notmuch_messages_has_more (messages);
+        notmuch_messages_advance (messages))
     {
        int first = 1;
-       message = notmuch_message_results_get (results);
+       message = notmuch_messages_get (messages);
 
        fprintf (output,
                 "%s (", notmuch_message_get_message_id (message));
@@ -1077,7 +1178,7 @@ dump_command (int argc, char *argv[])
 }
 
 static int
-restore_command (int argc, char *argv[])
+restore_command (unused (void *ctx), int argc, char *argv[])
 {
     FILE *input = NULL;
     notmuch_database_t *notmuch = NULL;
@@ -1186,7 +1287,7 @@ restore_command (int argc, char *argv[])
 }
 
 static int
-help_command (int argc, char *argv[]);
+help_command (void *ctx, int argc, char *argv[]);
 
 command_t commands[] = {
     { "setup", setup_command,
@@ -1204,7 +1305,7 @@ command_t commands[] = {
       "\t\t\"inbox\" and \"unread\".\n"
       "\n"
       "\t\tNote: \"notmuch new\" will skip any read-only directories,\n"
-      "\t\tso you can use that to mark tdirectories that will not\n"
+      "\t\tso you can use that to mark directories that will not\n"
       "\t\treceive any new mail (and make \"notmuch new\" faster)." },
     { "search", search_command,
       "<search-term> [...]\n\n"
@@ -1303,7 +1404,7 @@ usage (void)
 }
 
 static int
-help_command (int argc, char *argv[])
+help_command (unused (void *ctx), int argc, char *argv[])
 {
     command_t *command;
     unsigned int i;
@@ -1334,23 +1435,26 @@ help_command (int argc, char *argv[])
 int
 main (int argc, char *argv[])
 {
+    void *local = talloc_new (NULL);
     command_t *command;
     unsigned int i;
 
     if (argc == 1)
-       return setup_command (0, NULL);
+       return setup_command (local, 0, NULL);
 
     for (i = 0; i < ARRAY_SIZE (commands); i++) {
        command = &commands[i];
 
        if (strcmp (argv[1], command->name) == 0)
-           return (command->function) (argc - 2, &argv[2]);
+           return (command->function) (local, argc - 2, &argv[2]);
     }
 
     /* Don't complain about "help" being an unknown command when we're
        about to provide exactly what's wanted anyway. */
-    fprintf (stderr, "Error: Unknown command '%s'\n\n", argv[1]);
-    usage ();
+    fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch help\")\n",
+            argv[1]);
+
+    talloc_free (local);
 
     return 1;
 }