From 25c0d999666985929f375a75f4ed5018b7c5e9f3 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sat, 19 Apr 2008 03:23:15 +0000 Subject: [PATCH] * minibuffer.el (completion-table-with-context): Add support for `pred'. (completion-table-with-terminator): Don't use complete-with-action since we have to distinguish all three cases anyway. (completion-table-with-predicate): New function. (dynamic-completion-table): Add obsolete alias. * minibuf.texi (Programmed Completion): Replace dynamic-completion-table with the new completion-table-dynamic. --- doc/lispref/ChangeLog | 5 ++++ doc/lispref/minibuf.texi | 8 +++--- lisp/ChangeLog | 14 ++++++---- lisp/minibuffer.el | 59 ++++++++++++++++++++++++++++++---------- 4 files changed, 63 insertions(+), 23 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 416041014c..a2d510d6f7 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,8 @@ +2008-04-19 Stefan Monnier + + * minibuf.texi (Programmed Completion): + Replace dynamic-completion-table with the new completion-table-dynamic. + 2008-04-07 Chong Yidong * intro.texi (Some Terms): Change "fonts in this manual" index diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 2b435a2ca1..7353b57c65 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -1488,14 +1488,14 @@ completion to be encapsulated in a symbol. Emacs uses programmed completion when completing file names. @xref{File Name Completion}. -@defmac dynamic-completion-table function -This macro is a convenient way to write a function that can act as +@defun completion-table-dynamic function +This function is a convenient way to write a function that can act as programmed completion function. The argument @var{function} should be a function that takes one argument, a string, and returns an alist of possible completions of it. You can think of -@code{dynamic-completion-table} as a transducer between that interface +@code{completion-table-dynamic} as a transducer between that interface and the interface for programmed completion functions. -@end defmac +@end defun @node Yes-or-No Queries @section Yes-or-No Queries diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 133c02fac9..6c4b4a5db0 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,11 @@ 2008-04-19 Stefan Monnier + * minibuffer.el (completion-table-with-context): Add support for `pred'. + (completion-table-with-terminator): Don't use complete-with-action + since we have to distinguish all three cases anyway. + (completion-table-with-predicate): New function. + (dynamic-completion-table): Add obsolete alias. + * emacs-lisp/trace.el (trace-make-advice): Don't change selected-window. 2008-04-18 Sam Steingold @@ -13,11 +19,9 @@ 2008-04-18 Andreas Schwab - * Makefile.in ($(MH_E_DIR)/mh-loaddefs.el): Depend on - $(lisp)/subdirs.el. - ($(CAL_DIR)/cal-loaddefs.el): Likewise. - ($(CAL_DIR)/diary-loaddefs.el): Likewise. - ($(CAL_DIR)/hol-loaddefs.el): Likewise. + * Makefile.in ($(MH_E_DIR)/mh-loaddefs.el, $(CAL_DIR)/cal-loaddefs.el) + ($(CAL_DIR)/diary-loaddefs.el, $(CAL_DIR)/hol-loaddefs.el): + Depend on $(lisp)/subdirs.el. 2008-04-18 Juanma Barranquero diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 834aa589f2..76c365c5c3 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -108,12 +108,13 @@ You should give VAR a non-nil `risky-local-variable' property." ,var)))) (defun completion-table-with-context (prefix table string pred action) - ;; TODO: add `suffix', and think about how we should support `pred'. + ;; TODO: add `suffix' maybe? ;; Notice that `pred' is not a predicate when called from read-file-name ;; or Info-read-node-name-2. - ;; (if pred (setq pred (lexical-let ((pred pred)) - ;; ;; FIXME: this doesn't work if `table' is an obarray. - ;; (lambda (s) (funcall pred (concat prefix s)))))) + (if (functionp pred) + (setq pred (lexical-let ((pred pred)) + ;; FIXME: this doesn't work if `table' is an obarray. + (lambda (s) (funcall pred (concat prefix s)))))) (let ((comp (complete-with-action action table string pred))) (cond ;; In case of try-completion, add the prefix. @@ -128,19 +129,46 @@ You should give VAR a non-nil `risky-local-variable' property." (t comp)))) (defun completion-table-with-terminator (terminator table string pred action) - (let ((comp (complete-with-action action table string pred))) - (cond - ((eq action nil) + (cond + ((eq action nil) + (let ((comp (try-completion string table pred))) (if (eq comp t) (concat string terminator) (if (and (stringp comp) - (eq (complete-with-action action table comp pred) t)) + (eq (try-completion comp table pred) t)) (concat comp terminator) - comp))) - ;; completion-table-with-terminator is always used for - ;; "sub-completions" so it's only called if the terminator is missing, - ;; in which case `test-completion' should return nil. - ((eq action 'lambda) nil)))) + comp)))) + ((eq action t) (all-completions string table pred)) + ;; completion-table-with-terminator is always used for + ;; "sub-completions" so it's only called if the terminator is missing, + ;; in which case `test-completion' should return nil. + ((eq action 'lambda) nil))) + +(defun completion-table-with-predicate (table pred1 strict string pred2 action) + "Make a completion table equivalent to TABLE but filtered through PRED1. +PRED1 is a function of one argument which returns non-nil iff the +argument is an element of TABLE which should be considered for completion. +STRING, PRED2, and ACTION are the usual arguments to completion tables, +as described in `try-completion', `all-completions', and `test-completion'. +If STRICT is t, the predicate always applies, if nil it only applies if +it doesn't reduce the set of possible completions to nothing. +Note: TABLE needs to be a proper completion table which obeys predicates." + (cond + ((and (not strict) (eq action 'lambda)) + ;; Ignore pred1 since it doesn't really have to apply anyway. + (test-completion string tabel pred2)) + (t + (or (complete-with-action action table string + (if (null pred2) pred1 + (lexical-let ((pred1 pred2) (pred2 pred2)) + (lambda (x) + ;; Call `pred1' first, so that `pred2' + ;; really can't tell that `x' is in table. + (if (funcall pred1 x) (funcall pred2 x)))))) + ;; If completion failed and we're not applying pred1 strictly, try + ;; again without pred1. + (and (not strict) + (complete-with-action action table string pred2)))))) (defun completion-table-in-turn (&rest tables) "Create a completion table that tries each table in TABLES in turn." @@ -150,9 +178,12 @@ You should give VAR a non-nil `risky-local-variable' property." (complete-with-action action table string pred)) tables)))) -(defmacro complete-in-turn (a b) `(completion-table-in-turn ,a ,b)) +;; (defmacro complete-in-turn (a b) `(completion-table-in-turn ,a ,b)) +;; (defmacro dynamic-completion-table (fun) `(completion-table-dynamic ,fun)) (define-obsolete-function-alias 'complete-in-turn 'completion-table-in-turn "23.1") +(define-obsolete-function-alias + 'dynamic-completion-table 'completion-table-dynamic "23.1") ;;; Minibuffer completion -- 2.20.1