[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/ebdb 1a4870a 5/5: Make field customization more robust

From: Eric Abrahamsen
Subject: [elpa] externals/ebdb 1a4870a 5/5: Make field customization more robust
Date: Tue, 24 Apr 2018 16:27:00 -0400 (EDT)

branch: externals/ebdb
commit 1a4870aa225548eda80ae69f7dad6662000f55a2
Author: Eric Abrahamsen <address@hidden>
Commit: Eric Abrahamsen <address@hidden>

    Make field customization more robust
    * ebdb-com.el (ebdb-customization-record): Rename variable from 
      (ebdb-customization-field): New variable doing equivalent record-keeping.
      (ebdb-edit-field-customize): Have customization act on a field
      clone, rather than the field itself.
      (eieio-done-customizing): Once customization is complete (on the
      cloned field), then try to change the old field for the new field,
      in an atomic way.
      (eieio-done-customizing): Use ebdb-with-record-edits to both handle
      un-editable records, and record redisplay.
      (eieio-done-customizing): Use the new record-keeping variable.
 ebdb-com.el | 52 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/ebdb-com.el b/ebdb-com.el
index b543c85..69d8f1e 100644
--- a/ebdb-com.el
+++ b/ebdb-com.el
@@ -42,12 +42,11 @@
   "Keymap used for EBDB crm completions.")
-(defvar-local ebdb-custom-field-record nil
-  "Variable local to EBDB field customization buffers, pointing
-to the record that field belongs to.
+(defvar-local ebdb-customization-record nil
+  "Variable holding the record whose field is being customized.")
-A hacky bit of bookkeeping that lets us mark the record as dirty
-and redisplay it after the field is edited.")
+(defvar-local ebdb-customization-field nil
+  "Variable holding the field being customized.")
 ;; Customizations for display routines
@@ -1736,27 +1735,34 @@ commands, called from an *EBDB* buffer, and the 
    (list (ebdb-current-record)
-  (ebdb-with-record-edits record
-    (ebdb-record-delete-field record field)
-    (condition-case nil
-       (eieio-customize-object field)
-      (error (ebdb-record-insert-field record field))))
-  (setq ebdb-custom-field-record record))
-(cl-defmethod eieio-done-customizing ((f ebdb-field))
-  (let ((rec ebdb-custom-field-record))
-    (when rec
-      (ebdb-record-insert-field rec f))))
-(cl-defmethod eieio-done-customizing :after ((f ebdb-field))
-  (let ((rec ebdb-custom-field-record))
+  (let ((new-field (clone field)))
+    (eieio-customize-object new-field)
+    ;; The following two variables are buffer-local, and we're hoping
+    ;; this will make them local to the customization buffer: ie, an
+    ;; arbitrary number of *Customize* buffers can be opened, and the
+    ;; accept/apply options will all behave correctly.
+    (setq ebdb-customization-field field
+         ebdb-customization-record record)))
+(cl-defmethod eieio-done-customizing ((new-field ebdb-field))
+  "Do the actual insertion of the newly-customized field."
+  (let ((rec ebdb-customization-record)
+       (old-field ebdb-customization-field))
+    (when (and rec old-field)
+      (ebdb-record-change-field rec old-field new-field))))
+(cl-defmethod eieio-done-customizing :around ((_field ebdb-field))
+  "Check that the record owning FIELD can be edited.
+Also redisplays it after customization."
+  (let ((rec ebdb-customization-record))
     (when rec
-     (ebdb-redisplay-records rec 'reformat t))))
+      (ebdb-with-record-edits rec
+       (cl-call-next-method)))))
 (cl-defmethod eieio-done-customizing :after ((mail ebdb-field-mail))
   "Handle mail priority after customizing.
 Check that some mail is marked as primary after MAIL is edited."
-  (let* ((rec ebdb-custom-field-record)
+  (let* ((rec ebdb-customization-record)
         (all-mails (remove mail (ebdb-record-mail rec)))
         (primaries (when rec (seq-filter
                               (lambda (m)
@@ -1764,10 +1770,14 @@ Check that some mail is marked as primary after MAIL is 
         (prim (eq (slot-value mail 'priority) 'primary)))
     (cond ((and prim primaries)
+          ;; MAIL is primary, so set all other primary mails to
+          ;; normal.
           (dolist (p primaries)
             (ebdb-record-change-field rec p (clone p :priority 'normal))))
          ((and (null (or prim primaries))
                (car-safe all-mails))
+          ;; Nothing is primary, so try to set some other mail to
+          ;; primary.
            rec (car all-mails)
            (clone (car all-mails) :priority 'primary))))))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]