]> git.eshelyaron.com Git - emacs.git/commitdiff
Add `predicate' arg to `read-buffer' and use it for erc-iswitchb
authorStefan Monnier <monnier@iro.umontreal.ca>
Mon, 16 Mar 2015 18:49:01 +0000 (14:49 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Mon, 16 Mar 2015 18:49:01 +0000 (14:49 -0400)
Fixes: debbugs:20116
* src/minibuf.c (Fread_buffer): Add `predicate' argument.
* src/callint.c (Fcall_interactively): Adjust calls accordingly.

* lisp/erc/erc.el (erc-switch-to-buffer): Rename from erc-iswitchb and rewrite
using read-buffer.
(erc--buffer-p): New function, extracted from erc-buffer-filter.
(erc-buffer-filter): Use it.
(erc-with-all-buffers-of-server): Silence compile warning if the return
value is unused.
(erc-is-valid-nick-p, erc-common-server-suffixes, erc-get-arglist)
(erc-command-name, erc-popup-input-buffer): Use \` and \' to match
beg/end of string.

* lisp/obsolete/iswitchb.el (iswitchb-read-buffer): Add `predicate' arg.
* lisp/isearchb.el (isearchb-iswitchb): Adjust accordingly.
* lisp/ido.el (ido-read-buffer): Add `predicate' argument.
* lisp/misearch.el (unload-function-defs-list): Declare before use.

13 files changed:
etc/NEWS
lisp/ChangeLog
lisp/emulation/viper-init.el
lisp/erc/ChangeLog
lisp/erc/erc.el
lisp/ido.el
lisp/isearchb.el
lisp/misearch.el
lisp/obsolete/iswitchb.el
lisp/replace.el
src/ChangeLog
src/callint.c
src/minibuf.c

index 24ed0799b2c28bc7853cf7c98c45bc730c7e3119..cabd0087d92c11c65152a336ab07ee1e316f46a4 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -594,6 +594,8 @@ a typographically-correct documents.
 \f
 * Incompatible Lisp Changes in Emacs 25.1
 
+** read-buffer-function can now be called with a 4th argument (`predicate').
+
 ** completion-table-dynamic stays in the minibuffer.
 If you want the old behavior of calling the function in the buffer
 from which the minibuffer was entered, call it with the new argument
@@ -631,6 +633,8 @@ word syntax, use `\sw' instead.
 \f
 * Lisp Changes in Emacs 25.1
 
+** `read-buffer' takes a new `predicate' argument.
+
 ** Emacs Lisp now supports generators.
 
 ** New finalizer facility for running code when objects
index 1383fdb2ecf5d6cef51a856ba8a34b15a29cd4c9..e9e910a88570ebb3d803c867f72d4db3c97636c3 100644 (file)
@@ -1,3 +1,10 @@
+2015-03-16  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * obsolete/iswitchb.el (iswitchb-read-buffer): Add `predicate' arg.
+       * isearchb.el (isearchb-iswitchb): Adjust accordingly.
+       * ido.el (ido-read-buffer): Add `predicate' argument.
+       * misearch.el (unload-function-defs-list): Declare before use.
+
 2015-03-16  Vibhav Pant  <vibhavp@gmail.com>
 
        * net/browse-url.el (browse-url-browser-function): Add "Conkeror".
index 75932a80d44d609fc8efb294cb32dfdb1ab56ef2..e575eee6c93a0edfce6155979190d24eb8581a08 100644 (file)
@@ -463,7 +463,7 @@ color displays.  By default, the delimiters are used only on TTYs."
   :type 'boolean
   :group 'viper)
 
-(defcustom viper-read-buffer-function 'read-buffer
+(defcustom viper-read-buffer-function #'read-buffer
   "Function to use for prompting the user for a buffer name."
   :type 'symbol
   :group 'viper)
index 4f5fced1bd5be66d007fd95f314f17abd332494d..e75b8cc00787c5a432969f40b9622c8ec65321f8 100644 (file)
@@ -1,3 +1,15 @@
+2015-03-16  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * erc.el (erc-switch-to-buffer): Rename from erc-iswitchb and rewrite
+       using read-buffer (bug#20116).
+       (erc--buffer-p): New function, extracted from erc-buffer-filter.
+       (erc-buffer-filter): Use it.
+       (erc-with-all-buffers-of-server): Silence compile warning if the return
+       value is unused.
+       (erc-is-valid-nick-p, erc-common-server-suffixes, erc-get-arglist)
+       (erc-command-name, erc-popup-input-buffer): Use \` and \' to match
+       beg/end of string.
+
 2015-03-03  Kelvin White  <kwhite@gnu.org>
 
        * erc.el: Add old version string back to file header for
index a84f9f07523e0dd01344f0ff0ed8eaa989d754e1..7e76a6def4230aaf86d34b308d255ccce6867364 100644 (file)
@@ -1110,7 +1110,7 @@ which the local user typed."
     (define-key map "\C-a" 'erc-bol)
     (define-key map [home] 'erc-bol)
     (define-key map "\C-c\C-a" 'erc-bol)
-    (define-key map "\C-c\C-b" 'erc-iswitchb)
+    (define-key map "\C-c\C-b" 'erc-switch-to-buffer)
     (define-key map "\C-c\C-c" 'erc-toggle-interpret-controls)
     (define-key map "\C-c\C-d" 'erc-input-action)
     (define-key map "\C-c\C-e" 'erc-toggle-ctcp-autoresponse)
@@ -1647,6 +1647,14 @@ If PROC is not supplied, all processes are searched."
                 (throw 'buffer (current-buffer)))))
        proc))))
 
+(defun erc--buffer-p (buf predicate proc)
+  (with-current-buffer buf
+    (and (derived-mode-p 'erc-mode)
+        (or (not proc)
+            (eq proc erc-server-process))
+        (funcall predicate)
+        buf)))
+
 (defun erc-buffer-filter (predicate &optional proc)
   "Return a list of `erc-mode' buffers matching certain criteria.
 PREDICATE is a function executed with each buffer, if it returns t, that buffer
@@ -1659,12 +1667,7 @@ server connection, or nil which means all open connections."
      nil
      (mapcar (lambda (buf)
                (when (buffer-live-p buf)
-                 (with-current-buffer buf
-                   (and (eq major-mode 'erc-mode)
-                        (or (not proc)
-                            (eq proc erc-server-process))
-                        (funcall predicate)
-                        buf))))
+                (erc--buffer-p buf predicate proc)))
              (buffer-list)))))
 
 (defun erc-buffer-list (&optional predicate proc)
@@ -1695,42 +1698,32 @@ nil."
                                           ,pro))))
        ;; Silence the byte-compiler by binding the result of mapcar to
        ;; a variable.
