I've always wanted a function for easily copying the values of record
fields.
The attached patch replaces the `bbdb-copy-records-as-kill' function
with a new function, `bbdb-copy-records-or-fields-as-kill'.
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.
If the "*" prefix is given, the field value is copied from all records.
If point is on a field that has a label (ie phones or addresses), only
phones/addresses with the same label are copied from other records.
Lastly, a numeric prefix argument will select the corresponding item
from a field with a list value. If the field under point isn't a list,
the argument is ignored.
The implementation, while it seems to work just fine, is pretty ugly,
particularly working around the various types and labels. I would love
to know if this could be cleared up somehow.
Also I just realized I didn't make a ChangeLog note -- if this patch is
acceptable, I can send another version with the note included.
Thanks,
Eric
>From 195e25433ecc4c092f25b1f71c59d2749a954045 Mon Sep 17 00:00:00 2001
From: Eric Abrahamsen <e...@ericabrahamsen.net>
Date: Thu, 3 Sep 2015 14:25:30 +0800
Subject: [PATCH] New function for copying value of record fields
* lisp/bbdb-com.el (bbdb-copy-records-or-fields-as-kill): Replace old
function `bbdb-copy-records-as-kill' with new function
`bbdb-copy-records-or-fields-as-kill'.
* lisp/bbdb.el (bbdb-mode-map): Add new function to `bbdb-mode-map'.
---
lisp/bbdb-com.el | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-------
lisp/bbdb.el | 2 +-
2 files changed, 71 insertions(+), 10 deletions(-)
diff --git a/lisp/bbdb-com.el b/lisp/bbdb-com.el
index 6074bab..8137f22 100644
--- a/lisp/bbdb-com.el
+++ b/lisp/bbdb-com.el
@@ -2548,20 +2548,81 @@ Default is the first URL."
;;; Copy to kill ring
;;;###autoload
-(defun bbdb-copy-records-as-kill (records)
+(defun bbdb-copy-records-or-fields-as-kill (records &optional which)
"Copy displayed RECORDS to kill ring.
+
+If point is on the record name, copy the whole record. If point
+is on a particular field, copy only the value of that field.
+
Interactively, use BBDB prefix \
-\\<bbdb-mode-map>\\[bbdb-do-all-records], see `bbdb-do-all-records'."
- (interactive (list (bbdb-do-records t)))
- (let (drec marker)
+\\<bbdb-mode-map>\\[bbdb-do-all-records], see
+`bbdb-do-all-records'. If point is on a record name, all records
+will be copied. If point is on a record field, the value of this
+field for all records will be copied. 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
+argument."
+ (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))))
+ drec)
(dolist (record (bbdb-record-list records t))
- (push (buffer-substring (nth 2 record)
- (or (nth 2 (car (cdr (memq record bbdb-records))))
- (point-max)))
- drec))
+ (if (or (eq field-name 'name)
+ (not field-name))
+ ;; Copy the whole record.
+ (push (buffer-substring (nth 2 record)
+ (or (nth 2 (car (cdr (memq record bbdb-records))))
+ (point-max)))
+ drec)
+ ;; Or just the one field.
+ (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.
+ (setq val
+ (when (equal (aref v 0) (cdr field-type))
+ 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 which
+ (listp val))
+ (setq val (nth which val)))
+ (when val
+ (push val drec)))))
(kill-new (replace-regexp-in-string
"[ \t\n]*\\'" "\n"
- (mapconcat 'identity (nreverse drec) "")))))
+ (mapconcat (lambda (v)
+ (if (stringp v)
+ v
+ (mapconcat #'identity
+ v
+ (nth 1 (or (cdr (assq field bbdb-separator-alist))
+ bbdb-default-separator)))))
+ (nreverse drec) "\n")))
+ (message "Copied to kill ring")))
;;; Help and documentation
diff --git a/lisp/bbdb.el b/lisp/bbdb.el
index 514fb0d..f5976fc 100644
--- a/lisp/bbdb.el
+++ b/lisp/bbdb.el
@@ -1784,7 +1784,7 @@ if you want to call `bbdb-change-hook' and update the record unconditionally.")
(define-key km "?" 'bbdb-help)
;; (define-key km "q" 'quit-window) ; part of `special-mode' bindings
(define-key km "\C-x\C-t" 'bbdb-transpose-fields)
- (define-key km "C" 'bbdb-copy-records-as-kill)
+ (define-key km "C" 'bbdb-copy-records-or-fields-as-kill)
(define-key km "u" 'bbdb-browse-url)
;; (define-key km "P" 'bbdb-print)
(define-key km "=" 'delete-other-windows)
--
2.5.1
------------------------------------------------------------------------------
Monitor Your Dynamic Infrastructure at Any Scale With Datadog!
Get real-time metrics from all of your servers, apps and tools
in one place.
SourceForge users - Click here to start your Free Trial of Datadog now!
http://pubads.g.doubleclick.net/gampad/clk?id=241902991&iu=/4140
_______________________________________________
bbdb-info@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bbdb-info
BBDB Home Page: http://bbdb.sourceforge.net/