なんかいろいろエンコード/デコードする operator を提供するプラグイン

~/.vim/plugin とかに入れて,例えば

nmap <Leader>eu <Plug>encodeURIComponent
vmap <Leader>eu <Plug>encodeURIComponent
nmap <Leader>du <Plug>decodeURIComponent
vmap <Leader>du <Plug>decodeURIComponent
nmap <Leader>ej <Plug>encodeJSString
vmap <Leader>ej <Plug>encodeJSString
nmap <Leader>dj <Plug>decodeJSString
vmap <Leader>dj <Plug>decodeJSString

こんなかんじに設定し,「はやてちゃん」上で euiw とすると「%E3%81%AF%E3%82%84%E3%81%A6%E3%81%A1%E3%82%83%E3%82%93」になったり,ejiw とすると「\u306f\u3084\u3066\u3061\u3083\u3093」になったりする.
本当は

function! s:define_operator(keymap, func)
  function! l:op(type)
    let sel_save = &selection
    let &selection = 'inclusive'
    let reg_save = @@

    call s:select(a:type)
    silent execute "normal! c\<C-r>=" . a:func . "(@@)\<Esc>"

    let &selection = sel_save
    let @@ = reg_save
  endfunction

  execute 'nnoremap <silent> <Plug>' . a:keymap . ' :<C-u>set opfunc=l:op<CR>g@'
  execute 'vnoremap <silent> <Plug>' . a:keymap . ' :<C-u>call l:op(visualmode())<CR>'
endfunction

s:define_operator('encodeURIComponent', '<SID>encodeURIComponent')
s:define_operator('decodeURIComponent', '<SID>decodeURIComponent')
s:define_operator('encodeJSString', '<SID>encodeJSString')
s:define_operator('decodeJSString', '<SID>decodeJSString')

こんな風に書きたいんだけど,l:op 内で a:func が定義されていなくてエラー.
何かいい方法はないだろうか.