]> code.delx.au - gnu-emacs/blobdiff - lisp/erc/erc-button.el
; Merge from origin/emacs-25
[gnu-emacs] / lisp / erc / erc-button.el
index c8a7fec32bd1746ae12be63e064cfe73034ade35..f63ac17ab472d316ea56168865d4a3918ecdf5ed 100644 (file)
@@ -1,8 +1,9 @@
-;; erc-button.el --- A way of buttonizing certain things in ERC buffers
+;; erc-button.el --- A way of buttonizing certain things in ERC buffers  -*- lexical-binding:t -*-
 
-;; Copyright (C) 1996-2004, 2006-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1996-2004, 2006-2016 Free Software Foundation, Inc.
 
 ;; Author: Mario Lang <mlang@delysid.org>
+;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: irc, button, url, regexp
 ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcButton
 
@@ -25,7 +26,7 @@
 
 ;; Heavily borrowed from gnus-art.el. Thanks to the original authors.
 ;; This buttonizes nicks and other stuff to make it all clickable.
-;; To enable, add to your ~/.emacs:
+;; To enable, add to your init file:
 ;; (require 'erc-button)
 ;; (erc-button-mode 1)
 ;;
@@ -134,7 +135,7 @@ longer than `erc-fill-column'."
   '(('nicknames 0 erc-button-buttonize-nicks erc-nick-popup 0)
     (erc-button-url-regexp 0 t browse-url 0)
     ("<URL: *\\([^<> ]+\\) *>" 0 t browse-url 1)
-    ("(\\(\\([^~\n \t@][^\n \t@]*\\)@\\([a-zA-Z0-9.:-]+\\)\\)" 1 t finger 2 3)
+;;; ("(\\(\\([^~\n \t@][^\n \t@]*\\)@\\([a-zA-Z0-9.:-]+\\)\\)" 1 t finger 2 3)
     ;; emacs internal
     ("[`]\\([a-zA-Z][-a-zA-Z_0-9]+\\)[']" 1 t erc-button-describe-symbol 1)
     ;; pseudo links
@@ -164,11 +165,11 @@ REGEXP is the string matching text around the button or a symbol
   entries in lists or alists are considered to be nicks or other
   complete words.  Therefore they are enclosed in \\< and \\>
   while searching.  REGEXP can also be the quoted symbol
-  'nicknames, which matches the nickname of any user on the
+  \\='nicknames, which matches the nickname of any user on the
   current server.
 
 BUTTON is the number of the regexp grouping actually matching the
-  button,  This is ignored if REGEXP is 'nicknames.
+  button,  This is ignored if REGEXP is \\='nicknames.
 
 FORM is a lisp expression which must eval to true for the button to
   be added,
@@ -179,14 +180,17 @@ CALLBACK is the function to call when the user push this button.
 
 PAR is a number of a regexp grouping whose text will be passed to
   CALLBACK.  There can be several PAR arguments.  If REGEXP is
-  'nicknames, these are ignored, and CALLBACK will be called with
+  \\='nicknames, these are ignored, and CALLBACK will be called with
   the nickname matched as the argument."
   :group 'erc-button
+  :version "24.1"                       ; remove finger (bug#4443)
   :type '(repeat
           (list :tag "Button"
                 (choice :tag "Matches"
                         regexp
                         (variable :tag "Variable containing regexp")
+                        ;; FIXME It really does mean 'nicknames
+                        ;; rather than just nicknames.
                         (const :tag "Nicknames" 'nicknames))
                 (integer :tag "Number of the regexp section that matches")
                 (choice :tag "When to buttonize"
@@ -265,7 +269,7 @@ specified by `erc-button-alist'."
             (inhibit-point-motion-hooks t)
             (inhibit-field-text-motion t)
             (alist erc-button-alist)
-            entry regexp data)
+            regexp)
         (erc-button-remove-old-buttons)
         (dolist (entry alist)
           (if (equal (car entry) (quote (quote nicknames)))
@@ -296,14 +300,14 @@ specified by `erc-button-alist'."
     (when (or (eq t form)
               (eval form))
       (goto-char (point-min))
-      (while (forward-word 1)
-        (setq bounds (bounds-of-thing-at-point 'word))
-        (setq word (buffer-substring-no-properties
-                    (car bounds) (cdr bounds)))
-        (when (or (and (erc-server-buffer-p) (erc-get-server-user word))
-                  (and erc-channel-users (erc-get-channel-user word)))
-          (erc-button-add-button (car bounds) (cdr bounds)
-                                 fun t (list word)))))))
+      (while (erc-forward-word)
+        (when (setq bounds (erc-bounds-of-word-at-point))
+          (setq word (buffer-substring-no-properties
+                      (car bounds) (cdr bounds)))
+          (when (or (and (erc-server-buffer-p) (erc-get-server-user word))
+                    (and erc-channel-users (erc-get-channel-user word)))
+            (erc-button-add-button (car bounds) (cdr bounds)
+                                   fun t (list word))))))))
 
 (defun erc-button-add-buttons-1 (regexp entry)
   "Search through the buffer for matches to ENTRY and add buttons."
@@ -386,9 +390,9 @@ REGEXP is the regular expression which matched for this button."
   ;; merged correctly.  If we use overlays, then redisplay will be
   ;; very slow with lots of buttons.  This is why we manually merge
   ;; face text properties.
-  (let ((old (erc-list (get-text-property from 'face)))
+  (let ((old (erc-list (get-text-property from 'font-lock-face)))
         (pos from)
-        (end (next-single-property-change from 'face nil to))
+        (end (next-single-property-change from 'font-lock-face nil to))
         new)
     ;; old is the face at pos, in list form.  It is nil if there is no
     ;; face at pos.  If nil, the new face is FACE.  If not nil, the
@@ -396,16 +400,16 @@ REGEXP is the regular expression which matched for this button."
     ;; where this face changes.
     (while (< pos to)
       (setq new (if old (cons face old) face))
-      (put-text-property pos end 'face new)
+      (put-text-property pos end 'font-lock-face new)
       (setq pos end
-            old (erc-list (get-text-property pos 'face))
-            end (next-single-property-change pos 'face nil to)))))
+            old (erc-list (get-text-property pos 'font-lock-face))
+            end (next-single-property-change pos 'font-lock-face nil to)))))
 
 ;; widget-button-click calls with two args, we ignore the first.
 ;; Since Emacs runs this directly, rather than with
 ;; widget-button-click, we need to fake an extra arg in the
 ;; interactive spec.
-(defun erc-button-click-button (ignore event)
+(defun erc-button-click-button (_ignore event)
   "Call `erc-button-press-button'."
   (interactive "P\ne")
   (save-excursion
@@ -414,7 +418,7 @@ REGEXP is the regular expression which matched for this button."
 
 ;; XEmacs calls this via widget-button-press with a bunch of arguments
 ;; which we don't care about.
-(defun erc-button-press-button (&rest ignore)
+(defun erc-button-press-button (&rest _ignore)
   "Check text at point for a callback function.
 If the text at point has a `erc-callback' property,
 call it with the value of the `erc-data' text property."
@@ -430,19 +434,22 @@ call it with the value of the `erc-data' text property."
 (defun erc-button-next-function ()
   "Pseudo completion function that actually jumps to the next button.
 For use on `completion-at-point-functions'."
-    (when (< (point) (erc-beg-of-input-line))
-      `(lambda ()
-         (let ((here ,(point)))
-           (while (and (get-text-property here 'erc-callback)
-                       (not (= here (point-max))))
-             (setq here (1+ here)))
-           (while (and (not (get-text-property here 'erc-callback))
-                       (not (= here (point-max))))
-             (setq here (1+ here)))
-           (if (< here (point-max))
-               (goto-char here)
-             (error "No next button"))
-           t))))
+  ;; FIXME: This is an abuse of completion-at-point-functions.
+  (when (< (point) (erc-beg-of-input-line))
+    (let ((start (point)))
+      (lambda ()
+        (let ((here start))
+          ;; FIXME: Use next-single-property-change.
+          (while (and (get-text-property here 'erc-callback)
+                      (not (= here (point-max))))
+            (setq here (1+ here)))
+          (while (not (or (get-text-property here 'erc-callback)
+                          (= here (point-max))))
+            (setq here (1+ here)))
+          (if (< here (point-max))
+              (goto-char here)
+            (error "No next button"))
+          t)))))
 
 (defun erc-button-next ()
   "Go to the next button in this buffer."
@@ -504,12 +511,13 @@ Examples:
 
 (defun erc-nick-popup (nick)
   (let* ((completion-ignore-case t)
-         (action (completing-read (concat "What action to take on '" nick "'? ")
+         (action (completing-read (format-message
+                                   "What action to take on `%s'? " nick)
                                   erc-nick-popup-alist))
          (code (cdr (assoc action erc-nick-popup-alist))))
     (when code
       (erc-set-active-buffer (current-buffer))
-      (eval code))))
+      (eval code `((nick . ,nick))))))
 
 ;;; Callback functions
 (defun erc-button-describe-symbol (symbol-name)
@@ -530,8 +538,8 @@ and `apropos' for other symbols."
                      (- (car (current-time-zone)))))
          (hours (mod (floor seconds 3600) 24))
          (minutes (mod (round seconds 60) 60)))
-    (message (format "@%s is %d:%02d local time"
-                     beats hours minutes))))
+    (message "@%s is %d:%02d local time"
+             beats hours minutes)))
 
 (provide 'erc-button)
 
@@ -539,4 +547,3 @@ and `apropos' for other symbols."
 ;; Local Variables:
 ;; indent-tabs-mode: nil
 ;; End:
-