[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/ebdb 11fe701 047/350: Name classes now inherit from ebd
From: |
Eric Abrahamsen |
Subject: |
[elpa] externals/ebdb 11fe701 047/350: Name classes now inherit from ebdb-field-user |
Date: |
Mon, 14 Aug 2017 11:46:00 -0400 (EDT) |
branch: externals/ebdb
commit 11fe701d655a4508ade2843e87494bd1a91ba9b5
Author: Eric Abrahamsen <address@hidden>
Commit: Eric Abrahamsen <address@hidden>
Name classes now inherit from ebdb-field-user
* ebdb.el (ebdb-field-name): Inherit name classes from
`ebdb-field-user', allowing users to choose what kind of name goes
in the aka slot.
(ebdb-field-name-complex): Change human-readable tag to "alt name".
(ebdb-field-name-simple): Change human-readable tag to "nickname".
This required moving all the abstract field definitions higher in the
file.
---
ebdb.el | 242 +++++++++++++++++++++++++++++++--------------------------------
ebdb.org | 17 +++--
2 files changed, 133 insertions(+), 126 deletions(-)
diff --git a/ebdb.el b/ebdb.el
index ce48643..d698ec9 100644
--- a/ebdb.el
+++ b/ebdb.el
@@ -617,6 +617,123 @@ message."
(cl-defmethod ebdb-string ((field ebdb-field-uuid))
(slot-value field 'uuid))
+;;; The labeled abstract class. Can be subclassed, or used as a mixin.
+
+;; Probably there's no need to subclass from `ebdb-field'. Without
+;; this, it will be a pure mixin class. Probably we can do away with
+;; this inheritance without hurting anything.
+(defclass ebdb-field-labeled (ebdb-field eieio-named)
+ ;; Override the object-name slot from `eieio-named' so we can add a
+ ;; custom declaration to it.
+ ((object-name
+ :initarg :object-name
+ :custom (choice (const :tag "Empty" nil)
+ string)
+ :initform nil)
+ (label-list
+ :initform nil
+ :type (or null symbol)
+ :allocation :class
+ :documentation
+ "This class-allocated slot points to a variable holding a
+ list of known string labels for objects of the subclass."))
+ :abstract t
+ :documentation "A field with a string label.")
+
+(cl-defmethod ebdb-read :around ((class (subclass ebdb-field-labeled))
&optional slots obj)
+ "Prompt for a label for a new object of class CLASS, using OBJ
+ as a default, and store the result in SLOTS.
+
+All subclasses of `ebdb-field-labeled' should have a 'label-list
+slot pointing to a var holding known labels for that class. This
+method checks that the label is known, and asks for confirmation
+if it isn't.
+
+This method also signals the 'ebdb-empty error if the user gives
+an empty string as a label, which allows interruption of the read
+process."
+ ;; This is an :around method so the field label can be prompted for
+ ;; before the value.
+ (let* ((labels (symbol-value (oref-default class label-list)))
+ (human-readable (ebdb-field-readable-name class))
+ (label (plist-get slots :object-name)))
+ (unless label
+ (setq label (ebdb-read-string
+ (if (stringp human-readable)
+ (format "%s label: " (capitalize human-readable))
+ "Label: ")
+ (and obj (slot-value obj 'object-name))
+ labels nil)
+ slots (plist-put slots :object-name label)))
+ (if (or (member label labels)
+ (yes-or-no-p (format "%s is not a known label, define it? " label)))
+ (cl-call-next-method class slots obj)
+ (signal 'ebdb-empty (list class)))))
+
+(cl-defmethod ebdb-init-field ((field ebdb-field-labeled) &optional _record)
+ (let ((label-var (slot-value field 'label-list)))
+ (ebdb-add-to-list label-var (slot-value field 'object-name))
+ (cl-call-next-method)))
+
+;;; The obfuscated field type. This is a little goofy, but might come
+;;; in handy.
+
+(defclass ebdb-field-obfuscated (ebdb-field)
+ nil
+ :abstract t
+ :documentation
+ "A field class mixin that prevents the contents from being
+ displayed in the *EBDB* buffer. Use for mildly sensitive
+ information.")
+
+;;; User-defined fields. There are two kinds. The first is
+;;; `ebdb-field-user', which provides no information about labels or
+;;; slots, but simply gives us the right to live in the "fields" slot
+;;; of records. It must be subclassed to be useful.
+
+;;; The second is the `ebdb-field-user-simple', which subclasses
+;;; `ebdb-field-user' and `ebdb-field-labeled'. This class should
+;;; *not* be subclassed; it's the class that collects all the basic
+;;; label-plus-value fields that users might want to add. Instances
+;;; have no particular behavior, they're just key-value pairs.
+
+(defclass ebdb-field-user (ebdb-field)
+ nil
+ :abstract t
+ :documentation
+ "Fields that should be user-editable, but need more complicated
+ slot structures than the simple \"value\" provided by
+ `ebdb-field-user-simple', can subclass this class. Any field
+ class that subclasses this will be offered as a choice to the
+ user when inserting new fields.")
+
+(defvar ebdb-user-label-list nil
+ "List of existing labels of user fields.")
+
+(defclass ebdb-field-user-simple (ebdb-field-labeled ebdb-field-user)
+ ((label-list :initform ebdb-user-label-list)
+ (value
+ :initarg :value
+ :type (or atom list)
+ :initform ""
+ :custom string
+ :documentation "The value of this user-defined field."))
+ :human-readable "user field")
+
+(cl-defmethod ebdb-string ((field ebdb-field-user-simple))
+ (let ((val (slot-value field 'value)))
+ (if (stringp val)
+ val
+ (ebdb-concat (intern-soft (slot-value field 'object-name)) val))))
+
+;; TODO: Maybe replicate the ability to insert a lisp sexp directly,
+;; in interactive mode?
+(cl-defmethod ebdb-read ((class (subclass ebdb-field-user-simple)) &optional
slots obj)
+ (unless (plist-get slots :value)
+ (let ((default (when obj (ebdb-string obj))))
+ (setq slots (plist-put slots :value (ebdb-read-string "Value: "
default)))))
+ (cl-call-next-method class slots obj))
+
;;; The name fields. One abstract base class, and two instantiable
;;; subclasses.
@@ -624,7 +741,7 @@ message."
;; `ebdb-field-name-simple' or `ebdb-field-name-complex'. Or maybe on
;; a case-by-case basis?
-(defclass ebdb-field-name (ebdb-field)
+(defclass ebdb-field-name (ebdb-field-user)
nil
:abstract t
:documentation "Abstract base class for creating record
@@ -638,7 +755,7 @@ message."
:initform ""))
:documentation "A name class for \"simple\" names: ie plain
strings."
- :human-readable "name")
+ :human-readable "nickname")
(cl-defmethod ebdb-string ((name ebdb-field-name-simple))
(slot-value name 'name))
@@ -686,9 +803,7 @@ message."
:initform nil))
:documentation "A name class for \"complex\", ie structured,
names."
- ;; This returns "aka" because the prompt is only used when _adding_
- ;; another name to an existing record.
- :human-readable "aka")
+ :human-readable "alt name")
(cl-defmethod ebdb-name-last ((name ebdb-field-name-complex))
"Return the surname of this name field."
@@ -774,123 +889,6 @@ values, by default the search is not handed to the name
field itself."
(list (car bits)))
:surname (cdr bits))))
-;;; The labeled abstract class. Can be subclassed, or used as a mixin.
-
-;; Probably there's no need to subclass from `ebdb-field'. Without
-;; this, it will be a pure mixin class. Probably we can do away with
-;; this inheritance without hurting anything.
-(defclass ebdb-field-labeled (ebdb-field eieio-named)
- ;; Override the object-name slot from `eieio-named' so we can add a
- ;; custom declaration to it.
- ((object-name
- :initarg :object-name
- :custom (choice (const :tag "Empty" nil)
- string)
- :initform nil)
- (label-list
- :initform nil
- :type (or null symbol)
- :allocation :class
- :documentation
- "This class-allocated slot points to a variable holding a
- list of known string labels for objects of the subclass."))
- :abstract t
- :documentation "A field with a string label.")
-
-(cl-defmethod ebdb-read :around ((class (subclass ebdb-field-labeled))
&optional slots obj)
- "Prompt for a label for a new object of class CLASS, using OBJ
- as a default, and store the result in SLOTS.
-
-All subclasses of `ebdb-field-labeled' should have a 'label-list
-slot pointing to a var holding known labels for that class. This
-method checks that the label is known, and asks for confirmation
-if it isn't.
-
-This method also signals the 'ebdb-empty error if the user gives
-an empty string as a label, which allows interruption of the read
-process."
- ;; This is an :around method so the field label can be prompted for
- ;; before the value.
- (let* ((labels (symbol-value (oref-default class label-list)))
- (human-readable (ebdb-field-readable-name class))
- (label (plist-get slots :object-name)))
- (unless label
- (setq label (ebdb-read-string
- (if (stringp human-readable)
- (format "%s label: " (capitalize human-readable))
- "Label: ")
- (and obj (slot-value obj 'object-name))
- labels nil)
- slots (plist-put slots :object-name label)))
- (if (or (member label labels)
- (yes-or-no-p (format "%s is not a known label, define it? " label)))
- (cl-call-next-method class slots obj)
- (signal 'ebdb-empty (list class)))))
-
-(cl-defmethod ebdb-init-field ((field ebdb-field-labeled) &optional _record)
- (let ((label-var (slot-value field 'label-list)))
- (ebdb-add-to-list label-var (slot-value field 'object-name))
- (cl-call-next-method)))
-
-;;; The obfuscated field type. This is a little goofy, but might come
-;;; in handy.
-
-(defclass ebdb-field-obfuscated (ebdb-field)
- nil
- :abstract t
- :documentation
- "A field class mixin that prevents the contents from being
- displayed in the *EBDB* buffer. Use for mildly sensitive
- information.")
-
-;;; User-defined fields. There are two kinds. The first is
-;;; `ebdb-field-user', which provides no information about labels or
-;;; slots, but simply gives us the right to live in the "fields" slot
-;;; of records. It must be subclassed to be useful.
-
-;;; The second is the `ebdb-field-user-simple', which subclasses
-;;; `ebdb-field-user' and `ebdb-field-labeled'. This class should
-;;; *not* be subclassed; it's the class that collects all the basic
-;;; label-plus-value fields that users might want to add. Instances
-;;; have no particular behavior, they're just key-value pairs.
-
-(defclass ebdb-field-user (ebdb-field)
- nil
- :abstract t
- :documentation
- "Fields that should be user-editable, but need more complicated
- slot structures than the simple \"value\" provided by
- `ebdb-field-user-simple', can subclass this class. Any field
- class that subclasses this will be offered as a choice to the
- user when inserting new fields.")
-
-(defvar ebdb-user-label-list nil
- "List of existing labels of user fields.")
-
-(defclass ebdb-field-user-simple (ebdb-field-labeled ebdb-field-user)
- ((label-list :initform ebdb-user-label-list)
- (value
- :initarg :value
- :type (or atom list)
- :initform ""
- :custom string
- :documentation "The value of this user-defined field."))
- :human-readable "user field")
-
-(cl-defmethod ebdb-string ((field ebdb-field-user-simple))
- (let ((val (slot-value field 'value)))
- (if (stringp val)
- val
- (ebdb-concat (intern-soft (slot-value field 'object-name)) val))))
-
-;; TODO: Maybe replicate the ability to insert a lisp sexp directly,
-;; in interactive mode?
-(cl-defmethod ebdb-read ((class (subclass ebdb-field-user-simple)) &optional
slots obj)
- (unless (plist-get slots :value)
- (let ((default (when obj (ebdb-string obj))))
- (setq slots (plist-put slots :value (ebdb-read-string "Value: "
default)))))
- (cl-call-next-method class slots obj))
-
;;; Role fields.
(defvar ebdb-role-label-list nil)
diff --git a/ebdb.org b/ebdb.org
index 15a5dba..f7576ae 100644
--- a/ebdb.org
+++ b/ebdb.org
@@ -1,3 +1,4 @@
+ -*- sentence-end-double-space: t; -*-
#+TEXINFO_CLASS: info
#+TEXINFO_HEADER: @syncodeindex pg cp
#+TITLE: EBDB Manual
@@ -90,7 +91,15 @@ the record in, if there is more than one.
** Record classes
EBDB comes with two record classes, representing individuals and
organizations.
-
+** Record names
+EBDB comes with two classes for name fields: "simple" and "complex".
+Simple names are just a single string, complex names are split out
+into surname, given names, suffix, etc. All records have a single
+canonical name: person records have a complex name, organization
+records have a simple name. In addition, person records can have one
+or more "aka" names, and these akas can be either simple or complex.
+When adding fields to a record, the simple name class is labeled
+"nickname", and the complex class is labeled "alt name".
* Record fields
** Inserting new fields
Press "i" (`ebdb-insert-field') with point on a record will prompt for
@@ -144,7 +153,7 @@ your custom class name:
Besides the "plumbing" and "built-in" fields, all other fields belong
to one of two types: `ebdb-field-user' and `ebdb-field-user-simple'.
-The former is an abstract class, used to built fields with more
+The former is an abstract class, used to build fields with more
complicated structures. The latter is a simple class with a string
label and a string value.
@@ -156,8 +165,8 @@ the future.
Fields built from `ebdb-field-user' will have their own identifier.
EBDB comes with classes including "anniversary", "url", "id",
"relation", "role" and more. Many of these fields have their own list
-of labels (for instance, "anniversary" fields may be labeled
-"birthday", "wedding", etc).
+of labels (for instance, anniversary fields may be labeled "birthday",
+"wedding", etc).
Loading secondary libraries may make more field types available.
* MUA Interaction
- [elpa] externals/ebdb 55a8c97 085/350: Split ebdb-db-disable into interactive/non-interactive functions, (continued)
- [elpa] externals/ebdb 55a8c97 085/350: Split ebdb-db-disable into interactive/non-interactive functions, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb fb76dd3 032/350: Fix ebdb-search-duplicates, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb a43e883 026/350: Move record initialization out of load process, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 77eb15b 037/350: Add keybinding for ebdb-search-database, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 8eb2262 036/350: Add object-print method for records, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 20785a1 029/350: Additions to README and manual, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 8537076 052/350: Improvements to the gnorb-ebdb-org-tags field, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 6568bbf 053/350: Straighten out ebdb-separator-alist, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 9791ed5 030/350: Merge branch 'buff', Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 49b422e 035/350: Remove mentions and bindings for ebdb-do-all-records, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 11fe701 047/350: Name classes now inherit from ebdb-field-user,
Eric Abrahamsen <=
- [elpa] externals/ebdb 784f45c 060/350: New function ebdb-prompt-for-mail, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb a712f52 050/350: Update ebdb-pgp, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 118f567 062/350: Add a "defunct" arg to ebdb-record-mail, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 90cb02a 068/350: Remove ebdb-mail-address, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb decfc94 073/350: Update company-ebdb to work, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 47ac653 066/350: Fix autoload for ebdb-org-field-tags definition, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb b2fdb42 064/350: Include record name when prompting for mail, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb 41bc859 084/350: Still need to hash newly-added records, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb dc517a1 067/350: More fixes to merging logic in ebdb-db-load, Eric Abrahamsen, 2017/08/14
- [elpa] externals/ebdb b9d7727 087/350: Fill out the ebdb-parse process, Eric Abrahamsen, 2017/08/14