1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-25 19:11:56 +00:00

Add predicate' arg to read-buffer' and use it for erc-iswitchb

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.
This commit is contained in:
Stefan Monnier 2015-03-16 14:49:01 -04:00
parent 43a847c02c
commit f925fc93ba
13 changed files with 105 additions and 72 deletions

View File

@ -594,6 +594,8 @@ a typographically-correct documents.
* 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.
* 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

View 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".

View 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)

View 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

View 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

View 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

View 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

View 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'."

View File

@ -175,10 +175,10 @@
;; 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.

View 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))

View 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

View 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. */

View 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);
}