Closed alternateved closed 2 years ago
Ah okay, @galeo already mentioned that. I don't know how to resolve this. It seems like an Emacs event handler bug. You can probably work around this by adding this single line to your config:
(global-set-key [cape--done] #'ignore)
Hi @alternateved,
I haven't paid attention to this problem recently. Could you try the following code to see if there is any improvement:
(defun cape--company-call (&rest app)
"Apply APP and handle future return values."
;; Backends are non-interruptible. Disable interrupts!
(let ((toi throw-on-input)
(throw-on-input nil))
(pcase (apply app)
;; Handle async future return values.
(`(:async . ,fetch)
(let ((res 'cape--waiting))
(unwind-protect
(progn
(funcall fetch (lambda (arg)
(when (eq res 'cape--waiting)
(push 'cape--done unread-command-events))
(setq res arg)))
;; Force synchronization.
(while (eq res 'cape--waiting)
;; When we've got input, interrupt the computation.
(when unread-command-events (throw toi nil))
(sit-for 0.5 'nodisplay)))
;; Remove cape--done introduced by future callback.
;; NOTE: `sit-for' converts cape--done to (t . cape--done).
;; It seems that `sit-for' does not use a robust method to
;; reinject inputs, maybe the implementation will change in
;; the future.
(setq unread-command-events
(delq 'cape--done
(delete '(t . cape--done)
unread-command-events))))
(and (consp res) res)))
;; Plain old synchronous return value.
(res res))))
Thanks.
@galeo Where is the difference? I don't see how your code is supposed to solve the issue.
@galeo Where is the difference? I don't see how your code is supposed to solve the issue.
Just increase the sit-for time to 0.5 seconds. I did some tests and no error reported as before.
This does not sound like an actual fix, it rather makes the issue less likely?
This does not sound like an actual fix, it rather makes the issue less likely?
Indeed. I can't find the cause and solution of the problem either. I also encountered serious hangs situation similar to @alternateved. The above adjustments is only useable.
I wonder what the problem is. The code is essentially equivalent to the Company synchronization code.
@minad solution did not work for me, so I decided to test the master version of Emacs (I was lagging behind a couple of weeks behind master). It is hard to verify it - I will know more in next days - but for now it seems that no hangs are happening with that latest version.
Okay, sorry, false alarm. It is still happening.
I pushed a commit which tries a different synchronization method. Does this lead to improvements?
The hangs are not grabbing me now - I just encounter errors from which I get out immediately. This is what appears in the *Messages*
buffer:
<cape--done> is undefined
r is undefined
So you might say it is a bit better, although screen flashing for no reason (visual-bell
) is a bit disturbing.
Did you try the newest commit?
I just tried the newest one. I tried to record when it happens but it seems that the gif recording skipped the frame where error flashed.
Nevertheless you could see that the <cape--done> is undefined
message still occurs.
Okay, no idea about this. It is also low priority for me. My interest in fighting against badly designed Emacs APIs is limited. It is unclear to me how cape--done can escape from the synchronization code.
Did you try to define cape--done as global key as proposed in my other comment?
That's understandable. Defining cape--done as global key seems to work now (with earlier commits it was hanging), so it is better now. Thank you a lot for help.
@alternateved Please give it another try without the global-set-key. I think I understood the issue now. The problem was that the future wasn't properly canceled.
Amazing! I think it works now.
In a quick test it still echo message like x cape--done
occasionally.
@minad From my last message:
In a quick test it still echo message like
x cape--done
occasionally.
I'm trying to solve this problem. It seems that set echo-keystrokes
to 0
can avoid echoing the unfinished commands.
diff --git a/cape.el b/cape.el
index 17e3e11..d449883 100644
--- a/cape.el
+++ b/cape.el
@@ -908,7 +908,9 @@ If INTERACTIVE is nil the function acts like a capf."
(push 'cape--done unread-command-events)
(setq res arg))))
(when (eq res 'cape--waiting)
- (let ((ev (let (input-method-function) (read-event nil t))))
+ (let ((ev (let (input-method-function
+ (echo-keystrokes 0))
+ (read-event nil t))))
(unless (eq ev 'cape--done)
(push (cons t ev) unread-command-events)
(setq res 'cape--cancelled)
Thanks.
Hello,
I think I might suffer from similar issue as in #23. I try to use company adapter with
psc-ide
and itscompany-psc-ide-backend
like so:The result of that is that something (most likely completion but there is no child frame popup) hangs every now and then - I have to manually exit process by
C-g
- then in the minibuffer I see the message:If there is anything else that I could provide that would be helpful, please let me know.