Eric Abrahamsen <> writes:

> "Roland Winkler" <> writes:
>> On Sat Sep 5 2015 Roland Winkler wrote:
>>> On Thu Sep 3 2015 Eric Abrahamsen wrote:
>>> > Basically it does what it says: if point is on a record name, the
>>> > whole record is copied, like before. If point is on a particular
>>> > field, the value (but not label) of that field is copied.
>>> I am just trying to understand a typical usage pattern for the
>>> extended code.  I understand that it can make sense for a single
>>> record to grab the value of only one field.  Yet what would this be
>>> good for with multiple records?  It seems to me that with multiple
>>> records, this would make sense only if it included also the name of
>>> the record.
>> One more thought: Why treat names special?  The only field, where it
>> appears to make sense to grab its value from multiple records
>> without including some "identifier", would be the name field.
>> Then, treating all fields the same way might work best with a
>> separate command bbdb-copy-field-as-kill instead of extending the
>> functionality of bbdb-copy-records-as-kill.  The prefix arg could
>> then possibly be used in a different way: with prefix arg the
>> command could also grab the name field.  (Or: include the name field
>> whenever this command operates on more than one record?)
> Yup, I asked myself many of these same questions, and I'm not really
> sure why I settled on the current behavior. All I really need is a quick
> way to copy and share addresses, phone numbers, and mails from my
> contacts -- usually just one, and I don't need the name attached. Beyond
> that, I'm happy to work this however seems most useful.
> Your last suggestion seems as good as anything I could come up with: why
> don't we do a separate function that only copies fields. If the name was
> included automatically when copying multiple records, then the prefix
> arg could be saved for selecting members from a list value, like it does
> now. Mostly that's useful when people have a million different email
> addresses.

Okay, here's a new version of the patch that does that.


>From c54d8b7c24a98d5fb914683715467db2c2407364 Mon Sep 17 00:00:00 2001
From: Eric Abrahamsen <>
Date: Sun, 6 Sep 2015 14:50:56 +0800
Subject: [PATCH] bbdb-com.el: New function for copying field values

* lisp/bbdb-com.el (bbdb-copy-fields-as-kill): New function copies value
   of field under point to the kill ring.
 lisp/bbdb-com.el | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/lisp/bbdb-com.el b/lisp/bbdb-com.el
index 6074bab..13dae6a 100644
--- a/lisp/bbdb-com.el
+++ b/lisp/bbdb-com.el
@@ -2563,6 +2563,78 @@ Interactively, use BBDB prefix \
                "[ \t\n]*\\'" "\n"
                (mapconcat 'identity (nreverse drec) "")))))
+(defun bbdb-copy-fields-as-kill (records &optional which)
+  "Copy field values from displayed RECORDS to kill ring.
+Interactively, use BBDB prefix \
+\\<bbdb-mode-map>\\[bbdb-do-all-records], see
+`bbdb-do-all-records'.  The value of the field under point will
+be copied for all records, and prefixed with the name of the
+contact.  If point is on a field with a label, only field values
+with the same label will be copied.
+If a numeric prefix is given, and the field being copied has a
+list value, copy the list item at the index of the prefix
+  (interactive (list (bbdb-do-records t)
+		     (and current-prefix-arg
+                          (prefix-numeric-value current-prefix-arg))))
+  (let* ((field (bbdb-current-field))
+	 (field-name (car-safe field))
+	 (field-type (when field-name
+		       (cond
+			((eq 'xfields field-name)
+			 (caadr field))
+			((memq field-name '(phone address))
+			 (cons field-name (aref (cadr field) 0)))
+			(t field-name))))
+	 (single (= 1 (length records)))
+	 drec)
+    (dolist (record (bbdb-record-list records t))
+      (let ((val (bbdb-record-field
+		  (car record)
+		  (cond ((symbolp field-type)
+			 field-type)
+			((consp field-type)
+			 (car field-type))))))
+	(when (memq field-name '(phone address))
+	  (dolist (v val)
+	    ;; Only take phones and addresses with the proper label.
+	    (when (equal (aref v 0) (cdr field-type))
+	      (setq val v)))
+	  ;; Format phones and addresses properly.
+	  (when val
+	    (setq val
+		  (if (eq field-name 'phone)
+		      (bbdb-phone-string val)
+		    (bbdb-format-address-default val)))))
+	;; Prefix arg `which' asks for a specific element from a
+	;; list value
+	(when (and val
+		   (listp val))
+	  (setq val
+		(if which
+		    (nth which val)
+		  (mapconcat
+		   (lambda (v)
+		     (concat
+		      v (nth 1 (or (cdr (assq field bbdb-separator-alist))
+					bbdb-default-separator))))
+		   val "\n"))))
+	(unless single
+	  (setq val (cons (bbdb-record-name (car record)) val)))
+	(when val
+	  (push val drec))))
+    (kill-new (replace-regexp-in-string
+               "[ \t\n]*\\'" "\n"
+               (mapconcat (lambda (v)
+			    (if (consp v)
+				(concat (car v) "\n" (cdr v))
+			      v))
+			  (nreverse drec) "\n\n")))
+    (message "Copied to kill ring")))
 ;;; Help and documentation

BBDB Home Page:

Reply via email to