From 856166712438166741933e76b948c825a7661b21 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gerd=20M=C3=B6llmann?= Date: Sun, 16 Oct 2022 16:35:56 +0200 Subject: [PATCH] Handle packages in completion * lisp/minibuffer.el (completion-table-with-context): Add packagep case. * src/minibuf.c (Ftry_completion, Fall_completions), Ftest_completion): Take into account that predicate functions used with packages are the same that were used for obarrays. --- lisp/minibuffer.el | 2 ++ src/minibuf.c | 65 +++++++++++++++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 9f26e4f7f98..bf9321c5fa6 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -313,6 +313,8 @@ the form (concat S2 S)." ;; Predicates are called differently depending on the nature of ;; the completion table :-( (cond + ((packagep table) + (lambda (sym) (funcall pred (concat prefix (symbol-name sym))))) ((vectorp table) ;Obarray. (lambda (sym) (funcall pred (concat prefix (symbol-name sym))))) ((hash-table-p table) diff --git a/src/minibuf.c b/src/minibuf.c index 02bbb0df352..886d2dec936 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1622,7 +1622,13 @@ or from one of the possible completions. */) if (FUNCTIONP (collection)) return call3 (collection, string, predicate, Qnil); - if (PACKAGEP (collection)) + /* Use a package's symbol table for completion, but remember that we + are working on a package, because we are called with a predicate + that takes only one argument, which is a remnant ob obarrays. + Sad that we are receiving predicates of different arity depending + on the type of collection. */ + const bool symbol_table_p = PACKAGEP (collection); + if (symbol_table_p) collection = PACKAGE_SYMBOLS (collection); ptrdiff_t idx = 0; @@ -1689,15 +1695,18 @@ or from one of the possible completions. */) { if (EQ (predicate, Qcommandp)) tem = Fcommandp (elt, Qnil); - else + else if (HASH_TABLE_P (collection)) { - tem = (HASH_TABLE_P (collection) - ? call2 (predicate, elt, - HASH_VALUE (XHASH_TABLE (collection), - idx - 1)) - : call1 (predicate, elt)); + const Lisp_Object value = HASH_VALUE (XHASH_TABLE (collection), idx - 1); + if (symbol_table_p) + tem = call1 (predicate, value); + else + tem = call2 (predicate, elt, value); } - if (NILP (tem)) continue; + else + tem = call1 (predicate, elt); + if (NILP (tem)) + continue; } /* Update computation of how much all possible completions match */ @@ -1843,7 +1852,13 @@ with a space are ignored unless STRING itself starts with a space. */) if (type == 0) return call3 (collection, string, predicate, Qt); - if (type == 2) + /* Use a package's symbol table for completion, but remember that we + are working on a package, because we are called with a predicate + that takes only one argument, which is a remnant ob obarrays. + Sad that we are receiving predicates of different arity depending + on the type of collection. */ + const bool symbol_table_p = PACKAGEP (collection); + if (symbol_table_p) { collection = PACKAGE_SYMBOLS (collection); type = 3; @@ -1914,13 +1929,16 @@ with a space are ignored unless STRING itself starts with a space. */) { if (EQ (predicate, Qcommandp)) tem = Fcommandp (elt, Qnil); - else + else if (HASH_TABLE_P (collection)) { - tem = type == 3 - ? call2 (predicate, elt, - HASH_VALUE (XHASH_TABLE (collection), idx - 1)) - : call1 (predicate, elt); + const Lisp_Object value = HASH_VALUE (XHASH_TABLE (collection), idx - 1); + if (symbol_table_p) + tem = call1 (predicate, value); + else + tem = call2 (predicate, elt, value); } + else + tem = call1 (predicate, elt); if (NILP (tem)) continue; } /* Ok => put it on the list. */ @@ -2019,7 +2037,8 @@ the values STRING, PREDICATE and `lambda'. */) CHECK_STRING (string); - if (PACKAGEP (collection)) + const bool symbol_table_p = PACKAGEP (collection); + if (symbol_table_p) collection = PACKAGE_SYMBOLS (collection); if (NILP (collection) || (CONSP (collection) && !FUNCTIONP (collection))) @@ -2062,14 +2081,18 @@ the values STRING, PREDICATE and `lambda'. */) return Qnil; /* Finally, check the predicate. */ - if (!NILP (predicate)) + if (NILP (predicate)) + return Qt; + + if (HASH_TABLE_P (collection)) { - return HASH_TABLE_P (collection) - ? call2 (predicate, tem, HASH_VALUE (XHASH_TABLE (collection), i)) - : call1 (predicate, tem); + const Lisp_Object value = HASH_VALUE (XHASH_TABLE (collection), i); + if (symbol_table_p) + return call1 (predicate, value); + return call2 (predicate, tem, value); } - else - return Qt; + + return call1 (predicate, tem); } DEFUN ("internal-complete-buffer", Finternal_complete_buffer, Sinternal_complete_buffer, 3, 3, 0, -- 2.39.2