emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Turning completion table lambdas into symbols


From: Spencer Baugh
Subject: Turning completion table lambdas into symbols
Date: Tue, 28 Nov 2023 23:36:44 +0000 (UTC)

Juri Linkov <juri@linkov.net> writes:
>>> display-buffer has a similar problem, but the difference is that
>>> it's possible to identify a buffer by its name and use a regexp
>>> to match buffer names.  Whereas for completing-read it's not easy
>>> to identify a completion table.  A category matches a set of
>>> completion tables, so maybe we need another identification
>>> for individual tables?
>>
>> True, that would help.  Maybe the function symbol for the completion
>> table?  Tables are usually lambdas today, but maybe we could make it
>> easy to use a defun'd function instead, which would be very good for
>> comprehensibility in general IMO.
>
> Turning lambdas into symbols looks good, this is like the existing
> 'help--symbol-completion-table'.

Like 'help--symbol-completion-table' in what way?

One thing that requires a lambda is when the table is over some custom
data.  But that can sometimes be avoided by moving the logic into the
table, like this for example:

--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1765,6 +1765,13 @@ project-forget-project
 
 (defvar project--dir-history)
 
+(defun project--project-dir-completion-table (string pred action)
+  (cond
+   ((eq action 'metadata)
+    '(metadata . ((category . project-dir))))
+   (t
+    (complete-with-action action (cons "... (choose a dir)" project--list) 
string pred))))
+
 (defun project-prompt-project-dir ()
   "Prompt the user for a directory that is one of the known project roots.
 The project is chosen among projects known from the project list,
@@ -1772,18 +1779,14 @@ project-prompt-project-dir
 It's also possible to enter an arbitrary directory not in the list."
   (project--ensure-read-project-list)
   (let* ((dir-choice "... (choose a dir)")
-         (choices
-          ;; XXX: Just using this for the category (for the substring
-          ;; completion style).
-          (project--file-completion-table
-           (append project--list `(,dir-choice))))
          (project--dir-history (project-known-project-roots))
          (pr-dir ""))
     (while (equal pr-dir "")
       ;; If the user simply pressed RET, do this again until they don't.
       (setq pr-dir
             (let (history-add-new-input)
-              (completing-read "Select project: " choices nil t nil 
'project--dir-history))))
+              (completing-read "Select project: " 
#'project--project-dir-completion-table
+                               nil t nil 'project--dir-history))))
     (if (equal pr-dir dir-choice)
         (read-directory-name "Select directory: " default-directory nil t)
       pr-dir)))

The trickier case is when the table actually has some internal state or
calculation which it needs to preserve across multiple calls.  Like I
recently asked about in my recent mail to emacs-devel with subject
"State and caching in completion tables".

If there was a canonical way for a completion table to maintain some
state which *doesn't* require the completion table to be a lambda, I
think most completion tables could become defuns instead of lambdas.
(And then they could be customized based on the function symbol)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]