view plugins/voicenote/voicenote.vim @ 22:c8ad85e95854 default tip

Some general updates
author Luka Sitas <lsitas@avatarasoftware.com>
date Thu, 16 Jul 2026 14:47:23 -0400
parents 203279635445
children
line wrap: on
line source

" Voicenote
" A very simple plugin for transcribing text and inserting it into vim at the
" cursor.
" Utilizes simple shell commands to record audio at the press of a key binding
" Then stops recording after another keybinding
" After recording sends the audio to an openai compatible audio transcription
" endpoint
" Finally parses the output and inserts the text at the cursor.

let g:record_job = -1
let g:record_job_running = -1
let g:record_file = ''


" Begin new recording.
function! StartRecording()
  " Check for already running recording.
  if g:record_job_running < 0
    let l:file = tempname()
    let g:record_file = l:file
    let g:record_job = job_start(['arecord', '-f', 'cd', '-r', '44100', l:file])
    let g:record_job_running = 1
  endif
endfunction

"  Stop the recording and transcribe.
function! StopRecording()
  " Check if we're already starting recording.
  if g:record_job_running > 0
	call StopAndWait(g:record_job)

	" Transcribe the text.
	let l:response = system('curl -s "http://127.0.0.1:52625/v1/audio/transcriptions" -F "model=whisper-v3" -F file=@' . g:record_file)
    if !empty(l:response)
      let l:data = json_decode(l:response)
      if has_key(l:data, 'text')
        execute 'normal! a' . escape(l:data.text, '\')
      endif
    endif

	" Clean up.
  	let g:record_job_running = -1
	let g:record_job = -1
    let g:record_file = '' 

  endif
endfunction

function! StopAndWait(job)
  " If the job is already dead, nothing to do
  if empty(a:job) || job_status(a:job) == 'dead'
    return
  endif

  " Request the job to stop
  call job_stop(a:job)

  " Wait until the status reports it as dead
  while job_status(a:job) != 'dead'
    sleep 100m   " adjust granularity if needed
  endwhile
endfunction

nnoremap <leader>s :call StartRecording()<CR>
nnoremap <leader>e :call StopRecording()<CR>