minad / cape

🦸cape.el - Completion At Point Extensions
GNU General Public License v3.0
584 stars 20 forks source link

Error in `cape--company-call`: <cape--done> is undefined #23

Closed galeo closed 2 years ago

galeo commented 2 years ago

I am trying to use company-jedi (fetch completion candidates asynchronously) with cape-company-to-capf. It reports an error: <cape--done> is undefined.

After some digging, it turns out that the cape--done event added in the future callback are not removed from unread-command-events. The value of unread-command-events actually is ((t . cape--done)). I don't know why its value changed from (cape--done) to ((t . cape--done)).

https://github.com/minad/cape/blob/9db78299616bab3c601ace2bcab205c9fbff8dd0/cape.el#L895-L896

Simply changing the code (delq 'cape--done unread-command-events) to (delete (cons t 'cape--done) unread-command-events) can avoid this error. I'm just not clear why the value of unread-command-events changed.

Thanks.

minad commented 2 years ago

This is an Emacs bug. I think Company has observed the same issue.

minad commented 2 years ago

Simply changing the code (delq 'cape--done unread-command-events) to (delete (cons t 'cape--done) unread-command-events) can avoid this error.

We should keep the delq and add the delete on top. I think both cape--done and (t.cape--done) can occur.

galeo commented 2 years ago

We should keep the delq and add the delete on top. I think both cape--done and (t.cape--done) can occur.

👍

galeo commented 2 years ago

After 45fe322, it still reports the <cape--done> is undefined error, although unread-command-events is nil. I don't have enough time to check further now. I feel that the cape--done event added in the asynchronous callback was not removed in time before handling unread-command-events. Can we just ignore the interrupt handling when typing input? It may be similar to company--force-sync in company.

Thanks.

minad commented 2 years ago

Can we just ignore the interrupt handling when typing input? It may be similar to company--force-sync in company.

No. The interrupt handling should work as is. See company--fetch-candidates. Are we doing something differently?

EDIT: Turns out there was still an issue, since I used sit-for even in the case where synchronization should be forced in a noninterruptible way. This resulted in an expensive polling loop. But I am not sure if this actually caused the issue you are observing. Please try https://github.com/minad/cape/commit/3b019d5dea5346571926fa9d508a9879243be36a.

galeo commented 2 years ago

I've tried 3b019d5, the problem is still unresolved.