author |
Steve Losh <steve@stevelosh.com> |
date |
Thu, 14 Jul 2016 22:45:37 +0000 |
parents |
c0b7ab63d895 |
children |
122228d53e7a |
" TODO:
" fix showmode awfulness
" Disassembly mapping
" error handling
" multi-packet messages
"
if !exists("g:ooze_connection")
let g:ooze_connection = 0
endif
function! s:IsString(a) " {{{
return type(a:a) == 1
endfunction " }}}
function! s:GetString(msg, key, extra) " {{{
let val = get(a:msg, a:key)
if s:IsString(val)
return val . a:extra
else
return ''
endif
endfunction " }}}
let g:ooze_scratch_buffer_name = '__OozeScratch__'
function! s:OpenOozeScratch(contents) " {{{
if bufname('%') != g:ooze_scratch_buffer_name
wincmd s
execute "edit " . g:ooze_scratch_buffer_name
endif
set filetype=lisp
setlocal foldlevel=99
setlocal buftype=nofile
setlocal bufhidden=hide
setlocal noswapfile
setlocal buflisted
setlocal noreadonly
normal! ggdG
call append(0, a:contents)
setlocal readonly
endfunction " }}}
function! s:HandleMessage(msg) " {{{
let moutput = s:GetString(a:msg, 'macroexpand-1', "")
if moutput != ''
call s:OpenOozeScratch(split(moutput, "\n"))
return
endif
let output = ''
let output .= s:GetString(a:msg, 'stdout', "")
let output .= s:GetString(a:msg, 'stderr', "")
let output .= s:GetString(a:msg, 'value', "")
let output .= s:GetString(a:msg, 'error', "\n\n")
let output .= s:GetString(a:msg, 'original', "\n\n")
let output .= s:GetString(a:msg, 'backtrace', "\n")
let output .= s:GetString(a:msg, 'function-arglist', "\n\n")
let output .= s:GetString(a:msg, 'function-docstring', "\n")
if output != ''
echo substitute(output, '\n\+$', '', '')
endif
endfunction " }}}
function! s:HandleData(data) " {{{
for msg in bencode#BdecodeAll(a:data)
call s:HandleMessage(msg)
endfor
endfunction " }}}
" NeoVim job-handling {{{
silent! function s:JobHandler(job_id, data, event) " {{{
if a:event == 'stdout'
call s:HandleData(join(a:data, "\n"))
elseif a:event == 'stderr'
1
else
1
endif
endfunction " }}}
let s:callbacks = {
\ 'on_stdout': function('s:JobHandler'),
\ 'on_stderr': function('s:JobHandler'),
\ 'on_exit': function('s:JobHandler')
\ }
function! OozeSendMessage(msg)
if !g:ooze_connection
throw "Not connected!"
endif
try
call jobsend(g:ooze_connection, bencode#Bencode(a:msg))
catch /E900/
echo "Ooze connection died!"
let g:ooze_connection = 0
endtry
endfunction!
" }}}
function! s:FindPackage() " {{{
let view = winsaveview()
let package = ''
call cursor(1, 1)
if search('\v^\(in-package>\s*(\n\s*)?.', 'e', 40)
execute "normal v\<plug>(sexp_inner_element)"
let old_z = @z
normal! "zy
let package = @z
let @z = old_z
endif
call winrestview(view)
return package
endfunction " }}}
function! OozeDisconnect() " {{{
if g:ooze_connection
call jobstop(g:ooze_connection)
let g:ooze_connection = 0
endif
endfunction " }}}
function! OozeConnectToPort(port) " {{{
if g:ooze_connection
call OozeDisconnect()
endif
let g:ooze_connection = jobstart(['nc', 'localhost', a:port], s:callbacks)
endfunction " }}}
function! OozeConnect() " {{{
call OozeConnectToPort('8675')
endfunction " }}}
function! OozeMacroexpand(form) " {{{
let msg = {"op": "macroexpand", "form": a:form}
let package = s:FindPackage()
if package != ""
let msg["in-package"] = package
endif
call OozeSendMessage(msg)
endfunction " }}}
function! OozeMacroexpandSelection() " {{{
let z = @z
normal! gv"zy
call OozeMacroexpand(@z)
let @z = z
endfunction " }}}
function! OozeDocument(symbol) " {{{
let msg = {"op": "documentation", "symbol": a:symbol}
let package = s:FindPackage()
if package != ""
let msg["in-package"] = package
endif
call OozeSendMessage(msg)
endfunction " }}}
function! OozeDocumentSelection() " {{{
let z = @z
normal! gv"zy
call OozeDocument(@z)
let @z = z
endfunction " }}}
function! OozeDocumentFormHead() " {{{
let view = winsaveview()
execute "normal v\<plug>(sexp_inner_list)o\<plug>(sexp_inner_element)"
call OozeDocumentSelection()
call winrestview(view)
endfunction " }}}
function! OozeArglist(symbol) " {{{
if !g:ooze_connection
return
endif
let msg = {"op": "arglist", "symbol": a:symbol}
let package = s:FindPackage()
if package != ""
let msg["in-package"] = package
endif
set noshowmode
call OozeSendMessage(msg)
endfunction " }}}
function! OozeArglistSelection() " {{{
let z = @z
normal! gv"zy
call OozeArglist(@z)
let @z = z
endfunction " }}}
function! OozeArglistFormHead() " {{{
if synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") == "Comment"
" bail if we're in a comment
" TODO: make this suck less
return
endif
let view = winsaveview()
execute "normal v\<plug>(sexp_inner_list)o\<plug>(sexp_inner_element)"
call OozeArglistSelection()
call winrestview(view)
endfunction " }}}
function! OozeEval(code) " {{{
let msg = {"op": "eval", "code": a:code}
let package = s:FindPackage()
if package != ""
let msg["in-package"] = package
endif
call OozeSendMessage(msg)
endfunction " }}}
function! OozeEvalSelection() " {{{
let z = @z
normal! gv"zy
call OozeEval(@z)
let @z = z
endfunction " }}}
function! OozeLoad(path) " {{{
let msg = {"op": "load-file", "path": a:path}
call OozeSendMessage(msg)
endfunction " }}}
function! OozeLoadCurrent() " {{{
call OozeLoad(expand('%:p'))
endfunction " }}}
function! OozeSelectTopLevelForm() " {{{
execute "normal v\<Plug>(sexp_outer_top_list)"
endfunction " }}}
function! OozeHyperspec(symbol) " {{{
vnew
call termopen('clhs ' . a:symbol)
normal! a
endfunction " }}}
function! OozeHyperspecForm() " {{{
let view = winsaveview()
let z = @z
execute "normal v\<plug>(sexp_inner_element)o\<plug>(sexp_inner_element)"
normal! gv"zy
call OozeHyperspec(@z)
let @z = z
call winrestview(view)
endfunction " }}}
function! OozeMapKeys() " {{{
nnoremap <buffer> <localleader>C :call OozeConnect()<cr>
nnoremap <buffer> <localleader>K :call OozeDisconnect()<cr>
nnoremap <buffer> <localleader>h :call OozeHyperspecForm()<cr>
nnoremap <buffer> <localleader>H :call OozeHyperspec(input("? "))<cr>
nnoremap <buffer> <localleader>E :call OozeEval(input("? "))<cr>
vnoremap <buffer> <localleader>e :<c-u>call OozeEvalSelection()<cr>
nnoremap <buffer> <localleader>e mz:call OozeSelectTopLevelForm()<cr>:<c-u>call OozeEvalSelection()<cr>`z
nnoremap <buffer> <localleader>f mzvab:<c-u>call OozeEvalSelection()<cr>`z
nnoremap <buffer> <localleader>D :call OozeDocument(input("? "))<cr>
" nnoremap <buffer> <localleader>d mzviw:<c-u>call OozeDocumentSelection()<cr>`z
inoremap <buffer> <silent> <c-d> <c-o>:<c-u>call OozeDocumentFormHead()<cr>
inoremap <buffer> <silent> <space> <esc>:<c-u>call OozeArglistFormHead()<cr>a<c-v><space>
nnoremap <buffer> M mzviw:<c-u>call OozeDocumentSelection()<cr>`z
nnoremap <buffer> <localleader>M :call OozeMacroexpand(input("? "))<cr>
nnoremap <buffer> <localleader>m mzvab:<c-u>call OozeMacroexpandSelection()<cr>`z
nnoremap <buffer> <localleader>r :call OozeLoadCurrent()<cr>
endfunction " }}}
augroup ooze_dev " {{{
au!
autocmd BufWritePost ooze.vim source %
augroup END " }}}
augroup ooze_showmode_save
au!
" We save showmode around insert mode because the arglist command needs
" to disable it.
au InsertEnter * :let g:ooze_save_showmode=&showmode
au InsertLeave * :let &showmode=g:ooze_save_showmode
augroup END