From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Roland Winkler Newsgroups: gmane.emacs.devel Subject: Re: dynamic-completion-table Date: Tue, 24 Jun 2003 16:11:30 +0200 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <16120.23570.881095.34919@tfkp07.physik.uni-erlangen.de> References: <16113.51538.619271.508717@tfkp07.physik.uni-erlangen.de> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: main.gmane.org 1056465362 6872 80.91.224.249 (24 Jun 2003 14:36:02 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Tue, 24 Jun 2003 14:36:02 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Tue Jun 24 16:35:58 2003 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 19Uoro-0001aq-00 for ; Tue, 24 Jun 2003 16:33:52 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 19UovO-0000QF-00 for ; Tue, 24 Jun 2003 16:37:34 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.20) id 19Uod3-0007EB-VS for emacs-devel@quimby.gnus.org; Tue, 24 Jun 2003 10:18:37 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.20) id 19UoYF-00066S-GK for emacs-devel@gnu.org; Tue, 24 Jun 2003 10:13:39 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.20) id 19UoXJ-0005aA-SQ for emacs-devel@gnu.org; Tue, 24 Jun 2003 10:12:42 -0400 Original-Received: from max6.rrze.uni-erlangen.de ([131.188.3.214]) by monty-python.gnu.org with esmtp (Exim 4.20) id 19UoWE-00053o-8f; Tue, 24 Jun 2003 10:11:34 -0400 Original-Received: from tfkp07.physik.uni-erlangen.de by max6.rrze.uni-erlangen.de with ESMTP; Tue, 24 Jun 2003 16:11:32 +0200 Original-To: rms@gnu.org In-Reply-To: X-Mailer: VM 6.96 under Emacs 21.2.1 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1b5 Precedence: list List-Id: Emacs development discussions. List-Help: List-Post: List-Subscribe: , List-Archive: List-Unsubscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:15211 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:15211 On Fri Jun 20 2003 Richard Stallman wrote: > "Turn a function FUN returning a completion table, into a completion table. > > That sentence is very confusing--you need to say it a different > way. I suggest the following. I hope that the new docstring is less confusing. Note also that I modified the code: FUN is called with one argument, the string for which completion is required. Furthermore, in order to avoid name conflicts make-symbol is used to create local variables. (defmacro dynamic-completion-table (fun) "Use function FUN as a dynamic completion table. FUN is called with one argument, the string for which completion is required, and it should return an alist containing all the intended possible completions. If completion is performed in the minibuffer, FUN will be called in the buffer from which the minibuffer was entered. `dynamic-completion-table' then computes the completion, see Info node `(elisp)Programmed Completion'." ;; (declare (debug t)) (let ((win (make-symbol "window")) (string (make-symbol "string")) (predicate (make-symbol "predicate")) (mode (make-symbol "mode"))) `(lambda (,string ,predicate ,mode) (with-current-buffer (let ((,win (minibuffer-selected-window))) (if (window-live-p ,win) (window-buffer ,win) (current-buffer))) (cond ((eq ,mode t) (all-completions ,string (,fun ,string) ,predicate)) ((not ,mode) (try-completion ,string (,fun ,string) ,predicate)) (t (test-completion ,string (,fun ,string) ,predicate))))))) > I use dynamic-completion-table to define the global initial values > of buffer-local variables that contain completion lists. The idea is > that if the user hits tab, FUN calculates the completion list and > stores it in the buffer-local variables. > > Should this macro produce the code to do that? > It might be more useful that way. I think it is conceptually cleaner to create lazy completion tables by means of a second macro that uses dynamic-completion-table. My suggestion is the following: (defmacro lazy-completion-table (var fun &rest args) "Initialize variable VAR as a lazy completion table. If the completion table VAR is used for the first time (e.g., by passing VAR as an argument to `try-completion'), the function FUN is called with arguments ARGS. FUN must return the completion table that will be stored in VAR. If completion is requested in the minibuffer, FUN will be called in the buffer from which the minibuffer was entered. The return value of `lazy-completion-table' must be used to initialize the value of VAR." (let ((str (make-symbol "string"))) `(dynamic-completion-table (lambda (,str) (unless (listp ,var) (setq ,var (funcall ',fun ,@args))) ,var)))) Then a typical application of lazy-completion-table is the following: (defvar bibtex-reference-keys (lazy-completion-table bibtex-reference-keys bibtex-parse-keys nil nil t) "Completion table for BibTeX reference keys.") (make-variable-buffer-local 'bibtex-reference-keys) Is this code useful for other packages, too so that the above macros should be made available, e.g., in simple.el? Suggestions welcome! Roland