Skip to content

Instantly share code, notes, and snippets.

@Konfekt
Last active March 13, 2025 14:36
Show Gist options
  • Select an option

  • Save Konfekt/5748fbe2d72749ab9b2ea8362f703a7e to your computer and use it in GitHub Desktop.

Select an option

Save Konfekt/5748fbe2d72749ab9b2ea8362f703a7e to your computer and use it in GitHub Desktop.
Vim commands to pipe text to aichat and open a chat window; use AIChatAppend/Replace/Session to append / replace text or open a terminal session; pass a role by appending s slash, say `AIChatReplace /coder`. Consider abbreviating commands with https://github.com/Konfekt/vim-alias
if !executable('aichat') | finish | endif
function! s:ProcessInstruction(instruction) abort
let instruction = trim(a:instruction)
if instruction[0] ==# '/'
let i = match(instruction..' ', '\s')
if i > 1
" Extract the role and the remaining instruction
let role = instruction[1:i-1]
let instruction = trim(instruction[i:-1])
else
echoerr "Invalid role specification"
return [v:false, '', '']
endif
else
let role = ''
endif
let prompt = !empty(instruction) ? '"Please consider: '..instruction..'."' : ''
return [v:true, role, prompt]
endfunction
command! -bang -range -nargs=? -complete=customlist,s:AIChatRoleCompletion AIChatWrite <line1>,<line2>call s:AIChatWrite(<q-args>, <bang>0)
function! s:AIChatWrite(instruction, pad) range abort
let [valid, role, prompt] = s:ProcessInstruction(a:instruction)
if !valid | return | endif
silent let output = systemlist('aichat --no-stream'
\ ..(!empty(role) ? ' --role='..role : '')
\ ..' -- '..prompt,
\ getline(a:firstline, a:lastline))
if a:pad
" See https://github.com/habamax/vim-shout/issues/3#issuecomment-2053559665
" for a stable scratch buffer
if bufexists('AICHAT')
vsplit AICHAT
else
vnew | file AICHAT
setlocal buftype=nofile nobuflisted noswapfile filetype=markdown
endif
call append(line('$'), output)
else
call append(a:lastline, [''] + output)
endif
endfunction
command! -range -nargs=? -complete=customlist,s:AIChatRoleCompletion AIChatReplace <line1>,<line2>call s:AIChatReplace(<q-args>)
function! s:AIChatReplace(instruction) range abort
let [valid, role, prompt] = s:ProcessInstruction(a:instruction)
if !valid | return | endif
exe a:firstline.','.a:lastline '!aichat --no-stream'
\ (!empty(role) ? ' --role='..role : '')
\ '--' prompt
endfunction
command! -range=0 -nargs=? -complete=customlist,s:AIChatRoleCompletion AIChatSession <line1>,<line2>call s:AIChatSession(<count>, <q-args>)
function! s:AIChatSession(range, instruction) range abort
let [valid, role, prompt] = s:ProcessInstruction(a:instruction)
if !valid | return | endif
if !empty(role) && !empty(prompt)
" See https://github.com/sigoden/aichat/issues/1007
echoerr "Specify either role or prompt, not both!"
return
endif
exe 'tab'
\ (a:range == 0 || has('nvim') ? '' : a:firstline.','.a:lastline)
\ 'term' (has('nvim') ? '' : (a:range == 0 ? '++close' : '') .. ' ++rows='..&lines)
\ 'aichat --session'
\ (!empty(role) ? ' --role='..role : (!empty(prompt) ? ' --prompt='..prompt : ''))
\ '--'
endfunction
function! s:AIChatRoleCompletion(A,L,P) abort
silent let roles = systemlist('aichat --list-roles')
if a:A !~# '^/'
return []
else
call map(roles, '"/"..v:val')
return filter(roles, 'v:val =~ "^'..a:A..'"')
endif
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment