├── README └── plugin └── vimim.vim /README: -------------------------------------------------------------------------------- 1 | This is a mirror of http://www.vim.org/scripts/script.php?script_id=2506 2 | 3 | The VimIM is a Vim plugin designed as an independent IM (Input Method) 4 | to support CJK search and CJK input, with or without vim omni popup window. 5 |   6 | VimIM 是一个基于Vim的嵌入式中文输入法。 7 | 8 | 不启动中文输入法,不换模式,就可以输入中文。 9 | 不打开弹出式菜单,不敲中文,也可以搜索中文。 10 |      11 | 中文输入与英文输入不再相互折腾。 12 | 中文搜索与英文搜索不再分为彼此。 13 | 14 |    15 | 正常模式:  gi   无菜单窗中文输入 Insert text ...    16 | 正常模式:  n   无菜单窗中文搜索 Repeat the latest "/" or "?" ... 17 | 插入模式: i_CTRL-_ 开关中文输入法 Switch between languages ... 18 | 插入模式: i_CTRL-^ 切换中文输入法 Toggle the use of language ...  19 |        20 |                   21 | 最新程式: http://vimim.googlecode.com/svn/vimim/vimim.vim.html 22 | 项目管理: https://github.com/vimim/ 23 | 错误报告: http://code.google.com/p/vimim/issues/list 24 | 最新主页: http://vimim.googlecode.com/svn/vimim/vimim.html 25 | 新闻论坛: http://groups.google.com/group/vimim 26 | 论坛邮箱: vimim+subscribe@googlegroups.com 27 |                  28 | 标准字库: http://vimim.googlecode.com/svn/trunk/plugin/vimim.cjk.txt 29 | 海量词库: http://vimim.googlecode.com/svn/trunk/plugin/vimim.gbk.bsddb 30 | 英文词库: http://vimim.googlecode.com/svn/trunk/plugin/vimim.txt 31 | 民间词库: http://vimim-data.googlecode.com 32 |         33 |                         34 | vim i vimim CTRL-^ CTRL-^   35 |          36 | 日期:公元2012年7月4日 星期三 37 | 电脑:win32 0.011714 seconds 38 | 版本:gvim.exe=703 39 | 编码:utf-8 ucs-bom,utf8,chinese,gb18030 40 | 环境:English_United States.1252 41 | 词库:标准字库:C:/var/mobile/vim/vimfiles/plugin/vimim.cjk.txt 42 | 词库:英文词库:C:/var/mobile/vim/vimfiles/plugin/vimim.txt 43 | 词库:拼音词库:C:/var/mobile/vim/vimfiles/plugin/vimim.gbk.bsddb 44 | 词库:云词库:谷歌云 搜狗云  45 | 联网:Python2 Interface to Vim 46 | 输入:VimIM 拼音 四角号码 英文  47 | 选项:vimimrc 48 | :let g:vimim_cloud = 'google,sogou,baidu,qq' 49 | :let g:vimim_map = 'tab_as_gi' 50 | " :let g:vimim_mode = 'dynamic' 51 | " :let g:vimim_mycloud = 0 52 | " :let g:vimim_plugin = 'C:/var/mobile/vim/vimfiles/plugin' 53 | " :let g:vimim_punctuation = 2 54 | " :let g:vimim_shuangpin = 0 55 | " :let g:vimim_toggle = 'pinyin,google,sogou' 56 |   57 | -------------------------------------------------------------------------------- /plugin/vimim.vim: -------------------------------------------------------------------------------- 1 | " =========================================================== 2 | " VimIM —— Vim 中文輸入法 3 | " =========================================================== 4 | let s:egg = ' vimim easter egg:' " vim i vimim CTRL-^ CTRL-^ 5 | let s:url = ' http://vimim.googlecode.com/svn/vimim/vimim.vim.html' 6 | let s:url = ' http://code.google.com/p/vimim/source/list' 7 | let s:url = ' http://vim.sf.net/scripts/script.php?script_id=2506' 8 | 9 | let s:VimIM = [" ==== introduction ==== {{{"] 10 | " ================================================= 11 | " File: vimim.vim 12 | " Author: vimim 13 | " License: GNU Lesser General Public License 14 | " Readme: VimIM is a Vim plugin as an Input Method for i_CTRL-^ in Vim 15 | " (1) do Chinese input without mode change: Midas touch 16 | " (2) do Chinese search without typing Chinese: slash search 17 | " (3) support Google/Baidu/Sogou/QQ cloud input 18 | " (4) support bsd database with python interface to Vim 19 | " PnP: Plug and Play 20 | " (1) drop the vimim.vim to the plugin folder: plugin/vimim.vim 21 | " (2) [option] drop supported datafiles, like: plugin/vimim.txt 22 | " Usage: VimIM takes advantage of the definition from Vim 23 | " (1) :help gi Insert text ... 24 | " (2) :help n Repeat the latest '/' or '?' ... 25 | " (3) :help i_CTRL-^ Toggle the use of language ... 26 | " (4) :help i_CTRL-_ Switch between languages ... 27 | " (5) :help i_CTRL-U Delete all entered characters ... (internal) 28 | " (6) :help i_CTRL-L When ... is set: Go to ... mode ... (internal) 29 | 30 | " ============================================= }}} 31 | let s:VimIM += [" ==== initialization ==== {{{"] 32 | " ================================================= 33 | 34 | function! s:vimim_bare_bones_vimrc() 35 | set cpoptions=Bce$ go=cirMehf shm=aoOstTAI noloadplugins 36 | set gcr=a:blinkon0 shellslash noswapfile hlsearch viminfo= 37 | set fencs=ucs-bom,utf8,chinese,gb18030 gfn=Courier_New:h12:w7 38 | set enc=utf8 gfw=YaHei_Consolas_Hybrid,NSimSun-18030 39 | let unix = '/usr/local/bin:/usr/bin:/bin:.' 40 | let windows = '/bin/;/Python27;/Python31;/Windows/system32;.' 41 | let $PATH = has("unix") ? unix : windows 42 | endfunction 43 | 44 | if exists("g:Vimim_profile") || &iminsert == 1 || v:version < 700 45 | finish 46 | elseif &compatible 47 | call s:vimim_bare_bones_vimrc() 48 | endif 49 | scriptencoding utf-8 50 | let g:Vimim_profile = reltime() 51 | let s:plugin = expand(":p:h") 52 | 53 | function! s:vimim_initialize_debug() 54 | " gvim -u /var/mobile/vim/vimfiles/plugin/vimim.vim 55 | " gvim -u /home/vimim/svn/vimim/trunk/plugin/vimim.vim 56 | let s:plugon = simplify(s:plugin . '/../../../hjkl/') 57 | if empty(&cp) && exists('s:plugon') && isdirectory(s:plugon) 58 | let g:Vimim_map = 'tab_as_gi' 59 | let g:Vimim_cloud = 'google,sogou,baidu,qq' 60 | endif 61 | endfunction 62 | 63 | function! s:vimim_initialize_backdoor() 64 | let s:titlestring = &titlestring 65 | let s:cjk = { 'lines' : [] } 66 | let s:english = { 'lines' : [], 'line' : "" } 67 | let s:cjk.filename = s:vimim_filereadable("vimim.cjk.txt") 68 | let s:english.filename = s:vimim_filereadable("vimim.txt") 69 | let s:mandarin = len(s:english.filename) ? 0 : 1 " s/t chinese style 70 | let s:hit_and_run = len(s:cjk.filename) ? 0 : 1 " onekey continuity 71 | if len(s:cjk.filename) 72 | highlight! PmenuSbar NONE 73 | highlight! PmenuThumb NONE 74 | highlight! Pmenu NONE 75 | highlight! link PmenuSel NonText 76 | endif 77 | endfunction 78 | 79 | function! s:vimim_debug(...) 80 | " [.vimrc] :redir @+>> 81 | " [client] :sil!call s:vimim_debug(s:vimim_egg_vimim()) 82 | sil!echo "\n::::::::::::::::::::::::" 83 | if len(a:000) > 1 84 | sil!echo join(a:000, " :: ") 85 | elseif type(a:1) == type({}) 86 | for key in keys(a:1) 87 | sil!echo key . '::' . a:1[key] 88 | endfor 89 | elseif type(a:1) == type([]) 90 | for line in a:1 91 | sil!echo line 92 | endfor 93 | else 94 | sil!echo string(a:1) 95 | endif 96 | sil!echo "::::::::::::::::::::::::\n" 97 | endfunction 98 | 99 | function! s:vimim_initialize_global() 100 | highlight default lCursorIM guifg=NONE guibg=green gui=NONE 101 | highlight! link lCursor lCursorIM 102 | let s:space = ' ' 103 | let s:colon = ':' 104 | let g:Vimim = "VimIM 中文輸入法" 105 | let s:windowless_title = "VimIM" 106 | let s:today = s:vimim_imode_today_now('itoday') 107 | let s:multibyte = &encoding =~ "utf-8" ? 3 : 2 108 | let s:localization = &encoding =~ "utf-8" ? 0 : 2 109 | let s:seamless_positions = [] 110 | let s:starts = { 'row' : 0, 'column' : 1 } 111 | let s:quanpin_table = {} 112 | let s:shuangpin_table = {} 113 | let s:http_exe = "" 114 | let s:shuangpin = 'abc ms plusplus purple flypy nature' 115 | let s:abcd = split("'abcdvfgxz", '\zs') 116 | let s:qwer = split("pqwertyuio", '\zs') 117 | let s:az_list = map(range(97,122),"nr2char(".'v:val'.")") 118 | let s:valid_keys = s:az_list 119 | let s:valid_keyboard = "[0-9a-z']" 120 | let s:valid_wubi_keyboard = "[0-9a-z]" 121 | let s:shengmu_list = split('b p m f d t l n g k h j q x r z c s y w') 122 | let s:pumheights = { 'current' : &pumheight, 'saved' : &pumheight } 123 | let s:smart_quotes = { 'single' : 1, 'double' : 1 } 124 | let s:backend = { 'cloud' : {}, 'datafile' : {}, 'directory' : {} } 125 | let s:ui = { 'root' : '', 'im' : '', 'quote' : 0, 'frontends' : [] } 126 | let s:rc = {} 127 | let s:rc["g:Vimim_mode"] = 'dynamic' 128 | let s:rc["g:Vimim_shuangpin"] = 0 129 | let s:rc["g:Vimim_map"] = '' 130 | let s:rc["g:Vimim_toggle"] = 0 131 | let s:rc["g:Vimim_cloud"] = 'baidu,sogou,qq,google' 132 | let s:rc["g:Vimim_mycloud"] = 0 133 | let s:rc["g:Vimim_plugin"] = s:plugin 134 | let s:rc["g:Vimim_punctuation"] = 2 135 | call s:vimim_set_global_default() 136 | let s:plugin = isdirectory(g:Vimim_plugin) ? g:Vimim_plugin : s:plugin 137 | let s:plugin = s:plugin[-1:] != "/" ? s:plugin."/" : s:plugin 138 | let s:dynamic = {'onekey':0,'windowless':0,'dynamic':1,'static':0} 139 | let s:static = {'onekey':0,'windowless':0,'dynamic':0,'static':1} 140 | let s:onekey = {'onekey':1,'windowless':0,'dynamic':0,'static':0} 141 | let s:windowless = {'onekey':0,'windowless':1,'dynamic':0,'static':0} 142 | endfunction 143 | 144 | function! s:vimim_dictionary_keycodes() 145 | let s:keycodes = {} 146 | let cloud = ' google sogou baidu qq mycloud ' 147 | for key in split( cloud . ' pinyin ') 148 | let s:keycodes[key] = "['a-z0-9]" 149 | endfor 150 | for key in split('array30 phonetic') 151 | let s:keycodes[key] = "[.,a-z0-9;/]" 152 | endfor 153 | for key in split('zhengma taijima wubi cangjie hangul xinhua quick') 154 | let s:keycodes[key] = "['a-z]" 155 | endfor 156 | let s:keycodes.wu = "['a-z]" " s:ui.quote=1 157 | let s:keycodes.nature = "['a-z]" " s:ui.quote=1 158 | let s:keycodes.yong = "['a-z.;/]" " s:ui.quote=1 159 | let s:keycodes.erbi = "['a-z.;/,]" " s:ui.quote=1 160 | let s:keycodes.boshiamy = "['a-z.],[]" " s:ui.quote=1 161 | let ime = ' pinyin_sogou pinyin_quote_sogou pinyin_huge' 162 | let ime .= ' pinyin_fcitx pinyin_canton pinyin_hongkong' 163 | let ime .= ' wubi98 wubi2000 wubijd wubihf' 164 | let s:all_vimim_input_methods = keys(s:keycodes) + split(ime) 165 | endfunction 166 | 167 | function! s:vimim_set_frontend() 168 | let quote = 'erbi wu nature yong boshiamy' " quote in datafile 169 | let cloud = get(split(g:Vimim_cloud,','), 0) " default cloud 170 | let s:valid_keyboard = "[0-9a-z']" 171 | if !empty(s:ui.root) && empty(g:Vimim_shuangpin) 172 | let s:valid_keyboard = s:backend[s:ui.root][s:ui.im].keycode 173 | elseif g:Vimim_shuangpin == 'ms' || g:Vimim_shuangpin == 'purple' 174 | let s:valid_keyboard = "[0-9a-z';]" 175 | endif 176 | let i = 0 177 | let keycode_string = "" 178 | while i < 16*16 179 | if nr2char(i) =~# s:valid_keyboard 180 | let keycode_string .= nr2char(i) 181 | endif 182 | let i += 1 183 | endwhile 184 | let s:valid_keys = split(keycode_string, '\zs') 185 | let s:wubi = cloud =~ 'wubi' || s:ui.im =~ 'wubi\|erbi' ? 1 : 0 186 | let s:ui.quote = match(split(quote),s:ui.im) < 0 ? 0 : 1 187 | let s:gi_dynamic = s:ui.im =~ 'pinyin' || s:ui.root =~ 'cloud' ? 0 : 1 188 | let logo = s:chinese('dscj') 189 | let tail = s:mode.windowless ? s:today : '' 190 | if s:mode.dynamic || s:mode.static 191 | let logo = s:chinese('chinese',s:mode.static?'static':'dynamic') 192 | let tail = s:chinese('halfwidth') 193 | if g:Vimim_punctuation > 0 && s:toggle_punctuation > 0 194 | let tail = s:chinese('fullwidth') 195 | endif 196 | endif 197 | let g:Vimim = "VimIM".s:space.logo.' '.s:vimim_im_chinese().' '.tail 198 | call s:vimim_set_title(g:Vimim) 199 | endfunction 200 | 201 | function! s:vimim_set_global_default() 202 | let s:vimimrc = [] 203 | let s:vimimdefaults = [] 204 | for variable in keys(s:rc) 205 | if exists(variable) 206 | let value = string(eval(variable)) 207 | let vimimrc = ':let ' . variable .' = '. value .' ' 208 | call add(s:vimimrc, ' ' . vimimrc) 209 | else 210 | let value = string(s:rc[variable]) 211 | let vimimrc = ':let ' . variable .' = '. value .' ' 212 | call add(s:vimimdefaults, ' " ' . vimimrc) 213 | endif 214 | exe 'let '. variable .'='. value 215 | endfor 216 | endfunction 217 | 218 | " ============================================= }}} 219 | let s:VimIM += [" ==== easter eggs ==== {{{"] 220 | " ================================================= 221 | 222 | function! s:vimim_easter_chicken(keyboard) 223 | try 224 | return eval("s:vimim_egg_" . a:keyboard . "()") 225 | catch 226 | sil!call s:vimim_debug('egg', a:keyboard, v:exception) 227 | endtry 228 | return [] 229 | endfunction 230 | 231 | function! s:vimim_egg_vimimhelp() 232 | let eggs = split(s:url) 233 | let eggs += [''] + s:vimim_egg_vim() 234 | let eggs += [''] + s:vimim_egg_vimimgame() 235 | let eggs += [''] + s:vimim_egg_vimim() 236 | let eggs += [''] + s:vimim_egg_vimimvim() 237 | return map(eggs, 'v:val . " "') 238 | endfunction 239 | 240 | function! s:vimim_egg_vim() 241 | return ["Vim  文本編輯器", g:Vimim] 242 | endfunction 243 | 244 | function! s:vimim_egg_vimimgame() 245 | let mahjong = "春夏秋冬 梅兰竹菊 中發白囍 東南西北" 246 | return split(mahjong) 247 | endfunction 248 | 249 | function! s:vimim_egg_vimimvim() 250 | let vimim_pprint_filter = "strpart(" . 'v:val' . ", 0, 29)" 251 | return map(copy(s:VimIM), vimim_pprint_filter) 252 | endfunction 253 | 254 | function! s:vimim_egg_vimimrc() 255 | let vimim = s:vimimdefaults + s:vimimrc 256 | if g:Vimim_toggle > -1 " update g:Vimim_toggle if not closed 257 | let filter = "get(" . 'v:val' . ",1)" 258 | let g:Vimim_toggle = join(map(copy(s:ui.frontends),filter),",") 259 | let toggle = match(vimim, 'g:Vimim_toggle') 260 | let left = vimim[toggle][0 : 1 + match(vimim[toggle], '=')] 261 | let vimim[toggle] = left . string(g:Vimim_toggle) 262 | endif 263 | return sort(vimim) 264 | endfunction 265 | 266 | function! s:vimim_egg_vimim() 267 | let eggs = [] 268 | call add(eggs, s:chinese('date', s:colon) . s:today) 269 | let os = "win32unix win32 win64 macunix unix x11" 270 | for computer in split(os) 271 | if has(computer) | let os = computer | break | endif 272 | endfor 273 | let time = reltimestr(g:Vimim_profile) . ' seconds' 274 | call add(eggs, s:chinese('computer', s:colon) . os . time) 275 | let revision = v:progname ."=". v:version 276 | call add(eggs, s:chinese('revision', s:colon) . revision) 277 | let encoding = s:chinese('encoding', s:colon) . &encoding 278 | call add(eggs, encoding . s:space . &fileencodings) 279 | call add(eggs, s:chinese('env', s:colon) . v:lc_time) 280 | let db = s:chinese('database', s:colon) 281 | let input = "VimIM" . s:space . s:vimim_im_chinese() . s:space 282 | if len(s:cjk.filename) 283 | let input .= s:chinese('4corner') . s:space 284 | call add(eggs, db.s:chinese('cjk',s:colon).s:cjk.filename) 285 | endif 286 | if len(s:english.filename) 287 | let input .= s:chinese('english') . s:space 288 | call add(eggs, db.s:chinese('english').db.s:english.filename) 289 | endif 290 | let cloud = db . s:chinese('cloud') . db 291 | for [root, im] in s:ui.frontends 292 | let backend = s:backend[root][im] 293 | if root == "cloud" 294 | let cloud .= backend.name . s:chinese('cloud') . s:space 295 | else 296 | call add(eggs, db . backend.chinese . db . backend.name) 297 | endif 298 | endfor 299 | let exe = s:http_exe =~ 'Python' ? '' : "HTTP executable: " 300 | call add(eggs, cloud) 301 | call add(eggs, s:chinese('network', s:colon) . exe . s:http_exe) 302 | call add(eggs, s:chinese('input', s:colon) . input) 303 | call add(eggs, s:chinese('option', s:colon) . 'vimimrc') 304 | let results = map(eggs + s:vimim_egg_vimimrc(), 'v:val . " " ') 305 | return results 306 | endfunction 307 | 308 | " ============================================= }}} 309 | let s:VimIM += [" ==== hjkl vimimgame ==== {{{"] 310 | " ================================================= 311 | 312 | function! s:vimim_cache() 313 | let results = [] 314 | if !empty(s:pageup_pagedown) 315 | let length = len(s:match_list) 316 | if length > &pumheight 317 | let page = s:pageup_pagedown * &pumheight 318 | let partition = page ? page : length+page 319 | let B = s:match_list[partition :] 320 | let A = s:match_list[: partition-1] 321 | let results = B + A 322 | endif 323 | elseif s:touch_me_not 324 | if s:hjkl_h | let s:hjkl_h = 0 325 | for line in s:match_list 326 | let oneline = join(reverse(split(line,'\zs')),'') 327 | call add(results, oneline) 328 | endfor 329 | elseif s:hjkl_l | let s:hjkl_l = 0 330 | let results = reverse(copy(s:match_list)) 331 | endif 332 | endif 333 | return results 334 | endfunction 335 | 336 | function! s:vimim_get_hjkl_game(keyboard) 337 | let keyboard = a:keyboard 338 | let results = [] 339 | let poem = s:vimim_filereadable(keyboard) 340 | if keyboard =~# '^i' && keyboard =~ '\d' && empty(g:Vimim_shuangpin) 341 | return s:vimim_imode_number(keyboard) 342 | elseif keyboard ==# 'itoday' || keyboard ==# 'inow' 343 | return [s:vimim_imode_today_now(keyboard)] 344 | elseif keyboard == "''''''" 345 | return split(join(s:vimim_egg_vimimgame(),""),'\zs') 346 | elseif s:vimim_get_unicode_ddddd(keyboard) 347 | return s:vimim_unicode_list(s:vimim_get_unicode_ddddd(keyboard)) 348 | elseif keyboard == "''" 349 | let before = '' " get one chinese char before 350 | if !empty(len(s:vimim_left())) 351 | let before = getline(".")[col(".")-1-s:multibyte : col(".")-2] 352 | endif 353 | if empty(before) || before !~ '[^\x00-\xff]' 354 | if s:vimim_cjk() | return s:vimim_cjk_match('u') | endif 355 | let before = nr2char(19968) " the 214 standard unicode index 356 | endif " gi ,.. space ,.. space 357 | return s:vimim_unicode_list(char2nr(before)) 358 | elseif !empty(poem) 359 | let results = s:vimim_readfile(poem) " [hjkl] file in hjkl folder 360 | elseif keyboard ==# "vim" || keyboard =~# "^vimim" 361 | let results = s:vimim_easter_chicken(keyboard) " [hidden] egg 362 | elseif keyboard =~# '\l\+' . "'" . '\{4}$' 363 | let results = s:vimim_get_all_clouds(keyboard[:-5]) " fuck'''' 364 | elseif len(getreg('"')) > 3 365 | if keyboard == "''''" " visual: display buffer inside omni 366 | let results = split(getreg('"'), '\n') 367 | elseif keyboard =~ "'''''" " visual: display one-line-cjk property 368 | let line = substitute(getreg('"'),'[\x00-\xff]','','g') 369 | if len(line) 370 | for chinese in split(line, '\zs') 371 | let menu = s:vimim_cjk_property(chinese) 372 | let menu .= repeat(" ", 38-len(menu)) 373 | call add(results, chinese . " " . menu) 374 | endfor 375 | endif 376 | endif 377 | endif 378 | if len(results) 379 | let s:touch_me_not = 1 380 | if s:hjkl_m % 4 381 | for i in range(s:hjkl_m % 4) 382 | let results = s:vimim_hjkl_rotation(results) 383 | endfor 384 | endif 385 | let results = [s:space] + results + [s:space] 386 | endif 387 | return results 388 | endfunction 389 | 390 | function! s:vimim_hjkl_rotation(lines) 391 | let max = max(map(copy(a:lines), 'strlen(v:val)')) + 1 392 | let multibyte = match(a:lines,'\w') < 0 ? s:multibyte : 1 393 | let results = [] 394 | let rotations = [] 395 | for line in a:lines 396 | let spaces = '' " rotation makes more sense for cjk 397 | if (max-len(line)) / multibyte 398 | for i in range((max-len(line))/multibyte) 399 | let spaces .= s:space 400 | endfor 401 | endif 402 | let line .= spaces 403 | call add(rotations, line) 404 | endfor 405 | for i in range(max/multibyte) 406 | let column = '' 407 | for line in reverse(copy(rotations)) 408 | let line = get(split(line,'\zs'), i) 409 | if !empty(line) | let column .= line | endif 410 | endfor 411 | call add(results, column) 412 | endfor 413 | return results 414 | endfunction 415 | 416 | function! s:vimim_chinese_rotation() range abort 417 | :%s#\s*\r\=$## 418 | :let lines = getline(a:firstline, a:lastline) 419 | :let lines = s:vimim_hjkl_rotation(lines) 420 | :%d 421 | :for line in lines | put=line | endfor 422 | endfunction 423 | 424 | " ============================================= }}} 425 | let s:VimIM += [" ==== user interface ==== {{{"] 426 | " ================================================= 427 | 428 | function! s:vimim_dictionary_statusline() 429 | let one = " dscj wubi2000 taijima 4corner boshiamy input cjk nature" 430 | let two = " 点石成金,點石成金 新世纪,新世紀 太极码,太極碼" 431 | let two .= " 四角号码,四角號碼 呒虾米,嘸蝦米 输入,輸入" 432 | let two .= " 标准字库,標準字庫 自然码,自然碼" 433 | let one .= " computer database option flypy network cloud env " 434 | let one .= " encoding ms static dynamic erbi wubi hangul xinhua" 435 | let one .= " zhengma cangjie yong wu wubijd shuangpin" 436 | let two .= " 电脑,電腦 词库,詞庫 选项,選項 小鹤,小鶴 联网,聯網 云,雲 " 437 | let two .= " 环境,環境 编码,編碼 微软,微軟 静态,靜態 动态,動態" 438 | let two .= " 二笔,二筆 五笔,五筆 韩文,韓文 新华,新華 郑码,鄭碼" 439 | let two .= " 仓颉,倉頡 永码,永碼 吴语,吳語 极点,極點 双拼,雙拼" 440 | let one .= " hit fullwidth halfwidth english chinese purple plusplus" 441 | let one .= " quick wubihf mycloud wubi98 pin pinyin phonetic array30" 442 | let one .= " abc revision date google baidu sogou qq " 443 | let two .= " 打 全角 半角 英文 中文 紫光 加加 速成 海峰 自己的 98" 444 | let two .= " 拼 拼音 注音 行列 智能 版本 日期 谷歌 百度 搜狗 QQ" 445 | let s:chinese_statusline = s:vimim_key_value_hash(one, two) 446 | endfunction 447 | 448 | function! s:vimim_dictionary_punctuations() 449 | let s:antonym = " 〖〗 () 《》 【】 ‘’ “”" 450 | let one = " { } ( ) < > [ ] " 451 | let two = join(split(join(split(s:antonym)[:3],''),'\zs')) 452 | let antonyms = s:vimim_key_value_hash(one, two) 453 | let one = " , . + - ~ ^ _ " 454 | let two = " , 。 + - ~ …… —— " 455 | let mini_punctuations = s:vimim_key_value_hash(one, two) 456 | let one = " @ : # & % $ ! = ; ? * " 457 | let two = "   : # & % ¥ ! = ; ? ﹡" 458 | let most_punctuations = s:vimim_key_value_hash(one, two) 459 | call extend(most_punctuations, antonyms) 460 | let s:key_evils = { '\' : "、", "'" : "‘’", '"' : "“”" } 461 | let s:all_evils = {} " all punctuations for onekey_evils 462 | call extend(s:all_evils, mini_punctuations) 463 | call extend(s:all_evils, most_punctuations) 464 | let s:punctuations = {} 465 | if g:Vimim_punctuation > 0 " :let g:Vimim_punctuation = 1 466 | call extend(s:punctuations, mini_punctuations) 467 | endif 468 | if g:Vimim_punctuation > 1 " :let g:Vimim_punctuation = 2 469 | call extend(s:punctuations, most_punctuations) 470 | endif 471 | endfunction 472 | 473 | function! g:Vimim_slash() 474 | let range = col(".") - 1 - s:starts.column 475 | let chinese = strpart(getline("."), s:starts.column, range) 476 | let word = substitute(chinese,'\w','','g') 477 | let @/ = empty(word) ? @_ : word 478 | let repeat_times = len(word) / s:multibyte 479 | let key = repeat("\\",repeat_times) . g:Vimim_esc() 480 | sil!exe 'sil!return "' . key . '"' 481 | endfunction 482 | 483 | function! g:Vimim_bracket(offset) 484 | let cursor = "" 485 | let range = col(".") - 1 - s:starts.column 486 | let repeat_times = range / s:multibyte + a:offset 487 | if repeat_times 488 | let cursor = repeat("\\", repeat_times) 489 | elseif repeat_times < 1 490 | let cursor = strpart(getline("."), s:starts.column, s:multibyte) 491 | endif 492 | return cursor 493 | endfunction 494 | 495 | function! s:vimim_get_label(label) 496 | let labeling = a:label == 10 ? "0" : a:label 497 | if s:mode.onekey && a:label < 11 498 | let label2 = a:label < 2 ? "_" : get(s:abcd,a:label-1) 499 | let labeling = empty(labeling) ? '10' : labeling . label2 500 | if len(s:cjk.filename) && empty(s:hjkl_l%2) 501 | let labeling = " " . label2 502 | endif 503 | endif 504 | return labeling 505 | endfunction 506 | 507 | function! s:vimim_set_pumheight() 508 | let &completeopt = s:mode.windowless ? 'menu' : 'menuone' 509 | let &pumheight = s:pumheights.saved 510 | if empty(&pumheight) 511 | let &pumheight = 5 512 | if s:mode.onekey || len(s:valid_keys) > 28 513 | let &pumheight = 10 514 | endif 515 | endif 516 | let &pumheight = s:mode.windowless ? 1 : &pumheight 517 | let s:pumheights.current = copy(&pumheight) 518 | if s:touch_me_not 519 | let &pumheight = 0 520 | elseif s:hjkl_l 521 | let &pumheight = s:hjkl_l % 2 ? 0 : s:pumheights.current 522 | endif 523 | endfunction 524 | 525 | " ============================================= }}} 526 | let s:VimIM += [" ==== statusline ==== {{{"] 527 | " ================================================= 528 | 529 | function! s:vimim_set_title(title) 530 | if &laststatus < 2 531 | let &titlestring = a:title 532 | redraw 533 | endif 534 | if &term == 'screen' 535 | if s:mode.windowless 536 | let &l:statusline = '%{"'. a:title .'"}%<' 537 | else 538 | let &l:statusline = g:Vimim .' %h%m%r%=%-14.(%l,%c%V%) %P %<%f' 539 | endif 540 | endif 541 | endfunction 542 | 543 | function! s:vimim_im_chinese() 544 | if empty(s:ui.im) 545 | return "==broken python interface to vim==" 546 | endif 547 | let backend = s:backend[s:ui.root][s:ui.im] 548 | let title = has_key(s:keycodes, s:ui.im) ? backend.chinese : '' 549 | if s:ui.im =~ 'wubi' 550 | for wubi in split('wubi98 wubi2000 wubijd wubihf') 551 | if get(split(backend.name, '/'),-1) =~ wubi 552 | let title .= s:chinese(wubi) 553 | endif 554 | endfor 555 | elseif s:ui.im == 'mycloud' 556 | let title .= s:chinese('cloud', s:space) 557 | let title .= s:backend.cloud.mycloud.directory 558 | elseif s:ui.root == 'cloud' 559 | let title = s:chinese(s:space, s:cloud, 'cloud') 560 | let clouds = split(g:Vimim_cloud,',') 561 | let vimim_cloud = get(clouds, match(clouds, s:cloud)) 562 | if vimim_cloud =~ 'wubi' " g:Vimim_cloud='qq.wubi' 563 | let title .= s:chinese(s:space, 'wubi') 564 | elseif vimim_cloud =~ 'shuangpin' " qq.shuangpin.ms => ms 565 | let shuangpin = get(split(vimim_cloud,"[.]"),-1) 566 | if match(split(s:shuangpin),shuangpin) > -1 567 | let title .= s:chinese(s:space, shuangpin, 'shuangpin') 568 | endif 569 | endif 570 | endif 571 | if !empty(g:Vimim_shuangpin) 572 | let title = s:chinese(s:space, g:Vimim_shuangpin, 'shuangpin') 573 | endif 574 | if g:Vimim_shuangpin =~ 'abc' || g:Vimim_cloud =~ 'abc' 575 | let title = substitute(title,s:chinese('pin'),s:chinese('hit'),'') 576 | endif 577 | return title 578 | endfunction 579 | 580 | function! s:vimim_windowless_titlestring(cursor) 581 | let logo = "VimIM" 582 | let west = s:all_evils['['] 583 | let east = s:all_evils[']'] 584 | let title = substitute(s:windowless_title, west.'\|'.east, ' ', 'g') 585 | if title !~ '\s\+' . "'" . '\+\s\+' 586 | let title = substitute(title,"'",'','g') 587 | endif 588 | let title = substitute(title, '\s\*\=\d\=\s', ' ', '') 589 | let words = split(title)[1:] 590 | let cursor = s:cursor_at_windowless + a:cursor 591 | let hightlight = get(words, cursor) 592 | if !empty(hightlight) && len(words) > 1 593 | let west = join(words[1 : cursor-1]) . west 594 | let east .= join(words[cursor+1 :]) 595 | let s:cursor_at_windowless = cursor 596 | let keyboard = get(words,0)=='0' ? "" : get(words,0) 597 | let star = len(s:hjkl) ? s:hjkl : len(s:english.line) ? '*' : '' 598 | if empty(s:mode.windowless) || empty(s:cjk.filename) 599 | let logo .= s:space . s:vimim_im_chinese() 600 | endif 601 | let logo .= ' '. keyboard .' '. star . west . hightlight . east 602 | endif 603 | sil!call s:vimim_set_title(logo) 604 | endfunction 605 | 606 | function! g:Vimim_esc() 607 | let key = nr2char(27) " is if onekey or windowless 608 | if s:mode.windowless || s:mode.onekey 609 | if has("gui_running") 610 | sil!let @+ = getline(".") " to clipboard 611 | endif 612 | sil!let key = s:vimim_stop() . key " to escape 613 | sil!call s:vimim_set_title(s:space . getline(".")) 614 | elseif pumvisible() 615 | let key = g:Vimim_one_key_correction() " as correction 616 | endif 617 | sil!exe 'sil!return "' . key . '"' 618 | endfunction 619 | 620 | " ============================================= }}} 621 | let s:VimIM += [" ==== lmap imap nmap ==== {{{"] 622 | " ================================================= 623 | 624 | function! g:Vimim_cycle_vimim() 625 | if len(s:cjk.filename) " backdoor to cycle all 4 vimim modes 626 | let s:mode = s:mode.windowless ? s:onekey : 627 | \ s:mode.onekey ? s:dynamic : 628 | \ s:mode.dynamic ? s:static : s:windowless 629 | elseif s:mode.onekey || s:mode.windowless 630 | let s:mode = s:mode.onekey ? s:windowless : s:onekey 631 | elseif s:mode.static || s:mode.dynamic 632 | let s:toggle_punctuation = (s:toggle_punctuation + 1) % 2 633 | endif 634 | let s:hit_and_run = 0 635 | sil!call s:vimim_set_frontend() 636 | sil!call s:vimim_set_keyboard_maps() 637 | return "" 638 | endfunction 639 | 640 | function! g:Vimim_label(key) 641 | let key = a:key 642 | if pumvisible() 643 | let n = match(s:abcd, key) 644 | if key =~ '\d' 645 | let n = key < 1 ? 9 : key - 1 646 | endif 647 | let yes = repeat("\", n). '\' 648 | let omni = '\=g:Vimim()\' 649 | if s:mode.onekey 650 | if s:vimim_cjk() && a:key =~ '\d' 651 | let s:hjkl .= a:key " 1234567890 as filter 652 | let yes = '' 653 | elseif s:hit_and_run || a:key =~ '\d' 654 | let omni = s:vimim_stop() 655 | endif 656 | endif 657 | if len(yes) 658 | sil!call s:vimim_reset_after_insert() 659 | endif 660 | let key = yes . omni 661 | elseif s:mode.windowless && key =~ '\d' 662 | let key = s:vimim_windowless(key) 663 | endif 664 | sil!exe 'sil!return "' . key . '"' 665 | endfunction 666 | 667 | function! g:Vimim_page(key) 668 | let key = a:key 669 | if pumvisible() 670 | let page = '\\=g:Vimim()\' 671 | if key =~ '[][]' 672 | let left = key == "]" ? "\" : "" 673 | let right = key == "]" ? "\" : "" 674 | let _ = key == "]" ? 0 : -1 675 | let backspace = '\=g:Vimim_bracket('._.')\' 676 | let key = '\' . left . backspace . right 677 | elseif key =~ '[=.]' 678 | let s:pageup_pagedown = &pumheight ? 1 : 0 679 | let key = &pumheight ? page : '\' 680 | elseif key =~ '[-,]' 681 | let s:pageup_pagedown = &pumheight ? -1 : 0 682 | let key = &pumheight ? page : '\' 683 | endif 684 | elseif key =~ "[][=-]" && empty(s:mode.onekey) 685 | let key = g:Punctuation(key) 686 | endif 687 | sil!exe 'sil!return "' . key . '"' 688 | endfunction 689 | 690 | function! g:Wubi() 691 | if s:gi_dynamic_on 692 | let s:gi_dynamic_on = 0 | return "" 693 | endif 694 | let key = pumvisible() || s:mode.windowless && s:omni ? '\' : "" 695 | if s:wubi && empty(len(get(split(s:keyboard),0))%4) 696 | let key = pumvisible() ? '\' : s:mode.windowless ? "" : key 697 | endif 698 | sil!exe 'sil!return "' . key . '"' 699 | endfunction 700 | 701 | function! g:Vimim_hjkl(key) 702 | let key = a:key 703 | if pumvisible() 704 | if key ==# 'n' | call s:vimim_reset_after_insert() 705 | elseif key ==# 'm' | let s:hjkl_m += 1 706 | elseif key ==# 'h' | let s:hjkl_h += 1 " h 707 | elseif key ==# 'j' | let key = '\' " j 708 | elseif key ==# 'k' | let key = '\' " k 709 | elseif key ==# 'l' | let s:hjkl_l += 1 " l 710 | elseif key ==# 's' | let s:hjkl__ += 1 " s/t transfer 711 | elseif key =~ "[/?]" 712 | let key = '\\=g:Vimim_slash()\' . key . '\' 713 | elseif match(s:qwer, key) > -1 714 | let s:hjkl .= match(s:qwer, key) 715 | endif 716 | let key = key == a:key ? '\=g:Vimim()\' : key 717 | endif 718 | sil!exe 'sil!return "' . key . '"' 719 | endfunction 720 | 721 | function! s:vimim_punctuation_maps() 722 | for _ in keys(s:all_evils) 723 | if _ !~ s:valid_keyboard 724 | exe 'lnoremap '._.' g:Punctuation("'._.'")' 725 | endif 726 | endfor 727 | if empty(s:ui.quote) 728 | lnoremap ' =g:Vimim_single_quote() 729 | endif 730 | if g:Vimim_punctuation == 3 731 | lnoremap " =g:Vimim_double_quote() 732 | lnoremap =g:Vimim_bslash() 733 | endif 734 | endfunction 735 | 736 | function! g:Punctuation(key) 737 | let key = a:key 738 | if s:toggle_punctuation > 0 739 | if pumvisible() || getline(".")[col(".")-2] !~ '\w' 740 | if has_key(s:punctuations, a:key) 741 | let key = s:punctuations[a:key] 742 | endif 743 | endif 744 | endif 745 | if pumvisible() " the 2nd choice 746 | let key = a:key == ";" ? '\\' : '\' . key 747 | elseif s:mode.windowless && s:gi_dynamic 748 | let key = a:key == ";" ? '\' : key 749 | call g:Vimim_space() 750 | endif 751 | sil!exe 'sil!return "' . key . '"' 752 | endfunction 753 | 754 | function! g:Vimim_single_quote() 755 | let key = "'" 756 | if pumvisible() " the 3rd choice 757 | let key = '\\\' 758 | elseif s:mode.windowless && s:gi_dynamic 759 | let key = '\\' 760 | call g:Vimim_space() 761 | elseif g:Vimim_punctuation < 3 762 | return key 763 | elseif s:toggle_punctuation > 0 764 | let pairs = split(s:key_evils[key], '\zs') 765 | let s:smart_quotes.single += 1 766 | let key = get(pairs, s:smart_quotes.single % 2) 767 | endif 768 | sil!exe 'sil!return "' . key . '"' 769 | endfunction 770 | 771 | function! g:Vimim_double_quote() 772 | let key = '"' 773 | if s:toggle_punctuation > 0 774 | let pairs = split(s:key_evils[key], '\zs') 775 | let s:smart_quotes.double += 1 776 | let yes = pumvisible() ? '\' : "" 777 | let key = yes . get(pairs, s:smart_quotes.double % 2) 778 | endif 779 | sil!exe 'sil!return "' . key . '"' 780 | endfunction 781 | 782 | function! g:Vimim_bslash() 783 | let key = '\' 784 | if s:toggle_punctuation > 0 785 | let yes = pumvisible() ? '\' : "" 786 | let key = yes . s:key_evils[key] 787 | endif 788 | sil!exe 'sil!return "' . key . '"' 789 | endfunction 790 | 791 | " ============================================= }}} 792 | let s:VimIM += [" ==== mode: windowless ==== {{{"] 793 | " ================================================= 794 | 795 | function! g:Vimim_gi() 796 | let s:mode = s:windowless 797 | let key = s:vimim_start() 798 | sil!exe 'sil!return "' . key . '"' 799 | endfunction 800 | 801 | function! g:Vimim_tab(gi) 802 | " (1) Tab in insert mode => start Tab or windowless/onekey 803 | " (2) Tab in pumvisible => print out menu 804 | let key = "\t" 805 | if empty(len(s:vimim_left())) 806 | elseif pumvisible() || s:ctrl6 807 | let @0 = getline(".") " undo if dump out by accident 808 | let key = s:vimim_screenshot() 809 | else 810 | let s:mode = a:gi? s:windowless : s:onekey 811 | let key = s:vimim_start() . s:vimim_onekey_action() 812 | endif 813 | sil!exe 'sil!return "' . key . '"' 814 | endfunction 815 | 816 | function! s:vimim_windowless(key) 817 | " workaround to test if active completion 818 | let key = a:key " gi \bslash space space 819 | if s:pattern_not_found " gi ma space xj space ctrl+u space 820 | elseif s:vimim_left() && s:keyboard !~ ' ' " gi mmm.. space 7 space 821 | elseif s:omni " assume completion active 822 | let key = len(a:key) ? '\\=g:Vimim()\' : '\' 823 | let cursor = empty(len(a:key)) ? 1 : a:key < 1 ? 9 : a:key-1 824 | if s:vimim_cjk() " gi ma space isw8ql 825 | let s:hjkl .= a:key " 1234567890 for windowless filter 826 | else " 234567890 for windowless choice 827 | let key = a:key =~ '[02-9]' ? repeat('\', cursor) : key 828 | endif 829 | call s:vimim_windowless_titlestring(cursor) 830 | else 831 | call s:vimim_set_title(g:Vimim) 832 | endif 833 | sil!exe 'sil!return "' . key . '"' 834 | endfunction 835 | 836 | function! g:Vimim_pagedown() 837 | let key = ' ' 838 | if pumvisible() 839 | let s:pageup_pagedown = &pumheight ? 1 : 0 840 | let key = &pumheight ? g:Vimim() : '\' 841 | endif 842 | sil!exe 'sil!return "' . key . '"' 843 | endfunction 844 | 845 | function! g:Vimim_space() 846 | " (1) Space after English (valid keys) => trigger keycode menu 847 | " (2) Space after omni popup menu => insert Chinese 848 | " (3) Space after pattern not found => Space 849 | " (4) Space after chinese windowless => for next match 850 | " (5) Space after chinese windowless wubi => deactive completion 851 | let key = " " 852 | if pumvisible() 853 | let key = '\=g:Vimim()\' 854 | if s:mode.onekey && s:hit_and_run 855 | let key = s:vimim_stop() 856 | endif 857 | let cursor = s:mode.static ? '\\' : '' 858 | let key = cursor . '\' . key 859 | elseif s:pattern_not_found 860 | elseif s:mode.dynamic 861 | elseif s:mode.static 862 | let key = s:vimim_left() ? g:Vimim() : key 863 | elseif s:seamless_positions == getpos(".") " gi ma space enter space 864 | let s:smart_enter = 0 " Space is Space after Enter 865 | elseif s:mode.windowless && s:gi_dynamic 866 | let key = '' " gi m space (the 1st choice) 867 | let s:gi_dynamic_on = 1 " gi m ; (the 2nd choice) 868 | call s:vimim_set_title(g:Vimim) " gi m ' (the 3rd choice) 869 | else 870 | let key = s:vimim_onekey_action() 871 | endif 872 | call s:vimim_reset_after_insert() 873 | sil!exe 'sil!return "' . key . '"' 874 | endfunction 875 | 876 | function! g:Vimim_enter() 877 | let s:omni = 0 878 | let key = "" 879 | if pumvisible() 880 | let key = "\" 881 | let s:smart_enter = 1 " single Enter after English => seamless 882 | elseif s:vimim_left() || s:mode.windowless 883 | let s:smart_enter = 1 " gi ma space enter space space 884 | if s:seamless_positions == getpos(".") 885 | let s:smart_enter += 1 886 | endif 887 | else 888 | let s:smart_enter = 0 889 | endif 890 | if s:smart_enter == 1 891 | let s:seamless_positions = getpos(".") 892 | else 893 | let key = "\" " Enter is Enter after Enter 894 | let s:smart_enter = 0 895 | endif 896 | sil!call s:vimim_set_title(g:Vimim) 897 | sil!exe 'sil!return "' . key . '"' 898 | endfunction 899 | 900 | function! g:Vimim_one_key_correction() 901 | " :help i_CTRL-U Delete all entered characters ... 902 | let key = nr2char(21) 903 | if s:mode.windowless || s:mode.static && pumvisible() 904 | if s:omni " one_key_correction " gi m space a space ctrl+u 905 | let s:omni = -1 " gi mamahuhu space ctrl+u ctrl+u 906 | let key = '\\=g:Vimim()\\\' 907 | endif 908 | elseif pumvisible() 909 | let range = col(".") - 1 - s:starts.column 910 | let key = '\' . repeat("\\", range) 911 | endif 912 | sil!call s:vimim_reset_after_insert() 913 | sil!exe 'sil!return "' . key . '"' 914 | endfunction 915 | 916 | function! g:Vimim_backspace() 917 | " has special meaning in all 3 states of popupmenu-completion 918 | let s:omni = 0 " disable active omni completion state 919 | let key = pumvisible() ? '\=g:Vimim()\' : '' 920 | let key = '\\' . key 921 | sil!exe 'sil!return "' . key . '"' 922 | endfunction 923 | 924 | function! s:vimim_screenshot() 925 | let keyboard = get(split(s:keyboard),0) 926 | let space = repeat(" ", virtcol(".")-len(keyboard)-1) 927 | if s:keyboard =~ '^vim' 928 | let space = "" " no need to format if it is egg 929 | elseif !empty(s:keyboard) 930 | call setline(".", keyboard) 931 | endif 932 | let saved_position = getpos(".") 933 | for items in s:popup_list 934 | let line = printf('%s', items.word) 935 | if has_key(items, "abbr") 936 | let line = printf('%s', items.abbr) 937 | if has_key(items, "menu") 938 | let line = printf('%s %s', items.abbr, items.menu) 939 | endif 940 | endif 941 | put=space.line 942 | endfor 943 | call setpos(".", saved_position) 944 | let key = g:Vimim_esc() 945 | sil!exe 'sil!return "' . key . '"' 946 | endfunction 947 | 948 | " ============================================= }}} 949 | let s:VimIM += [" ==== mode: onekey ==== {{{"] 950 | " ================================================= 951 | 952 | function! g:Vimim_onekey() 953 | " (1) OneKey in insert mode => start omni popup mode 954 | " (2) OneKey in onekey mode => close omni popup mode 955 | " (3) OneKey in chinese mode => switch to the next im 956 | " (4) OneKey in pumvisible => print out menu 957 | let key = '' 958 | if pumvisible() 959 | let key = s:vimim_screenshot() 960 | elseif empty(s:ctrl6) 961 | let key = s:vimim_start() . s:vimim_onekey_action() 962 | elseif s:mode.onekey 963 | let key = s:vimim_stop() 964 | else 965 | let s:toggle_im += 1 966 | let switch = s:toggle_im % len(s:ui.frontends) 967 | let s:ui.root = get(get(s:ui.frontends, switch), 0) 968 | let s:ui.im = get(get(s:ui.frontends, switch), 1) 969 | if s:ui.root == 'cloud' && s:ui.im != 'mycloud' 970 | let s:cloud = s:ui.im 971 | endif 972 | let key = s:vimim_start() 973 | endif 974 | sil!exe 'sil!return "' . key . '"' 975 | endfunction 976 | 977 | function! s:vimim_onekey_action() 978 | let s:hjkl = "" 979 | let key = s:vimim_onekey_evils() 980 | if empty(key) 981 | if s:vimim_left() 982 | let key = g:Vimim() 983 | elseif s:mode.windowless 984 | let key = s:vimim_windowless("") 985 | endif 986 | endif 987 | sil!exe 'sil!return "' . key . '"' 988 | endfunction 989 | 990 | function! s:vimim_onekey_evils() 991 | let key = "" " punctuations can be made not so evil .. 992 | let one = getline(".")[col(".")-2] " one byte before 993 | let two = getline(".")[col(".")-3] " two byte before 994 | let onekey_evils = copy(s:all_evils) 995 | call extend(onekey_evils, s:key_evils) 996 | if getline(".")[col(".")-3 : col(".")-2] == ".." " before_before 997 | " [game] dot dot => quotes => popup menu 998 | let three = getline(".")[col(".")-4] 999 | if col(".") < 5 || empty(three) || three =~ '\s' 1000 | let key = "''''''" " <= .. plays mahjong 1001 | elseif three =~# "[0-9a-z]" 1002 | let key = "'''" " <= xx.. plays hjkl_m 1003 | else 1004 | let key = "''" " <= 香.. plays same cjk 1005 | endif 1006 | let key = "\\" . key . '\=g:Vimim()\' 1007 | elseif one == "'" && two =~ "[a-z']" " force cloud 1008 | elseif one =~# "[0-9a-z]" || one =~# '\s' || empty(one) 1009 | elseif two =~# "[0-9a-z]" || one =~# '\u' 1010 | let key = " " " ma,space => ma, space 1011 | elseif has_key(onekey_evils, one) 1012 | for char in keys(onekey_evils) 1013 | if two ==# char || two =~# '\u' 1014 | return " " " no transfer if punctuation punctuation 1015 | endif 1016 | endfor 1017 | let bs = onekey_evils[one] " make Chinese punctuation 1018 | if one == '"' || one == '"' 1019 | let bs .= '\' 1020 | endif 1021 | let key = "\\" . bs 1022 | endif 1023 | sil!exe 'sil!return "' . key . '"' 1024 | endfunction 1025 | 1026 | function! s:vimim_get_no_quote_head(keyboard) 1027 | let keyboard = a:keyboard 1028 | if keyboard =~ '\d' || s:ui.root == 'cloud' 1029 | return keyboard 1030 | endif 1031 | if s:hjkl_m && s:hjkl_m % 2 || keyboard =~ '^\l\l\+'."'''".'$' 1032 | " [shoupin] hjkl_m || sssss.. => sssss''' => s's's's's 1033 | let keyboard = substitute(keyboard, "'", "", 'g') 1034 | let keyboard = join(split(keyboard,'\zs'), "'") 1035 | endif 1036 | if keyboard =~ "'" && keyboard[-1:] != "'" 1037 | " [quote_by_quote] wo'you'yi'ge'meng 1038 | let keyboards = split(keyboard,"'") 1039 | let keyboard = get(keyboards,0) 1040 | let tail = join(keyboards[1:],"'") 1041 | let tail = len(tail) == 1 ? "'" . tail : tail 1042 | let s:keyboard = keyboard . " " . tail 1043 | endif 1044 | return keyboard 1045 | endfunction 1046 | 1047 | " ============================================= }}} 1048 | let s:VimIM += [" ==== mode: chinese ==== {{{"] 1049 | " ================================================= 1050 | 1051 | function! g:Vimim_chinese() 1052 | let s:mode = g:Vimim_mode =~ 'static' ? s:static : s:dynamic 1053 | let s:switch = empty(s:ui.frontends) ? -1 : s:switch ? 0 : 1 1054 | return s:switch<0 ? "" : s:switch ? s:vimim_start() : s:vimim_stop() 1055 | endfunction 1056 | 1057 | function! s:vimim_set_keyboard_maps() 1058 | let common_punctuations = split("] [ = -") 1059 | let common_labels = s:ui.im =~ 'phonetic' ? [] : range(10) 1060 | let s:gi_dynamic = s:mode.windowless ? s:gi_dynamic : 0 1061 | let both_dynamic = s:mode.dynamic || s:gi_dynamic ? 1 : 0 1062 | if both_dynamic 1063 | for char in s:valid_keys 1064 | sil!exe 'lnoremap ' . char . ' ' . 1065 | \ '=g:Wubi()' . char . '=g:Vimim()' 1066 | endfor 1067 | elseif s:mode.static 1068 | for char in s:valid_keys 1069 | sil!exe 'lnoremap ' . char . ' ' . char 1070 | endfor 1071 | else 1072 | let common_punctuations += split(". ,") 1073 | let common_labels += s:abcd[1:] 1074 | let pqwertyuio = s:vimim_cjk() ? s:qwer : [] 1075 | for _ in pqwertyuio + split("h j k l m n / ? s") 1076 | sil!exe 'lnoremap '._.' g:Vimim_hjkl("'._.'")' 1077 | endfor 1078 | endif 1079 | if g:Vimim_punctuation < 0 1080 | elseif both_dynamic || s:mode.static 1081 | sil!call s:vimim_punctuation_maps() 1082 | endif 1083 | for _ in s:mode.windowless ? [] : common_punctuations 1084 | if _ !~ s:valid_keyboard 1085 | sil!exe 'lnoremap '._.' g:Vimim_page("'._.'")' 1086 | endif 1087 | endfor 1088 | for _ in common_labels 1089 | sil!exe 'lnoremap '._.' g:Vimim_label("'._.'")' 1090 | endfor 1091 | endfunction 1092 | 1093 | function! s:vimim_set_im_toggle_list() 1094 | let toggle_list = [] 1095 | if g:Vimim_toggle < 0 1096 | let toggle_list = [get(s:ui.frontends,0)] 1097 | elseif empty(g:Vimim_toggle) 1098 | let toggle_list = s:ui.frontends 1099 | else 1100 | for toggle in split(g:Vimim_toggle, ",") 1101 | for [root, im] in s:ui.frontends 1102 | if toggle == im 1103 | call add(toggle_list, [root, im]) 1104 | endif 1105 | endfor 1106 | endfor 1107 | endif 1108 | if s:backend[s:ui.root][s:ui.im].name =~ "bsddb" 1109 | let toggle_list = toggle_list[:2] " one bsddb two clouds 1110 | endif 1111 | let s:frontends = copy(toggle_list) 1112 | let s:ui.frontends = copy(toggle_list) 1113 | let s:ui.root = get(get(s:ui.frontends,0), 0) 1114 | let s:ui.im = get(get(s:ui.frontends,0), 1) 1115 | endfunction 1116 | 1117 | function! s:vimim_get_seamless(cursor_positions) 1118 | if empty(s:seamless_positions) 1119 | \|| s:seamless_positions[0] != a:cursor_positions[0] 1120 | \|| s:seamless_positions[1] != a:cursor_positions[1] 1121 | \|| s:seamless_positions[3] != a:cursor_positions[3] 1122 | return -1 1123 | endif 1124 | let current_line = getline(a:cursor_positions[1]) 1125 | let seamless_column = s:seamless_positions[2]-1 1126 | let len = a:cursor_positions[2]-1 - seamless_column 1127 | let snip = strpart(current_line, seamless_column, len) 1128 | if empty(len(snip)) 1129 | return -1 1130 | endif 1131 | for char in split(snip, '\zs') 1132 | if char !~ s:valid_keyboard 1133 | return -1 1134 | endif 1135 | endfor 1136 | return seamless_column 1137 | endfunction 1138 | 1139 | " ============================================= }}} 1140 | let s:VimIM += [" ==== input: visual ==== {{{"] 1141 | " ================================================= 1142 | 1143 | function! g:Vimim_visual() 1144 | let key = "" 1145 | let lines = split(getreg('"'), '\n') 1146 | let line = get(lines,0) 1147 | let space = "\=repeat(' '," .string(virtcol("'<'")-2). ")\" 1148 | if len(lines) == 1 && len(line) == s:multibyte 1149 | " highlight one chinese => get antonym or number loop 1150 | let results = s:vimim_imode_visual(line) 1151 | if !empty(results) 1152 | let key = "gvr" . get(results,0) . "ga" 1153 | endif 1154 | if s:vimim_cjk() 1155 | let line = match(s:cjk.lines, "^".line) 1156 | call s:vimim_set_title(s:space.get(s:cjk.lines,line)) 1157 | endif 1158 | elseif match(lines,'\d') > -1 && join(lines) !~ '[^0-9[:blank:].]' 1159 | call setpos(".", getpos("'>'")) " vertical digit block => 1160 | let sum = eval(join(lines,'+')) " count*average=summary 1161 | let ave = printf("%.2f", 1.0*sum/len(lines)) 1162 | let line = substitute(ave."=".string(sum), '[.]0\+', '', 'g') 1163 | let line = string(len(lines)) . '*' . line 1164 | let key = "o" . nr2char(4) . space . " " . line . nr2char(27) 1165 | else 1166 | sil!call s:vimim_start() 1167 | let visual = nr2char(30) . "\=g:Vimim()\" 1168 | if len(lines) < 2 " highlight multiple cjk => show property 1169 | let s:seamless_positions = getpos("'<'") 1170 | let chinese = get(split(line,'\zs'),0) 1171 | let ddddd = char2nr(chinese) =~ '\d\d\d\d\d' ? "'''''" : line 1172 | let key = "gvc" . ddddd . visual 1173 | else " highlighted block => play block with hjkl 1174 | let key = "O^\" . space . "''''" . visual 1175 | endif 1176 | endif 1177 | return feedkeys(key,"n") 1178 | endfunction 1179 | 1180 | function! s:vimim_imode_visual(char_before) 1181 | let items = [] 1182 | let numbers = [] 1183 | let results = [] 1184 | if empty(s:loops) 1185 | for i in range(len(s:numbers)) 1186 | call add(items, split(s:numbers[i],'\zs')) 1187 | endfor 1188 | for j in range(len(get(items,0))) 1189 | let number = "" 1190 | for line in items 1191 | let number .= get(line,j) 1192 | endfor 1193 | call add(numbers, number) 1194 | endfor 1195 | for loop in numbers + split(s:antonym) + split("金石 真假 胜败") 1196 | let loops = split(loop, '\zs') 1197 | for i in range(len(loops)) 1198 | let j = i==len(loops)-1 ? 0 : i+1 1199 | let s:loops[loops[i]] = loops[j] 1200 | endfor 1201 | endfor 1202 | endif 1203 | let char_before = a:char_before 1204 | if has_key(s:loops, char_before) 1205 | let start = char_before 1206 | let next = "" 1207 | while start != next 1208 | let next = s:loops[char_before] 1209 | call add(results, next) 1210 | let char_before = next 1211 | endwhile 1212 | endif 1213 | return results 1214 | endfunction 1215 | 1216 | " ============================================= }}} 1217 | let s:VimIM += [" ==== input: number ==== {{{"] 1218 | " ================================================= 1219 | 1220 | function! s:vimim_dictionary_numbers() 1221 | let s:loops = {} 1222 | let s:numbers = {} 1223 | let s:numbers.1 = "一壹⑴①甲" 1224 | let s:numbers.2 = "二贰⑵②乙" 1225 | let s:numbers.3 = "三叁⑶③丙" 1226 | let s:numbers.4 = "四肆⑷④丁" 1227 | let s:numbers.5 = "五伍⑸⑤戊" 1228 | let s:numbers.6 = "六陆⑹⑥己" 1229 | let s:numbers.7 = "七柒⑺⑦庚" 1230 | let s:numbers.8 = "八捌⑻⑧辛" 1231 | let s:numbers.9 = "九玖⑼⑨壬" 1232 | let s:numbers.0 = "〇零⑽⑩癸" 1233 | let s:quantifiers = copy(s:numbers) 1234 | let s:quantifiers.2 .= "两俩" 1235 | let s:quantifiers.b = "百佰步把包杯本笔部班" 1236 | let s:quantifiers.c = "次餐场串处床" 1237 | let s:quantifiers.d = "第度点袋道滴碟顶栋堆对朵堵顿" 1238 | let s:quantifiers.f = "分份发封付副幅峰方服" 1239 | let s:quantifiers.g = "个根股管" 1240 | let s:quantifiers.h = "行盒壶户回毫" 1241 | let s:quantifiers.j = "斤家具架间件节剂具捲卷茎记" 1242 | let s:quantifiers.k = "克口块棵颗捆孔" 1243 | let s:quantifiers.l = "里粒类辆列轮厘领缕" 1244 | let s:quantifiers.m = "米名枚面门秒" 1245 | let s:quantifiers.n = "年" 1246 | let s:quantifiers.p = "磅盆瓶排盘盆匹片篇撇喷" 1247 | let s:quantifiers.q = "千仟群" 1248 | let s:quantifiers.r = "日人" 1249 | let s:quantifiers.s = "十拾时升艘扇首双所束手" 1250 | let s:quantifiers.t = "天吨条头通堂趟台套桶筒贴" 1251 | let s:quantifiers.w = "万位味碗窝晚微" 1252 | let s:quantifiers.x = "席些项" 1253 | let s:quantifiers.y = "月元叶亿" 1254 | let s:quantifiers.z = "种只张株支总枝盏座阵桩尊则站幢宗兆" 1255 | endfunction 1256 | 1257 | let s:translators = {} 1258 | function! s:translators.translate(english) dict 1259 | let inputs = split(a:english) 1260 | return join(map(inputs,'get(self.dict,tolower(v:val),v:val)'), '') 1261 | endfunction 1262 | 1263 | function! s:vimim_imode_today_now(keyboard) 1264 | let one = " year sunday monday tuesday wednesday thursday" 1265 | let one .= " friday saturday month day hour minute second" 1266 | let two = join(split("年 日 一 二 三 四 五 六"), " 星期") 1267 | let two .= " 月 日 时 分 秒" 1268 | let chinese = copy(s:translators) 1269 | let chinese.dict = s:vimim_key_value_hash(one, two) 1270 | let time = '公元' 1271 | let time .= strftime("%Y") . ' year ' 1272 | let time .= strftime("%m") . ' month ' 1273 | let time .= strftime("%d") . ' day ' 1274 | if a:keyboard ==# 'itoday' 1275 | let time .= s:space .' '. strftime("%A") 1276 | elseif a:keyboard ==# 'inow' 1277 | let time .= strftime("%H") . ' hour ' 1278 | let time .= strftime("%M") . ' minute ' 1279 | let time .= strftime("%S") . ' second ' 1280 | endif 1281 | let filter = "substitute(" . 'v:val' . ",'^0','','')" 1282 | return chinese.translate(join(map(split(time), filter))) 1283 | endfunction 1284 | 1285 | function! s:vimim_imode_number(keyboard) 1286 | let keyboard = a:keyboard 1287 | let ii = keyboard[0:1] " sample: i88 ii88 isw8ql iisw8ql 1288 | let keyboard = ii==#'ii' ? keyboard[2:] : keyboard[1:] 1289 | let dddl = keyboard=~#'^\d*\l\{1}$' ? keyboard[:-2] : keyboard 1290 | let number = "" 1291 | let keyboards = split(dddl, '\ze') 1292 | for char in keyboards 1293 | if has_key(s:quantifiers, char) 1294 | let quantifier_list = split(s:quantifiers[char], '\zs') 1295 | let chinese = get(quantifier_list, 0) 1296 | if ii ==# 'ii' && char =~# '[0-9sbq]' 1297 | let chinese = get(quantifier_list, 1) 1298 | endif 1299 | let number .= chinese 1300 | endif 1301 | endfor 1302 | if empty(number) | return [] | endif 1303 | let results = [number] 1304 | let last_char = keyboard[-1:] 1305 | if !empty(last_char) && has_key(s:quantifiers, last_char) 1306 | let quantifier_list = split(s:quantifiers[last_char], '\zs') 1307 | if keyboard =~# '^[ds]\=\d*\l\{1}$' 1308 | if keyboard =~# '^[ds]' 1309 | let number = strpart(number,0,len(number)-s:multibyte) 1310 | endif 1311 | let results = map(copy(quantifier_list), 'number . v:val') 1312 | elseif keyboard =~# '^\d*$' && len(keyboards)<2 && ii != 'ii' 1313 | let results = quantifier_list 1314 | endif 1315 | endif 1316 | return results 1317 | endfunction 1318 | 1319 | " ============================================= }}} 1320 | let s:VimIM += [" ==== input: unicode ==== {{{"] 1321 | " ================================================= 1322 | 1323 | function! s:vimim_i18n(line) 1324 | let line = a:line 1325 | if s:localization == 1 1326 | return iconv(line, "chinese", "utf-8") 1327 | elseif s:localization == 2 1328 | return iconv(line, "utf-8", &enc) 1329 | endif 1330 | return line 1331 | endfunction 1332 | 1333 | function! s:vimim_unicode_list(ddddd) 1334 | let results = [] 1335 | for i in range(99) 1336 | call add(results, nr2char(a:ddddd+i)) 1337 | endfor 1338 | return results 1339 | endfunction 1340 | 1341 | function! s:vimim_get_unicode_ddddd(keyboard) 1342 | let ddddd = 0 1343 | if a:keyboard =~# '^u\x\{4}$' " u9f9f => 40863 1344 | let ddddd = str2nr(a:keyboard[1:],16) 1345 | elseif a:keyboard =~# '^\d\{5}$' " 39532 => 39532 1346 | let ddddd = str2nr(a:keyboard, 10) 1347 | endif 1348 | let max = &encoding=="utf-8" ? 19968+20902 : 0xffff 1349 | if ddddd < 8080 || ddddd > max 1350 | let ddddd = 0 1351 | endif 1352 | return ddddd 1353 | endfunction 1354 | 1355 | function! s:vimim_unicode_to_utf8(xxxx) 1356 | let utf8 = '' " u808f => 32911 => e8828f 1357 | let ddddd = str2nr(a:xxxx, 16) 1358 | if ddddd < 128 1359 | let utf8 .= nr2char(ddddd) 1360 | elseif ddddd < 2048 1361 | let utf8 .= nr2char(192+((ddddd-(ddddd%64))/64)) 1362 | let utf8 .= nr2char(128+(ddddd%64)) 1363 | else 1364 | let utf8 .= nr2char(224+((ddddd-(ddddd%4096))/4096)) 1365 | let utf8 .= nr2char(128+(((ddddd%4096)-(ddddd%64))/64)) 1366 | let utf8 .= nr2char(128+(ddddd%64)) 1367 | endif 1368 | return utf8 1369 | endfunction 1370 | 1371 | function! s:vimim_url_xx_to_chinese(xx) 1372 | let output = a:xx " %E9%A6%AC => \xE9\xA6\xAC => 馬 u99AC 1373 | if s:http_exe =~ 'libvimim' 1374 | let output = libcall(s:http_exe, "do_unquote", output) 1375 | else 1376 | let pat = '%\(\x\x\)' 1377 | let sub = '\=eval(''"\x''.submatch(1).''"'')' 1378 | let output = substitute(output, pat, sub, 'g') 1379 | endif 1380 | return output 1381 | endfunction 1382 | 1383 | function! s:vimim_rot13(keyboard) 1384 | let a = "12345abcdefghijklmABCDEFGHIJKLM" 1385 | let z = "98760nopqrstuvwxyzNOPQRSTUVWXYZ" 1386 | return tr(a:keyboard, a.z, z.a) 1387 | endfunction 1388 | 1389 | function! s:vimim_left() 1390 | let key = 0 " validate the character on the left of the cursor 1391 | let one_byte_before = getline(".")[col(".")-2] 1392 | if one_byte_before =~ '\s' || empty(one_byte_before) 1393 | let key = "" 1394 | elseif one_byte_before =~# s:valid_keyboard 1395 | let key = 1 1396 | endif 1397 | return key 1398 | endfunction 1399 | 1400 | function! s:vimim_key_value_hash(single, double) 1401 | let hash = {} 1402 | let singles = split(a:single) 1403 | let doubles = split(a:double) 1404 | for i in range(len(singles)) 1405 | let hash[get(singles,i)] = get(doubles,i) 1406 | endfor 1407 | return hash 1408 | endfunction 1409 | 1410 | function! s:chinese(...) 1411 | let chinese = "" 1412 | for english in a:000 1413 | let cjk = english 1414 | if has_key(s:chinese_statusline, english) 1415 | let twins = split(s:chinese_statusline[english], ",") 1416 | let cjk = get(twins, 0) 1417 | if len(twins) > 1 && s:mandarin 1418 | let cjk = get(twins,1) 1419 | endif 1420 | endif 1421 | let chinese .= cjk 1422 | endfor 1423 | return chinese 1424 | endfunction 1425 | 1426 | " ============================================= }}} 1427 | let s:VimIM += [" ==== input: cjk ==== {{{"] 1428 | " ================================================= 1429 | 1430 | function! s:vimim_cjk() 1431 | if empty(s:cjk.filename) 1432 | return 0 1433 | elseif empty(s:cjk.lines) 1434 | let s:cjk.lines = s:vimim_readfile(s:cjk.filename) 1435 | if len(s:cjk.lines) != 20902 | return 0 | endif 1436 | endif 1437 | return 1 1438 | endfunction 1439 | 1440 | function! s:vimim_cjk_in_4corner(chinese, info) 1441 | let digit_head = "" " gi ma 马  => 7712 <=> mali 7 4 1442 | let digit_tail = "" " gi mali 马力 => 7 4002 <=> mali74 1443 | let chinese = substitute(a:chinese,'[\x00-\xff]','','g') 1444 | for cjk in split(chinese, '\zs') 1445 | let line = match(s:cjk.lines, "^" . cjk) 1446 | if line > -1 1447 | let values = split(get(s:cjk.lines, line)) 1448 | let digit_head .= get(values,1)[:0] 1449 | let digit_tail = get(values,1)[1:] 1450 | endif 1451 | endfor 1452 | let key = digit_head . digit_tail 1453 | let key = empty(a:info) && match(key, "^".s:hjkl) < 0 ? 0 : key 1454 | return key 1455 | endfunction 1456 | 1457 | function! s:vimim_cjk_property(chinese) 1458 | let ddddd = char2nr(a:chinese) 1459 | let xxxx = printf('u%04x', ddddd) 1460 | let unicode = ddddd . s:space . xxxx 1461 | if s:vimim_cjk() 1462 | let unicode = repeat(s:space,3) . xxxx . s:space . ddddd 1463 | let line = match(s:cjk.lines, "^" . a:chinese) 1464 | if line > -1 1465 | let values = split(get(s:cjk.lines, line)) 1466 | let digit = get(values, 1) . s:space 1467 | let frequency = get(values, -1) !~ '\D' ? 1 : 0 1468 | let pinyin = join(frequency ? values[2:-2] : values[2:]) 1469 | let unicode = digit . xxxx . s:space . pinyin 1470 | endif 1471 | endif 1472 | return unicode 1473 | endfunction 1474 | 1475 | function! s:vimim_cjk_match(key) 1476 | let key = a:key 1477 | if empty(key) || empty(s:vimim_cjk()) | return [] | endif 1478 | let grep = "" 1479 | let grep_frequency = '.*' . '\s\d\+$' 1480 | if key =~ '\d' 1481 | if key =~# '^\l\l\+[1-4]\>' && empty(len(s:hjkl)) 1482 | let grep = key . '[a-z ]' " cjk pinyin: huan2hai2 yi1 1483 | else 1484 | let digit = "" 1485 | if key =~ '^\d\+' && key !~ '[^0-9]' 1486 | let digit = key " free style digit: 7 77 771 7712 1487 | elseif key =~# '^\l\+\d\+' " free style: ma7 ma77 ma771 ma7712 1488 | let digit = substitute(key,'\a','','g') 1489 | endif 1490 | if !empty(digit) 1491 | let space = '\d\{' . string(4-len(digit)) . '}' 1492 | let space = len(digit)==4 ? "" : space 1493 | let grep = '\s\+' . digit . space . '\s' 1494 | let alpha = substitute(key,'\d','','g') 1495 | if len(alpha) 1496 | let grep .= '\(\l\+\d\)\=' . alpha " le|yue: le4yue4 1497 | elseif len(key) == 1 1498 | let grep .= grep_frequency " grep l|y: happy music 1499 | endif 1500 | endif 1501 | endif 1502 | elseif s:ui.im != 'mycloud' 1503 | if len(key) == 1 " one cjk by frequency y72/yue72 l72/le72 1504 | let grep = '[ 0-9]' . key . '\l*\d' . grep_frequency 1505 | let grep = key == 'u' ? ' u\( \|$\)' : grep " 214 unicode 1506 | elseif key =~# '^\l\+' " cjk list: /huan /hai /yet /huan2 /hai2 1507 | let grep = '[ 0-9]' . key . '[0-9]' 1508 | endif 1509 | endif 1510 | let results = [] 1511 | if !empty(grep) 1512 | let line = match(s:cjk.lines, grep) 1513 | while line > -1 1514 | let fields = split(get(s:cjk.lines, line)) 1515 | let frequency = get(fields,-1)=~'\l' ? 9999 : get(fields,-1) 1516 | call add(results, get(fields,0) . ' ' . frequency) 1517 | let line = match(s:cjk.lines, grep, line+1) 1518 | endwhile 1519 | endif 1520 | let results = sort(results, "s:vimim_sort_on_last") 1521 | let filter = "strpart(" . 'v:val' . ", 0, s:multibyte)" 1522 | return map(results, filter) 1523 | endfunction 1524 | 1525 | function! s:vimim_get_cjk_head(key) 1526 | let key = a:key 1527 | if empty(s:cjk.filename) || key =~ "'" | return "" | endif 1528 | if key =~# '^i' && empty (s:english.line) " iuuqwuqew => 77127132 1529 | let key = s:vimim_qwertyuiop_1234567890(key[1:]) 1530 | endif 1531 | let head = "" 1532 | if s:touch_me_not || len(key) == 1 1533 | let head = key 1534 | elseif key =~ '\d' 1535 | if key =~ '^\d' && key !~ '\D' 1536 | let head = len(key) > 4 ? s:vimim_get_head(key, 4) : key 1537 | let s:hjkl = empty(len(s:hjkl)) ? head : s:hjkl 1538 | elseif key =~# '^\l\+\d\+\>' " 7712 in 77124002 1539 | let partition = match(key,'\d') " ma7 ma77 ma771 1540 | let head = key[0 : partition-1] " mali in mali74 1541 | let tail = key[partition :] " 74 in mali74 1542 | if empty(s:vimim_get_pinyin(head)) && tail =~ '[1-4]' 1543 | return key " pinyin with tone: ma1/ma2/ma3/ma4 1544 | endif 1545 | let s:hjkl = empty(len(s:hjkl)) ? tail : s:hjkl 1546 | elseif key =~# '^\l\+\d\+' " wo23 for input wo23you40 1547 | let partition = match(key, '\(\l\+\d\+\)\@<=\D') 1548 | let head = s:vimim_get_head(key, partition) 1549 | endif 1550 | elseif empty(s:english.line) " muuqwxeyqpjeqqq => m7712x3610j3111 1551 | if key =~# '^\l' && len(key)%5 < 1 " awwwr/a2224 arrow color 1552 | let dddd = s:vimim_qwertyuiop_1234567890(key[1:4]) 1553 | if !empty(dddd) 1554 | let key = key[0:0] . dddd . key[5:-1] 1555 | let head = s:vimim_get_head(key, 5) 1556 | endif 1557 | else 1558 | let head = key " get single character from cjk 1559 | endif 1560 | endif 1561 | return head 1562 | endfunction 1563 | 1564 | function! s:vimim_get_head(keyboard, partition) 1565 | if a:partition < 0 | return a:keyboard | endif 1566 | let head = a:keyboard[0 : a:partition-1] 1567 | if s:keyboard !~ '\S\s\S' 1568 | let s:keyboard = head 1569 | let tail = a:keyboard[a:partition : -1] 1570 | if !empty(tail) 1571 | let s:keyboard = head . " " . tail 1572 | endif 1573 | endif 1574 | return head 1575 | endfunction 1576 | 1577 | function! s:vimim_qwertyuiop_1234567890(keyboard) 1578 | if a:keyboard =~ '\d' | return "" | endif 1579 | let dddd = "" " output is 7712 for input uuqw 1580 | for char in split(a:keyboard, '\zs') 1581 | let digit = match(s:qwer, char) 1582 | if digit < 0 1583 | return "" 1584 | else 1585 | let dddd .= digit 1586 | endif 1587 | endfor 1588 | return dddd 1589 | endfunction 1590 | 1591 | function! s:vimim_sort_on_last(line1, line2) 1592 | let line1 = get(split(a:line1),-1) + 1 1593 | let line2 = get(split(a:line2),-1) + 1 1594 | if line1 < line2 1595 | return -1 1596 | elseif line1 > line2 1597 | return 1 1598 | endif 1599 | return 0 1600 | endfunction 1601 | 1602 | function! s:vimim_chinese_transfer() range abort 1603 | " the quick and dirty way to transfer between Chinese 1604 | if s:vimim_cjk() 1605 | exe a:firstline.",".a:lastline.'s/./\=s:vimim_1to1(submatch(0))' 1606 | endif 1607 | endfunction 1608 | 1609 | function! s:vimim_1to1(char) 1610 | if a:char =~ '[\x00-\xff]' | return a:char | endif 1611 | let grep = '^' . a:char 1612 | let line = match(s:cjk.lines, grep, 0) 1613 | if line < 0 | return a:char | endif 1614 | let values = split(get(s:cjk.lines, line)) 1615 | let traditional_chinese = get(split(get(values,0),'\zs'),1) 1616 | return empty(traditional_chinese) ? a:char : traditional_chinese 1617 | endfunction 1618 | 1619 | " ============================================= }}} 1620 | let s:VimIM += [" ==== input: english ==== {{{"] 1621 | " ================================================= 1622 | 1623 | function! s:vimim_get_english(keyboard) 1624 | if empty(s:english.filename) 1625 | return "" " english: obama/now/version/ice/o2 1626 | elseif empty(s:english.lines) 1627 | let s:english.lines = s:vimim_readfile(s:english.filename) 1628 | endif " [sql] select english from vimim.txt 1629 | let grep = '^' . a:keyboard . '\s\+' 1630 | let cursor = match(s:english.lines, grep) 1631 | let keyboards = s:vimim_get_pinyin(a:keyboard) 1632 | if cursor < 0 && len(a:keyboard) > 3 && len(keyboards) 1633 | let grep = '^' . get(split(a:keyboard,'\d'),0) " mxj7 => mxj 1634 | let cursor = match(s:english.lines, grep) 1635 | endif 1636 | let oneline = "" " [pinyin] cong => cong 1637 | if cursor > -1 " [english] congr => congratulation 1638 | let oneline = get(s:english.lines, cursor) 1639 | if a:keyboard != get(split(oneline),0) 1640 | let pairs = split(oneline) " haag haagendazs 1641 | let oneline = join(pairs[1:] + pairs[:0]) 1642 | let oneline = a:keyboard . " " . oneline 1643 | endif 1644 | endif 1645 | return oneline 1646 | endfunction 1647 | 1648 | function! s:vimim_filereadable(filename) 1649 | let datafile_1 = s:plugin . a:filename 1650 | let datafile_2 = s:plugon . a:filename 1651 | if filereadable(datafile_1) 1652 | return datafile_1 1653 | elseif filereadable(datafile_2) 1654 | return datafile_2 1655 | endif 1656 | return "" 1657 | endfunction 1658 | 1659 | function! s:vimim_readfile(datafile) 1660 | let lines = [] 1661 | if filereadable(a:datafile) 1662 | if s:localization 1663 | for line in readfile(a:datafile) 1664 | call add(lines, s:vimim_i18n(line)) 1665 | endfor 1666 | else 1667 | return readfile(a:datafile) 1668 | endif 1669 | endif 1670 | return lines 1671 | endfunction 1672 | 1673 | " ============================================= }}} 1674 | let s:VimIM += [" ==== input: pinyin ==== {{{"] 1675 | " ================================================= 1676 | 1677 | function! s:vimim_get_all_valid_pinyin_list() 1678 | return split(" 'a 'ai 'an 'ang 'ao ba bai ban bang bao bei ben beng bi 1679 | \ bian biao bie bin bing bo bu ca cai can cang cao ce cen ceng cha chai 1680 | \ chan chang chao che chen cheng chi chong chou chu chua chuai chuan 1681 | \ chuang chui chun chuo ci cong cou cu cuan cui cun cuo da dai dan dang 1682 | \ dao de dei deng di dia dian diao die ding diu dong dou du duan dui dun 1683 | \ duo 'e 'ei 'en 'er fa fan fang fe fei fen feng fiao fo fou fu ga gai 1684 | \ gan gang gao ge gei gen geng gong gou gu gua guai guan guang gui gun 1685 | \ guo ha hai han hang hao he hei hen heng hong hou hu hua huai huan huang 1686 | \ hui hun huo 'i ji jia jian jiang jiao jie jin jing jiong jiu ju juan 1687 | \ jue jun ka kai kan kang kao ke ken keng kong kou ku kua kuai kuan kuang 1688 | \ kui kun kuo la lai lan lang lao le lei leng li lia lian liang liao lie 1689 | \ lin ling liu long lou lu luan lue lun luo lv ma mai man mang mao me mei 1690 | \ men meng mi mian miao mie min ming miu mo mou mu na nai nan nang nao ne 1691 | \ nei nen neng 'ng ni nian niang niao nie nin ning niu nong nou nu nuan 1692 | \ nue nuo nv 'o 'ou pa pai pan pang pao pei pen peng pi pian piao pie pin 1693 | \ ping po pou pu qi qia qian qiang qiao qie qin qing qiong qiu qu quan 1694 | \ que qun ran rang rao re ren reng ri rong rou ru ruan rui run ruo sa sai 1695 | \ san sang sao se sen seng sha shai shan shang shao she shei shen sheng 1696 | \ shi shou shu shua shuai shuan shuang shui shun shuo si song sou su suan 1697 | \ sui sun suo ta tai tan tang tao te teng ti tian tiao tie ting tong tou 1698 | \ tu tuan tui tun tuo 'u 'v wa wai wan wang wei wen weng wo wu xi xia 1699 | \ xian xiang xiao xie xin xing xiong xiu xu xuan xue xun ya yan yang yao 1700 | \ ye yi yin ying yo yong you yu yuan yue yun za zai zan zang zao ze zei 1701 | \ zen zeng zha zhai zhan zhang zhao zhe zhen zheng zhi zhong zhou zhu 1702 | \ zhua zhuai zhuan zhuang zhui zhun zhuo zi zong zou zu zuan zui zun zuo") 1703 | endfunction 1704 | 1705 | function! s:vimim_quanpin_transform(pinyin) 1706 | if empty(s:quanpin_table) 1707 | for key in s:vimim_get_all_valid_pinyin_list() 1708 | if key[0] == "'" 1709 | let s:quanpin_table[key[1:]] = key[1:] 1710 | else 1711 | let s:quanpin_table[key] = key 1712 | endif 1713 | endfor 1714 | for shengmu in s:shengmu_list + split("zh ch sh") 1715 | let s:quanpin_table[shengmu] = shengmu 1716 | endfor 1717 | endif 1718 | let item = a:pinyin 1719 | let index = 0 " follow ibus rule, plus special case for fan'guo 1720 | let pinyinstr = "" 1721 | while index < len(item) 1722 | if item[index] !~ "[a-z]" 1723 | let index += 1 1724 | continue 1725 | endif 1726 | for i in range(6,1,-1) 1727 | let tmp = item[index : ] 1728 | if len(tmp) < i 1729 | continue 1730 | endif 1731 | let end = index+i 1732 | let matchstr = item[index : end-1] 1733 | if has_key(s:quanpin_table, matchstr) 1734 | let tempstr = item[end-1 : end] 1735 | let tempstr2 = item[end-2 : end+1] 1736 | let tempstr3 = item[end-1 : end+1] 1737 | let tempstr4 = item[end-1 : end+2] 1738 | if (tempstr == "ge" && tempstr3 != "ger") 1739 | \ || (tempstr == "ne" && tempstr3 != "ner") 1740 | \ || (tempstr4 == "gong" || tempstr3 == "gou") 1741 | \ || (tempstr4 == "nong" || tempstr3 == "nou") 1742 | \ || (tempstr == "ga" || tempstr == "na") 1743 | \ || tempstr2 == "ier" || tempstr == "ni" 1744 | \ || tempstr == "gu" || tempstr == "nu" 1745 | if has_key(s:quanpin_table, matchstr[:-2]) 1746 | let i -= 1 1747 | let matchstr = matchstr[:-2] 1748 | endif 1749 | endif 1750 | let pinyinstr .= "'" . s:quanpin_table[matchstr] 1751 | let index += i 1752 | break 1753 | elseif i == 1 1754 | let pinyinstr .= "'" . item[index] 1755 | let index += 1 1756 | break 1757 | else 1758 | continue 1759 | endif 1760 | endfor 1761 | endwhile 1762 | return pinyinstr[0] == "'" ? pinyinstr[1:] : pinyinstr 1763 | endfunction 1764 | 1765 | function! s:vimim_more_pinyin_datafile(keyboard, sentence) 1766 | let results = [] 1767 | let backend = s:backend[s:ui.root][s:ui.im] 1768 | for candidate in s:vimim_more_pinyin_candidates(a:keyboard) 1769 | let pattern = '^' . candidate . '\>' 1770 | let cursor = match(backend.lines, pattern, 0) 1771 | if cursor < 0 1772 | continue 1773 | elseif a:sentence 1774 | return [candidate] 1775 | endif 1776 | let oneline = get(backend.lines, cursor) 1777 | call extend(results, s:vimim_make_pairs(oneline)) 1778 | endfor 1779 | return results 1780 | endfunction 1781 | 1782 | function! s:vimim_get_pinyin(keyboard) 1783 | let keyboard = s:vimim_quanpin_transform(a:keyboard) 1784 | let results = split(keyboard, "'") 1785 | if len(results) > 1 1786 | return results 1787 | endif 1788 | return [] 1789 | endfunction 1790 | 1791 | function! s:vimim_more_pinyin_candidates(keyboard) 1792 | " make standard menu layout: mamahuhu => mamahu, mama 1793 | if len(s:english.line) || s:ui.im !~ 'pinyin' 1794 | \|| !empty(g:Vimim_shuangpin) || g:Vimim_cloud =~ 'shuangpin' 1795 | return [] 1796 | endif 1797 | let candidates = [] 1798 | let keyboards = s:vimim_get_pinyin(a:keyboard) 1799 | if len(keyboards) 1800 | for i in reverse(range(len(keyboards)-1)) 1801 | let candidate = join(keyboards[0 : i], "") 1802 | if !empty(candidate) 1803 | call add(candidates, candidate) 1804 | endif 1805 | endfor 1806 | if len(candidates) > 2 1807 | let candidates = candidates[0 : len(candidates)-2] 1808 | endif 1809 | endif 1810 | return candidates 1811 | endfunction 1812 | 1813 | function! s:vimim_cloud_pinyin(keyboard, match_list) 1814 | let match_list = [] 1815 | let keyboards = s:vimim_get_pinyin(a:keyboard) 1816 | for chinese in a:match_list 1817 | let len_chinese = len(split(chinese,'\zs')) 1818 | let english = join(keyboards[len_chinese :], "") 1819 | let pair = empty(english) ? chinese : chinese.english 1820 | call add(match_list, pair) 1821 | endfor 1822 | return match_list 1823 | endfunction 1824 | 1825 | " ============================================= }}} 1826 | let s:VimIM += [" ==== input: shuangpin ==== {{{"] 1827 | " ================================================= 1828 | 1829 | function! s:vimim_shuangpin_generic() 1830 | let shengmu_list = {} " generate shuangpin table default value 1831 | for shengmu in s:shengmu_list 1832 | let shengmu_list[shengmu] = shengmu 1833 | endfor 1834 | let shengmu_list["'"] = "o" 1835 | let yunmu_list = {} 1836 | for yunmu in split("a o e i u v") 1837 | let yunmu_list[yunmu] = yunmu 1838 | endfor 1839 | return [shengmu_list, yunmu_list] 1840 | endfunction 1841 | 1842 | function! s:vimim_shuangpin_rules(shuangpin, rules) 1843 | let rules = a:rules 1844 | let key = ' ou ei ang en iong ua er ng ia ie ing un uo in ue ' 1845 | let key .= ' uan iu uai ong eng iang ui ai an ao iao ian uang ' 1846 | let v = '' " various value to almost the same key set 1847 | if a:shuangpin == 'ms' " test: viui => zhishi 1848 | let v = join(split('bzhfswrgwx;pontrqysgdvljkcmdy','\zs')) 1849 | call extend(rules[0], { "zh" : "v", "ch" : "i", "sh" : "u" }) 1850 | let key .= 'v' " microsoft shuangpin has one additional key 1851 | elseif a:shuangpin == 'abc' " test: vtpc => shuang pin 1852 | let v = 'b q h f s d r g d x y n o c m p r c s g t m l j k z w t' 1853 | call extend(rules[0], { "zh" : "a", "ch" : "e", "sh" : "v" }) 1854 | elseif a:shuangpin == 'nature' " test: woui => wo shi => i am 1855 | let v = 'b z h f s w r g w x y p o n t r q y s g d v l j k c m d' 1856 | call extend(rules[0], { "zh" : "v", "ch" : "i", "sh" : "u" }) 1857 | elseif a:shuangpin == 'plusplus' 1858 | let v = 'p w g r y b q t b m q z o l x c n x y t h v s f d k j h' 1859 | call extend(rules[0], { "zh" : "v", "ch" : "u", "sh" : "i" }) 1860 | elseif a:shuangpin == 'purple' 1861 | let v = 'z k s w h x j t x d ; m o y n l j y h t g n p r q b f g' 1862 | call extend(rules[0], { "zh" : "u", "ch" : "a", "sh" : "i" }) 1863 | elseif a:shuangpin == 'flypy' 1864 | let v = 'z w h f s x r g x p k y o b t r q k s g l v d j c n m l' 1865 | call extend(rules[0], { "zh" : "v", "ch" : "i", "sh" : "u" }) 1866 | endif 1867 | call extend(rules[1], s:vimim_key_value_hash(key, v)) 1868 | return rules 1869 | endfunction 1870 | 1871 | function! s:vimim_create_shuangpin_table(rules) 1872 | let pinyin_list = s:vimim_get_all_valid_pinyin_list() 1873 | let sptable = {} " generate table for shengmu-yunmu pairs match 1874 | for key in pinyin_list 1875 | if key !~ "['a-z]*" 1876 | continue 1877 | endif 1878 | let shengmu = key[0] 1879 | let yunmu = key[1:] 1880 | if key[1] == "h" 1881 | let shengmu = key[:1] 1882 | let yunmu = key[2:] 1883 | endif 1884 | if has_key(a:rules[0], shengmu) 1885 | let shuangpin_shengmu = a:rules[0][shengmu] 1886 | else 1887 | continue 1888 | endif 1889 | if has_key(a:rules[1], yunmu) 1890 | let shuangpin_yunmu = a:rules[1][yunmu] 1891 | else 1892 | continue 1893 | endif 1894 | let sp1 = shuangpin_shengmu.shuangpin_yunmu 1895 | if !has_key(sptable, sp1) 1896 | let sptable[sp1] = key[0] == "'" ? key[1:] : key 1897 | endif 1898 | endfor 1899 | if match(split("abc purple nature flypy"), g:Vimim_shuangpin) > -1 1900 | let jxqy = {"jv":"ju", "qv":"qu", "xv":"xu", "yv":"yu"} 1901 | call extend(sptable, jxqy) 1902 | elseif g:Vimim_shuangpin == 'ms' " jxqy+v special case handling 1903 | let jxqy = {"jv":"jue", "qv":"que", "xv":"xue", "yv":"yue"} 1904 | call extend(sptable, jxqy) 1905 | endif 1906 | if g:Vimim_shuangpin == 'flypy' " flypy special case handling 1907 | let key = 'ou eg er an ao ai aa en oo os ah ee ei' 1908 | let value = 'ou eng er an ao ai a en o ong ang e ei' 1909 | call extend(sptable, s:vimim_key_value_hash(key, value)) 1910 | endif 1911 | if g:Vimim_shuangpin == 'nature' " nature special case handling 1912 | let nature = {"aa":"a", "oo":"o", "ee":"e" } 1913 | call extend(sptable, nature) 1914 | endif 1915 | for [key, value] in items(a:rules[0]) 1916 | let sptable[value] = key " table for shengmu-only match 1917 | if key[0] == "'" 1918 | let sptable[value] = "" 1919 | endif 1920 | endfor 1921 | return sptable 1922 | endfunction 1923 | 1924 | function! s:vimim_shuangpin_transform(keyboard) 1925 | let size = strlen(a:keyboard) 1926 | let ptr = 0 1927 | let output = "" 1928 | let bchar = "" " workaround for sogou 1929 | while ptr < size 1930 | if a:keyboard[ptr] !~ "[a-z;]" " bypass all non-characters 1931 | let output .= a:keyboard[ptr] 1932 | let ptr += 1 1933 | else 1934 | let sp1 = a:keyboard[ptr] 1935 | if a:keyboard[ptr+1] =~ "[a-z;]" 1936 | let sp1 .= a:keyboard[ptr+1] 1937 | endif 1938 | if has_key(s:shuangpin_table, sp1) 1939 | let output .= bchar . s:shuangpin_table[sp1] 1940 | else " the last odd shuangpin code as only shengmu 1941 | let output .= sp1 " invalid shuangpin code are preserved 1942 | endif 1943 | let ptr += strlen(sp1) 1944 | endif 1945 | endwhile 1946 | return output[0] == "'" ? output[1:] : output 1947 | endfunction 1948 | 1949 | " ============================================= }}} 1950 | let s:VimIM += [" ==== python2 python3 ==== {{{"] 1951 | " ================================================= 1952 | 1953 | function! s:vimim_initialize_bsddb(datafile) 1954 | :sil!python << EOF 1955 | import vim 1956 | encoding = vim.eval("&encoding") 1957 | datafile = vim.eval('a:datafile') 1958 | try: 1959 | import bsddb3 as bsddb 1960 | except ImportError: 1961 | import bsddb as bsddb 1962 | edw = bsddb.btopen(datafile,'r') 1963 | def getstone(stone): 1964 | if stone not in edw: 1965 | while stone and stone not in edw: stone = stone[:-1] 1966 | return stone 1967 | def getgold(stone): 1968 | gold = stone 1969 | if stone and stone in edw: 1970 | gold = edw.get(stone) 1971 | if encoding == 'utf-8': 1972 | if datafile.find("gbk"): 1973 | gold = unicode(gold,'gb18030','ignore') 1974 | gold = gold.encode(encoding,'ignore') 1975 | gold = stone + ' ' + gold 1976 | return gold 1977 | EOF 1978 | endfunction 1979 | 1980 | function! s:vimim_get_stone_from_bsddb(stone) 1981 | :sil!python << EOF 1982 | try: 1983 | stone = vim.eval('a:stone') 1984 | marble = getstone(stone) 1985 | vim.command("return '%s'" % marble) 1986 | except vim.error: 1987 | print("vim error: %s" % vim.error) 1988 | EOF 1989 | return "" 1990 | endfunction 1991 | 1992 | function! s:vimim_get_gold_from_bsddb(stone) 1993 | :sil!python << EOF 1994 | try: 1995 | gold = getgold(vim.eval('a:stone')) 1996 | vim.command("return '%s'" % gold) 1997 | except vim.error: 1998 | print("vim error: %s" % vim.error) 1999 | EOF 2000 | return "" 2001 | endfunction 2002 | 2003 | function! s:vimim_get_from_python2(input, cloud) 2004 | :sil!python << EOF 2005 | import vim, urllib2, socket 2006 | cloud = vim.eval('a:cloud') 2007 | input = vim.eval('a:input') 2008 | encoding = vim.eval("&encoding") 2009 | try: 2010 | socket.setdefaulttimeout(20) 2011 | urlopen = urllib2.urlopen(input, None) 2012 | response = urlopen.read() 2013 | res = "'" + str(response) + "'" 2014 | if cloud == 'qq': 2015 | if encoding != 'utf-8': 2016 | res = unicode(res, 'utf-8').encode('utf-8') 2017 | elif cloud == 'google': 2018 | if encoding != 'utf-8': 2019 | res = unicode(res, 'unicode_escape').encode("utf8") 2020 | elif cloud == 'baidu': 2021 | if encoding != 'utf-8': 2022 | res = str(response) 2023 | else: 2024 | res = unicode(response, 'gbk').encode(encoding) 2025 | vim.command("let g:Baidu = %s" % res) 2026 | vim.command("return %s" % res) 2027 | urlopen.close() 2028 | except vim.error: 2029 | print("vim error: %s" % vim.error) 2030 | EOF 2031 | return "" 2032 | endfunction 2033 | 2034 | function! s:vimim_get_from_python3(input, cloud) 2035 | :sil!python3 << EOF 2036 | import vim, urllib.request 2037 | try: 2038 | cloud = vim.eval('a:cloud') 2039 | input = vim.eval('a:input') 2040 | urlopen = urllib.request.urlopen(input) 2041 | response = urlopen.read() 2042 | if cloud != 'baidu': 2043 | res = "'" + str(response.decode('utf-8')) + "'" 2044 | else: 2045 | if vim.eval("&encoding") != 'utf-8': 2046 | res = str(response)[2:-1] 2047 | else: 2048 | res = response.decode('gbk') 2049 | vim.command("let g:Baidu = %s" % res) 2050 | vim.command("return %s" % res) 2051 | urlopen.close() 2052 | except vim.error: 2053 | print("vim error: %s" % vim.error) 2054 | EOF 2055 | return "" 2056 | endfunction 2057 | 2058 | function! s:vimim_mycloud_python_init() 2059 | :sil!python << EOF 2060 | import vim, sys, socket 2061 | BUFSIZE = 1024 2062 | def tcpslice(sendfunc, data): 2063 | senddata = data 2064 | while len(senddata) >= BUFSIZE: 2065 | sendfunc(senddata[0:BUFSIZE]) 2066 | senddata = senddata[BUFSIZE:] 2067 | if senddata[-1:] == "\n": 2068 | sendfunc(senddata) 2069 | else: 2070 | sendfunc(senddata+"\n") 2071 | def tcpsend(data, host, port): 2072 | addr = host, port 2073 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 2074 | try: 2075 | s.connect(addr) 2076 | except Exception, inst: 2077 | s.close() 2078 | return None 2079 | ret = "" 2080 | for item in data.split("\n"): 2081 | if item == "": 2082 | continue 2083 | tcpslice(s.send, item) 2084 | cachedata = "" 2085 | while cachedata[-1:] != "\n": 2086 | data = s.recv(BUFSIZE) 2087 | cachedata += data 2088 | if cachedata == "server closed\n": 2089 | break 2090 | ret += cachedata 2091 | s.close() 2092 | return ret 2093 | def parsefunc(keyb, host="localhost", port=10007): 2094 | src = keyb.encode("base64") 2095 | ret = tcpsend(src, host, port) 2096 | if type(ret).__name__ == "str": 2097 | try: 2098 | return ret.decode("base64") 2099 | except Exception: 2100 | return "" 2101 | else: 2102 | return "" 2103 | EOF 2104 | endfunction 2105 | 2106 | function! s:vimim_mycloud_python_client(cmd) 2107 | :sil!python << EOF 2108 | try: 2109 | cmd = vim.eval("a:cmd") 2110 | HOST = vim.eval("s:mycloud_host") 2111 | PORT = int(vim.eval("s:mycloud_port")) 2112 | ret = parsefunc(cmd, HOST, PORT) 2113 | vim.command('return "%s"' % ret) 2114 | except vim.error: 2115 | print("vim error: %s" % vim.error) 2116 | EOF 2117 | endfunction 2118 | 2119 | " ============================================= }}} 2120 | let s:VimIM += [" ==== backend: file ==== {{{"] 2121 | " ================================================= 2122 | 2123 | function! s:vimim_set_datafile(im, datafile) 2124 | let im = a:im 2125 | if isdirectory(a:datafile) | return 2126 | elseif im =~ '^wubi' | let im = 'wubi' 2127 | elseif im =~ '^pinyin' | let im = 'pinyin' | endif 2128 | let s:ui.root = 'datafile' 2129 | let s:ui.im = im 2130 | call insert(s:ui.frontends, [s:ui.root, s:ui.im]) 2131 | let s:backend.datafile[im] = {} 2132 | let s:backend.datafile[im].root = s:ui.root 2133 | let s:backend.datafile[im].im = s:ui.im 2134 | let s:backend.datafile[im].name = a:datafile 2135 | let s:backend.datafile[im].keycode = s:keycodes[im] 2136 | let s:backend.datafile[im].chinese = s:chinese(im) 2137 | let s:backend.datafile[im].lines = [] 2138 | endfunction 2139 | 2140 | function! s:vimim_sentence_datafile(keyboard) 2141 | let backend = s:backend[s:ui.root][s:ui.im] 2142 | let fuzzy = s:ui.im =~ 'pinyin' ? ' ' : "" 2143 | let pattern = '^\V' . a:keyboard . fuzzy 2144 | let cursor = match(backend.lines, pattern) 2145 | if cursor > -1 | return a:keyboard | endif 2146 | let candidates = s:vimim_more_pinyin_datafile(a:keyboard,1) 2147 | if !empty(candidates) | return get(candidates,0) | endif 2148 | let max = len(a:keyboard) 2149 | while max > 1 2150 | let max -= 1 2151 | let pattern = '^\V' . strpart(a:keyboard,0,max) . ' ' 2152 | let cursor = match(backend.lines, pattern) 2153 | if cursor > -1 | break | endif 2154 | endwhile 2155 | return cursor < 0 ? "" : a:keyboard[: max-1] 2156 | endfunction 2157 | 2158 | function! s:vimim_get_from_datafile(keyboard) 2159 | let fuzzy = s:ui.im =~ 'pinyin' ? ' ' : "" 2160 | let pattern = '^\V' . a:keyboard . fuzzy 2161 | let backend = s:backend[s:ui.root][s:ui.im] 2162 | let cursor = match(backend.lines, pattern) 2163 | if cursor < 0 | return [] | endif 2164 | let oneline = get(backend.lines, cursor) 2165 | let results = split(oneline)[1:] 2166 | if len(s:english.line) || len(results) > 10 2167 | return results 2168 | endif 2169 | if s:ui.im =~ 'pinyin' 2170 | let extras = s:vimim_more_pinyin_datafile(a:keyboard,0) 2171 | let results = s:vimim_make_pairs(oneline) + extras 2172 | else " http://code.google.com/p/vimim/issues/detail?id=121 2173 | let results = [] 2174 | let s:show_extra_menu = 1 2175 | for i in range(10) 2176 | let cursor += i " get more if less 2177 | let oneline = get(backend.lines, cursor) 2178 | let results += s:vimim_make_pairs(oneline) 2179 | endfor 2180 | endif 2181 | return results 2182 | endfunction 2183 | 2184 | function! s:vimim_get_from_database(keyboard) 2185 | let oneline = s:vimim_get_gold_from_bsddb(a:keyboard) 2186 | if empty(oneline) | return [] | endif 2187 | let results = s:vimim_make_pairs(oneline) 2188 | if empty(s:english.line) && len(results) && len(results) < 20 2189 | for candidate in s:vimim_more_pinyin_candidates(a:keyboard) 2190 | let oneline = s:vimim_get_gold_from_bsddb(candidate) 2191 | if empty(oneline) || match(oneline,' ')<0 | continue | endif 2192 | let results += s:vimim_make_pairs(oneline) 2193 | if len(results) > 20*2 | break | endif 2194 | endfor 2195 | endif 2196 | return results 2197 | endfunction 2198 | 2199 | function! s:vimim_make_pairs(oneline) 2200 | if empty(a:oneline) || match(a:oneline,' ') < 0 2201 | return [] 2202 | endif 2203 | let oneline_list = split(a:oneline) 2204 | let menu = remove(oneline_list, 0) 2205 | let results = [] 2206 | for chinese in oneline_list 2207 | call add(results, menu .' '. chinese) 2208 | endfor 2209 | return results 2210 | endfunction 2211 | 2212 | " ============================================= }}} 2213 | let s:VimIM += [" ==== backend: dir ==== {{{"] 2214 | " ================================================= 2215 | 2216 | function! s:vimim_set_directory(dir) 2217 | let im = "pinyin" 2218 | let s:ui.root = 'directory' 2219 | let s:ui.im = im 2220 | call insert(s:ui.frontends, [s:ui.root, s:ui.im]) 2221 | let s:backend.directory[im] = {} 2222 | let s:backend.directory[im].root = s:ui.root 2223 | let s:backend.directory[im].im = im 2224 | let s:backend.directory[im].name = a:dir 2225 | let s:backend.directory[im].keycode = s:keycodes[im] 2226 | let s:backend.directory[im].chinese = s:chinese(im) 2227 | endfunction 2228 | 2229 | function! s:vimim_sentence_directory(keyboard, directory) 2230 | let filename = a:directory . a:keyboard 2231 | if filereadable(filename) | return a:keyboard | endif 2232 | let max = len(a:keyboard) 2233 | while max > 1 2234 | let max -= 1 " workaround: filereadable("/filename.") return true 2235 | let head = strpart(a:keyboard, 0, max) 2236 | let filename = a:directory . head 2237 | if filereadable(filename) && head[-1:-1] != "." | break | endif 2238 | endwhile 2239 | return filereadable(filename) ? a:keyboard[: max-1] : "" 2240 | endfunction 2241 | 2242 | function! s:vimim_set_backend_embedded() 2243 | " (1/3) scan pinyin directory database 2244 | let dir = s:plugin . "pinyin" " always test ../plugin/pinyin/pinyin 2245 | if isdirectory(dir) 2246 | if filereadable(dir . "/pinyin") 2247 | return s:vimim_set_directory(dir . "/") 2248 | endif 2249 | endif 2250 | " (2/3) scan bsddb database as edw: enterprise data warehouse 2251 | if has("python") " bsddb is from Python 2 only with 46,694,400 Bytes 2252 | let datafile = s:vimim_filereadable("vimim.gbk.bsddb") 2253 | if !empty(datafile) 2254 | return s:vimim_set_datafile("pinyin", datafile) 2255 | endif 2256 | endif 2257 | " (3/3) scan all supported data files, in order 2258 | for im in s:all_vimim_input_methods 2259 | let datafile = s:vimim_filereadable("vimim." . im . ".txt") 2260 | if empty(datafile) 2261 | let filename = "vimim." . im . "." . &encoding . ".txt" 2262 | let datafile = s:vimim_filereadable(filename) 2263 | endif 2264 | if !empty(datafile) 2265 | call s:vimim_set_datafile(im, datafile) 2266 | endif 2267 | endfor 2268 | endfunction 2269 | 2270 | " ============================================= }}} 2271 | let s:VimIM += [" ==== backend: clouds ==== {{{"] 2272 | " ================================================= 2273 | 2274 | function! s:vimim_set_backend_clouds() 2275 | let cloud_defaults = split(s:rc["g:Vimim_cloud"],',') 2276 | let s:cloud = get(cloud_defaults,0) 2277 | if g:Vimim_cloud < 0 | return | endif 2278 | let clouds = split(g:Vimim_cloud,',') 2279 | for cloud in clouds 2280 | let cloud = get(split(cloud,'[.]'),0) 2281 | call remove(cloud_defaults, match(cloud_defaults,cloud)) 2282 | endfor 2283 | let clouds += cloud_defaults 2284 | let g:Vimim_cloud = join(clouds,',') 2285 | let default = get(split(get(clouds,0),'[.]'),0) 2286 | if match(s:rc["g:Vimim_cloud"], default) > -1 2287 | let s:cloud = default 2288 | endif 2289 | if !empty(s:vimim_check_http_executable()) 2290 | let s:ui.root = 'cloud' 2291 | for cloud in reverse(split(g:Vimim_cloud,',')) 2292 | let im = get(split(cloud,'[.]'),0) 2293 | let s:ui.im = im 2294 | call insert(s:ui.frontends, [s:ui.root, s:ui.im]) 2295 | let s:backend.cloud[im] = {} 2296 | let s:backend.cloud[im].root = s:ui.root 2297 | let s:backend.cloud[im].im = 0 " used for cloud key 2298 | let s:backend.cloud[im].keycode = s:keycodes[im] 2299 | let s:backend.cloud[im].name = s:chinese(im) 2300 | let s:backend.cloud[im].chinese = s:chinese(im) 2301 | endfor 2302 | endif 2303 | endfunction 2304 | 2305 | function! s:vimim_check_http_executable() 2306 | if g:Vimim_cloud < 0 && len(g:Vimim_mycloud) < 3 2307 | return 0 2308 | elseif len(s:http_exe) > 3 2309 | return s:http_exe 2310 | endif 2311 | " step 1 of 4: try to find libvimim for mycloud 2312 | let lib = has("win32") || has("win32unix") ? "dll" : "so" 2313 | let libvimim = s:plugin . "libvimim." . lib 2314 | if filereadable(libvimim) 2315 | let libvimim = has("win32") ? libvimim[:-5] : libvimim 2316 | if libcall(libvimim, "do_geturl", "__isvalid") ==# "True" 2317 | let s:http_exe = libvimim 2318 | endif 2319 | endif 2320 | " step 2 of 4: try to use dynamic python: 2321 | if empty(s:http_exe) 2322 | if has('python') 2323 | let s:http_exe = 'Python2 Interface to Vim' " +python/dyn 2324 | elseif has('python3') && &relativenumber 2325 | let s:http_exe = 'Python3 Interface to Vim' " +python3/dyn 2326 | endif 2327 | endif 2328 | " step 3 of 4: try to find wget 2329 | if empty(s:http_exe) || has("macunix") 2330 | let wget_exe = s:plugin . 'wget.exe' 2331 | let wget = filereadable(wget_exe) ? wget_exe : 'wget' 2332 | if executable(wget) 2333 | let wget_option = " -qO - --timeout 20 -t 10 " 2334 | let s:http_exe = wget . wget_option 2335 | endif 2336 | endif 2337 | " step 4 of 4: try to find curl if wget not available 2338 | if empty(s:http_exe) && executable('curl') 2339 | let s:http_exe = "curl -s " 2340 | endif 2341 | return s:http_exe 2342 | endfunction 2343 | 2344 | function! s:vimim_get_cloud(keyboard, cloud) 2345 | let keyboard = a:keyboard " remove evil leading/trailing quote 2346 | let keyboard = keyboard[:0] == "'" ? keyboard[1:] : keyboard 2347 | let keyboard = keyboard[-1:] == "'" ? keyboard[:-2] : keyboard 2348 | if keyboard !~ s:valid_keyboard || empty(a:cloud) 2349 | return [] 2350 | endif 2351 | let cloud = "s:vimim_get_cloud_" . a:cloud . "(keyboard)" 2352 | let results = [] 2353 | try 2354 | let results = eval(cloud) 2355 | catch 2356 | sil!call s:vimim_debug(a:cloud, v:exception) 2357 | endtry 2358 | if !empty(results) && s:keyboard !~ '\S\s\S' 2359 | let s:keyboard = keyboard 2360 | endif 2361 | return results 2362 | endfunction 2363 | 2364 | function! s:vimim_get_from_http(input, cloud) 2365 | if empty(a:input) || empty(s:vimim_check_http_executable()) 2366 | return "" 2367 | endif 2368 | try 2369 | if s:http_exe =~ 'Python3' 2370 | return s:vimim_get_from_python3(a:input, a:cloud) 2371 | elseif s:http_exe =~ 'Python2' 2372 | return s:vimim_get_from_python2(a:input, a:cloud) 2373 | elseif s:http_exe =~ 'libvimim' 2374 | return libcall(s:http_exe, "do_geturl", a:input) 2375 | elseif len(s:http_exe) 2376 | return system(s:http_exe . shellescape(a:input)) 2377 | endif 2378 | catch 2379 | sil!call s:vimim_debug("s:http_exe exception", v:exception) 2380 | endtry 2381 | return "" 2382 | endfunction 2383 | 2384 | function! s:vimim_get_cloud_sogou(keyboard) 2385 | " http://web.pinyin.sogou.com/api/py?key=32&query=xj 2386 | let results = [] 2387 | if empty(s:backend.cloud.sogou.im) " as cloud key 2388 | let key_sogou = "http://web.pinyin.sogou.com/web_ime/patch.php" 2389 | let output = s:vimim_get_from_http(key_sogou, 'sogou') 2390 | let s:backend.cloud.sogou.im = get(split(output, '"'), 1) 2391 | endif 2392 | let input = 'http://web.pinyin.sogou.com/api/py' 2393 | let input .= '?key=' . s:backend.cloud.sogou.im 2394 | let input .= '&query=' . a:keyboard 2395 | let output = s:vimim_get_from_http(input, 'sogou') 2396 | if empty(output) || output =~ '502 bad gateway' 2397 | return [] 2398 | endif 2399 | let first = match(output, '"', 0) 2400 | let second = match(output, '"', 0, 2) 2401 | if first && second 2402 | let output = strpart(output, first+1, second-first-1) 2403 | let output = s:vimim_url_xx_to_chinese(output) 2404 | endif 2405 | let output = s:localization ? s:vimim_i18n(output) : output 2406 | for item in split(output, '\t+') 2407 | let item_list = split(item, s:colon) 2408 | if len(item_list) > 1 2409 | let english = strpart(a:keyboard, 0, get(item_list,1)) 2410 | let english_chinese = english . " " . get(item_list,0) 2411 | call add(results, english_chinese) 2412 | endif 2413 | endfor 2414 | return results 2415 | endfunction 2416 | 2417 | function! s:vimim_get_cloud_qq(keyboard) 2418 | " http://ime.qq.com/fcgi-bin/getword?key=32&q=mxj 2419 | let results = [] 2420 | let input = 'http://ime.qq.com/fcgi-bin/' 2421 | if empty(s:backend.cloud.qq.im) " as cloud key 2422 | let output = s:vimim_get_from_http(input . 'getkey', 'qq') 2423 | let s:backend.cloud.qq.im = get(split(output, '"'), 3) 2424 | endif 2425 | let clouds = split(g:Vimim_cloud,',') " qq.shuangpin.abc,google 2426 | let vimim_cloud = get(clouds, match(clouds,'qq')) " qq.shuangpin.abc 2427 | if vimim_cloud =~ 'wubi' 2428 | let input .= 'gwb' 2429 | else 2430 | let input .= 'getword' 2431 | endif 2432 | let input .= '?key=' . s:backend.cloud.qq.im 2433 | if vimim_cloud =~ 'fanti' 2434 | let input .= '&jf=1' 2435 | endif 2436 | let md = vimim_cloud =~ 'mixture' ? 3 : 0 2437 | if vimim_cloud =~ 'shuangpin' 2438 | let md = 2 " qq.shuangpin.ms => ms 2439 | let shuangpin = get(split(vimim_cloud,"[.]"), -1) 2440 | let st = match(split(s:shuangpin),shuangpin) + 1 2441 | if st 2442 | let input .= '&st=' . st 2443 | endif 2444 | endif 2445 | if md 2446 | let input .= '&md=' . md 2447 | endif 2448 | if vimim_cloud =~ 'fuzzy' 2449 | let input .= '&mh=1' 2450 | endif 2451 | let input .= '&q=' . a:keyboard 2452 | let output = s:vimim_get_from_http(input, 'qq') 2453 | if empty(output) || output =~ '502 bad gateway' 2454 | return [] 2455 | endif " qq => {'q':'fuck','rs':['\xe5\xa6\x87'] 2456 | let output = s:localization ? s:vimim_i18n(output) : output 2457 | let output_hash = eval(output) 2458 | if type(output_hash) == type({}) && has_key(output_hash, 'rs') 2459 | let results = output_hash['rs'] " as key 2460 | endif 2461 | if vimim_cloud !~ 'wubi' && vimim_cloud !~ 'shuangpin' 2462 | let results = s:vimim_cloud_pinyin(a:keyboard, results) 2463 | endif 2464 | return results 2465 | endfunction 2466 | 2467 | function! s:vimim_get_cloud_google(keyboard) 2468 | " http://google.com/transliterate?tl_app=3&tlqt=1&num=20&text=mxj 2469 | let input = 'http://www.google.com/transliterate/chinese' 2470 | let input .= '?langpair=en|zh' . '&num=20' . '&tl_app=3' 2471 | let input .= '&tlqt=1' . '&text=' . a:keyboard 2472 | let output = join(split(s:vimim_get_from_http(input,'google'))) 2473 | let results = [] " [{'ew':'fuck','hws':['\u5987\u4EA7\u79D1',]},] 2474 | if s:localization 2475 | if s:http_exe =~ 'Python2' 2476 | let output = s:vimim_i18n(output) 2477 | else 2478 | for item in split(get(split(output),8),",") 2479 | let utf8 = "" " play with unicode 2480 | for xxxx in split(item, "\u") 2481 | let utf8 .= s:vimim_unicode_to_utf8(xxxx) 2482 | endfor 2483 | let output = s:vimim_i18n(utf8) 2484 | call add(results, output) 2485 | endfor 2486 | return results 2487 | endif 2488 | endif 2489 | let output_hash = get(eval(output),0) 2490 | if type(output_hash) == type({}) && has_key(output_hash, 'hws') 2491 | let results = output_hash['hws'] " as key 2492 | endif 2493 | let results = s:vimim_cloud_pinyin(a:keyboard, results) 2494 | return results 2495 | endfunction 2496 | 2497 | function! s:vimim_get_cloud_baidu(keyboard) 2498 | " http://olime.baidu.com/py?rn=0&pn=20&py=mxj 2499 | let results = [] 2500 | let url = 'http://olime.baidu.com/py' 2501 | let input = '?rn=0' . '&pn=20' . '&py=' . a:keyboard 2502 | let output = s:vimim_get_from_http(url . input, 'baidu') 2503 | let output_list = [] " ['[[['\xc3\xb0\xcf\xd5',3] 2504 | if exists("g:Baidu") && type(g:Baidu) == type([]) 2505 | let output_list = get(g:Baidu,0) 2506 | endif 2507 | if empty(output_list) 2508 | if empty(output) || output =~ '502 bad gateway' 2509 | return [] 2510 | elseif empty(s:localization) 2511 | let output = iconv(output, "gbk", "utf-8") 2512 | endif 2513 | let output_list = get(eval(output),0) 2514 | endif 2515 | for item_list in output_list 2516 | let keyboard = substitute(a:keyboard,'\W','','g') 2517 | let english = strpart(keyboard, get(item_list,1)) 2518 | call add(results, get(item_list,0) . english) 2519 | endfor 2520 | return results 2521 | endfunction 2522 | 2523 | function! s:vimim_get_all_clouds(key) 2524 | let results = [] 2525 | for cloud in split(s:rc["g:Vimim_cloud"], ',') 2526 | let start = reltime() 2527 | let title = s:chinese(s:space, cloud, 'cloud', s:space) 2528 | let outputs = s:vimim_get_cloud(a:key, cloud) 2529 | let outputs = &number ? outputs : outputs[0:9] 2530 | let filter = "substitute(" . 'v:val' . ",'[a-z ]','','g')" 2531 | call add(results, a:key . title . reltimestr(reltime(start))) 2532 | call add(results, join(map(outputs,filter))) 2533 | call add(results, s:space) 2534 | endfor 2535 | return results 2536 | endfunction 2537 | 2538 | " ============================================= }}} 2539 | let s:VimIM += [" ==== backend: mycloud ==== {{{"] 2540 | " ================================================= 2541 | 2542 | function! s:vimim_set_backend_mycloud() 2543 | let s:mycloud_arg = "" 2544 | let s:mycloud_mode = "libcall" 2545 | let s:mycloud_func = "do_getlocal" 2546 | let s:mycloud_host = "localhost" 2547 | let s:mycloud_port = 10007 2548 | let s:mycloud_initialization = 0 2549 | if !empty(g:Vimim_mycloud) && g:Vimim_mycloud != -1 2550 | let s:ui.root = 'cloud' 2551 | let s:ui.im = 'mycloud' 2552 | call insert(s:ui.frontends, [s:ui.root, s:ui.im]) 2553 | let s:backend.cloud.mycloud = {} 2554 | let s:backend.cloud.mycloud.root = s:ui.root 2555 | let s:backend.cloud.mycloud.name = s:chinese(s:ui.im) 2556 | let s:backend.cloud.mycloud.chinese = s:chinese(s:ui.im) 2557 | let s:backend.cloud.mycloud.keycode = s:valid_keyboard 2558 | let s:backend.cloud.mycloud.directory = s:ui.im 2559 | let s:backend.cloud.mycloud.im = s:ui.im 2560 | endif 2561 | endfunction 2562 | 2563 | function! s:vimim_get_mycloud(keyboard) 2564 | if s:mycloud_initialization < 0 2565 | return [] 2566 | elseif s:mycloud_initialization < 1 2567 | let s:mycloud_initialization = 1 2568 | let mycloud = s:vimim_mycloud_set_and_play() 2569 | if empty(mycloud) 2570 | let s:mycloud_initialization = -1 " fail to start mycloud 2571 | return [] 2572 | endif " mycloud late binding: get/set real data from server 2573 | let s:backend.cloud.mycloud.im = mycloud 2574 | let ret = s:vimim_mycloud(mycloud, "__getkeychars") 2575 | let s:backend.cloud.mycloud.keycode = split(ret,"\t")[0] 2576 | let ret = s:vimim_mycloud(mycloud, "__getname") 2577 | let s:backend.cloud.mycloud.directory = split(ret,"\t")[0] 2578 | call s:vimim_set_frontend() 2579 | endif 2580 | let results = [] 2581 | let output = s:vimim_mycloud(s:backend.cloud.mycloud.im, a:keyboard) 2582 | for item in split(output, '\n') 2583 | let item_list = split(item, '\t') 2584 | let chinese = get(item_list,0) 2585 | let chinese = s:localization ? s:vimim_i18n(chinese) : chinese 2586 | if empty(chinese) || get(item_list,1,-1) < 0 2587 | continue 2588 | endif 2589 | let extra_text = get(item_list,2) 2590 | let english = a:keyboard[get(item_list,1):] 2591 | call add(results, extra_text . " " . chinese . english) 2592 | endfor 2593 | return results 2594 | endfunction 2595 | 2596 | function! s:vimim_mycloud_set_and_play() 2597 | let part = split(g:Vimim_mycloud, ':') 2598 | if len(part) <= 1 2599 | sil!call s:vimim_debug('alert', "mycloud_url_too_short") 2600 | elseif part[0] ==# 'py' && has("python") 2601 | " :let g:Vimim_mycloud = "py:127.0.0.1" 2602 | if len(part) > 2 2603 | let s:mycloud_host = part[1] 2604 | let s:mycloud_port = part[2] 2605 | elseif len(part) > 1 2606 | let s:mycloud_host = part[1] 2607 | endif 2608 | try 2609 | call s:vimim_mycloud_python_init() 2610 | let s:mycloud_mode = "python" 2611 | if s:vimim_mycloud_isvalid(part[1]) 2612 | return "python" 2613 | endif 2614 | catch 2615 | sil!call s:vimim_debug('python_mycloud=', v:exception) 2616 | endtry 2617 | elseif part[0] ==# 'app' && !has("gui_win32") 2618 | " :let g:Vimim_mycloud = "app:python d:/mycloud/mycloud.py" 2619 | let cloud = part[1] 2620 | if len(part) == 3 2621 | let part1 = part[1][0] == '/' ? part[1][1:] : part[1] 2622 | let cloud = part1 . ':' . part[2] 2623 | endif 2624 | if executable(split(cloud)[0]) 2625 | let s:mycloud_mode = "system" 2626 | if s:vimim_mycloud_isvalid(cloud) 2627 | return cloud 2628 | endif 2629 | endif 2630 | elseif part[0] ==# "dll" 2631 | " :let g:Vimim_mycloud = "dll:/data/libvimim.so:192.168.0.1" 2632 | let base = len(part[1]) == 1 ? 1 : 0 2633 | if len(part) >= base+4 2634 | let s:mycloud_func = part[base+3] 2635 | endif 2636 | let s:mycloud_arg = len(part) >= base+3 ? part[base+2] : "" 2637 | let libvimim = base == 1 ? part[1] . ':' . part[2] : part[1] 2638 | if filereadable(libvimim) 2639 | let s:mycloud_mode = "libcall" 2640 | let libvimim = has("win32") ? libvimim[:-5] : libvimim 2641 | if s:vimim_mycloud_isvalid(libvimim) 2642 | return libvimim 2643 | endif 2644 | endif 2645 | elseif part[0] ==# "http" || part[0] ==# "https" 2646 | " :let g:Vimim_mycloud = "http://pim-cloud.appspot.com/qp/" 2647 | if !empty(s:vimim_check_http_executable()) 2648 | let s:mycloud_mode = "www" 2649 | if s:vimim_mycloud_isvalid(g:Vimim_mycloud) 2650 | return g:Vimim_mycloud 2651 | endif 2652 | endif 2653 | else 2654 | sil!call s:vimim_debug('alert', "invalid_mycloud_url") 2655 | endif 2656 | return 0 2657 | endfunction 2658 | 2659 | function! s:vimim_mycloud(cloud, cmd) 2660 | let ret = "" 2661 | if s:mycloud_mode == "libcall" 2662 | let arg = empty(s:mycloud_arg) ? '' : s:mycloud_arg . " " 2663 | let ret = libcall(a:cloud, s:mycloud_func, arg . a:cmd) 2664 | elseif s:mycloud_mode == "python" 2665 | let ret = s:vimim_mycloud_python_client(a:cmd) 2666 | elseif s:mycloud_mode == "system" 2667 | let ret = system(a:cloud . " " . shellescape(a:cmd)) 2668 | elseif s:mycloud_mode == "www" 2669 | let input = a:cloud . s:vimim_rot13(a:cmd) 2670 | if s:http_exe =~ 'libvimim' 2671 | let ret = libcall(s:http_exe, "do_geturl", input) 2672 | elseif len(s:http_exe) 2673 | let ret = system(s:http_exe . shellescape(input)) 2674 | endif 2675 | if len(ret) 2676 | let output = s:vimim_rot13(ret) 2677 | let ret = s:vimim_url_xx_to_chinese(output) 2678 | endif 2679 | endif 2680 | return ret 2681 | endfunction 2682 | 2683 | function! s:vimim_mycloud_isvalid(cloud) 2684 | let ret = s:vimim_mycloud(a:cloud, "__isvalid") 2685 | if split(ret, "\t")[0] == "True" 2686 | return 1 2687 | endif 2688 | return 0 2689 | endfunction 2690 | 2691 | " ============================================= }}} 2692 | let s:VimIM += [" ==== /search ==== {{{"] 2693 | " ================================================= 2694 | 2695 | function! g:Vimim_search() 2696 | let results = [] 2697 | let english = @/ 2698 | if len(english) > 1 && len(english) < 20 && english !~ "[^0-9a-z']" 2699 | \&& v:errmsg =~# english && v:errmsg =~# '^E486: ' 2700 | try 2701 | let results = s:vimim_search_chinese_by_english(english) 2702 | catch 2703 | sil!call s:vimim_debug('slash search /', v:exception) 2704 | endtry 2705 | endif 2706 | if !empty(results) 2707 | let results = split(substitute(join(results),'\w','','g')) 2708 | call sort(results, "s:vimim_sort_on_length") 2709 | let slash = join(results[0:9], '\|') 2710 | let @/ = empty(search(slash,'nw')) ? english : slash 2711 | endif 2712 | echon "/" . english 2713 | let v:errmsg = "" 2714 | endfunction 2715 | 2716 | function! s:vimim_sort_on_length(i1, i2) 2717 | return len(a:i2) - len(a:i1) 2718 | endfunc 2719 | 2720 | function! s:vimim_search_chinese_by_english(key) 2721 | let key = tolower(a:key) 2722 | let results = [] 2723 | " 1/3 first try search from mycloud or cloud if available 2724 | if s:ui.im == 'mycloud' 2725 | let results = s:vimim_get_mycloud(key) 2726 | elseif s:ui.root == 'cloud' || key[-1:] == "'" 2727 | let results = s:vimim_get_cloud(key, s:cloud) 2728 | endif 2729 | if len(results) | return results | endif 2730 | " 2/3 search unicode or cjk /search unicode /u808f 2731 | let ddddd = s:vimim_get_unicode_ddddd(key) 2732 | if !empty(ddddd) 2733 | let results = [nr2char(ddddd)] 2734 | elseif s:vimim_cjk() 2735 | while len(key) > 1 2736 | let head = s:vimim_get_cjk_head(key) 2737 | if empty(head) " /muuqwxeyqpjeqqq 2738 | break " /m7712x3610j3111 2739 | else " /ma77xia36ji31 2740 | let matches = s:vimim_cjk_match(head) 2741 | if len(matches) 2742 | let chinese = join(matches[:9], '') 2743 | call add(results, "[" . chinese . "]") 2744 | endif 2745 | let key = strpart(key, len(head)) 2746 | endif 2747 | endwhile 2748 | let results = len(results) > 1 ? [join(results,'')] : results 2749 | endif 2750 | if len(results) | return results | endif 2751 | " 3/3 search datafile and english: /ma and /horse 2752 | let key = tolower(a:key) 2753 | let results = split(s:vimim_get_english(key)) 2754 | if empty(results) 2755 | let results = s:vimim_embedded_backend_engine(key) 2756 | endif 2757 | return results 2758 | endfunction 2759 | 2760 | " ============================================= }}} 2761 | let s:VimIM += [" ==== core workflow ==== {{{"] 2762 | " ================================================= 2763 | 2764 | function! s:vimim_start() 2765 | sil!call s:vimim_save_vimrc() 2766 | sil!call s:vimim_set_vimrc() 2767 | sil!call s:vimim_set_frontend() 2768 | sil!call s:vimim_set_keyboard_maps() 2769 | lnoremap g:Vimim_backspace() 2770 | lnoremap g:Vimim_esc() 2771 | lnoremap g:Vimim_one_key_correction() 2772 | lnoremap g:Vimim_cycle_vimim() 2773 | if s:ui.im =~ 'array' 2774 | lnoremap g:Vimim_space() 2775 | lnoremap g:Vimim_pagedown() 2776 | else 2777 | lnoremap g:Vimim_enter() 2778 | lnoremap g:Vimim_space() 2779 | endif 2780 | let key = '' 2781 | if empty(s:ctrl6) 2782 | let s:ctrl6 = 32911 2783 | let key = nr2char(30) 2784 | endif 2785 | sil!exe 'sil!return "' . key . '"' 2786 | endfunction 2787 | 2788 | function! s:vimim_stop() 2789 | if has("gui_running") 2790 | lmapclear 2791 | endif 2792 | let key = nr2char(30) " i_CTRL-^ 2793 | let s:ui.frontends = copy(s:frontends) 2794 | sil!call s:vimim_restore_vimrc() 2795 | sil!call s:vimim_super_reset() 2796 | sil!exe 'sil!return "' . key . '"' 2797 | endfunction 2798 | 2799 | function! s:vimim_save_vimrc() 2800 | let s:cpo = &cpo 2801 | let s:omnifunc = &omnifunc 2802 | let s:complete = &complete 2803 | let s:completeopt = &completeopt 2804 | let s:statusline = &statusline 2805 | let s:lazyredraw = &lazyredraw 2806 | endfunction 2807 | 2808 | function! s:vimim_set_vimrc() 2809 | set title noshowmatch shellslash 2810 | set completeopt=menuone 2811 | set complete=. 2812 | set nolazyredraw 2813 | set omnifunc=VimIM 2814 | endfunction 2815 | 2816 | function! s:vimim_restore_vimrc() 2817 | let &cpo = s:cpo 2818 | let &omnifunc = s:omnifunc 2819 | let &complete = s:complete 2820 | let &completeopt = s:completeopt 2821 | let &statusline = s:statusline 2822 | let &lazyredraw = s:lazyredraw 2823 | let &titlestring = s:titlestring 2824 | let &pumheight = s:pumheights.saved 2825 | endfunction 2826 | 2827 | function! s:vimim_super_reset() 2828 | sil!call s:vimim_reset_before_anything() 2829 | sil!call s:vimim_reset_before_omni() 2830 | sil!call s:vimim_reset_after_insert() 2831 | endfunction 2832 | 2833 | function! s:vimim_reset_before_anything() 2834 | let s:has_shuangpin_transform = 0 " todo 2835 | let s:mode = s:onekey 2836 | let s:keyboard = "" 2837 | let s:omni = 0 2838 | let s:ctrl6 = 0 2839 | let s:switch = 0 2840 | let s:toggle_im = 0 2841 | let s:smart_enter = 0 2842 | let s:gi_dynamic_on = 0 2843 | let s:toggle_punctuation = 1 2844 | let s:popup_list = [] 2845 | endfunction 2846 | 2847 | function! s:vimim_reset_before_omni() 2848 | let s:english.line = "" 2849 | let s:touch_me_not = 0 2850 | let s:show_extra_menu = 0 2851 | let s:cursor_at_windowless = 0 2852 | endfunction 2853 | 2854 | function! s:vimim_reset_after_insert() 2855 | let s:match_list = [] 2856 | let s:pageup_pagedown = 0 2857 | let s:pattern_not_found = 0 2858 | let s:hjkl = "" " reset for nothing 2859 | let s:hjkl__ = 0 " toggle simplified/traditional 2860 | let s:hjkl_h = 0 " toggle cjk property 2861 | let s:hjkl_l = 0 " toggle label length 2862 | let s:hjkl_m = 0 " toggle cjjp/c'j'j'p 2863 | endfunction 2864 | 2865 | " ============================================= }}} 2866 | let s:VimIM += [" ==== core engine ==== {{{"] 2867 | " ================================================= 2868 | 2869 | function! VimIM(start, keyboard) 2870 | let valid_keyboard = s:wubi ? s:valid_wubi_keyboard : s:valid_keyboard 2871 | if a:start 2872 | let cursor_positions = getpos(".") 2873 | let start_row = cursor_positions[1] 2874 | let start_column = cursor_positions[2]-1 2875 | let current_line = getline(start_row) 2876 | let before = current_line[start_column-1] 2877 | let seamless_column = s:vimim_get_seamless(cursor_positions) 2878 | if seamless_column < 0 2879 | let s:seamless_positions = [] 2880 | let last_seen_bslash_column = copy(start_column) 2881 | let last_seen_nonsense_column = copy(start_column) 2882 | let all_digit = 1 2883 | while start_column 2884 | if before =~# valid_keyboard 2885 | let start_column -= 1 2886 | if before !~# "[0-9']" || s:ui.im =~ 'phonetic' 2887 | let last_seen_nonsense_column = start_column 2888 | let all_digit = all_digit ? 0 : all_digit 2889 | endif 2890 | elseif before == '\' " do nothing if leading bslash found 2891 | let s:pattern_not_found = 1 2892 | return last_seen_bslash_column 2893 | else 2894 | break 2895 | endif 2896 | let before = current_line[start_column-1] 2897 | endwhile 2898 | if all_digit < 1 && current_line[start_column] =~ '\d' 2899 | let start_column = last_seen_nonsense_column 2900 | endif 2901 | else 2902 | let start_column = seamless_column 2903 | endif 2904 | let len = cursor_positions[2]-1 - start_column 2905 | let keyboard = strpart(current_line, start_column, len) 2906 | if s:keyboard !~ '\S\s\S' 2907 | let s:keyboard = keyboard 2908 | endif 2909 | let s:starts.column = start_column 2910 | return start_column 2911 | else 2912 | if s:omni < 0 " one_key_correction 2913 | return [s:space] 2914 | endif 2915 | let results = s:vimim_cache() 2916 | if empty(results) 2917 | sil!call s:vimim_reset_before_omni() 2918 | else 2919 | return s:vimim_popupmenu_list(results) 2920 | endif 2921 | let keyboard = a:keyboard 2922 | if !empty(str2nr(keyboard)) " for digit input: 23554022100080204420 2923 | let keyboard = get(split(s:keyboard),0) 2924 | endif 2925 | if empty(keyboard) || keyboard !~ valid_keyboard 2926 | return [] 2927 | else " [english] first check if it is english or not 2928 | let s:english.line = s:vimim_get_english(keyboard) 2929 | endif 2930 | if s:mode.onekey || s:mode.windowless 2931 | let results = s:vimim_get_hjkl_game(keyboard) 2932 | if empty(results) && s:vimim_cjk() 2933 | let head = s:vimim_get_no_quote_head(keyboard) 2934 | let head = s:vimim_get_cjk_head(head) 2935 | let results = !empty(head) ? s:vimim_cjk_match(head) : [] 2936 | endif 2937 | if len(results) 2938 | return s:vimim_popupmenu_list(results) 2939 | elseif len(s:hjkl) && s:keyboard !~ "'" 2940 | let keyboard = get(split(keyboard,'\d'),0) " mali74 2941 | elseif get(split(s:keyboard),1) =~ "'" " ssss.. for cloud 2942 | let keyboard = s:vimim_get_no_quote_head(keyboard) 2943 | endif 2944 | endif 2945 | if s:ui.im == "mycloud" 2946 | let results = s:vimim_get_mycloud(keyboard) 2947 | if len(results) 2948 | let s:show_extra_menu = 1 2949 | return s:vimim_popupmenu_list(results) 2950 | else " flat failure from mycloud 2951 | sil!call s:vimim_debug('mycloud fatal', keyboard, v:exception) 2952 | return [] 2953 | endif 2954 | endif 2955 | if !empty(g:Vimim_shuangpin) && g:Vimim_cloud !~ 'shuangpin' 2956 | if empty(s:shuangpin_table) 2957 | let rules = s:vimim_shuangpin_generic() 2958 | let rules = s:vimim_shuangpin_rules(g:Vimim_shuangpin, rules) 2959 | let s:shuangpin_table = s:vimim_create_shuangpin_table(rules) 2960 | endif 2961 | if empty(s:has_shuangpin_transform) 2962 | let keyboard = s:vimim_shuangpin_transform(keyboard) 2963 | let s:keyboard = keyboard 2964 | endif 2965 | endif 2966 | if s:ui.root == 'cloud' || keyboard[-1:] == "'" && empty(s:ui.quote) 2967 | let results = s:vimim_get_cloud(keyboard, s:cloud) 2968 | endif 2969 | if empty(results) 2970 | if s:wubi && len(keyboard) > 4 2971 | let keyboard = strpart(keyboard, 4*((len(keyboard)-1)/4)) 2972 | let s:keyboard = keyboard " wubi auto insert on the 4th 2973 | endif " [backend] plug-n-play embedded file/directory engine 2974 | let results = s:vimim_embedded_backend_engine(keyboard) 2975 | endif 2976 | if len(s:english.line) 2977 | let s:keyboard = s:keyboard !~ "'" ? keyboard : s:keyboard 2978 | let results = s:vimim_make_pairs(s:english.line) + results 2979 | endif 2980 | if empty(results) " [the_last_resort] force shoupin or force cloud 2981 | if s:mode.onekey || s:mode.windowless 2982 | if len(keyboard) > 1 2983 | let shoupin = s:vimim_get_no_quote_head(keyboard."'''") 2984 | let results = s:vimim_cjk_match(shoupin) 2985 | if empty(results) 2986 | let results = s:vimim_get_cloud(keyboard, s:cloud) 2987 | endif 2988 | else 2989 | let results = [keyboard == 'i' ? "我" : s:space] 2990 | endif 2991 | elseif s:mode.static 2992 | let s:pattern_not_found = 1 2993 | endif 2994 | endif 2995 | return s:vimim_popupmenu_list(results) 2996 | endif 2997 | endfunction 2998 | 2999 | function! s:vimim_popupmenu_list(lines) 3000 | let s:match_list = a:lines 3001 | let keyboards = split(s:keyboard) " mmmm => ['m',"m'm'm"] 3002 | let keyboard = join(keyboards,"") 3003 | let tail = len(keyboards) < 2 ? "" : get(keyboards,1) 3004 | if empty(a:lines) || type(a:lines) != type([]) 3005 | return [] 3006 | elseif s:vimim_cjk() && len(s:hjkl) 3007 | let results = [] " use 1234567890 as filter for windowless 3008 | for chinese in a:lines 3009 | if s:vimim_cjk_in_4corner(chinese,0) 3010 | call add(results, chinese) 3011 | endif 3012 | endfor 3013 | if empty(results) 3014 | let s:hjkl = "" " make digits recyclable 3015 | else " gi ma space 7777777777 3016 | let s:match_list = results 3017 | endif 3018 | endif 3019 | let label = 1 3020 | let one_list = [] 3021 | let s:popup_list = [] 3022 | for chinese in s:match_list 3023 | let complete_items = {} 3024 | if s:vimim_cjk() && s:hjkl__ && s:hjkl__%2 3025 | let simplified_traditional = "" 3026 | for char in split(chinese, '\zs') 3027 | let simplified_traditional .= s:vimim_1to1(char) 3028 | endfor 3029 | let chinese = simplified_traditional 3030 | endif 3031 | let titleline = s:vimim_get_label(label) 3032 | if empty(s:touch_me_not) 3033 | let menu = "" 3034 | let pairs = split(chinese) 3035 | let pair_left = get(pairs,0) 3036 | if len(pairs) > 1 && pair_left !~ '[^\x00-\xff]' 3037 | let chinese = get(pairs,1) 3038 | let menu = s:show_extra_menu ? pair_left : menu 3039 | endif 3040 | if s:hjkl_h && s:hjkl_h % 2 3041 | let char = get(split(chinese,'\zs'),0) 3042 | let menu = s:vimim_cjk_property(char) 3043 | endif 3044 | let label2 = s:english.line =~ chinese ? '*' : ' ' 3045 | let titleline = printf('%3s ', label2 . titleline) 3046 | let chinese .= empty(tail) || tail == "'" ? '' : tail 3047 | let complete_items["abbr"] = titleline . chinese 3048 | let complete_items["menu"] = menu 3049 | endif 3050 | if s:mode.windowless 3051 | if s:vimim_cjk() " display sexy english and dynamic 4corner 3052 | let star = substitute(titleline,'[0-9a-z_ ]','','g') 3053 | let digit = s:vimim_cjk_in_4corner(chinese,1) " ma7 712 3054 | let titleline = star . digit[len(s:hjkl) : 3] 3055 | elseif label < 11 " 234567890 for windowless selection 3056 | let titleline = label == 10 ? "0" : label 3057 | endif 3058 | call add(one_list, titleline . chinese) 3059 | endif 3060 | let label += 1 3061 | let complete_items["dup"] = 1 3062 | let complete_items["word"] = empty(chinese) ? s:space : chinese 3063 | call add(s:popup_list, complete_items) 3064 | endfor 3065 | if s:mode.windowless 3066 | let s:windowless_title = 'VimIM ' . keyboard .' '. join(one_list) 3067 | call s:vimim_windowless_titlestring(1) 3068 | endif 3069 | call s:vimim_set_pumheight() 3070 | Debug s:match_list[:1] 3071 | return s:popup_list 3072 | endfunction 3073 | 3074 | function! s:vimim_embedded_backend_engine(keyboard) 3075 | let keyboard = a:keyboard 3076 | if empty(s:ui.im) || empty(s:ui.root) 3077 | return [] 3078 | endif 3079 | let head = 0 3080 | let results = [] 3081 | let backend = s:backend[s:ui.root][s:ui.im] 3082 | if backend.name =~ "quote" && keyboard !~ "[']" " has apostrophe 3083 | let keyboard = s:vimim_quanpin_transform(keyboard) 3084 | endif 3085 | if s:ui.root =~# "directory" 3086 | let head = s:vimim_sentence_directory(keyboard, backend.name) 3087 | let results = s:vimim_readfile(backend.name . head) 3088 | if keyboard ==# head && len(results) && len(results) < 20 3089 | let extras = [] 3090 | for candidate in s:vimim_more_pinyin_candidates(keyboard) 3091 | let lines = s:vimim_readfile(backend.name . candidate) 3092 | let extras += map(lines, 'candidate." ".v:val') 3093 | endfor 3094 | let results = extras + map(results, 'keyboard." ".v:val') 3095 | endif 3096 | elseif s:ui.root =~# "datafile" 3097 | if backend.name =~ "bsddb" 3098 | if empty(backend.lines) 3099 | let backend.lines = ["4MB_in_memory_46MB_on_disk"] 3100 | sil!call s:vimim_initialize_bsddb(backend.name) 3101 | endif 3102 | let head = s:vimim_get_stone_from_bsddb(keyboard) 3103 | if !empty(head) 3104 | let results = s:vimim_get_from_database(head) 3105 | endif 3106 | else 3107 | if empty(backend.lines) 3108 | let backend.lines = s:vimim_readfile(backend.name) 3109 | endif 3110 | let head = s:vimim_sentence_datafile(keyboard) 3111 | let results = s:vimim_get_from_datafile(head) 3112 | endif 3113 | endif 3114 | if s:keyboard !~ '\S\s\S' 3115 | if empty(head) 3116 | let s:keyboard = keyboard 3117 | elseif len(head) < len(keyboard) 3118 | let tail = strpart(keyboard,len(head)) 3119 | let s:keyboard = head . " " . tail 3120 | endif 3121 | endif 3122 | return results 3123 | endfunction 3124 | 3125 | function! g:Vimim() 3126 | let s:omni = s:omni < 0 ? -1 : 0 " one_key_correction 3127 | let s:keyboard = empty(s:pageup_pagedown) ? "" : s:keyboard 3128 | let key = s:vimim_left() ? '\\\=g:Omni()\' : "" 3129 | sil!exe 'sil!return "' . key . '"' 3130 | endfunction 3131 | 3132 | function! g:Omni() 3133 | let s:omni = s:omni < 0 ? 0 : 1 " as if omni completion pattern found 3134 | let key = s:mode.static ? '\\' : '\\' 3135 | let key = pumvisible() ? key : "" 3136 | sil!exe 'sil!return "' . key . '"' 3137 | endfunction 3138 | 3139 | " ============================================= }}} 3140 | let s:VimIM += [" ==== core driver ==== {{{"] 3141 | " ================================================= 3142 | 3143 | function! s:vimim_plug_and_play() 3144 | nnoremap i=g:Vimim_chinese() 3145 | inoremap =g:Vimim_chinese() 3146 | inoremap =g:Vimim_onekey() 3147 | xnoremap y:call g:Vimim_visual() 3148 | if g:Vimim_map !~ 'no-gi' 3149 | nnoremap gi a=g:Vimim_gi() 3150 | xmap gi 3151 | endif 3152 | if g:Vimim_map !~ 'no-search' 3153 | nnoremap n :call g:Vimim_search()n 3154 | endif 3155 | if g:Vimim_map =~ 'c-bslash' " use Ctrl-\ '' 3156 | imap 3157 | nmap 3158 | elseif g:Vimim_map =~ 'c-space' " use Ctrl-Space 3159 | if has("win32unix") 3160 | nmap 3161 | imap 3162 | else 3163 | imap 3164 | nmap 3165 | endif 3166 | elseif g:Vimim_map =~ 'm-space' " use Alt-Space 3167 | imap 3168 | nmap 3169 | endif 3170 | if g:Vimim_map =~ 'tab' " use Tab 3171 | xmap 3172 | if g:Vimim_map =~ 'tab_as_gi' 3173 | inoremap =g:Vimim_tab(1) 3174 | elseif g:Vimim_map =~ 'tab_as_onekey' 3175 | inoremap =g:Vimim_tab(0) 3176 | endif 3177 | endif 3178 | :com! -range=% ViMiM ,call s:vimim_chinese_rotation() 3179 | :com! -range=% VimIM ,call s:vimim_chinese_transfer() 3180 | :com! -nargs=* Debug :sil!call s:vimim_debug() 3181 | endfunction 3182 | 3183 | sil!call s:vimim_initialize_debug() 3184 | sil!call s:vimim_initialize_global() 3185 | sil!call s:vimim_initialize_backdoor() 3186 | sil!call s:vimim_dictionary_statusline() 3187 | sil!call s:vimim_dictionary_punctuations() 3188 | sil!call s:vimim_dictionary_numbers() 3189 | sil!call s:vimim_dictionary_keycodes() 3190 | sil!call s:vimim_super_reset() 3191 | sil!call s:vimim_set_backend_clouds() 3192 | sil!call s:vimim_set_backend_embedded() 3193 | sil!call s:vimim_set_backend_mycloud() 3194 | sil!call s:vimim_set_im_toggle_list() 3195 | sil!call s:vimim_plug_and_play() 3196 | :let g:Vimim_profile = reltime(g:Vimim_profile) 3197 | " ============================================= }}} 3198 | Debug s:vimim_egg_vimim() 3199 | --------------------------------------------------------------------------------