]> git.notmuchmail.org Git - notmuch/blobdiff - emacs/notmuch-hello.el
emacs: make headings outline-minor-mode compatible
[notmuch] / emacs / notmuch-hello.el
index fa31694ff0f79a7f2781849394390a673f75aade..28ffedd98ef33be6b4d8ab37f5aaef9cadde223d 100644 (file)
@@ -37,6 +37,8 @@
                  (&optional query query-context target buffer-name open-target))
 
 
+;;; Options
+
 (defun notmuch-saved-search-get (saved-search field)
   "Get FIELD from SAVED-SEARCH.
 
@@ -192,6 +194,8 @@ fields of the search."
 (defvar notmuch-hello-indent 4
   "How much to indent non-headers.")
 
+(defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png")))
+
 (defcustom notmuch-show-logo t
   "Should the notmuch logo be shown?"
   :type 'boolean
@@ -367,36 +371,62 @@ supported for \"Customized queries section\" items."
   :group 'notmuch-hello
   :type 'boolean)
 
+;;; Internal variables
+
 (defvar notmuch-hello-hidden-sections nil
   "List of sections titles whose contents are hidden.")
 
 (defvar notmuch-hello-first-run t
   "True if `notmuch-hello' is run for the first time, set to nil afterwards.")
 
-(defun notmuch-hello-nice-number (n)
-  (let (result)
-    (while (> n 0)
-      (push (% n 1000) result)
-      (setq n (/ n 1000)))
-    (setq result (or result '(0)))
-    (apply #'concat
-          (number-to-string (car result))
-          (mapcar (lambda (elem)
-                    (format "%s%03d" notmuch-hello-thousands-separator elem))
-                  (cdr result)))))
-
-(defun notmuch-hello-search (&optional search)
-  (unless (null search)
-    (setq search (string-trim search))
-    (let ((history-delete-duplicates t))
-      (add-to-history 'notmuch-search-history search)))
-  (notmuch-search search notmuch-search-oldest-first))
-
-(defun notmuch-hello-add-saved-search (widget)
-  (interactive)
-  (let ((search (widget-value
-                (symbol-value
-                 (widget-get widget :notmuch-saved-search-widget))))
+;;; Widgets for inserters
+
+(define-widget 'notmuch-search-item 'item
+  "A recent search."
+  :format "%v\n"
+  :value-create 'notmuch-search-item-value-create)
+
+(defun notmuch-search-item-value-create (widget)
+  (let ((value (widget-get widget :value)))
+    (widget-insert (make-string notmuch-hello-indent ?\s))
+    (widget-create 'editable-field
+                  :size (widget-get widget :size)
+                  :parent widget
+                  :action #'notmuch-hello-search
+                  value)
+    (widget-insert " ")
+    (widget-create 'push-button
+                  :parent widget
+                  :notify #'notmuch-hello-add-saved-search
+                  "save")
+    (widget-insert " ")
+    (widget-create 'push-button
+                  :parent widget
+                  :notify #'notmuch-hello-delete-search-from-history
+                  "del")))
+
+(defun notmuch-search-item-field-width ()
+  (max 8 ; Don't let the search boxes be less than 8 characters wide.
+       (- (window-width)
+         notmuch-hello-indent ; space at bol
+         notmuch-hello-indent ; space at eol
+         1    ; for the space before the [save] button
+         6    ; for the [save] button
+         1    ; for the space before the [del] button
+         5))) ; for the [del] button
+
+;;; Widget actions
+
+(defun notmuch-hello-search (widget &rest _event)
+  (let ((search (widget-value widget)))
+    (when search
+      (setq search (string-trim search))
+      (let ((history-delete-duplicates t))
+       (add-to-history 'notmuch-search-history search)))
+    (notmuch-search search notmuch-search-oldest-first)))
+
+(defun notmuch-hello-add-saved-search (widget &rest _event)
+  (let ((search (widget-value (widget-get widget :parent)))
        (name (completing-read "Name for saved search: "
                               notmuch-saved-searches)))
     ;; If an existing saved search with this name exists, remove it.
@@ -412,15 +442,20 @@ supported for \"Customized queries section\" items."
     (message "Saved '%s' as '%s'." search name)
     (notmuch-hello-update)))
 
-(defun notmuch-hello-delete-search-from-history (widget)
-  (interactive)
-  (let ((search (widget-value
-                (symbol-value
-                 (widget-get widget :notmuch-saved-search-widget)))))
-    (setq notmuch-search-history (delete search
-                                        notmuch-search-history))
+(defun notmuch-hello-delete-search-from-history (widget &rest _event)
+  (when (y-or-n-p "Are you sure you want to delete this search? ")
+    (let ((search (widget-value (widget-get widget :parent))))
+      (setq notmuch-search-history
+           (delete search notmuch-search-history)))
     (notmuch-hello-update)))
 
+;;; Button utilities
+
+;; `notmuch-hello-query-counts', `notmuch-hello-nice-number' and
+;; `notmuch-hello-insert-buttons' are used outside this section.
+;; All other functions that are defined in this section are only
+;; used by these two functions.
+
 (defun notmuch-hello-longest-label (searches-alist)
   (or (cl-loop for elem in searches-alist
               maximize (length (notmuch-saved-search-get elem :name)))
@@ -555,6 +590,18 @@ the CLI and emacs interface."))
           (list (plist-put elem-plist :count message-count)))))
      query-list)))
 
+(defun notmuch-hello-nice-number (n)
+  (let (result)
+    (while (> n 0)
+      (push (% n 1000) result)
+      (setq n (/ n 1000)))
+    (setq result (or result '(0)))
+    (apply #'concat
+          (number-to-string (car result))
+          (mapcar (lambda (elem)
+                    (format "%s%03d" notmuch-hello-thousands-separator elem))
+                  (cdr result)))))
+
 (defun notmuch-hello-insert-buttons (searches)
   "Insert buttons for SEARCHES.
 
@@ -609,7 +656,7 @@ with `notmuch-hello-query-counts'."
     (unless (eq (% count tags-per-line) 0)
       (widget-insert "\n"))))
 
-(defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png")))
+;;; Mode
 
 (defun notmuch-hello-update ()
   "Update the notmuch-hello buffer."
@@ -693,6 +740,8 @@ Complete list of currently available key bindings:
   ;;(setq buffer-read-only t)
   )
 
+;;; Inserters
+
 (defun notmuch-hello-generate-tag-alist (&optional hide-tags)
   "Return an alist from tags to queries to display in the all-tags section."
   (cl-mapcan (lambda (tag)
@@ -768,8 +817,7 @@ Complete list of currently available key bindings:
                 ;; search boxes.
                 :size (max 8 (- (window-width) notmuch-hello-indent
                                 (length "Search: ")))
-                :action (lambda (widget &rest ignore)
-                          (notmuch-hello-search (widget-value widget))))
+                :action #'notmuch-hello-search)
   ;; Add an invisible dot to make `widget-end-of-line' ignore
   ;; trailing spaces in the search widget field.  A dot is used
   ;; instead of a space to make `show-trailing-whitespace'
@@ -783,58 +831,18 @@ Complete list of currently available key bindings:
   "Insert recent searches."
   (when notmuch-search-history
     (widget-insert "Recent searches: ")
-    (widget-create 'push-button
-                  :notify (lambda (&rest ignore)
-                            (when (y-or-n-p "Are you sure you want to clear the searches? ")
-                              (setq notmuch-search-history nil)
-                              (notmuch-hello-update)))
-                  "clear")
+    (widget-create
+     'push-button
+     :notify (lambda (&rest _ignore)
+              (when (y-or-n-p "Are you sure you want to clear the searches? ")
+                (setq notmuch-search-history nil)
+                (notmuch-hello-update)))
+     "clear")
     (widget-insert "\n\n")
-    (let ((start (point)))
-      (cl-loop for i from 1 to notmuch-hello-recent-searches-max
-              for search in notmuch-search-history do
-              (let ((widget-symbol (intern (format "notmuch-hello-search-%d" i))))
-                (set widget-symbol
-                     (widget-create 'editable-field
-                                    ;; Don't let the search boxes be
-                                    ;; less than 8 characters wide.
-                                    :size (max 8
-                                               (- (window-width)
-                                                  ;; Leave some space
-                                                  ;; at the start and
-                                                  ;; end of the
-                                                  ;; boxes.
-                                                  (* 2 notmuch-hello-indent)
-                                                  ;; 1 for the space
-                                                  ;; before the
-                                                  ;; `[save]' button. 6
-                                                  ;; for the `[save]'
-                                                  ;; button.
-                                                  1 6
-                                                  ;; 1 for the space
-                                                  ;; before the `[del]'
-                                                  ;; button. 5 for the
-                                                  ;; `[del]' button.
-                                                  1 5))
-                                    :action (lambda (widget &rest ignore)
-                                              (notmuch-hello-search (widget-value widget)))
-                                    search))
-                (widget-insert " ")
-                (widget-create 'push-button
-                               :notify (lambda (widget &rest ignore)
-                                         (notmuch-hello-add-saved-search widget))
-                               :notmuch-saved-search-widget widget-symbol
-                               "save")
-                (widget-insert " ")
-                (widget-create 'push-button
-                               :notify (lambda (widget &rest ignore)
-                                         (when (y-or-n-p "Are you sure you want to delete this search? ")
-                                           (notmuch-hello-delete-search-from-history widget)))
-                               :notmuch-saved-search-widget widget-symbol
-                               "del"))
-              (widget-insert "\n"))
-      (indent-rigidly start (point) notmuch-hello-indent))
-    nil))
+    (let ((width (notmuch-search-item-field-width)))
+      (dolist (search (seq-take notmuch-search-history
+                               notmuch-hello-recent-searches-max))
+       (widget-create 'notmuch-search-item :value search :size width)))))
 
 (defun notmuch-hello-insert-searches (title query-list &rest options)
   "Insert a section with TITLE showing a list of buttons made from QUERY-LIST.
@@ -933,6 +941,8 @@ following:
     (let ((fill-column (- (window-width) notmuch-hello-indent)))
       (center-region start (point)))))
 
+;;; Hello!
+
 ;;;###autoload
 (defun notmuch-hello (&optional no-display)
   "Run notmuch and display saved searches, known tags, etc."
@@ -984,7 +994,7 @@ following:
   (run-hooks 'notmuch-hello-refresh-hook)
   (setq notmuch-hello-first-run nil))
 
-;;
+;;; _
 
 (provide 'notmuch-hello)