* how to determine the current table (really) being used for minibuffer completion? @ 2009-09-25 17:20 Drew Adams 2009-09-25 20:01 ` Stefan Monnier 0 siblings, 1 reply; 8+ messages in thread From: Drew Adams @ 2009-09-25 17:20 UTC (permalink / raw) To: emacs-devel Since the Emacs 23 changes to minibuffer completion, there is little doc, and there are few doc strings. It's not always obvious how to determine the current state of evaluation. In particular, when completion tables are tried in sequence under the covers, how is it possible to know at some point which table is actually being tried? For example, how to know, during file-name completion, whether the table currently being tried is `(completion--make-envvar-table)' or `(completion--file-name-table)'? We have the global variable `minibuffer-completion-table', but that is apparently useless in this context. That var might be bound to some function `foo', but that doesn't mean that it is `foo' that is actually trying to perform completion at the moment, since completion now can involve several completion attempts using different tables (e.g. functions), successively. For example, the table (function) `read-file-name-internal', which is the value of `minibuffer-completion-table', is now an alias for the closure returned by this: (completion-table-in-turn 'completion--embedded-envvar-table 'completion--file-name-table) So not only is checking `minibuffer-completion-table' against `read-file-name-internal' useless, there is no way to know which of the two tables (functions) tried in turn is actually being used at a given time. Unless I'm missing something. How about (at least) recording in some global var the table that is currently being used/tried? ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to determine the current table (really) being used for minibuffer completion? 2009-09-25 17:20 how to determine the current table (really) being used for minibuffer completion? Drew Adams @ 2009-09-25 20:01 ` Stefan Monnier 2009-09-25 21:22 ` Drew Adams 0 siblings, 1 reply; 8+ messages in thread From: Stefan Monnier @ 2009-09-25 20:01 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel > Since the Emacs 23 changes to minibuffer completion, there is little > doc, and there are few doc strings. It's not always obvious how to > determine the current state of evaluation. I do not know what you mean. Please give a concrete example showing how you used to do it in Emacs-22. > In particular, when completion tables are tried in sequence under the > covers, how is it possible to know at some point which table is > actually being tried? If you mean uses of completion-table-in-turn: you can't and neither could you in Emacs-22; and this is not strictly a change in the minibuffer completion but in the implementation of some completion tables (yes, I made changes to both because the minibuffer completion changes needed some adjustments in the competion tables to work better, and because I wanted to rewrite in Lisp the C implementation of some of the completion tables, and because I wanted to give the code more structure). > For example, how to know, during file-name completion, whether the table > currently being tried is `(completion--make-envvar-table)' or > `(completion--file-name-table)'? You can't (and neither could you before, AFAICT). Could you give us some context to beter understand when you need it? > We have the global variable `minibuffer-completion-table', but that is > apparently useless in this context. That var might be bound to some > function `foo', but that doesn't mean that it is `foo' that is > actually trying to perform completion at the moment, since completion > now can involve several completion attempts using different tables > (e.g. functions), successively. It does mean that `foo' is the table that does the completion. That table may be decomposed into several distinct cases, but that's nothing new. The same was already the case when completing for Info-goto-node, for example. > So not only is checking `minibuffer-completion-table' against > `read-file-name-internal' useless, Comparing functions is usually a bad idea. Sometimes, there's not much else we can do, admittedly. > How about (at least) recording in some global var the table that is > currently being used/tried? It's not even clear what that would mean. Stefan ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: how to determine the current table (really) being used for minibuffer completion? 2009-09-25 20:01 ` Stefan Monnier @ 2009-09-25 21:22 ` Drew Adams 2009-09-26 1:53 ` Stefan Monnier 0 siblings, 1 reply; 8+ messages in thread From: Drew Adams @ 2009-09-25 21:22 UTC (permalink / raw) To: 'Stefan Monnier'; +Cc: emacs-devel > > Since the Emacs 23 changes to minibuffer completion, there is little > > doc, and there are few doc strings. It's not always obvious how to > > determine the current state of evaluation. > > I do not know what you mean. Please give a concrete example > showing how you used to do it in Emacs-22. How I used to do what? There is no concrete example. The point is that it is impossible (difficult?) to know which kind of completion function is currently being attempted, or which type completed successfully. Previously, comparing `minibuffer-completion-table' against a given function gave some idea. And surely you know what I mean wrt doc and doc strings. ;-) > > In particular, when completion tables are tried in sequence > > under the covers, how is it possible to know at some point > > which table is actually being tried? > > If you mean uses of completion-table-in-turn: you can't and neither > could you in Emacs-22; and this is not strictly a change in the > minibuffer completion but in the implementation of some completion > tables (yes, I made changes to both because the minibuffer completion > changes needed some adjustments in the competion tables to > work better, and because I wanted to rewrite in Lisp the C implementation > of some of the completion tables, and because I wanted to give the > code more structure). So you've confirmed what I said: one cannot know. The request is to be able to know. IOW, to be able to have some finer-grain knowledge of the completion state. > > For example, how to know, during file-name completion, > > whether the table currently being tried is > > `(completion--make-envvar-table)' or > > `(completion--file-name-table)'? > > You can't (and neither could you before, AFAICT). > Could you give us some context to beter understand when you need it? No. I didn't say I needed it in some concrete way. The point is that now there can be radically different kinds of completion that are used, all within the same `read-file-name-internal' (for example). I would like to be able to know which phase of that completion processing I'm in, or which phase succeeded if completion was successful. I would like, for instance (just an example), to be able to distinguish file-name completion per se from env var completion, both of which are now included as part of "file-name" completion in a larger sense. > > We have the global variable `minibuffer-completion-table', > > but that is apparently useless in this context. That var might > > be bound to some function `foo', but that doesn't mean that > > it is `foo' that is actually trying to perform completion > > at the moment, since completion now can involve several > > completion attempts using different tables > > (e.g. functions), successively. > > It does mean that `foo' is the table that does the completion. Only in a general way. `foo' or `read-file-name-internal' is the overall completion function, to be sure, but the completion processing is now decomposed into several distinct cases (as you say, next). For `read-file-name-internal', these are `completion--embedded-envvar-table' and `completion--file-name-table'. `read-file-name-internal' doesn't really call directly for any low-level completion act (e.g. `try-completion') anymore. > That table may be decomposed into several distinct cases, but that's > nothing new. The same was already the case when completing for > Info-goto-node, for example. Well, yes and no. Yes, this is a quantitative expansion of the kind of thing that has already been done in `Info-read-node-name' (but it did only one kind of completion or another, not a sequence of different kinds of completions) - but it pretty much becomes a qualitative change because it is so pervasive now. > > So not only is checking `minibuffer-completion-table' against > > `read-file-name-internal' useless, > > Comparing functions is usually a bad idea. Sometimes, > there's not much else we can do, admittedly. The Emacs code still compares `minibuffer-completion-table' against `read-file-name-internal', in particular, in many locations. I assume that all of those occurrences still work as intended. ;-) But I might want to do something different, depending on whether, say, an env var is being completed or a file name (properly speaking) is being completed at the moment (or was completed successfully). Maybe just display a msg; it really doesn't matter what. This doesn't depend on any particular concrete case (need). It is a general request. > > How about (at least) recording in some global var the table that is > > currently being used/tried? > > It's not even clear what that would mean. Maybe have a global variable `current-completion-table', analogous to `minibuffer-completion-table. Maybe `complete-with-action' could set it to the table it is currently using. That might make it possible to know which type of completion was used successfully. I obviously don't have a great feel for how to best implement what I'm asking for or how best to use it. It just seems that we should be able to have some way to test what's going on - what kind of completion is being attempted - and what kind of completion was successful. The act of completion is now a multi-act epic play. It's good to be able to know which act is in progress or what the outcome of the previous act was. That's all. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to determine the current table (really) being used for minibuffer completion? 2009-09-25 21:22 ` Drew Adams @ 2009-09-26 1:53 ` Stefan Monnier 2009-09-26 14:58 ` Drew Adams 0 siblings, 1 reply; 8+ messages in thread From: Stefan Monnier @ 2009-09-26 1:53 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel > How I used to do what? There is no concrete example. Please, then say clearly that your problem is hypothetical, that will help us answer your questions more directly. > So you've confirmed what I said: one cannot know. The request is to be > able to know. IOW, to be able to have some finer-grain knowledge of > the completion state. Define what you mean by "have some finer-grain knownledge of the completion state". I think this request is like a solution waiting for a problem. So once we find a concrete problem, we'll know better how to solve it. But in the abstract like that, it's really unclear what kind of solution would be needed/possible. > The point is that now there can be radically different kinds of > completion that are used, all within the same > `read-file-name-internal' (for example). That has always been a possibility. Maybe this is used a bit more now, tho. > I would like to be able to know which phase of that completion > processing I'm in, When? Who's "I"? Do you mean, given the position of point which kind of completion will take place? The closest right now is to use completion-boundaries, which won't tell you what completion table will be used, but at least it'll tell you which part of the buffer around point will be "affected". > I would like, for instance (just an example), to be able to distinguish > file-name completion per se from env var completion, both of which are now > included as part of "file-name" completion in a larger sense. completion-boundaries can help you do that. But again, without knowing to what purpose you want to distinguish those two cases, it's hard to know what would really be a good answer. > Only in a general way. `foo' or `read-file-name-internal' is the > overall completion function, to be sure, but the completion processing > is now decomposed into several distinct cases (as you say, next). For > `read-file-name-internal', these are > `completion--embedded-envvar-table' and `completion--file-name-table'. > `read-file-name-internal' doesn't really call directly for any > low-level completion act (e.g. `try-completion') anymore. read-file-name-internal is pretty much the only one that I changed in this way, BTW. It can now complete either files or env-vars. In the future it will probably also be able to complete ~<user> user names. >> > So not only is checking `minibuffer-completion-table' against >> > `read-file-name-internal' useless, >> Comparing functions is usually a bad idea. Sometimes, >> there's not much else we can do, admittedly. > The Emacs code still compares `minibuffer-completion-table' against > `read-file-name-internal', in particular, in many locations. Not sure how you define "many", but my grep found only one place where we do it: in complete.el which could advise read-file-name-internal instead (but since it's on the way to obsolescence, it doesn't matter much either way). > I assume that all of those occurrences still work as intended. ;-) Why wouldn't they? ;-) BTW, all the uses I've ever found (other than complete.el's) were changed to use minibuffer-completing-file-name or to work in all cases. > It is a general request. We have plenty of real concrete problems to address and improvements to implement, so yours will inevitably end up at the very bottom of the lot. > I obviously don't have a great feel for how to best implement what I'm > asking for or how best to use it. Come back when you do know. Stefan ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: how to determine the current table (really) being used for minibuffer completion? 2009-09-26 1:53 ` Stefan Monnier @ 2009-09-26 14:58 ` Drew Adams 2009-09-26 21:26 ` Stefan Monnier 0 siblings, 1 reply; 8+ messages in thread From: Drew Adams @ 2009-09-26 14:58 UTC (permalink / raw) To: 'Stefan Monnier'; +Cc: emacs-devel Hypothetical example that might make the request clearer: (completion-all-completions STRING 'read-file-name-internal nil (length STRING)) The result returned might be a list of relative file names, or it might be a list of env vars. A result such as ("CATACOMBS" "CATAPHILE" "CATASTROPHE" . 4) could be either. I would like (via Lisp) to know which kind of completion was in fact used successfully: file-name completion per se or env var completion. I don't want to analyze STRING (e.g. check for `$') to figure out what might be the case. (completion-boundaries STRING 'read-file-name-internal nil "") just gives something like (0 . 0), indicating the whole STRING. Emacs should be able to tell me directly what the last completion table/function used was. It should be easy to make this info available somehow, e.g. in a global variable. Similarly, for multiple, successive completion types using `completion-styles', I would like to know which type (style) was in fact successful. This is the kind of thing I'm talking about. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to determine the current table (really) being used for minibuffer completion? 2009-09-26 14:58 ` Drew Adams @ 2009-09-26 21:26 ` Stefan Monnier 2009-09-27 0:02 ` Drew Adams 0 siblings, 1 reply; 8+ messages in thread From: Stefan Monnier @ 2009-09-26 21:26 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel > Hypothetical example that might make the request clearer: > (completion-all-completions > STRING 'read-file-name-internal nil (length STRING)) > The result returned might be a list of relative file names, or it > might be a list of env vars. A result such as ("CATACOMBS" > "CATAPHILE" "CATASTROPHE" . 4) could be either. > I would like (via Lisp) to know which kind of completion was in fact used > successfully: file-name completion per se or env var completion. In which form? Do you want a symbol like `file' vs `envvar', or do you want a completion-table (which can then be a has-table, an obarray, an alist, a list, a symbol-function, or a lambda expression)? The second might be doable in many cases (actually more so in Emacs-23 than in Emacs-22, since most functional completion tables now get composed using primitives like complete-with-action or completion-table-*, so we could add a 5th method (additionally to the original 3, try-completions, all-completions, and test-completion, plus the new completion-boundaries) a bit more easily), but I'm not sure it would be easy to use. > I don't want to analyze STRING (e.g. check for `$') to figure out what > might be the case. (completion-boundaries STRING > 'read-file-name-internal nil "") just gives something like (0 . 0), > indicating the whole STRING. (completion-boundaries "to/to" 'read-file-name-internal nil "") returns (3 . 0), (completion-boundaries "to/$to" 'read-file-name-internal nil "") returns (4 . 0) and (completion-boundaries "to/${to" 'read-file-name-internal nil "") returns (5 . 0), so by looking at (aref STR (1- (car (completion-boundaries STR ...)))) you can "easily" tell which case is currently relevant. But of course, that requires knowledge of the behavior of read-file-name-internal. > Emacs should be able to tell me directly what the last completion > table/function used was. It should be easy to make this info > available somehow, e.g. in a global variable. It might be easy in 99% of the cases, depending on exactly what you want. In my experience, providing this info before seeing actual uses for it is a perfect recipe for "features" which are unusable in practice because they don't quite give the info we need. So I'm definitely not opposed to providing this info, but I'll wait for a practical use for it, so I'll be in a better position to provide the right info. > Similarly, for multiple, successive completion types using > `completion-styles', I would like to know which type (style) was in > fact successful. Same answer here. Actually, this one is even a bit worse, because I strongly suspect that if some code needs this info, it's probably not doing the right thing. But in any case, we'll see it when we get there. Stefan ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: how to determine the current table (really) being used for minibuffer completion? 2009-09-26 21:26 ` Stefan Monnier @ 2009-09-27 0:02 ` Drew Adams 2009-09-27 18:24 ` Stefan Monnier 0 siblings, 1 reply; 8+ messages in thread From: Drew Adams @ 2009-09-27 0:02 UTC (permalink / raw) To: 'Stefan Monnier'; +Cc: emacs-devel > > Hypothetical example that might make the request clearer: > > (completion-all-completions > > STRING 'read-file-name-internal nil (length STRING)) > > > The result returned might be a list of relative file names, or it > > might be a list of env vars. A result such as ("CATACOMBS" > > "CATAPHILE" "CATASTROPHE" . 4) could be either. > > > I would like (via Lisp) to know which kind of completion > > was in fact used successfully: file-name completion per se > > or env var completion. > > In which form? Do you want a symbol like `file' vs `envvar', > or do you want a completion-table (which can then be a > has-table, an obarray, an alist, a list, a symbol-function, > or a lambda expression)? The second might be doable in many > cases (actually more so in Emacs-23 than in Emacs-22, since > most functional completion tables now get composed using > primitives like complete-with-action or completion-table-*, > so we could add a 5th method (additionally to the original 3, > try-completions, all-completions, and test-completion, plus > the new completion-boundaries) a bit more easily), but I'm > not sure it would be easy to use. As you recognize, it is better to test a known symbol (e.g. `envvar') than a completion table (function or list or hash table or obarray...). What I suggest is this: Use a data structure (an alist), to have a standard list of symbols (the keys of the alist) that can be tested. @ In the case of completion styles (determining which style performed the completion), just reuse `completion-styles-alist': be able to test the alist key - `basic', `emacs22', `emacs21', or `partial-completion'. (But using whatever real alist entries are in `completion-styles-alist' at the time of testing.) This will provide a knowable and unambiguous set of symbols to test. @ In the case of env-var and file-name completion: Do the same thing. Implement something similar to `completion-styles-alist'. It would be good to use an alist here anyway, for flexibility of use and ease of maintenance. After successful completion, set a global variable to the symbol that represents the completion style. This is simply additional information to be, in effect, returned by the completion function. We already return the set of completions, and you've hacked that list to also carry the base size in its last cdr. This third piece of info about the completion state can be returned in a global variable. (It can be at least as important as the base size, IMO.) Your code comments acknowledge the hackiness of how base-size is returned, and they point to possibly also returning a `completion-extra-size' and `completion-no-auto-exit' in the future. The point is that completion is a complex process, and it can return more useful info than simply the list of completions. -- Also, it is somewhat inconvenient to have `completion-styles-alist' as a defvar, not a defcustom. It is the real fulcrum for all of the code. It is baked once by Emacs development, and then it is used as the basis for the rest. User customization of `completion-styles' is limited to choosing among predefined styles. It would be better to have a single option that lets users both (a) choose the styles to use and (b) define new styles (their names and their defining completion functions). IOW, combine `completion-styles-alist' with `completion-styles' as a single option that users can customize. That way, the code would still automatically adjust to the possible set of completion styles, but those styles would not be limited to choices from a predefined list. Users could still just as easily add or remove predefined styles, but they could also more easily add their own. > > Emacs should be able to tell me directly what the last completion > > table/function used was. It should be easy to make this info > > available somehow, e.g. in a global variable. > > It might be easy in 99% of the cases, depending on exactly what > you want. See above. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to determine the current table (really) being used for minibuffer completion? 2009-09-27 0:02 ` Drew Adams @ 2009-09-27 18:24 ` Stefan Monnier 0 siblings, 0 replies; 8+ messages in thread From: Stefan Monnier @ 2009-09-27 18:24 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel > After successful completion, set a global variable to the symbol that > represents the completion style. Returning info via a global variable is evil. > We already return the set of completions, and you've hacked that list > to also carry the base size in its last cdr. No, that was an ugly hack I managed to get rid of before releasing Emacs-23. > This third piece of info about the completion state can be returned in > a global variable. (It can be at least as important as the base > size, IMO.) Reality check: you can't even come up with a concrete case where it would be useful, so how can you claim it can be at least as important as the base-size which has been needed since the introduction of choose-completion (Emacs-21? Emacs-20?) > Also, it is somewhat inconvenient to have `completion-styles-alist' as > a defvar, not a defcustom. It is the real fulcrum for all of the > code. It is baked once by Emacs development, and then it is used as > the basis for the rest. User customization of `completion-styles' is > limited to choosing among predefined styles. A defcustom? It contains pointers to functions and those functions use a non-trivial calling convention, so there's very little chance you'll be able to add entries there without writing Lisp code. `completion-styles-alist' is definitely not a candidate for defcustom. > It would be better to have a single option that lets users both (a) > choose the styles to use and (b) define new styles (their names and > their defining completion functions). IOW, combine > `completion-styles-alist' with `completion-styles' as a single option > that users can customize. And where do you keep the list of options from which they can choose? > That way, the code would still automatically adjust to the possible set of > completion styles, but those styles would not be limited to choices from a > predefined list. Users could still just as easily add or remove predefined > styles, but they could also more easily add their own. How hard can it be to add their new style to completion-styles-alist and then to completion-styles as well? Especially compared to the amount of work required in writing that new style? I must be misunderstanding something. >> It might be easy in 99% of the cases, depending on exactly what >> you want. > See above. The "above" didn't tell me what you want to do. Stefan PS: FWIW, I can think of at least one case where the "file vs envvar" information could potentially be used. So maybe if you try hard enough, you too can come up with an example. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-09-27 18:24 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-09-25 17:20 how to determine the current table (really) being used for minibuffer completion? Drew Adams 2009-09-25 20:01 ` Stefan Monnier 2009-09-25 21:22 ` Drew Adams 2009-09-26 1:53 ` Stefan Monnier 2009-09-26 14:58 ` Drew Adams 2009-09-26 21:26 ` Stefan Monnier 2009-09-27 0:02 ` Drew Adams 2009-09-27 18:24 ` Stefan Monnier
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.