natrys / whisper.el

Speech-to-Text interface for Emacs using OpenAI's whisper model and whisper.cpp as inference engine.
140 stars 10 forks source link

Temporarily disabling `whisper-insert-text-at-point` #27

Closed NightMachinery closed 2 months ago

NightMachinery commented 2 months ago

@natrys I am trying to define a command that opens a temp buffer:

(defun night/whisper-run-tmp ()
    (interactive)
    (let ((whisper-insert-text-at-point nil))
      (whisper-run)))

But this does not work?

[*] Recording audio
[-] Transcribing/Translating audio
error in process sentinel: Wrong type argument: stringp, nil [2 times]
natrys commented 2 months ago

Yeah dynamic bindings basically doesn't work in any kind of asynchronous elisp code where you have to register a callback function to run later to the event loop. Basically, dynamic binding is only valid for the current context of execution. But in asynchronous code, the current context finishes immediately. What you have is a piece of code registered for future when some event will happen later, but by then the current context is dead and event loop will run that code in a new context where the dynamic binding is no longer valid, hence it fallbacks to global value.

Vast majority of elisp isn't doing anything with asynchronous code so dynamic binding just works. But here we necessarily need to use make-process, and as far as I can tell through experimentation with other such APIs like run-with-timer, this will break dynamic binding.

Anyway what you want is still doable, it's just going to be incredibly ugly. Something like:

(defun night/whisper-run-tmp ()
  (interactive)
  (setq whisper-insert-text-at-point nil)
  (whisper-run)
  (add-hook 'whisper-after-insert-hook #'night/revert-whisper-insert-text-at-point))

(defun night/revert-whisper-insert-text-at-point ()
  (unless whisper-insert-text-at-point
    (setq whisper-insert-text-at-point t))
  (remove-hook 'whisper-after-insert-hook #'night/revert-whisper-insert-text-at-point))