Skip to content

Conversation

@r0man
Copy link
Contributor

@r0man r0man commented Jun 25, 2025

This command uses whisper.el (if installed) to record audio until the user presses RET. The recorded audio will then be transcribed to text and placed into the chat buffer.

Open questions, things todo:

  • Is eca-chat-talk a good command name? Other options could be eca-chat-record, eca-chat-whisper, ....
  • The UX uses calls to message. Using the eca spinner would be better, but whipser.el itself uses message calls under the hood and I wasn't able to silence them (due to them being called in an async way in hooks).
  • Maybe we can collaborate with the whipser.el author to silence those message calls and move some of this code into whipser.el (could be useful for other modes).
  • A friend recommended me https://github.com/alphacep/vosk-api as an alternative to whipser, but I could not find an Emacs mode for it.

This command uses whisper.el (if installed) to record audio until the
user presses `RET`. The recorded audio will then be transcribed to
text and placed into the chat buffer.
eca-chat.el Outdated
(defun eca-chat-talk ()
"Talk to the assistent by recording audio and transcribing it."
(interactive)
(unless (featurep 'whisper)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be a if and do not execute the rest of the code if whisper is not installed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I would say calling this function (via M-x or the keybinding) without whisper.el installed is a user error and we should tell them what to do instead, no? I don't really mind, but I would not be silent about it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, agree, but my point is that the unless block is not wrapping the rest of the code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, so in my mind this is a guard, because user-error raises a condition. The code following it, won't be called. See: https://www.gnu.org/software/emacs/manual/html_node/elisp/Signaling-Errors.html

Here is a similar example from the CIDER code base:
https://github.com/r0man/cider/blob/aa8d638814d4f4da70e5f0fe5a9aec63eb6c5a8f/cider-clojuredocs.el#L195-L196

I could do an if/else branch like this if you prefer:

(defun eca-chat-talk ()
  "Talk to the assistent by recording audio and transcribing it."
  (interactive)
  (if (not (require 'whisper nil t))
      (user-error "Whisper.el is not available, please install it first")
    (eca-chat-open)
    (with-current-buffer (eca-chat--get-buffer)
      (goto-char (point-max)))
    (let ((buffer (get-buffer-create "*whisper-stdout*")))
      (with-current-buffer buffer
        (erase-buffer)
        (make-local-variable 'whisper-after-transcription-hook)
        (add-hook 'whisper-after-transcription-hook
                  (lambda ()
                    (let ((transcription (buffer-substring
                                          (line-beginning-position)
                                          (line-end-position))))
                      (with-current-buffer eca-chat-buffer-name
                        (insert transcription)
                        (newline)
                        (eca-chat--key-pressed-return))))
                  nil t)
        (whisper-run)
        (eca-info "Recording audio. Press RET when you are done.")
        (while (not (equal ?\r (read-char)))
          (sit-for 0.5))
        (whisper-run)))))

Wdyt?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh makes sense, forgot about this behavior of error.

@r0man
Copy link
Contributor Author

r0man commented Jun 26, 2025

I added 2 more commits:

  • I use require with the no-error option to actually load whipser if it isn't loaded yet. featurep didn't do that
  • I added an autoload cookie to the command

@ericdallo
Copy link
Member

Looks good!

@ericdallo ericdallo merged commit 36aa793 into editor-code-assistant:master Jun 26, 2025
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants