|
| 1 | +" vim:set ts=8 sts=2 sw=2 tw=0: |
| 2 | +" |
| 3 | +" googletranslate.vim - Translate between English and Locale Language |
| 4 | +" using Google |
| 5 | +" @see [http://code.google.com/apis/ajaxlanguage/ Google AJAX Language API] |
| 6 | +" |
| 7 | +" Author: Yasuhiro Matsumoto <[email protected]> |
| 8 | +" Contribute: hotoo (闲耘™) |
| 9 | +" Contribute: MURAOKA Taro <[email protected]> |
| 10 | +" Based On: excitetranslate.vim |
| 11 | +" Last Change: 29-Apr-2011. |
| 12 | + |
| 13 | +if !exists('g:googletranslate_options') |
| 14 | + let g:googletranslate_options = ["register","buffer"] |
| 15 | +endif |
| 16 | +" default language setting. |
| 17 | +if !exists('g:googletranslate_locale') |
| 18 | + let g:googletranslate_locale = substitute(v:lang, '^\([a-z]*\).*$', '\1', '') |
| 19 | +endif |
| 20 | + |
| 21 | +let s:endpoint = 'http://ajax.googleapis.com/ajax/services/language/translate' |
| 22 | + |
| 23 | +function! s:CheckLang(word) |
| 24 | + let all = strlen(a:word) |
| 25 | + let eng = strlen(substitute(a:word, '[^\t -~]', '', 'g')) |
| 26 | + return eng * 2 < all ? '' : 'en' |
| 27 | +endfunction |
| 28 | + |
| 29 | +function! s:nr2byte(nr) |
| 30 | + if a:nr < 0x80 |
| 31 | + return nr2char(a:nr) |
| 32 | + elseif a:nr < 0x800 |
| 33 | + return nr2char(a:nr/64+192).nr2char(a:nr%64+128) |
| 34 | + else |
| 35 | + return nr2char(a:nr/4096%16+224).nr2char(a:nr/64%64+128).nr2char(a:nr%64+128) |
| 36 | + endif |
| 37 | +endfunction |
| 38 | + |
| 39 | +function! s:nr2enc_char(charcode) |
| 40 | + if &encoding == 'utf-8' |
| 41 | + return nr2char(a:charcode) |
| 42 | + endif |
| 43 | + let char = s:nr2byte(a:charcode) |
| 44 | + if strlen(char) > 1 |
| 45 | + let char = strtrans(iconv(char, 'utf-8', &encoding)) |
| 46 | + endif |
| 47 | + return char |
| 48 | +endfunction |
| 49 | + |
| 50 | +" @see http://vim.g.hatena.ne.jp/eclipse-a/20080707/1215395816 |
| 51 | +function! s:char2hex(c) |
| 52 | + if a:c =~# '^[:cntrl:]$' | return '' | endif |
| 53 | + let r = '' |
| 54 | + for i in range(strlen(a:c)) |
| 55 | + let r .= printf('%%%02X', char2nr(a:c[i])) |
| 56 | + endfor |
| 57 | + return r |
| 58 | +endfunction |
| 59 | +function! s:encodeURI(s) |
| 60 | + return substitute(a:s, '[^0-9A-Za-z-._~!''()*#$&+,/:;=?@]', |
| 61 | + \ '\=s:char2hex(submatch(0))', 'g') |
| 62 | +endfunction |
| 63 | +function! s:encodeURIComponent(s) |
| 64 | + return substitute(a:s, '[^0-9A-Za-z-._~!''()*]', |
| 65 | + \ '\=s:char2hex(submatch(0))', 'g') |
| 66 | +endfunction |
| 67 | + |
| 68 | +function! s:quote(s) |
| 69 | + let q = '"' |
| 70 | + if &shellxquote == '"' |
| 71 | + let q = "'" |
| 72 | + endif |
| 73 | + return q.a:s.q |
| 74 | +endfunction |
| 75 | + |
| 76 | +function! GoogleTranslate(word, from, to) |
| 77 | + if !executable("curl") |
| 78 | + echohl WarningMsg |
| 79 | + echo "GoogleTranslate require 'curl' command." |
| 80 | + echohl None |
| 81 | + return |
| 82 | + endif |
| 83 | + let mode = a:from . "|" . a:to |
| 84 | + let data = 'v=1.0&langpair='.mode.'&q='.s:encodeURIComponent(a:word) |
| 85 | + let oldshellredir=&shellredir |
| 86 | + setlocal shellredir=> |
| 87 | + let text = system("curl -s -d ".s:quote(data)." ".s:endpoint) |
| 88 | + let &shellredir=oldshellredir |
| 89 | + let text = iconv(text, "utf-8", &encoding) |
| 90 | + let text = substitute(text, '\\u\(\x\x\x\x\)', '\=s:nr2enc_char("0x".submatch(1))', 'g') |
| 91 | + let [null,true,false] = [0,1,0] |
| 92 | + let obj = eval(text) |
| 93 | + if type(obj.responseData) == 4 |
| 94 | + let text = obj.responseData.translatedText |
| 95 | + let text = substitute(text, '>', '>', 'g') |
| 96 | + let text = substitute(text, '<', '<', 'g') |
| 97 | + let text = substitute(text, '"', '"', 'g') |
| 98 | + let text = substitute(text, ''', "'", 'g') |
| 99 | + let text = substitute(text, ' ', ' ', 'g') |
| 100 | + let text = substitute(text, '¥', '\¥', 'g') |
| 101 | + let text = substitute(text, '&#\(\d\+\);', '\=s:nr2enc_char(submatch(1))', 'g') |
| 102 | + let text = substitute(text, '&', '\&', 'g') |
| 103 | + else |
| 104 | + if !has_key(obj, 'responseDetails') |
| 105 | + let obj.responseDetails = 'unknown server error' |
| 106 | + endif |
| 107 | + echohl WarningMsg |
| 108 | + echo obj.responseDetails |
| 109 | + echohl None |
| 110 | + let text = '' |
| 111 | + endif |
| 112 | + return text |
| 113 | +endfunction |
| 114 | + |
| 115 | +function! GoogleTranslateRange(...) range |
| 116 | + " Concatenate input string. |
| 117 | + let curline = a:firstline |
| 118 | + let strline = '' |
| 119 | + |
| 120 | + if a:0 >= 3 |
| 121 | + let strline = a:3 |
| 122 | + else |
| 123 | + while curline <= a:lastline |
| 124 | + let tmpline = substitute(getline(curline), '^\s\+\|\s\+$', '', 'g') |
| 125 | + if tmpline=~ '\m^\a' && strline =~ '\m\a$' |
| 126 | + let strline = strline .' '. tmpline |
| 127 | + else |
| 128 | + let strline = strline . tmpline |
| 129 | + endif |
| 130 | + let curline = curline + 1 |
| 131 | + endwhile |
| 132 | + endif |
| 133 | + |
| 134 | + let from = '' |
| 135 | + let to = g:googletranslate_locale |
| 136 | + if a:0 == 0 |
| 137 | + let from = s:CheckLang(strline) |
| 138 | + let to = 'en'==from ? g:googletranslate_locale : 'en' |
| 139 | + elseif a:0 == 1 |
| 140 | + let to = a:1 |
| 141 | + elseif a:0 >= 2 |
| 142 | + let from = a:1 |
| 143 | + let to = a:2 |
| 144 | + endif |
| 145 | + |
| 146 | + " Do translate. |
| 147 | + let jstr = GoogleTranslate(strline, from, to) |
| 148 | + if len(jstr) == 0 |
| 149 | + return |
| 150 | + endif |
| 151 | + |
| 152 | + " Echo |
| 153 | + if index(g:googletranslate_options, 'echo') != -1 |
| 154 | + echo jstr |
| 155 | + endif |
| 156 | + " Put to buffer. |
| 157 | + if index(g:googletranslate_options, 'buffer') != -1 |
| 158 | + " Open or go result buffer. |
| 159 | + let bufname = '==Google Translate==' |
| 160 | + let winnr = bufwinnr(bufname) |
| 161 | + if winnr < 1 |
| 162 | + silent execute 'below 10new '.escape(bufname, ' ') |
| 163 | + nmap <buffer> q :<c-g><c-u>bw!<cr> |
| 164 | + vmap <buffer> q :<c-g><c-u>bw!<cr> |
| 165 | + else |
| 166 | + if winnr != winnr() |
| 167 | + execute winnr.'wincmd w' |
| 168 | + endif |
| 169 | + endif |
| 170 | + setlocal buftype=nofile bufhidden=hide noswapfile wrap ft= |
| 171 | + " Append translated string. |
| 172 | + if line('$') == 1 && getline('$').'X' ==# 'X' |
| 173 | + call setline(1, jstr) |
| 174 | + else |
| 175 | + call append(line('$'), '--------') |
| 176 | + call append(line('$'), jstr) |
| 177 | + endif |
| 178 | + normal! Gzt |
| 179 | + endif |
| 180 | + " Put to unnamed register. |
| 181 | + if index(g:googletranslate_options, 'register') != -1 |
| 182 | + let @" = jstr |
| 183 | + endif |
| 184 | +endfunction |
| 185 | + |
| 186 | +command! -nargs=* -range GoogleTranslate <line1>,<line2>call GoogleTranslateRange(<f-args>) |
| 187 | +command! -nargs=* -range Trans <line1>,<line2>call GoogleTranslateRange(<f-args>) |
0 commit comments