+       (ignore res)
        res)))
 
-;; (iswitchb-mode) will autoload iswitchb.el
-(defvar iswitchb-temp-buflist)
-(declare-function iswitchb-read-buffer "iswitchb"
-                  (prompt &optional default require-match start matches-set))
-(defvar iswitchb-make-buflist-hook)
-
-(defun erc-iswitchb (&optional arg)
-  "Use `iswitchb-read-buffer' to prompt for a ERC buffer to switch to.
+(define-obsolete-function-alias 'erc-iswitchb 'erc-switch-to-buffer "25.1")
+(defun erc-switch-to-buffer (&optional arg)
+  "Prompt for a ERC buffer to switch to.
 When invoked with prefix argument, use all erc buffers.  Without prefix
 ARG, allow only buffers related to same session server.
 If `erc-track-mode' is in enabled, put the last element of
-`erc-modified-channels-alist' in front of the buffer list.
-
-Due to some yet unresolved reason, global function `iswitchb-mode'
-needs to be active for this function to work."
+`erc-modified-channels-alist' in front of the buffer list."
   (interactive "P")
-  (let ((enabled (bound-and-true-p iswitchb-mode)))
-    (or enabled (iswitchb-mode 1))
-    (unwind-protect
-        (let ((iswitchb-make-buflist-hook
-               (lambda ()
-                 (setq iswitchb-temp-buflist
-                       (mapcar 'buffer-name
-                               (erc-buffer-list
-                                nil
-                                (when arg erc-server-process)))))))
-          (switch-to-buffer
-           (iswitchb-read-buffer
-            "Switch-to: "
-            (if (boundp 'erc-modified-channels-alist)
-                (buffer-name (caar (last erc-modified-channels-alist)))
-              nil)
-            t)))
-      (or enabled (iswitchb-mode -1)))))
+  (switch-to-buffer
+   (read-buffer "Switch to ERC buffer: "
+               (when (boundp 'erc-modified-channels-alist)
+                 (buffer-name (caar (last erc-modified-channels-alist))))
+               t
+               ;; Only allow ERC buffers in the same session.
+               (let ((proc (unless arg erc-server-process)))
+                 (lambda (bufname)
+                   (let ((buf (get-buffer bufname)))
+                     (when buf
+                       (erc--buffer-p buf (lambda () t) proc)
+                       (with-current-buffer buf
+                         (and (derived-mode-p 'erc-mode)
+                              (or (null proc)
+                                  (eq proc erc-server-process)))))))))))
 
 (defun erc-channel-list (proc)
   "Return a list of channel buffers.
@@ -2189,7 +2182,7 @@ be invoked for the values of the other parameters."
 Arguments are the same as for `erc'."
   (interactive (erc-select-read-args))
   (let ((erc-server-connect-function 'erc-open-tls-stream))
-    (apply 'erc r)))
+    (apply #'erc r)))
 
 (defun erc-open-tls-stream (name buffer host port)
   "Open an TLS stream to an IRC server.
@@ -2403,7 +2396,7 @@ If STRING is nil, the function does nothing."
 
 (defun erc-is-valid-nick-p (nick)
   "Check if NICK is a valid IRC nickname."
-  (string-match (concat "^" erc-valid-nick-regexp "$") nick))
+  (string-match (concat "\\`" erc-valid-nick-regexp "\\'") nick))
 
 (defun erc-display-line (string &optional buffer)
   "Display STRING in the ERC BUFFER.
@@ -2602,9 +2595,9 @@ server within `erc-lurker-threshold-time'.  See also
            erc-lurker-threshold-time))))
 
 (defcustom erc-common-server-suffixes
-  '(("openprojects.net$" . "OPN")
-    ("freenode.net$" . "freenode")
-    ("oftc.net$" . "OFTC"))
+  '(("openprojects.net\\'" . "OPN")
+    ("freenode.net\\'" . "freenode")
+    ("oftc.net\\'" . "OFTC"))
   "Alist of common server name suffixes.
 This variable is used in mode-line display to save screen
 real estate.  Set it to nil if you want to avoid changing
@@ -2640,7 +2633,7 @@ ARGS, PARSED, and TYPE are used to format MSG sensibly.
 
 See also `erc-format-message' and `erc-display-line'."
   (let ((string (if (symbolp msg)
-                    (apply 'erc-format-message msg args)
+                    (apply #'erc-format-message msg args)
                   msg)))
     (setq string
           (cond
@@ -2689,7 +2682,7 @@ See also `erc-server-send'."
 (defun erc-get-arglist (fun)
   "Return the argument list of a function without the parens."
   (let ((arglist (format "%S" (erc-function-arglist fun))))
-    (if (string-match "^(\\(.*\\))$" arglist)
+    (if (string-match "\\`(\\(.*\\))\\'" arglist)
         (match-string 1 arglist)
       arglist)))
 
@@ -2705,7 +2698,7 @@ is not alive, nil otherwise."
   "For CMD being the function name of a ERC command, something like
 erc-cmd-FOO, this returns a string /FOO."
   (let ((command-name (symbol-name cmd)))
-    (if (string-match "^erc-cmd-\\(.*\\)$" command-name)
+    (if (string-match "\\`erc-cmd-\\(.*\\)\\'" command-name)
         (concat "/" (match-string 1 command-name))
       command-name)))
 
@@ -2796,7 +2789,7 @@ VALUE is computed by evaluating the rest of LINE in Lisp."
     (erc-display-line
      (concat "Available user variables:\n"
              (apply
-              'concat
+              #'concat
               (mapcar
                (lambda (var)
                  (let ((val (symbol-value var)))
@@ -3775,7 +3768,7 @@ Unban all currently banned users in the current channel."
                t)))
           (erc-server-send (format "MODE %s b" chnl)))))
 
-     (t (let ((bans (mapcar 'cdr erc-channel-banlist)))
+     (t (let ((bans (mapcar #'cdr erc-channel-banlist)))
           (when bans
             ;; Glob the bans into groups of three, and carry out the unban.
             ;; eg. /mode #foo -bbb a*!*@* b*!*@* c*!*@*
@@ -3930,7 +3923,7 @@ If `point' is at the beginning of a channel name, use that as default."
      (concat "Set topic of " (erc-default-target) ": ")
      (when erc-channel-topic
        (let ((ss (split-string erc-channel-topic "\C-o")))
-         (cons (apply 'concat (if (cdr ss) (butlast ss) ss))
+         (cons (apply #'concat (if (cdr ss) (butlast ss) ss))
                0))))))
   (let ((topic-list (split-string topic "\C-o"))) ; strip off the topic setter
     (erc-cmd-TOPIC (concat (erc-default-target) " " (car topic-list)))))
@@ -5052,7 +5045,7 @@ arg-modes is a list of triples of the form:
 
   (MODE-CHAR ON/OFF ARGUMENT)."
   (if (string-match "^\\s-*\\(\\S-+\\)\\(\\s-.*$\\|$\\)" mode-string)
-      (let ((chars (mapcar 'char-to-string (match-string 1 mode-string)))
+      (let ((chars (mapcar #'char-to-string (match-string 1 mode-string)))
             ;; arguments in channel modes
             (args-str (match-string 2 mode-string))
             (args nil)
@@ -5998,7 +5991,7 @@ Returns a list of the form (HIGH LOW), compatible with Emacs time format."
                             (if (> minutes 0)
                                 `("%d minutes, %d seconds" ,minutes ,seconds)
                               `("%d seconds" ,seconds))))
-          output        (apply 'format format-args))
+          output        (apply #'format format-args))
     ;; Change all "1 units" to "1 unit".
     (while (string-match "\\([^0-9]\\|^\\)1 \\S-+\\(s\\)" output)
       (setq output (erc-replace-match-subexpression-in-string
@@ -6246,7 +6239,7 @@ if `erc-away' is non-nil."
 
 (defun erc-format-channel-modes ()
   "Return the current channel's modes."
-  (concat (apply 'concat
+  (concat (apply #'concat
                  "+" erc-channel-modes)
           (cond ((and erc-channel-user-limit erc-channel-key)
                  (if erc-show-channel-key-p
@@ -6438,7 +6431,7 @@ All windows are opened in the current frame."
                 "Mode: "
                 (mapcar (lambda (e)
                           (list (symbol-name e)))
-                        (apropos-internal "-mode$" 'commandp))
+                        (apropos-internal "-mode\\'" 'commandp))
                 nil t))))
     (pop-to-buffer (make-indirect-buffer (current-buffer) buffer-name))
     (funcall mode)
@@ -6634,7 +6627,7 @@ See also `format-spec'."
       (error "No format spec for message %s" msg))
     (when (functionp entry)
       (setq entry (apply entry args)))
-    (format-spec entry (apply 'format-spec-make args))))
+    (format-spec entry (apply #'format-spec-make args))))
 
 ;;; Various hook functions
 
index 563f406aeb6ef13b4896018e0231b2db7a8d0911..60a59d6e99d3fbbd2fe799c7e82f46955243f84d 100644 (file)
@@ -1590,10 +1590,10 @@ enable the mode if ARG is omitted or nil."
   (when ido-everywhere
     (when (memq ido-mode '(both file))
       (put 'ido-everywhere 'file (cons read-file-name-function nil))
-      (setq read-file-name-function 'ido-read-file-name))
+      (setq read-file-name-function #'ido-read-file-name))
     (when (memq ido-mode '(both buffer))
       (put 'ido-everywhere 'buffer (cons read-buffer-function nil))
-      (setq read-buffer-function 'ido-read-buffer))))
+      (setq read-buffer-function #'ido-read-buffer))))
 
 (defvar ido-minor-mode-map-entry nil)
 
@@ -4782,7 +4782,7 @@ Modified from `icomplete-completions'."
 (put 'dired-do-rename 'ido 'ignore)
 
 ;;;###autoload
-(defun ido-read-buffer (prompt &optional default require-match)
+(defun ido-read-buffer (prompt &optional default require-match predicate)
   "Ido replacement for the built-in `read-buffer'.
 Return the name of a buffer selected.
 PROMPT is the prompt to give to the user.  DEFAULT if given is the default
@@ -4796,7 +4796,7 @@ If REQUIRE-MATCH is non-nil, an existing buffer must be selected."
     (if (eq ido-exit 'fallback)
        (let ((read-buffer-function nil))
          (run-hook-with-args 'ido-before-fallback-functions 'read-buffer)
-         (read-buffer prompt default require-match))
+         (read-buffer prompt default require-match predicate))
       buf)))
 
 ;;;###autoload
index ffd4d62be38cd223907cf562b0daba02a3d64edb..5e7771cea524ad7eb1684c5a054fd4330b6972f5 100644 (file)
@@ -75,7 +75,9 @@
 ;;   killing iswitchb.el and then trying to switch back is broken
 ;;   make sure TAB isn't broken
 
-(require 'iswitchb)
+;;; Code:
+
+(require 'iswitchb)                     ;FIXME: Don't rely on iswitchb!
 
 (defgroup isearchb nil
   "Switch between buffers using a mechanism like isearch."
@@ -118,7 +120,7 @@ Its purpose is to pass different call arguments to
   (interactive)
   (let* ((prompt "iswitch ")
         (iswitchb-method 'samewindow)
-        (buf (iswitchb-read-buffer prompt nil nil iswitchb-text t)))
+        (buf (iswitchb-read-buffer prompt nil nil nil iswitchb-text t)))
     (if (eq iswitchb-exit 'findfile)
        (call-interactively 'find-file)
       (when buf
index dcc819564fb62bbdcd057d410ad2d4637f4eed04..65969113d93754b5da1ed7ca361de94a8d0bc6e3 100644 (file)
@@ -234,7 +234,7 @@ set in `multi-isearch-buffers' or `multi-isearch-buffers-regexp'."
         (ido-ignore-item-temp-list bufs))
     (while (not (string-equal
                 (setq buf (read-buffer
-                           (if (eq read-buffer-function 'ido-read-buffer)
+                           (if (eq read-buffer-function #'ido-read-buffer)
                                "Next buffer to search (C-j to end): "
                              "Next buffer to search (RET to end): ")
                            nil t))
@@ -377,6 +377,8 @@ whose file names match the specified wildcard."
     (goto-char (if isearch-forward (point-min) (point-max)))
     (isearch-forward-regexp nil t)))
 
+(defvar unload-function-defs-list)
+
 (defun multi-isearch-unload-function ()
   "Remove autoloaded variables from `unload-function-defs-list'.
 Also prevent the feature from being reloaded via `isearch-mode-hook'."
index 6b1e5347e2196a242161bcccea5012f3e67ea26c..111de8537d30f0c02d1eee4e164424eac671302c 100644 (file)
 ;; iswitchb-read-buffer has been written to be a drop in replacement
 ;; for the normal buffer selection routine `read-buffer'.  To use
 ;; iswitch for all buffer selections in Emacs, add:
-;; (setq read-buffer-function 'iswitchb-read-buffer)
+;; (setq read-buffer-function #'iswitchb-read-buffer)
 ;; (This variable was introduced in Emacs 20.3.)
 ;; XEmacs users can get the same behavior by doing:
-;; (defalias 'read-buffer 'iswitchb-read-buffer)
+;; (defalias 'read-buffer #'iswitchb-read-buffer)
 ;; since `read-buffer' is defined in lisp.
 
 ;; Using iswitchb for other completion tasks.
@@ -586,7 +586,7 @@ in a separate window.
           ))))
 
 (defun iswitchb-read-buffer (prompt &optional default require-match
-                                   start matches-set)
+                                   _predicate start matches-set)
   "Replacement for the built-in `read-buffer'.
 Return the name of a buffer selected.
 PROMPT is the prompt to give to the user.
index e0636e0728c286f6ea30521e197c25d729175bf4..70b86dd2016c23c904ef683209090412a2be793c 100644 (file)
@@ -1369,7 +1369,7 @@ See also `multi-occur-in-matching-buffers'."
           (ido-ignore-item-temp-list bufs))
       (while (not (string-equal
                   (setq buf (read-buffer
-                             (if (eq read-buffer-function 'ido-read-buffer)
+                             (if (eq read-buffer-function #'ido-read-buffer)
                                  "Next buffer to search (C-j to end): "
                                "Next buffer to search (RET to end): ")
                              nil t))
index e328afcde8f19bb38453e72e4030e5455119716a..fbf8fb452fc3f792c725843f941abfc266178fd8 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-16  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * minibuf.c (Fread_buffer): Add `predicate' argument.
+       * callint.c (Fcall_interactively): Adjust calls accordingly.
+
 2015-03-15  Eli Zaretskii  <eliz@gnu.org>
 
        * xdisp.c (handle_invisible_prop): Fix up it->position even when
index 0c6c03036c8167306b47a8e4ac24276e717a61af..cf50e0c3788d49b8ff79f57951b1954cbff74dcf 100644 (file)
@@ -531,13 +531,13 @@ invoke it.  If KEYS is omitted or nil, the return value of
          args[i] = Fcurrent_buffer ();
          if (EQ (selected_window, minibuf_window))
            args[i] = Fother_buffer (args[i], Qnil, Qnil);
-         args[i] = Fread_buffer (callint_message, args[i], Qt);
+         args[i] = Fread_buffer (callint_message, args[i], Qt, Qnil);
          break;
 
        case 'B':               /* Name of buffer, possibly nonexistent.  */
          args[i] = Fread_buffer (callint_message,
                                  Fother_buffer (Fcurrent_buffer (), Qnil, Qnil),
-                                 Qnil);
+                                 Qnil, Qnil);
          break;
 
         case 'c':              /* Character.  */
index e7c288b251be965295128ce793ecb1748c77f9a8..c03316965d376612e2aa814a464dfbdead701580 100644 (file)
@@ -1081,7 +1081,7 @@ A user option, or customizable variable, is one for which
   return Fintern (name, Qnil);
 }
 
-DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 3, 0,
+DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 4, 0,
        doc: /* Read the name of a buffer and return as a string.
 Prompt with PROMPT.
 Optional second arg DEF is value to return if user enters an empty line.
@@ -1093,8 +1093,11 @@ The argument PROMPT should be a string ending with a colon and a space.
 If `read-buffer-completion-ignore-case' is non-nil, completion ignores
 case while reading the buffer name.
 If `read-buffer-function' is non-nil, this works by calling it as a
-function, instead of the usual behavior.  */)
-  (Lisp_Object prompt, Lisp_Object def, Lisp_Object require_match)
+function, instead of the usual behavior.
+Optional arg PREDICATE if non-nil is a function limiting the buffers that can
+be considered.  */)
+  (Lisp_Object prompt, Lisp_Object def, Lisp_Object require_match,
+   Lisp_Object predicate)
 {
   Lisp_Object result;
   char *s;
@@ -1136,11 +1139,16 @@ function, instead of the usual behavior.  */)
        }
 
       result = Fcompleting_read (prompt, intern ("internal-complete-buffer"),
-                                Qnil, require_match, Qnil,
+                                predicate, require_match, Qnil,
                                 Qbuffer_name_history, def, Qnil);
     }
   else
-    result = call3 (Vread_buffer_function, prompt, def, require_match);
+    result = (NILP (predicate)
+             /* Partial backward compatibility for older read_buffer_functions
+                which don't expect a `predicate' argument.  */
+             ? call3 (Vread_buffer_function, prompt, def, require_match)
+             : call4 (Vread_buffer_function, prompt, def, require_match,
+                      predicate));
   return unbind_to (count, result);
 }
 \f