]> git.notmuchmail.org Git - notmuch/blobdiff - emacs/notmuch-address.el
emacs: fully add the notmuch-address customize group
[notmuch] / emacs / notmuch-address.el
index 36c796f9e34d11145dda5162a3360cf5db2f31c6..d504ff2d9fd4e0a952116761104a28fb1a1d2602 100644 (file)
 
 (defvar notmuch-address-full-harvest-finished nil
   "t indicates that full completion address harvesting has been
 
 (defvar notmuch-address-full-harvest-finished nil
   "t indicates that full completion address harvesting has been
-finished")
+finished. Use notmuch-address--harvest-ready to access as that
+will load a saved hash if necessary (and available).")
+
+(defun notmuch-address--harvest-ready ()
+  "Return t if there is a full address hash available.
+
+If the hash is not present it attempts to load a saved hash."
+  (or notmuch-address-full-harvest-finished
+      (notmuch-address--load-address-hash)))
 
 (defcustom notmuch-address-command 'internal
   "Determines how address completion candidates are generated.
 
 (defcustom notmuch-address-command 'internal
   "Determines how address completion candidates are generated.
@@ -58,6 +66,7 @@ disabled."
          (const :tag "Disable address completion" nil)
          (string :tag "Use external completion command"))
   :group 'notmuch-send
          (const :tag "Disable address completion" nil)
          (string :tag "Use external completion command"))
   :group 'notmuch-send
+  :group 'notmuch-address
   :group 'notmuch-external)
 
 (defcustom notmuch-address-internal-completion '(sent nil)
   :group 'notmuch-external)
 
 (defcustom notmuch-address-internal-completion '(sent nil)
@@ -85,6 +94,19 @@ This should be a list of the form '(DIRECTION FILTER), where
         (setq notmuch-address-completions (clrhash notmuch-address-completions))
         (setq notmuch-address-full-harvest-finished nil))
   :group 'notmuch-send
         (setq notmuch-address-completions (clrhash notmuch-address-completions))
         (setq notmuch-address-full-harvest-finished nil))
   :group 'notmuch-send
+  :group 'notmuch-address
+  :group 'notmuch-external)
+
+(defcustom notmuch-address-save-filename nil
+  "Filename to save the cached completion addresses.
+
+All the addresses notmuch uses for address completion will be
+cached in this file. This has obvious privacy implications so you
+should make sure it is not somewhere publicly readable."
+  :type '(choice (const :tag "Off" nil)
+                (file :tag "Filename"))
+  :group 'notmuch-send
+  :group 'notmuch-address
   :group 'notmuch-external)
 
 (defcustom notmuch-address-selection-function 'notmuch-address-selection-function
   :group 'notmuch-external)
 
 (defcustom notmuch-address-selection-function 'notmuch-address-selection-function
@@ -96,9 +118,10 @@ See documentation of function `notmuch-address-selection-function'
 to know how address selection is made by default."
   :type 'function
   :group 'notmuch-send
 to know how address selection is made by default."
   :type 'function
   :group 'notmuch-send
+  :group 'notmuch-address
   :group 'notmuch-external)
 
   :group 'notmuch-external)
 
-(defcustom notmuch-address-completion-hook nil
+(defcustom notmuch-address-post-completion-functions nil
   "Functions called after completing address.
 
 The completed address is passed as an argument to each function.
   "Functions called after completing address.
 
 The completed address is passed as an argument to each function.
@@ -126,7 +149,8 @@ matching `notmuch-address-completion-headers-regexp'.
 (defcustom notmuch-address-use-company t
   "If available, use company mode for address completion"
   :type 'boolean
 (defcustom notmuch-address-use-company t
   "If available, use company mode for address completion"
   :type 'boolean
-  :group 'notmuch-send)
+  :group 'notmuch-send
+  :group 'notmuch-address)
 
 (defun notmuch-address-setup ()
   (let* ((setup-company (and notmuch-address-use-company
 
 (defun notmuch-address-setup ()
   (let* ((setup-company (and notmuch-address-use-company
@@ -147,11 +171,11 @@ toggles the setting in this buffer."
   (interactive)
   (if (local-variable-p 'notmuch-address-command)
       (kill-local-variable 'notmuch-address-command)
   (interactive)
   (if (local-variable-p 'notmuch-address-command)
       (kill-local-variable 'notmuch-address-command)
-    (setq-local notmuch-address-command 'internal))
+    (notmuch-setq-local notmuch-address-command 'internal))
   (if (boundp 'company-idle-delay)
       (if (local-variable-p 'company-idle-delay)
          (kill-local-variable 'company-idle-delay)
   (if (boundp 'company-idle-delay)
       (if (local-variable-p 'company-idle-delay)
          (kill-local-variable 'company-idle-delay)
-       (setq-local company-idle-delay nil))))
+       (notmuch-setq-local company-idle-delay nil))))
 
 (defun notmuch-address-matching (substring)
   "Returns a list of completion candidates matching SUBSTRING.
 
 (defun notmuch-address-matching (substring)
   "Returns a list of completion candidates matching SUBSTRING.
@@ -170,7 +194,7 @@ elisp-based implementation or older implementation requiring
 external commands."
   (cond
    ((eq notmuch-address-command 'internal)
 external commands."
   (cond
    ((eq notmuch-address-command 'internal)
-    (when (not notmuch-address-full-harvest-finished)
+    (unless (notmuch-address--harvest-ready)
       ;; First, run quick synchronous harvest based on what the user
       ;; entered so far
       (notmuch-address-harvest original t))
       ;; First, run quick synchronous harvest based on what the user
       ;; entered so far
       (notmuch-address-harvest original t))
@@ -218,7 +242,7 @@ external commands."
            (push chosen notmuch-address-history)
            (delete-region beg end)
            (insert chosen)
            (push chosen notmuch-address-history)
            (delete-region beg end)
            (insert chosen)
-           (run-hook-with-args 'notmuch-address-completion-hook chosen))
+           (run-hook-with-args 'notmuch-address-post-completion-functions chosen))
        (message "No matches.")
        (ding))))
    (t nil)))
        (message "No matches.")
        (ding))))
    (t nil)))
@@ -323,6 +347,64 @@ execution, CALLBACK is called when harvesting finishes."
   ;; return value
   nil)
 
   ;; return value
   nil)
 
+(defvar notmuch-address--save-hash-version 1
+  "Version format of the save hash.")
+
+(defun notmuch-address--get-address-hash ()
+  "Returns the saved address hash as a plist.
+
+Returns nil if the save file does not exist, or it does not seem
+to be a saved address hash."
+  (when notmuch-address-save-filename
+    (condition-case nil
+       (with-temp-buffer
+         (insert-file-contents notmuch-address-save-filename)
+         (let ((name (read (current-buffer)))
+               (plist (read (current-buffer))))
+           ;; We do two simple sanity checks on the loaded file. We just
+           ;; check a version is specified, not that it is the current
+           ;; version, as we are allowed to over-write and a save-file with
+           ;; an older version.
+           (when (and (string= name "notmuch-address-hash")
+                      (plist-get plist :version))
+             plist)))
+      ;; The error case catches any of the reads failing.
+      (error nil))))
+
+(defun notmuch-address--load-address-hash ()
+  "Read the saved address hash and set the corresponding variables."
+  (let ((load-plist (notmuch-address--get-address-hash)))
+    (when (and load-plist
+              ;; If the user's setting have changed, or the version
+              ;; has changed, return nil to make sure the new settings
+              ;; take effect.
+              (equal (plist-get load-plist :completion-settings)
+                     notmuch-address-internal-completion)
+              (equal (plist-get load-plist :version)
+                     notmuch-address--save-hash-version))
+      (setq notmuch-address-last-harvest (plist-get load-plist :last-harvest)
+           notmuch-address-completions (plist-get load-plist :completions)
+           notmuch-address-full-harvest-finished t)
+      ;; Return t to say load was successful.
+      t)))
+
+(defun notmuch-address--save-address-hash ()
+  (when notmuch-address-save-filename
+    (if (or (not (file-exists-p notmuch-address-save-filename))
+             ;; The file exists, check it is a file we saved
+           (notmuch-address--get-address-hash))
+       (with-temp-file notmuch-address-save-filename
+         (let ((save-plist (list :version notmuch-address--save-hash-version
+                                 :completion-settings notmuch-address-internal-completion
+                                 :last-harvest notmuch-address-last-harvest
+                                 :completions notmuch-address-completions)))
+           (print "notmuch-address-hash" (current-buffer))
+           (print save-plist (current-buffer))))
+      (message "\
+Warning: notmuch-address-save-filename %s exists but doesn't
+appear to be an address savefile.  Not overwriting."
+              notmuch-address-save-filename))))
+
 (defun notmuch-address-harvest-trigger ()
   (let ((now (float-time)))
     (when (> (- now notmuch-address-last-harvest) 86400)
 (defun notmuch-address-harvest-trigger ()
   (let ((now (float-time)))
     (when (> (- now notmuch-address-last-harvest) 86400)
@@ -333,7 +415,9 @@ execution, CALLBACK is called when harvesting finishes."
                                 ;; again when the trigger is next
                                 ;; called
                                 (if (string= event "finished\n")
                                 ;; again when the trigger is next
                                 ;; called
                                 (if (string= event "finished\n")
-                                    (setq notmuch-address-full-harvest-finished t)
+                                    (progn
+                                      (notmuch-address--save-address-hash)
+                                      (setq notmuch-address-full-harvest-finished t))
                                   (setq notmuch-address-last-harvest 0)))))))
 
 ;;
                                   (setq notmuch-address-last-harvest 0)))))))
 
 ;;