diff options
Diffstat (limited to 'lisp/erc/erc-bbdb.el')
-rw-r--r-- | lisp/erc/erc-bbdb.el | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/lisp/erc/erc-bbdb.el b/lisp/erc/erc-bbdb.el new file mode 100644 index 00000000000..7d27f7f4868 --- /dev/null +++ b/lisp/erc/erc-bbdb.el @@ -0,0 +1,269 @@ +;;; erc-bbdb.el --- Integrating the BBDB into ERC + +;; Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007 +;; 2008, 2009 Free Software Foundation, Inc. + +;; Author: Andreas Fuchs <asf@void.at> +;; Maintainer: Mario Lang <mlang@delysid.org> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This mode connects the BBDB to ERC. Whenever a known nick +;; connects, the corresponding BBDB record pops up. To identify +;; users, use the irc-nick field. Define it, if BBDB asks you about +;; that. When you use /WHOIS on a known nick, the corresponding +;; record will be updated. + +;;; History + +;; Andreas Fuchs <asf@void.at> wrote zenirc-bbdb-whois.el, which was +;; adapted for ERC by Mario Lang <mlang@delysid.org>. + +;; Changes by Edgar Gonçalves <edgar.goncalves@inesc-id.pt> +;; May 31 2005: +;; - new variable: erc-bbdb-bitlbee-name-field - the field name for the +;; msn/icq/etc nick +;; - nick doesn't go the the name. now it asks for an existing record to +;; merge with. If none, then create a new one with the nick as name. + +;;; Code: + +(require 'erc) +(require 'bbdb) +(require 'bbdb-com) +(require 'bbdb-gui) +(require 'bbdb-hooks) + +(defgroup erc-bbdb nil + "Variables related to BBDB usage." + :group 'erc) + +(defcustom erc-bbdb-auto-create-on-whois-p nil + "*If nil, don't create bbdb records automatically when a WHOIS is done. +Leaving this at nil is a good idea, but you can turn it +on if you want to have lots of People named \"John Doe\" in your BBDB." + :group 'erc-bbdb + :type 'boolean) + +(defcustom erc-bbdb-auto-create-on-join-p nil + "*If nil, don't create bbdb records automatically when a person joins a channel. +Leaving this at nil is a good idea, but you can turn it +on if you want to have lots of People named \"John Doe\" in your BBDB." + :group 'erc-bbdb + :type 'boolean) + +(defcustom erc-bbdb-auto-create-on-nick-p nil + "*If nil, don't create bbdb records automatically when a person changes her nick. +Leaving this at nil is a good idea, but you can turn it +on if you want to have lots of People named \"John Doe\" in your BBDB." + :group 'erc-bbdb + :type 'boolean) + +(defcustom erc-bbdb-popup-type 'visible + "*If t, pop up a BBDB buffer showing the record of a WHOISed person +or the person who has just joined a channel. + +If set to 'visible, the BBDB buffer only pops up when someone was WHOISed +or a person joined a channel visible on any frame. + +If set to nil, never pop up a BBDD buffer." + :group 'erc-bbdb + :type '(choice (const :tag "When visible" visible) + (const :tag "When joining" t) + (const :tag "Never" nil))) + +(defcustom erc-bbdb-irc-nick-field 'irc-nick + "The notes field name to use for annotating IRC nicknames." + :group 'erc-bbdb + :type 'symbol) + +(defcustom erc-bbdb-irc-channel-field 'irc-channel + "The notes field name to use for annotating IRC channels." + :group 'erc-bbdb + :type 'symbol) + +(defcustom erc-bbdb-irc-highlight-field 'irc-highlight + "The notes field name to use for highlighting a person's messages." + :group 'erc-bbdb + :type 'symbol) + +(defcustom erc-bbdb-bitlbee-name-field 'bitlbee-name + "The notes field name to use for annotating bitlbee displayed name. +This is the name that a bitlbee (AIM/MSN/ICQ) contact provides as +their \"displayed name\"." + :group 'erc-bbdb + :type 'symbol) + +(defcustom erc-bbdb-elide-display nil + "*If t, show BBDB popup buffer elided." + :group 'erc-bbdb + :type 'boolean) + +(defcustom erc-bbdb-electric-p nil + "*If t, BBDB popup buffer is electric." + :group 'erc-bbdb + :type 'boolean) + +(defun erc-bbdb-search-name-and-create (create-p name nick finger-host silent) + (let* ((ircnick (cons erc-bbdb-irc-nick-field (concat "^" + (regexp-quote nick)))) + (finger (cons bbdb-finger-host-field (regexp-quote finger-host))) + (record (or (bbdb-search (bbdb-records) nil nil nil ircnick) + (and name (bbdb-search-simple name nil)) + (bbdb-search (bbdb-records) nil nil nil finger) + (unless silent + (bbdb-completing-read-one-record + "Merge using record of (C-g to skip, RET for new): ")) + (when create-p + (bbdb-create-internal (or name + "John Doe") + nil nil nil nil nil))))) + ;; sometimes, the record will be a list. I don't know why. + (if (listp record) + (car record) + record))) + +(defun erc-bbdb-show-entry (record channel proc) + (let ((bbdb-display-layout (bbdb-grovel-elide-arg erc-bbdb-elide-display)) + (bbdb-electric-p erc-bbdb-electric-p)) + (when (and record (or (eq erc-bbdb-popup-type t) + (and (eq erc-bbdb-popup-type 'visible) + (and channel + (or (eq channel t) + (get-buffer-window (erc-get-buffer + channel proc) + 'visible)))))) + (bbdb-display-records (list record))))) + +(defun erc-bbdb-insinuate-and-show-entry-1 (create-p proc nick name finger-host silent &optional chan new-nick) + (let ((record (erc-bbdb-search-name-and-create + create-p nil nick finger-host silent))) ;; don't search for a name + (when record + (bbdb-annotate-notes record (or new-nick nick) erc-bbdb-irc-nick-field) + (bbdb-annotate-notes record finger-host bbdb-finger-host-field) + (and name + (bbdb-annotate-notes record name erc-bbdb-bitlbee-name-field t)) + (and chan + (not (eq chan t)) + (bbdb-annotate-notes record chan erc-bbdb-irc-channel-field)) + (erc-bbdb-highlight-record record) + (erc-bbdb-show-entry record chan proc)))) + +(defun erc-bbdb-insinuate-and-show-entry (create-p proc nick name finger-host silent &optional chan new-nick) + ;; run this outside of the IRC filter process, to avoid an annoying + ;; error when the user hits C-g + (run-at-time 0.1 nil + #'erc-bbdb-insinuate-and-show-entry-1 + create-p proc nick name finger-host silent chan new-nick)) + +(defun erc-bbdb-whois (proc parsed) + (let (; We could use server name too, probably + (nick (second (erc-response.command-args parsed))) + (name (erc-response.contents parsed)) + (finger-host (concat (third (erc-response.command-args parsed)) + "@" + (fourth (erc-response.command-args parsed))))) + (erc-bbdb-insinuate-and-show-entry erc-bbdb-auto-create-on-whois-p proc + nick name finger-host nil t))) + +(defun erc-bbdb-JOIN (proc parsed) + (let* ((sender (erc-parse-user (erc-response.sender parsed))) + (nick (nth 0 sender))) + (unless (string= nick (erc-current-nick)) + (let* ((channel (erc-response.contents parsed)) + (finger-host (concat (nth 1 sender) "@" (nth 2 sender)))) + (erc-bbdb-insinuate-and-show-entry + erc-bbdb-auto-create-on-join-p proc + nick nil finger-host t channel))))) + +(defun erc-bbdb-NICK (proc parsed) + "Annotate new nick name to a record in case it already exists." + (let* ((sender (erc-parse-user (erc-response.sender parsed))) + (nick (nth 0 sender))) + (unless (string= nick (erc-current-nick)) + (let* ((finger-host (concat (nth 1 sender) "@" (nth 2 sender)))) + (erc-bbdb-insinuate-and-show-entry + erc-bbdb-auto-create-on-nick-p proc + nick nil finger-host t nil (erc-response.contents parsed)))))) + +(defun erc-bbdb-init-highlighting-hook-fun (proc parsed) + (erc-bbdb-init-highlighting)) + +(defun erc-bbdb-init-highlighting () + "Initialize the highlighting based on BBDB fields. +This function typically gets called on a successful server connect. +The field name in the BBDB which controls highlighting is specified by +`erc-bbdb-irc-highlight-field'. Fill in either \"pal\" +\"dangerous-host\" or \"fool\". They work exactly like their +counterparts `erc-pals', `erc-dangerous-hosts' and `erc-fools'." + (let* ((irc-highlight (cons erc-bbdb-irc-highlight-field + ".+")) + (matching-records (bbdb-search (bbdb-records) + nil nil nil irc-highlight))) + (mapcar 'erc-bbdb-highlight-record matching-records))) + +(defun erc-bbdb-highlight-record (record) + (let* ((notes (bbdb-record-raw-notes record)) + (highlight-field (assoc erc-bbdb-irc-highlight-field notes)) + (nick-field (assoc erc-bbdb-irc-nick-field notes))) + (if (and highlight-field + nick-field) + (let ((highlight-types (split-string (cdr highlight-field) + bbdb-notes-default-separator)) + (nick-names (split-string (cdr nick-field) + (concat "\\(\n\\|" + bbdb-notes-default-separator + "\\)")))) + (mapcar + (lambda (highlight-type) + (mapcar + (lambda (nick-name) + (if (member highlight-type + '("pal" "dangerous-host" "fool")) + (add-to-list (intern (concat "erc-" highlight-type "s")) + (regexp-quote nick-name)) + (error (format "\"%s\" (in \"%s\") is not a valid highlight type!" + highlight-type nick-name)))) + nick-names)) + highlight-types))))) + +;;;###autoload (autoload 'erc-bbdb-mode "erc-bbdb") +(define-erc-module bbdb nil + "In ERC BBDB mode, you can directly interact with your BBDB." + ((add-hook 'erc-server-311-functions 'erc-bbdb-whois t) + (add-hook 'erc-server-JOIN-functions 'erc-bbdb-JOIN t) + (add-hook 'erc-server-NICK-functions 'erc-bbdb-NICK t) + (add-hook 'erc-server-376-functions 'erc-bbdb-init-highlighting-hook-fun t)) + ((remove-hook 'erc-server-311-functions 'erc-bbdb-whois) + (remove-hook 'erc-server-JOIN-functions 'erc-bbdb-JOIN) + (remove-hook 'erc-server-NICK-functions 'erc-bbdb-NICK) + (remove-hook 'erc-server-376-functions 'erc-bbdb-init-highlighting-hook-fun))) + +(provide 'erc-bbdb) + +;;; erc-bbdb.el ends here +;; +;; Local Variables: +;; indent-tabs-mode: t +;; tab-width: 8 +;; coding: utf-8 +;; End: + +;; arch-tag: 1edf3729-cd49-47dc-aced-70fcfc28c815 |