Skip to content

Instantly share code, notes, and snippets.

@rbtnn
Created January 13, 2014 05:17
Show Gist options
  • Save rbtnn/8395118 to your computer and use it in GitHub Desktop.
Save rbtnn/8395118 to your computer and use it in GitHub Desktop.
call s:S.define('Assert',expand("<sfile>"),1)
let s:save_cpo = &cpo
set cpo&vim
function! s:_vital_loaded(V)
let s:assert_config = {
\ 'equal_separator' : ['<=>','<=>'],
\ 'not_equal_separator' : ['<!>','<!>'],
\ 'enable' : 1,
\ }
let s:V = a:V
let s:L = s:V.import('Text.Lexer')
let s:lexer_obj = s:L.lexer([
\ s:assert_config.equal_separator,
\ s:assert_config.not_equal_separator,
\ ['scriptfunc', 's:[0-9a-zA-Z_]\+'],
\ ['ident', '[0-9a-zA-Z_]\+'],
\ ['ws', '\s\+'],
\ ['d_string', '"\(\\.\|[^"]\)*"'],
\ ['s_string', '''\(''''\|[^'']\)*'''],
\ ['otherwise', '.']
\ ])
endfunction
function! s:_vital_depends()
return ['Text.Lexer']
endfunction
function! s:_outputter(dict)
if ! a:dict.is_success
echohl Error
endif
echo printf("%s %s :%s",
\ a:dict.cmd,
\ a:dict.expr,
\ (a:dict.is_success ? 'Succeeded' : 'Failed'),
\ )
if ! a:dict.is_success
echo printf("> assert_point: %s", a:dict.assert_point)
echo printf("> lhs: %s", a:dict.lhs)
echo printf("> rhs: %s", a:dict.rhs)
echohl None
throw 'vital: Assertion: EXIT_FAILURE'
endif
endfunction
function! s:_redir(cmd)
let oldverbosefile = &verbosefile
try
set verbosefile=
redir => res
silent! execute a:cmd
redir END
finally
let &verbosefile = oldverbosefile
endtry
return res
endfunction
function! s:_define_scriptfunction( fname, assert_point)
let scriptnames_list = map(split(s:_redir('scriptnames'),"\n"),'matchlist(v:val,''^\s*\(\d\+\)\s*:\s*\(.*\)\s*$'')[:2]')
let target = []
for m in scriptnames_list
if tr(fnamemodify(get(m,2,''),':p'),'\','/') =~# tr(fnamemodify(a:assert_point,':p'),'\','/')
let target = m
endif
endfor
if ! empty(target)
if exists(printf("*<SNR>%d_%s", target[1], a:fname[2:]))
execute printf('let %s = function(%s)',a:fname,string(printf("<SNR>%d_%s",target[1],a:fname[2:])))
endif
endif
endfunction
function! s:_assertion( q_args, local, assert_point, cmd)
let s:_local = {}
for s:_local.key in keys(a:local)
execute printf('let %s = %s',s:_local.key,string(a:local[s:_local.key]))
endfor
if s:assert_config.enable
let s:_local.tkns = s:lexer_obj.exec(a:q_args)
let s:_local.is_lhs = 1
let s:_local.is_not = 0
let s:_local.lhs_tkns = []
let s:_local.rhs_tkns = []
for s:_local.tkn in s:_local.tkns
if s:_local.is_lhs && s:_local.tkn.label is s:assert_config.equal_separator[0]
let s:_local.is_lhs = 0
let s:_local.is_not = 0
elseif s:_local.is_lhs && s:_local.tkn.label is s:assert_config.not_equal_separator[0]
let s:_local.is_lhs = 0
let s:_local.is_not = 1
elseif s:_local.is_lhs
let s:_local.lhs_tkns += [s:_local.tkn]
else
let s:_local.rhs_tkns += [s:_local.tkn]
endif
if s:_local.tkn.label is# 'scriptfunc'
call s:_define_scriptfunction(s:_local.tkn.matched_text, a:assert_point)
endif
endfor
let s:_local.lhs_text = join(map(s:_local.lhs_tkns ,'v:val.matched_text'),'')
let s:_local.rhs_text = join(map(s:_local.rhs_tkns ,'v:val.matched_text'),'')
let s:_local.is_success = 0
if type("") is type(eval(s:_local.lhs_text))
let s:_local.is_success = eval(s:_local.lhs_text) is# eval(s:_local.rhs_text)
else
let s:_local.is_success = eval(s:_local.lhs_text) is eval(s:_local.rhs_text)
endif
let s:_local.is_success = s:_local.is_not ? ! s:_local.is_success : s:_local.is_success
call s:_outputter({
\ 'config' : copy(s:assert_config),
\ 'cmd' : a:cmd,
\ 'is_not' : s:_local.is_not,
\ 'is_success' : s:_local.is_success,
\ 'lhs' : s:_local.lhs_text,
\ 'rhs' : s:_local.rhs_text,
\ 'expr' : a:q_args,
\ 'assert_point' : a:assert_point,
\ })
endif
endfunction
function! s:define(cmd_name,assert_point,...)
let enable_assert = (0 < len(a:000)) ? a:1 : 0
if enable_assert
execute 'command! -buffer -nargs=1 ' . a:cmd_name . ' call s:_assertion(<q-args>,(exists(''l:'')?eval(''l:''):{}), ''' . tr(a:assert_point,'\','/') . ''', ' . string(a:cmd_name) . ')'
else
execute 'command! -buffer -nargs=1 '.a:cmd_name
endif
endfunction
function! s:set_config(config)
" TODO
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set ts=2 sts=2 sw=2 ft=vim fdm=indent ff=unix expandtab:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment