" retoor <retoor@molodetz.nl>
" Self-contained config for the ppy container. No external plugins or managers:
" it works out of the box with the stock vim, and the AI edit feature uses only
" curl and the PRAVDA_* gateway env that every instance is launched with.
set nocompatible
filetype plugin indent on
syntax on
set encoding=utf-8
set fileencoding=utf-8
set termencoding=utf-8
set mouse=a
set backspace=indent,eol,start
set autoindent
set smartindent
set tabstop=4
set shiftwidth=4
set expandtab
set number
set showmatch
set showtabline=2
set laststatus=2
set hidden
set incsearch
set hlsearch
set wildmenu
set ttimeoutlen=50
if has('clipboard')
set clipboard=unnamedplus
endif
if !isdirectory(expand('~/.vim/undo'))
call mkdir(expand('~/.vim/undo'), 'p')
endif
set undofile
set undodir=~/.vim/undo
set statusline=%f\ %h%m%r\ %=\ [%{&filetype}]\ [%l,%c]\ %p%%
highlight StatusLine cterm=bold ctermfg=15 ctermbg=24
highlight StatusLineNC cterm=none ctermfg=250 ctermbg=236
highlight ErrorMsg cterm=bold ctermfg=red ctermbg=none
let mapleader = ","
inoremap <C-n> <ESC>:tabnext<CR>
inoremap <C-p> <ESC>:tabprevious<CR>
nnoremap <C-n> :tabnext<CR>
nnoremap <C-p> :tabprevious<CR>
nnoremap <Tab> :tabnext<CR>
nnoremap <C-Tab> :tabprevious<CR>
nnoremap <C-e> :tabnew<Space>
inoremap <C-e> <ESC>:tabnew<Space>
if has('autocmd')
autocmd BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif
function! s:GetVisualSelection() abort
let [l:line_start, l:col_start] = [line("'<"), col("'<")]
let [l:line_end, l:col_end] = [line("'>"), col("'>")]
let l:lines = getline(l:line_start, l:line_end)
if empty(l:lines)
return ''
endif
let l:lines[-1] = l:lines[-1][: l:col_end - (l:line_start == l:line_end ? 1 : 2)]
let l:lines[0] = l:lines[0][l:col_start - 1 :]
return join(l:lines, "\n")
endfunction
function! s:GatewayUrl() abort
let l:base = substitute($PRAVDA_OPENAI_URL, '/\+$', '', '')
if empty(l:base)
return 'https://openai.app.molodetz.nl/v1/chat/completions'
elseif l:base =~# '/chat/completions$'
return l:base
endif
return l:base . '/chat/completions'
endfunction
function! AiEditSelection() abort
let l:instruction = input('AI instruction: ')
if empty(l:instruction)
echo 'Cancelled.'
return
endif
let l:orig = s:GetVisualSelection()
if empty(l:orig)
echo 'No selection.'
return
endif
let l:prompt = l:instruction . "\n\nHere is the text:\n" . l:orig
\ . "\n\nOutput only the transformed text. No explanations, markdown, or code blocks."
let l:api_key = !empty($PRAVDA_API_KEY) ? $PRAVDA_API_KEY : $DEEPSEEK_API_KEY
let l:json = '{"model":"deepseek-chat","messages":[{"role":"user","content":' . json_encode(l:prompt) . '}]}'
let l:cmd = 'curl -sS -X POST ' . shellescape(s:GatewayUrl())
\ . ' -H ' . shellescape('Authorization: Bearer ' . l:api_key)
\ . ' -H ' . shellescape('Content-Type: application/json')
\ . ' -d ' . shellescape(l:json)
let l:reply = system(l:cmd)
if v:shell_error
echohl ErrorMsg | echom 'AI request failed' | echohl None
return
endif
let l:text = matchstr(l:reply, '"content":\s*"\zs\(.\{-}\)\ze"\s*[,}]')
if empty(l:text)
echohl ErrorMsg | echom 'No content in AI response' | echohl None
return
endif
let l:text = substitute(l:text, '\\n', "\n", 'g')
let l:text = substitute(l:text, '\\"', '"', 'g')
let l:text = substitute(l:text, '\\t', "\t", 'g')
normal! gv
normal! c
call feedkeys(l:text, 'n')
endfunction
xnoremap <silent> <Leader>a :<C-u>call AiEditSelection()<CR>