79 dicwin2.vim (5-4) 関連項目に飛べるようにした

辞書引きプラグイン dicwin2.vim の話題。

「メモ」なんかで検索すると分かるんだけど、これじゃないよって結果になることがままあった。関連項目とそのURLへ飛べるようにすることでカバーすることにした。

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 r = get(matchlist(s, '結果内容-->\(\_.\{-}\)<!--/結果内容'), 1, '')
  let rs = split(substitute(r, '\%(\r\|\n\)', '', 'g'), '</table>')
  let rs = map(rs, 'matchstr(v:val, ''<a.\{-}>\_.\{-}</a>'')')
  let pat = '^.*href="\(.\{-}\)".\{-}>\(.*\)</a>$'
  let rs = map(rs, 'substitute(v:val, pat, ''\2:\1'', "")')
  let r = join(rs, "\n")
  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, 'relation': r}
  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
  if !&previewwindow | return | endif
  silent! nnoremap <unique> <silent> <buffer> <CR>
        \ :call AL_open_url(matchstr(getline('.'), 'https\?://\S\+'), '')<CR>
  let s = result['title'] . "\n" . result['description'] . "\n" . url . "\n\n"
  let s .= get(result, 'relation', '')
  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

正直強引な対応。HTMLにおけるリンクぽいものをVim上で実現するのって割と面倒だな。タグまわりの機能を使って簡単にできないのかな。あんまり詳しくないからわからない。

[news]今日の新聞

  • 朝一面:反戦ビラ配布 処罰合憲 「表現の自由」違反せず 最高裁、上告棄却。ビラ配布が居住者を平穏に生活する権利を侵害するかや、表現の自由を萎縮するなどの点で注目すべきらしい。
  • 朝一面:タイヤ脱落 固定ボルトが全損 整備状況 国交省調査へ 構造の問題も視野。静岡県東名高速道路で、トラックのタイヤが脱落し、対向車線を走っていた観光バスに直撃、運転手が死亡したらしい。
  • 社説:猟銃規制。思っている以上に許可を受けた銃での事件が多いことなどにふれ、もっと管理を考えるべきだとまとめ。
  • 社説:メタボ検診。腹囲の測定はあくまで目安、もっと自覚させるような取り組みが必要とのこと。

[diary]基本日記(7.5-)

01:30-09:00。09:30-11:00。12:30-14:00。殺害任務。資格試験(変な試験)。

トースト
バナナスティックパン
コーンクリームシチューを二杯

夕食のシチューは、はじめ母が作っていたが、途中から僕が作った。自分で作るとうまい。