77 dicwin2.vim (5-3) pedit コマンドで表示するようにした
昨日、一昨日あたりから書いている「辞書引きプラグイン」。pedit で表示するようにしたのが、今日の主な変更点。
substitute() の \= は便利
alice.vim の AL_urlencode() を参考に修正してみた。AL_urlencode() から学んだ一番大きいことが \= だ。 substitute() の sub-replaced-special の一つで sub-replace-expression というものらしい。詳しくはヘルプを参照してほしい。一文字ずつスクリプトローカル変数 strpart2() で回していたのを、substitute() 一つに収めることができた。
1バイトずつなら char2nr() は encoding に影響されない
他に学んだことといえば、1バイトずつ char2nr() するとき、 encoding の値が結果に影響しないということ。iconv() で変換したら、あとは1バイトずつ処理さえすれば encoding を考慮する必要はない。
で、今回の修正点は
修正点としては、「pedit コマンドを使用するようにしたこと」と「上記の二点を反映して全体的にコードをシンプルにしたこと」と「簡単なメッセージを表示するようにしたこと」と「古い側のマッピング \dy を削除し、\dY に割り当てていたものを \dy に割り当てた」この四点だ。
以下はそのコード。
function! s:YahooKokugo(html) let s = iconv(a:html, 'utf-8', &enc) let s = get(matchlist(s, '<body\>\_.\{-}>\(\_.*\)</body>'), 1, '') let s = get(matchlist(s, '<div id="contents">\(\_.*\)</div>'), 1, '') let s = get(matchlist(s, '<div align="center">\(\_.*\)</div>'), 1, '') let s = get(matchlist(s, '<td valign="top">\(\_.*\)</td>'), 1, '') let t = get(matchlist(s, '<b>\(.\{-}\)</b>'), 1, '') let s = get(matchlist(s, '<table\(\_.\{-}\)</table>', 0, 3), 1, '') let d = get(matchlist(s, '<td>\(.\{-}\)</td>'), 1, '') let d = substitute(d, '<br\s*/\{0,1}>', "\n", 'g') let t = substitute(t, '<.\{-}>', '', 'g') let d = substitute(d, '<.\{-}>', '', 'g') if t == '' || d == '' return {} else return {'title': t, 'description': d} endif endfunction let g:dicwin2_dict = { \ 'encoding': 'utf-8', \ 'url': \ 'http://dic.yahoo.co.jp/dsearch?enc=UTF-8&stype=0&dtype=0&p=%keyword%', \ 'parser': function('s:YahooKokugo') \ } silent! nnoremap <unique> <silent> \dy :call <SID>dicwin2()<CR> function! s:dicwin2() let dict = g:dicwin2_dict let cmd = 'curl "%URL%"' if type(dict) != type({}) || \ !has_key(dict, 'encoding') || \ !has_key(dict, 'url') || \ !has_key(dict, 'parser') echohl WarningMsg redraw | echo printf("dicwin2: '%s' is invalid", 'dicwin2_dict') echohl None return endif let keyword = expand('<cword>') let kw_enc = iconv(keyword, &encoding, dict['encoding']) let kw_enc = s:encodeURIComponent2(kw_enc) let kw_enc = iconv(kw_enc, dict['encoding'], &encoding) let url = s:replace(dict['url'], '%keyword%', kw_enc) let cmd = s:replace(cmd, '%URL%', url) redraw | echo 'dicwin2: searching...' let html = system(cmd) redraw | echo 'dicwin2: parsing...' let result = call(dict['parser'], [html]) if type(result) != type({}) || \ !has_key(result, 'title') || \ !has_key(result, 'description') echohl WarningMsg redraw | echo printf("dicwin2: '%s' is not found", keyword) echohl None return endif pclose silent! pedit +set\ noswapfile\ buftype=nofile dicwin2 wincmd P let s = result['title'] . "\n" . result['description'] " url . "\n\n" . silent! put =s normal ggdd wincmd p redraw! endfunction function! s:char2hex(c) if a:c =~# '^[:cntrl:]$' | return '' | endif let r = '' for i in range(strlen(a:c)) let r .= printf('%%%02X', char2nr(a:c[i])) endfor return r endfunction function! s:encodeURIComponent2(s) return substitute(a:s, '[^0-9A-Za-z-._~!''()*]', \ '\=s:char2hex(submatch(0))', 'g') endfunction function! s:encodeURI2(s) return substitute(a:s, '[^0-9A-Za-z-._~!''()*#$&+,/:;=?@]', \ '\=s:char2hex(submatch(0))', 'g') endfunction function! s:replace(s, t, r) return substitute(a:s, '\C\V' . escape(a:t, '\'), escape(a:r, '&~\'), 'g') endfunction