diff --git a/README.md b/README.md index f29e538..5483524 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ For more details about ECA, check [ECA server](https://github.com/editor-code-as - External `eca` server binary - Automatic downloaded if `eca-custom-command` is `nil` - Place it on your `$PATH` or customize `eca-custom-command` +- [whisper.el](https://github.com/natrys/whisper.el/blob/master/whisper.el) for Speech-to-Text support (optional) ## Installation @@ -43,6 +44,25 @@ M-x package-install eca 3. Type your prompt after the `> ` and press RET. 4. Attach more context auto completing after the `@`. +## Usage + +### Speech-to-Text support + +If you have [whisper.el](https://github.com/natrys/whisper.el/blob/master/whisper.el) installed you can use the `eca-chat-talk` +command (or use the `C-t` keybinding) to talk to the Editor Code +Assistant. This will record audio until you press `RET`. Then, the +recorded audio will be transcribed to text and placed into the chat +buffer. + +We recommend to use the `small`, it is a good trade-off between +accuracy and transcription speed. + +```elisp +(use-package whisper + :custom + (whisper-model "small")) +``` + ## Contributing Contributions are very welcome, please open a issue for discussion or pull request. diff --git a/eca-chat.el b/eca-chat.el index 5adaac7..788c61e 100644 --- a/eca-chat.el +++ b/eca-chat.el @@ -129,6 +129,7 @@ Must be a valid model supported by server, check `eca-chat-select-model`." (define-key map (kbd "S-") #'eca-chat--key-pressed-newline) (define-key map (kbd "S-") #'eca-chat--key-pressed-newline) (define-key map (kbd "C-k") #'eca-chat-clear) + (define-key map (kbd "C-t") #'eca-chat-talk) (define-key map (kbd "") #'eca-chat--key-pressed-return) map) "Keymap used by `eca-chat-mode'.") @@ -583,5 +584,36 @@ This is similar to `backward-delete-char' but protects the prompt/context line." (when-let* ((behavior (completing-read "Select a behavior:" (append (eca--session-chat-behaviors eca--session) nil) nil t))) (setq eca-chat-custom-behavior behavior))) +(declare-function whisper-run "ext:whisper" ()) + +;;;###autoload +(defun eca-chat-talk () + "Talk to the assistent by recording audio and transcribing it." + (interactive) + (unless (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)))) + (provide 'eca-chat) ;;; eca-chat.el ends here