Source

frawor / plugin / frawor / checks.vim

"▶1 Header
scriptencoding utf-8
if exists('s:_pluginloaded') || exists('g:fraworOptions._donotload') ||
            \exists('g:frawor__donotload')
    finish
endif
execute frawor#Setup('0.0', {'@/fwc': '0.0',
            \          '@/functions': '0.0'}, 1)
"▶1 _messages
if v:lang=~?'ru'
    let s:_messages={
                \'uchecker': 'Ошибка создания проверки для дополнения %s: '.
                \            'аргумент, описывающий проверку, '.
                \            'не принадлежит ни к одному из известных типов',
                \'chkncall': 'Ошибка создания проверки для дополнения %s: '.
                \            'проверочная функция не может быть вызвана '.
                \            '(возможно вы использовали ссылку на внутренную '.
                \            'функцию дополнения без раскрытия «s:» '.
                \            'в «<SNR>_{SID}»?)',
                \ 'ufilter': 'Ошибка создания фильтра для дополнения %s: '.
                \            'аргумент, описывающий фильтр, '.
                \            'не принадлежит ни к одному из известных типов',
                \'filncall': 'Ошибка создания фильтра для дополнения %s: '.
                \            'проверочная функция не может быть вызвана '.
                \            '(возможно вы использовали ссылку на внутренную '.
                \            'функцию дополнения без раскрытия «s:» '.
                \            'в «<SNR>_{SID}»?)',
                \'idnotstr': 'Ошибка при обработке запроса на удаление от '.
                \            'дополнения %s: идентификатор не является строкой',
            \}
else
    let s:_messages={
                \'uchecker': 'Error while creating checker for plugin %s: '.
                \            'unknown check description type',
                \'chkncall': 'Error while creating checker for plugin %s: '.
                \            '(perhaps you tried to use a reference to '.
                \            'a script-local function without replacing `s:'' '.
                \            'with `<SNR>_{SID}'')',
                \ 'ufilter': 'Error while creating filter for plugin %s: '.
                \            'unknown filter description type',
                \'filncall': 'Error while creating filter for plugin %s: '.
                \            '(perhaps you tried to use a reference to '.
                \            'a script-local function without replacing `s:'' '.
                \            'with `<SNR>_{SID}'')',
                \'idnotstr': 'Error while processing delete request from '.
                \            'plugin %s: ID is not a string',
            \}
endif
"▶1 conschecker feature
let s:checkers={'lastid': 0}
"▶2 conschecker  :: {f}, checker → chkfunc + s:checkers
function s:F.conschecker(plugdict, fdict, Chk)
    let id=printf('%x', s:checkers.lastid)
    call add(a:fdict.ids, id)
    let s:checkers.lastid+=1
    if type(a:Chk)==2
        if !exists('*a:Chk')
            call s:_f.throw('chkncall', a:plugdict.id)
        endif
        return a:Chk
    else
        call s:_f.throw('uchecker', a:plugdict.id)
    endif
endfunction
"▶2 delcheckers  :: {f} → + s:checkers
function s:F.delcheckers(plugdict, fdict)
    for id in filter(a:fdict.ids, 'has_key(s:checkers, v:val)')
        unlet s:checkers[id]
    endfor
endfunction
"▶2 Register feature
call s:_f.newfeature('conschecker', {'cons': s:F.conschecker,
            \                      'unload': s:F.delcheckers,
            \                        'init': {'ids': []}})
"▶1 consfilter feature
let s:filters={'lastid': 0}
"▶2 consfilter  :: {f}, filter → filfunc + s:filters
function s:F.consfilter(plugdict, fdict, Fil)
    let id=printf('%x', s:filters.lastid)
    call add(a:fdict.ids, id)
    let s:filters.lastid+=1
    if type(a:Fil)==2
        if !exists('*a:Fil')
            call s:_f.throw('filncall', a:plugdict.id)
        endif
        return a:Fil
    else
        call s:_f.throw('ufilter', a:plugdict.id)
    endif
endfunction
"▶2 delfilters  :: {f} → + s:filters
function s:F.delfilters(plugdict, fdict)
    for id in a:fdict.ids
        unlet s:filters[id]
    endfor
endfunction
"▶2 Register feature
call s:_f.newfeature('consfilter', {'cons': s:F.consfilter,
            \                     'unload': s:F.delfilters,
            \                       'init': {'ids': []}})
"▶1 Decorators: checker and filter
let s:F.de={}
"▶2 checker
function s:F.de.checker(plugdict, fname, Arg)
    let throwargs="'".a:fname."', ".
                \substitute(string(a:plugdict.id), "\n", '''."\\n".''', 'g')
    return [128, '@@@', a:plugdict.g._f.conschecker(a:Arg),
                \['if !@%@(@@@)',
                \     'call s:_f.throw("checkfailed", '.throwargs.')',
                \ 'endif',], [], 0]
endfunction
call s:_f.adddecorator('checker', s:F.de.checker)
"▶2 filter
function s:F.de.filter(plugdict, fname, Arg)
    let throwargs="'".a:fname."', ".
                \substitute(string(a:plugdict.id), "\n", '''."\\n".''', 'g')
    return [64, 'args', a:plugdict.g._f.consfilter(a:Arg),
                \['let args=@%@(@@@)',
                \ 'if type(args)!='.type([]),
                \ '    call s:_f.throw("filterfailed", '.throwargs.')',
                \ 'endif',], [], 0]
endfunction
call s:_f.adddecorator('filter', s:F.de.filter)
"▲2
unlet s:F.de
"▶1
call frawor#Lockvar(s:, 'checkers,filters')
" vim: fmr=▶,▲ sw=4 ts=4 sts=4 et tw=80