From c3bcd7d11b67a15a1760505c036e760e7028b125 Mon Sep 17 00:00:00 2001 From: Mark Walters Date: Mon, 13 Feb 2012 23:31:45 +0000 Subject: [PATCH 2/2] emacs: a semi-working async pick --- emacs/notmuch-pick.el | 111 ++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 87 insertions(+), 24 deletions(-) diff --git a/emacs/notmuch-pick.el b/emacs/notmuch-pick.el index 46eb720..f944d79 100644 --- a/emacs/notmuch-pick.el +++ b/emacs/notmuch-pick.el @@ -287,7 +287,7 @@ This command toggles the sort order for the current search." (query-context notmuch-pick-query-context) (buffer-name notmuch-pick-buffer-name)) (erase-buffer) - (notmuch-pick-worker thread-id query-context buffer-name))) + (notmuch-pick-worker thread-id query-context (get-buffer buffer-name)))) (defun notmuch-pick-toggle-view () "Toggle showing threads or as isolated messages." @@ -531,34 +531,97 @@ Complete list of currently available key bindings: (setq buffer-read-only t truncate-lines t)) -(defun notmuch-pick-worker (thread-id &optional query-context buffer-name) +(defvar notmuch-pick-process-filter-data nil + "Data that has not yet been processed.") +(make-variable-buffer-local 'notmuch-pick-process-filter-data) + +(defun notmuch-pick-process-sentinel (proc msg) + "Add a message to let user know when \"notmuch pick\" exits" + (let ((buffer (process-buffer proc)) + (status (process-status proc)) + (exit-status (process-exit-status proc)) + (never-found-target-thread nil)) + (if (memq status '(exit signal)) + (if (buffer-live-p buffer) + (with-current-buffer buffer + (save-excursion + (let ((inhibit-read-only t) + (atbob (bobp))) + (goto-char (point-max)) + (if (eq status 'signal) + (insert "Incomplete search results (pick process was killed).\n")) + (when (eq status 'exit) + (if (not (string= notmuch-pick-process-filter-data "\n]")) + (insert (concat "Error: Unexpected output from notmuch pick:\n" + notmuch-pick-process-filter-data))) + (insert "End of search results.") + (unless (= exit-status 0) + (insert (format " (process returned %d)" exit-status))) + (insert "\n"))))))))) + +(defun notmuch-pick-process-filter (proc string) + "Process and filter the output of \"notmuch show\" (for pick)" + (let ((buffer (process-buffer proc))) + (if (buffer-live-p buffer) + (with-current-buffer buffer + (save-excursion + (let ((line 0) + (more t) + (inhibit-read-only t) + (string (concat notmuch-pick-process-filter-data string))) + (while (string-match "\n.*\n" string) + (let ((frame (match-string 0 string)) + (frame-end (match-end 0))) + (when (or (= (elt frame 1) ?\[) (= (elt frame 1) ?,)) + (let (json) + (with-temp-buffer + (let ((json-object-type 'plist) + (json-array-type 'list) + (json-false 'nil)) + (insert frame) + (goto-char (point-min)) + (search-forward "[") + (backward-char) + (setq json (json-read)))) + (goto-char (point-max)) + (notmuch-pick-insert-forest (list json)))) + (setq string (substring string (- frame-end 1))))) + (setq notmuch-pick-process-filter-data string))))))) + +(defun notmuch-pick-worker (thread-id &optional query-context buffer) (interactive) (notmuch-pick-mode) (setq notmuch-pick-thread-id thread-id) (setq notmuch-pick-query-context query-context) - (setq notmuch-pick-buffer-name buffer-name) + (setq notmuch-pick-buffer-name (buffer-name buffer)) (erase-buffer) (goto-char (point-min)) - (save-excursion - (let* ((basic-args (list thread-id)) - (args (if query-context - (append (list "\'") basic-args (list "and (" query-context ")\'")) - (append (list "\'") basic-args (list "\'")))) - (message-arg (if notmuch-pick-view-just-messages - "--thread=none" - "--thread=entire")) - (sort-arg (if notmuch-pick-oldest-first - "--sort=oldest-first" - "--sort=newest-first"))) - - (notmuch-pick-insert-forest (notmuch-query-get-threads args "--headers-only" message-arg sort-arg)) - ;; If the query context reduced the results to nothing, run - ;; the basic query. - (when (and (eq (buffer-size) 0) - query-context) - (notmuch-pick-insert-forest - (notmuch-query-get-threads basic-args message-arg sort-arg)))))) + (let* (args + (basic-args thread-id) + (search-args (concat + basic-args (if query-context (concat " and (" query-context ")")))) + (message-arg (if notmuch-pick-view-just-messages + "--thread=none" + "--thread=entire")) + (sort-arg (if notmuch-pick-oldest-first + "--sort=oldest-first" + "--sort=newest-first")) + (proc (start-process + "notmuch-pick" buffer + notmuch-command "show" "--headers-only" "--format=json" + message-arg sort-arg search-args))) + (set-process-sentinel proc 'notmuch-pick-process-sentinel) + (set-process-filter proc 'notmuch-pick-process-filter) + (set-process-query-on-exit-flag proc nil))) +;; (notmuch-pick-insert-forest (notmuch-query-get-threads args "--headers-only" message-arg sort-arg)) +;; (message "time3 (end forest): %s" (current-time)) +;; If the query context reduced the results to nothing, run +;; the basic query. +;; (when (and (eq (buffer-size) 0) +;; query-context) +;; (notmuch-pick-insert-forest +;; (notmuch-query-get-threads basic-args message-arg sort-arg)))))) (defun notmuch-pick (&optional query query-context buffer-name) "Run notmuch pick with the given `query' and display the results" @@ -567,14 +630,14 @@ Complete list of currently available key bindings: (setq query (notmuch-read-query "Notmuch pick: "))) (let ((buffer (get-buffer-create (generate-new-buffer-name (or buffer-name - (concat "*notmuch-" query "*"))))) + (concat "*notmuch-pick-" query "*"))))) (inhibit-read-only t)) (switch-to-buffer buffer) ;; Don't track undo information for this buffer (set 'buffer-undo-list t) - (notmuch-pick-worker query query-context buffer-name) + (notmuch-pick-worker query query-context buffer) (setq truncate-lines t))) -- 1.7.2.3