Re: [O] Completing with anything
> With these two modifications, it runs fine (that is, using the old calling > convention and just using (setq-default completion-at-point-functions > '(my-dabbrev-expand))) Thanks, installed, Stefan
Re: [O] Completing with anything
26/05/11 04:23, Stefan Monnier >>> Another is to do it more selectively, flag some of >>> completion-at-point-functions as "not-exclusive", meaning that if >>> completion fails with those we should keep trying with subsequent >>> functions. E.g. the nick completion in rcirc could be flagged as >>> non-exclusive since it applies everywhere, which in turn would let >>> your dabbrev-expand kick in when nick-completion fails. > >> This seems to be the most flexible, while still keeping all the >> completions in the same UI. I'd make the non-exclusive behaviour the >> default though: let the functions that want to "take over" the >> completion state it explicitely. > > I actually much prefer the it the other way around. > Most completion-at-point-functions should be pretty specific, checking > the context to decide whether they should be used at point, so they can > be exclusive. > Can you try the patch below to see if it gives you back the old behavior > in ERC? > > > Stefan > > > === modified file 'lisp/erc/erc-pcomplete.el' > --- lisp/erc/erc-pcomplete.el 2011-04-29 15:23:59 + > +++ lisp/erc/erc-pcomplete.el 2011-05-26 02:12:19 + > @@ -73,7 +73,10 @@ >"ERC completion data from pcomplete. > for use on `completion-at-point-function'." >(when (> (point) (erc-beg-of-input-line)) > -(pcomplete-completions-at-point))) > +(or (let ((pcomplete-default-completion-function #'ignore)) > + (pcomplete-completions-at-point)) > +(nconc (pcomplete-completions-at-point) > + '(:exclusivity 'non-exclusive) There's a double quoting here that messes up the test (took me a while to figure out why 'non-exclusive was not equal to non-exclusive ...). Also, the (let ((pcomplete-default-completion-function #'ignore)) (pcomplete-completions-at-point)) check always return non-nil, so I removed it for testing purposes (not sure what your intent was here). With these two modifications, it runs fine (that is, using the old calling convention and just using (setq-default completion-at-point-functions '(my-dabbrev-expand))) > > (defun erc-pcomplete () >"Complete the nick before point." > > === modified file 'lisp/minibuffer.el' > --- lisp/minibuffer.el2011-05-24 02:45:50 + > +++ lisp/minibuffer.el2011-05-26 02:16:05 + > @@ -1436,9 +1436,13 @@ > `:predicate' a predicate that completion candidates need to > satisfy.") > > (defvar completion--capf-misbehave-funs nil > - "List of functions found on `completion-at-point-functions' that > misbehave.") > + "List of functions found on `completion-at-point-functions' that misbehave. > +These are functions that neither return completion data nor a completion > +function but instead perform completion right away.") > (defvar completion--capf-safe-funs nil > - "List of well-behaved functions found on `completion-at-point-functions'.") > + "List of well-behaved functions found on `completion-at-point-functions'. > +These are functions which return proper completion data rather than > +a completion function or god knows what else.") > > (defun completion--capf-wrapper (fun which) >;; FIXME: The safe/misbehave handling assumes that a given function will > @@ -1451,9 +1455,23 @@ > (optimist (not (member fun completion--capf-misbehave-funs >(let ((res (funcall fun))) > (cond > - ((consp res) > + ((and (consp res) (not (functionp res))) >(unless (member fun completion--capf-safe-funs) > -(push fun completion--capf-safe-funs))) > +(push fun completion--capf-safe-funs)) > + (and (eq 'non-exclusive (plist-get (nthcdr 3 res) :exclusivity)) > + ;; FIXME: Here we'd need to decide whether there are > + ;; valid completions against the current text. But this > depends > + ;; on the actual completion UI (e.g. with the default > completion > + ;; it depends on completion-style) ;-( > + ;; We approximate this result by checking whether prefix > + ;; completion might work, which means that non-prefix > completion > + ;; will not work (or not right) for completion functions that > + ;; are non-exclusive. > + (null (try-completion (buffer-substring-no-properties > + (car res) (point)) > + (nth 2 res) > + (plist-get (nthcdr 3 res) :predicate))) > + (setq res nil))) > ((not (or (listp res) (functionp res))) >(unless (member fun completion--capf-misbehave-funs) > (message
Re: [O] Completing with anything
>> Another is to do it more selectively, flag some of >> completion-at-point-functions as "not-exclusive", meaning that if >> completion fails with those we should keep trying with subsequent >> functions. E.g. the nick completion in rcirc could be flagged as >> non-exclusive since it applies everywhere, which in turn would let >> your dabbrev-expand kick in when nick-completion fails. > This seems to be the most flexible, while still keeping all the > completions in the same UI. I'd make the non-exclusive behaviour the > default though: let the functions that want to "take over" the > completion state it explicitely. I actually much prefer the it the other way around. Most completion-at-point-functions should be pretty specific, checking the context to decide whether they should be used at point, so they can be exclusive. Can you try the patch below to see if it gives you back the old behavior in ERC? Stefan === modified file 'lisp/erc/erc-pcomplete.el' --- lisp/erc/erc-pcomplete.el 2011-04-29 15:23:59 + +++ lisp/erc/erc-pcomplete.el 2011-05-26 02:12:19 + @@ -73,7 +73,10 @@ "ERC completion data from pcomplete. for use on `completion-at-point-function'." (when (> (point) (erc-beg-of-input-line)) -(pcomplete-completions-at-point))) +(or (let ((pcomplete-default-completion-function #'ignore)) + (pcomplete-completions-at-point)) +(nconc (pcomplete-completions-at-point) + '(:exclusivity 'non-exclusive) (defun erc-pcomplete () "Complete the nick before point." === modified file 'lisp/minibuffer.el' --- lisp/minibuffer.el 2011-05-24 02:45:50 + +++ lisp/minibuffer.el 2011-05-26 02:16:05 + @@ -1436,9 +1436,13 @@ `:predicate' a predicate that completion candidates need to satisfy.") (defvar completion--capf-misbehave-funs nil - "List of functions found on `completion-at-point-functions' that misbehave.") + "List of functions found on `completion-at-point-functions' that misbehave. +These are functions that neither return completion data nor a completion +function but instead perform completion right away.") (defvar completion--capf-safe-funs nil - "List of well-behaved functions found on `completion-at-point-functions'.") + "List of well-behaved functions found on `completion-at-point-functions'. +These are functions which return proper completion data rather than +a completion function or god knows what else.") (defun completion--capf-wrapper (fun which) ;; FIXME: The safe/misbehave handling assumes that a given function will @@ -1451,9 +1455,23 @@ (optimist (not (member fun completion--capf-misbehave-funs (let ((res (funcall fun))) (cond - ((consp res) + ((and (consp res) (not (functionp res))) (unless (member fun completion--capf-safe-funs) -(push fun completion--capf-safe-funs))) +(push fun completion--capf-safe-funs)) + (and (eq 'non-exclusive (plist-get (nthcdr 3 res) :exclusivity)) + ;; FIXME: Here we'd need to decide whether there are + ;; valid completions against the current text. But this depends + ;; on the actual completion UI (e.g. with the default completion + ;; it depends on completion-style) ;-( + ;; We approximate this result by checking whether prefix + ;; completion might work, which means that non-prefix completion + ;; will not work (or not right) for completion functions that + ;; are non-exclusive. + (null (try-completion (buffer-substring-no-properties + (car res) (point)) + (nth 2 res) + (plist-get (nthcdr 3 res) :predicate))) + (setq res nil))) ((not (or (listp res) (functionp res))) (unless (member fun completion--capf-misbehave-funs) (message
Re: [O] Completing with anything
24/05/11 20:05, Stefan Monnier >> Oh well, I guess that I'm the only one who wants this kind of behaviour, >> so I just ended up with an advice which seems to do the trick. Sorry for >> hijacking this thread. In case anyone is interested: > > To get back to this discussion. Before worrying about how to implement > it, I'm wondering what should the behavior be. > > The way I look at it, the issue is whether the completion data returned > by completion-at-point-functions is "exclusive": currently it is > exclusive, which means that if that data leads to a completion failure, > then the whole completion-at-point fails, even though there might be > further functions on completion-at-point-functions which could return > data that does lead to a successful completion. > > This "exclusive"ness is a bit similar to the must-match argument of > completion-read: it presumes that the function knows that anything > outside of the completion table is simply undesirable at point. > > This "exclusive" behavior is what causes you pain. Now one possible > strategy is to make the behavior non-exclusive and keep trying the next > functions until one of them returns data that leads to a successful > completion, which is largely what used to happen with > comint-dynamic-complete-function. > > Another is to do it more selectively, flag some of > completion-at-point-functions as "not-exclusive", meaning that if > completion fails with those we should keep trying with subsequent > functions. E.g. the nick completion in rcirc could be flagged as > non-exclusive since it applies everywhere, which in turn would let your > dabbrev-expand kick in when nick-completion fails. This seems to be the most flexible, while still keeping all the completions in the same UI. I'd make the non-exclusive behaviour the default though: let the functions that want to "take over" the completion state it explicitely.
Re: [O] Completing with anything
> Oh well, I guess that I'm the only one who wants this kind of behaviour, > so I just ended up with an advice which seems to do the trick. Sorry for > hijacking this thread. In case anyone is interested: To get back to this discussion. Before worrying about how to implement it, I'm wondering what should the behavior be. The way I look at it, the issue is whether the completion data returned by completion-at-point-functions is "exclusive": currently it is exclusive, which means that if that data leads to a completion failure, then the whole completion-at-point fails, even though there might be further functions on completion-at-point-functions which could return data that does lead to a successful completion. This "exclusive"ness is a bit similar to the must-match argument of completion-read: it presumes that the function knows that anything outside of the completion table is simply undesirable at point. This "exclusive" behavior is what causes you pain. Now one possible strategy is to make the behavior non-exclusive and keep trying the next functions until one of them returns data that leads to a successful completion, which is largely what used to happen with comint-dynamic-complete-function. Another is to do it more selectively, flag some of completion-at-point-functions as "not-exclusive", meaning that if completion fails with those we should keep trying with subsequent functions. E.g. the nick completion in rcirc could be flagged as non-exclusive since it applies everywhere, which in turn would let your dabbrev-expand kick in when nick-completion fails. Yet another is to do what your defadvice does: let all completion functions from completion-at-point-functions be exclusive with respect to each other, but make them non-exclusive with respect to some "fallback completion". Stefan
Re: [O] Completing with anything
24/05/11 16:05, Stefan Monnier >> (defadvice completion-at-point >> (after completion-at-point-complete-if-failed activate) >> "Fallback on dabbrev if completion didn't do anything useful." >> (unless ad-return-value >> (dabbrev-expand nil))) > > BTW, you can avoid the advice by using your own > > (defun al-completion-at-point () > (interactive) > (or (completion-at-point) > (dabbrev-expand nil))) I'd do that, but completion-at-point is used in places I don't fully understand when I set (setq tab-always-indent 'complete). Also there's some weirdness with dabbrev that makes it bug out when it's called indirectly. For instance, seemingly simple code like (artificial example here, but similar things happen when for instance you indent and then complete with the same key) (setq counter 0) (defun my-my-dabbrev-expand () (interactive) (setq counter (mod (+ 1 counter) 2)) (when (equal counter 0) (dabbrev-expand nil))) (local-set-key (kbd "C-c C-c") 'my-my-dabbrev-expand) behaves in a very unexpected way : it actually jumps (!) to the location where the completion was found. I wasn't able to understand this, but it's definitely a bug in dabbrev. It looks like it's related to the way dabbrev checks it's continuing a completion: (eq last-command this-command) but I wouldn't know how to fix this.
Re: [O] Completing with anything
> (defadvice completion-at-point > (after completion-at-point-complete-if-failed activate) > "Fallback on dabbrev if completion didn't do anything useful." > (unless ad-return-value > (dabbrev-expand nil))) BTW, you can avoid the advice by using your own (defun al-completion-at-point () (interactive) (or (completion-at-point) (dabbrev-expand nil))) -- Stefan
Re: [O] Completing with anything
> Oh well, I guess that I'm the only one who wants this kind of behaviour, No, I'm interested as well, but haven't found a good solution yet. Stefan
Re: [O] Completing with anything
24/05/11 14:47, Stefan Monnier >> So, could you add 'failed, which means that no function was able to >> complete? That way I could do something like > >> (setq completion-extra-properties '(:exit-function my-exit-function)) > >> (defun my-exit-function (string finished) >> (when (eq finished 'failed) >> (dabbrev-expand))) > >> and always get a dabbrev-expand as fallback to completion-at-point? > > Hmm... interesting way to attack that problem. I don't think that will > work quite like this: if the completion provides its own :exit-function > (e.g. to add a terminator string), then yours won't be run. Mmh, true. Oh well, I guess that I'm the only one who wants this kind of behaviour, so I just ended up with an advice which seems to do the trick. Sorry for hijacking this thread. In case anyone is interested: (defadvice completion-at-point (after completion-at-point-complete-if-failed activate) "Fallback on dabbrev if completion didn't do anything useful." (unless ad-return-value (dabbrev-expand nil)))
Re: [O] Completing with anything
> So, could you add 'failed, which means that no function was able to > complete? That way I could do something like > (setq completion-extra-properties '(:exit-function my-exit-function)) > (defun my-exit-function (string finished) > (when (eq finished 'failed) > (dabbrev-expand))) > and always get a dabbrev-expand as fallback to completion-at-point? Hmm... interesting way to attack that problem. I don't think that will work quite like this: if the completion provides its own :exit-function (e.g. to add a terminator string), then yours won't be run. Stefan
Re: [O] Completing with anything
On Tue, May 24 2011, Stefan Monnier wrote: > I've now added a :exit-function property that > completion-at-point-functions can return which is a function that gets > called when completion is finished. It operates outside of the > completion-table, so has access to the buffer text and can do things > like abbrev-expand. > > It gets a status argument which tells it whether the completion is > `exact' (basically, it's valid according to the completion-table, but > there may be further completions available), `sole' (it's the only > completion), and `finished' (not only it's the sole completion, but the > user is not expected to want to change it). `sole' is used by cycling, > so the :exit-function can call abbrev-expand when the status is > `finished' and it won't interfere with cycling (which simply won't > benefit from abbrev-expansion). That sounds really tremendous Stefan! Just what was needed. Thanks a lot. -- Julien Danjou ❱ http://julien.danjou.info pgpSrPZ76Mjx7.pgp Description: PGP signature
Re: [O] Completing with anything
> > So at least cycling-completion seems fundamentally incompatible with > > this idea of abbrev-expansion-after-completion, at least if you want to > > allow arbitrarily complex abbrevs like skeletons. > Indeed, this is a real problem. I've now added a :exit-function property that completion-at-point-functions can return which is a function that gets called when completion is finished. It operates outside of the completion-table, so has access to the buffer text and can do things like abbrev-expand. It gets a status argument which tells it whether the completion is `exact' (basically, it's valid according to the completion-table, but there may be further completions available), `sole' (it's the only completion), and `finished' (not only it's the sole completion, but the user is not expected to want to change it). `sole' is used by cycling, so the :exit-function can call abbrev-expand when the status is `finished' and it won't interfere with cycling (which simply won't benefit from abbrev-expansion). Stefan
Re: [O] Completing with anything
On Wed, May 04 2011, Stefan Monnier wrote: > So at least cycling-completion seems fundamentally incompatible with > this idea of abbrev-expansion-after-completion, at least if you want to > allow arbitrarily complex abbrevs like skeletons. Indeed, this is a real problem. > Could you give me an idea of what kind of abbrevs the code should try > to accommodate? IIUC, your nic/nicolas example perfectly fits in. This is what I tried to achieve in message-mode (using org-contacts as the database). Maybe what's needed is a different completion type, which would be a built on top of both completion and abbrev. It would try to complete based on an abbrev list until there's no possible doubt about the alias the users wants, and finally would do the expand-abbrev operation. At least, that sounds like a completion mode we would need in message-mode case. -- Julien Danjou ❱ http://julien.danjou.info pgpqaO08ZXoM6.pgp Description: PGP signature
Re: [O] Completing with anything
>> Hmm... good point, doing it in completion-choices is not reliable, tho >> using as completion table something like: >> >> (lambda (string pred action) >> (let ((res (complete-with-action action completion-choices string pred))) >> (if (and (eq action nil) >> (assq (if (eq res t) string res) )) >> (cdr (assq (if (eq res t) string res) )) >> res))) >> >> should work OK for prefix completion, but that means using the expansion >> "by hand" rather than via expand-abbrev, which may not be an option. > Yeah. That does not looks like a simple/good option. > As it stands, I guess the bbdb solution to return a function doing the > replacement rather than trying to return a list and conform with the > (current) way of doing completion is really simpler, unfortunately. :( While taking a look at adding the necessary functionality to minibuffer.el, I bumped into a problem: If you complete "ni" to "nic" which is a valid alias and you also have a "nicolas" alias, running expand-abbrev after the completion may not be right since it will prevent you from getting to "nicolas". Now, this is a minor problem. But the more general case is when the user has set completion-cycle-threshold so that completion happened via cycling: the string after completion is a valid abbrev (presumably) but calling expand-abbrev on it will interfere with the cycling in a big way (the details of what will happen depend on the way cycling is implemented and what kind of abbrevs we're talking about). So at least cycling-completion seems fundamentally incompatible with this idea of abbrev-expansion-after-completion, at least if you want to allow arbitrarily complex abbrevs like skeletons. Could you give me an idea of what kind of abbrevs the code should try to accommodate? Stefan
Re: [O] Completing with anything
On Sun, Mar 27 2011, Michael Markert wrote: > Attached code handles both capturing from summary and message > buffer. I've added this file into contrib, beside org-contacts.el -- Julien Danjou ❱ http://julien.danjou.info pgpYWL7yrdunj.pgp Description: PGP signature
Re: [O] Completing with anything
On 11 Apr 2011, Michael Markert wrote: > On 11 Apr 2011, Bastien wrote: > >> Julien Danjou writes: >> >>> On Sat, Apr 09 2011, Michael Markert wrote: >>> No, but if it's necessary (or helping) I'll do so. >>> >>> Well, since org-contacts is part of contrib I think it's not necessary, >>> so I'll merge it as it is unless Bastien says I'm wrong. >> >> You're right. No need for FSF copyright assignment for code in the >> contrib/ directory, as this directory does not go to the Emacs trunk. >> >> Still, it's always better to get the assignment process done in case >> code from contrib has to move to Org's core. > > I'll do so then. > > Michael Today I received the assignment papers and signed them. Next week they'll be on their way to the FSF. So feel free to include my code if that hindered you from doing so yet. Michael pgp6jgIkBtjBr.pgp Description: PGP signature
Re: [O] Completing with anything
On Tue, Apr 12 2011, Stefan Monnier wrote: > Hmm... good point, doing it in completion-choices is not reliable, tho > using as completion table something like: > > (lambda (string pred action) > (let ((res (complete-with-action action completion-choices string pred))) > (if (and (eq action nil) > (assq (if (eq res t) string res) )) > (cdr (assq (if (eq res t) string res) )) > res))) > > should work OK for prefix completion, but that means using the expansion > "by hand" rather than via expand-abbrev, which may not be an option. Yeah. That does not looks like a simple/good option. As it stands, I guess the bbdb solution to return a function doing the replacement rather than trying to return a list and conform with the (current) way of doing completion is really simpler, unfortunately. :( -- Julien Danjou ❱ http://julien.danjou.info pgp0LZN7uU1rU.pgp Description: PGP signature
Re: [O] Completing with anything
> Because this one return (list start end completion-choies), and does not > do anything else. I can't do it myself using the current completion > mechanism, IIUC. Hmm... good point, doing it in completion-choices is not reliable, tho using as completion table something like: (lambda (string pred action) (let ((res (complete-with-action action completion-choices string pred))) (if (and (eq action nil) (assq (if (eq res t) string res) )) (cdr (assq (if (eq res t) string res) )) res))) should work OK for prefix completion, but that means using the expansion "by hand" rather than via expand-abbrev, which may not be an option. Stefan