" ================================================= " "VimIM —— Vim 中文输入法" " ------------------------------------------------- " VimIM -- Input Method by Vim, of Vim, for Vimmers " ================================================= " == "The VimIM Introduction" == {{{ " ================================== " File: vimim.vim " Author: vimim@googlegroups.com " Latest: 20090320T223858 " URL: http://vim.sourceforge.net/scripts/script.php?script_id=2506 " ----------------------------------------------------------- " Readme: The VimIM is a Vim plugin designed as an independent " IM (Input Method) to support the input of any language. " It can be used as yet another way to input non-ascii " using CTRL-^ in addition to builtin CTRL-V and CTRL-K. " The VimIM aims to complete the Vim as an editor. " ----------------------------------------------------------- " Features: # "Plug & Play" " # CJK can be input as long as it can be read using Vim. " # It is independent of the Operating System. " # It is independent of Vim mbyte-XIM/mbyte-IME API. " # The Input Methods can be freely defined without limit. " # The "VimIM One Key" speeds up ad hoc Chinese input. " # The "VimIM Chinese Input Mode" makes CJK input pleasure. " # "Dynamically adjust menu order" on past usage frequency. " # Support "all input methods": PinYin, Wubi, Cangjie, etc " # Support all-power "fuzzy search" and "wildcards search" " # Support "Direct Unicode Input" using number or hex " # Support "pinyin fuzzy phonetic" " # Support "Quick English Input" " # Support input of traditional Chinese (Big5 or GBK set) " # Intelligent error correction for commonly misspelled words " # The format of datafile is open, simple and flexible. " ----------------------------------------------------------- " EasterEgg: (1) (Neither data file nor configuration needed) " (2) (in Vim Command-line Mode, type:) :source % " (3) (in Vim Insert Mode, type 4 char) vim " ----------------------------------------------------------- " Install: (1) download any data file you like from the link below " (2) drop this file and the datafile to the plugin directory " ----------------------------------------------------------- " Data File: http://maxiangjiang.googlepages.com/vimim.pinyin.txt " http://maxiangjiang.googlepages.com/vimim.english.txt " ----------------------------------------------------------- " Data File: http://maxiangjiang.googlepages.com/vimim.4corner.txt " http://maxiangjiang.googlepages.com/vimim.wubi.txt " http://maxiangjiang.googlepages.com/vimim.quick.txt " http://maxiangjiang.googlepages.com/vimim.cangjie.txt " http://maxiangjiang.googlepages.com/vimim.array30.txt " http://maxiangjiang.googlepages.com/vimim.phonetic.txt " ----------------------------------------------------------- " Usage [A] in Insert Mode, "to insert Chinese ad hoc": " # type key code and hit CTRL-^ to insert Chinese " ----------------------------------------------------------- " Usage [B] in Insert Mode, "to input Chinese continously": " # hit CTRL-\ to toggle to VimIM Chinese Input Mode " # type any key code defined in input method, and hit Space " ----------------------------- }}} " == "The VimIM Instruction" == {{{ " ================================= " ----------------------- " "The VimIM Design Goal" " ----------------------- " # Chinese can be input using Vim regardless of encoding " # Without negative impact to Vim if VimIM is not used " # No comprise for high speed and low memory usage " # Most VimIM options are activated by default " # All VimIM options can be explicitly disabled at will " --------------------------------- " "Sample vimrc to display Chinese" " --------------------------------- " set gfn=Courier_New:h12:w7,Arial_Unicode_MS " set gfw=NSimSun-18030,NSimSun ambiwidth=double " set enc=utf8 fencs=ucs-bom,utf8,chinese,taiwan,ansi " ------------------- " "The VimIM Options" " ------------------- " Detailed usages of all options can be found from references " "The VimIM OneKey Input" " - use OneKey to insert the default candidate " - use OneKey again to perform cycle navigation " - use OneKey to directly insert unicode " - use OneKey in Visual to do English to Chinese Translation " The default key is CTRL-^ (Vim Insert Mode & Visual Mode) " # To disable :let g:vimim_disable_one_key=1 " "The VimIM Smart Chinese Input Mode" " - show dynamic menu as you type " - trigger the popup menu using Smart " - toggle VimIM Insert Mode automatically " - toggle English and Chinese punctuation " The default key is CTRL-\ (Vim Insert Mode) " # To disable :let g:vimim_disable_smart_space=1 " The VimIM Quick English Input " - Quick English input within VimIM Chinese Input Mode " (1) *alphabet ==> alphabet (starting with star) " (2) ENGLISH ==> ENGLISH " # To disable :let g:vimim_disable_quick_english_input=1 " The VimIM default settings for XingMa user " - No fuzzy search (:let g:vimim_disable_fuzzy_search=1) " - No quick key mode (:let g:vimim_disable_quick_key=1) " - No menu order update on past usage " - It is automatically enabled for WuBi, CangJie, Quick and Array " # To enable :let g:vimim_enable_xingma_preference=1 " # To enable VimIM "Default Off" Options " ----------------------------------- " let g:vimim_enable_label_navigation=1 " let g:vimim_enable_... " # To disable VimIM "Default On" Options " ----------------------------------- " let g:vimim_menu_order_update_frequency=999 " let g:vimim_disable_fuzzy_search=1 " let g:vimim_disable_... " --------------------- " "The VimIM Data File" " --------------------- " Non UTF-8 datafile is also supported: when the data filename " includes 'chinese', it is assumed to be encoded in 'chinese'. " The datafile is assumed in order, otherwise, it is sorted automatically. " The basic format of the data file is simple and flexible: " +------+--+-------+ " | | || " |======|==|=======| " | mali | | 馬力 | " +------+--+-------+ " The is what is typed in alphabet, ready to be replaced. " The , separated by spaces, is what will be input. " The 2nd and the 3rd column can be repeated without restriction. " Following sample data files are provided: " -------------------------------------------------- " vimim.pinyin.txt => input method for PinYin " vimim.phonetic.txt => input method for Phonetic " vimim.english.txt => input method for English " vimim.4corner.txt => input method for 4Corner " vimim.wubi.txt => input method for WuBi " vimim.cangjie.txt => input method for CangJie " vimim.quick.txt => input method for Quick " vimim.array30.txt => input method for Array 30 " -------------------------------------------------- " ============================= }}} " == "The VimIM Core Engine" == {{{ " ================================= if exists("b:loaded_vimim") || &cp || v:version < 700 finish endif let b:loaded_vimim = 1 set completefunc=b:VimIM " -------------------------------- function! b:VimIM(start, keyboard) " -------------------------------- if a:start let start_row = line('.') let start_column = col('.')-1 let current_line = getline(start_row) let char_before = current_line[start_column-1] " avoid hanging on triggering nothing " ----------------------------------- if start_column < 1 return endif " avoid hanging on triggering non-word char " ----------------------------------------- if char_before !~ s:char_valid return endif " note: use =~# for case sensitive match " -------------------------------------- while start_column > 0 && current_line[start_column-1] =~ s:char_valid let start_column -= 1 endwhile " get user's previous selection " ----------------------------- if s:vimim_menu_order_update_frequency < 999 if start_row >= s:start_row_before && s:usage_update > 0 let row = start_row let col = start_column let row2 = s:start_row_before let col2 = s:start_column_before let chinese = s:VimIM_usage(row,col,row2,col2,s:keyboard_key) if len(chinese)>0 && chinese !~ '\w' let s:keyboard_chinese = chinese let s:keyboard_counts += 1 endif endif let s:start_row_before = start_row let s:start_column_before = start_column endif return start_column else let keyboard = a:keyboard " support direct Unicode input: " (1) 5 whole digits: eg 39340 as 馬 in HTML " (2) 4 hex digits: eg 99ac as 馬 in HTML " ----------------------------------------------------------------- if s:vimim_disable_direct_unicode_input < 1 && &encoding == "utf-8" let unicode = [] if keyboard =~ '\d\{5}' let unicode = s:VimIM_unicode(keyboard, 10) elseif keyboard =~ '\x\{4}' let unicode = s:VimIM_unicode(keyboard, 16) endif if len(unicode) > 0 return unicode endif endif " do quick english input and hunt for easter eggs " ----------------------------------------------- if s:vimim_disable_quick_english_input < 1 sil!let english = s:VimIM_quick_English_input(keyboard) if len(english) > 0 return english endif endif " Now, build again valid keyboard characters " ------------------------------------------ if strlen(keyboard) < 1 \|| keyboard !~ s:char_valid \|| keyboard =~ '\' \|| (keyboard =~ '[' && keyboard =~ ']') \|| keyboard =~ '^[*?]\+' \|| (keyboard !~# "vim" && s:vimim_easter_eggs>0) return endif " hunt real VimIM easter eggs ... vim " ---------------------------------------- if keyboard =~# "vim" return VimIM_popupmenu_list(s:easter_eggs, 3) endif " The data file is loaded once and only once " ------------------------------------------ if s:vimim_datafile_loaded < 1 let s:vimim_datafile_loaded = 1 if len(s:current_datafile)>0 && filereadable(s:current_datafile) let s:datafile_lines = readfile(s:current_datafile) endif endif let localization = s:VimIM_localization() let lines = s:datafile_lines " initialize and re-order the data file " ------------------------------------- " modify the datafile in memory based on past usage if s:vimim_menu_order_update_frequency < 999 let chinese = s:keyboard_chinese let lines_new = s:VimIM_order_new(s:keyboard_key, chinese, lines) if len(lines_new) > 0 let lines = lines_new let frequency = s:vimim_menu_order_update_frequency let frequency = (frequency < 1) ? 24 : frequency if s:keyboard_counts%frequency==0 sil!call s:VimIM_save_datafile(lines) endif endif endif " add boundary to datafile search by one letter only " -------------------------------------------------- let ranges = s:VimIM_search_boundary(keyboard, lines) if len(ranges) < 1 return elseif ranges[0] > ranges[1] let lines = sort(lines) sil!call s:VimIM_save_datafile(lines) let ranges = s:VimIM_search_boundary(keyboard, lines) endif " now only play with portion of datafile of interest " -------------------------------------------------- let lines = lines[ranges[0] : ranges[1]] " ------------------------------------------- " do wildcard search: explicitly fuzzy search " ------------------------------------------- if s:vimim_disable_wildcard_search < 1 let wildcard_pattern = '[.*]' if s:current_datafile=~'array' || s:current_datafile=~'phonetic' let wildcard_pattern = '[?*]' endif let wildcard = match(keyboard, wildcard_pattern) if wildcard > 0 let s:usage_update = -1 let fuzzies = substitute(keyboard,'[*]','.*','g') if s:current_datafile=~'array'||s:current_datafile=~'phonetic' let fuzzies = substitute(keyboard,'?','.','g') endif let fuzzy = '^' . fuzzies . '\>' call filter(lines, 'v:val =~ fuzzy') return VimIM_popupmenu_list(lines, localization) endif endif " For '4corner', replace the first 0 with o for simplicity " For 'Array/Phonetic Input Method', escape literal dot " ------------------------------------------------------ if s:current_datafile =~ 'array' || s:current_datafile =~ 'phonetic' let keyboard = substitute(keyboard,'\.','\\.','g') endif let match_start = -1 let match_start = match(lines, '^'.keyboard) " ------------------------------------------ " to guess user's intention using auto_spell " ------------------------------------------ if s:vimim_enable_auto_spell > 0 \ && match_start < 0 let key = s:VimIM_auto_spell(keyboard) let match_start = match(lines, '^'.key) endif " -------------------------------------------- " to guess user's intention using fuzzy_pinyin " -------------------------------------------- if s:vimim_enable_fuzzy_pinyin > 0 \ && match_start < 0 let key = s:VimIM_fuzzy_pinyin(keyboard) let match_start = match(lines, '^'.key) endif " ---------------------------------------- " do exact match search on sorted datafile " ---------------------------------------- if match_start > -1 let s:usage_update = 0 let s:keyboard_key = keyboard let match_end = VimIM_exact_match(match_start, keyboard, lines) let matched_list = lines[match_start : match_end] return VimIM_popupmenu_list(matched_list, localization) endif " ---------------------------------------- " do fuzzy search, implicitly fuzzy search " ---------------------------------------- if s:vimim_disable_fuzzy_search < 1 \ && match_start < 0 \ && strlen(keyboard) > 2 let s:usage_update = -1 let fuzzies = join(split(keyboard,'\ze'),'.*') let fuzzy = '^' . fuzzies . '.*' let lines = filter(lines, 'v:val =~ fuzzy') return VimIM_popupmenu_list(lines, localization) endif endif endfunction " -------------------------------------------------------- function! VimIM_popupmenu_list(matched_list, localization) " -------------------------------------------------------- let matched_list = a:matched_list if len(matched_list) < 1 return [] endif let pair_matched_list = [] " ---------------------- for line in matched_list " ---------------------- if len(line) < 1 continue endif if a:localization == 1 let line = iconv(line, "chinese", "utf-8") elseif a:localization == 2 let line = iconv(line, "utf-8", &enc) endif let oneline_list = split(line, '\s\+') let menu = remove(oneline_list, 0) for word in oneline_list call add(pair_matched_list, menu .' '. word) endfor endfor let label = 1 - s:vimim_enable_zero_based_label let popupmenu_list = [] " ---------------------------- for words in pair_matched_list " ---------------------------- let pairs = split(words) let word = get(pairs, 1) let complete_items = {} if len(word) > 1 let complete_items["word"] = word endif if s:vimim_disable_popup_label < 1 let abbr = printf('%2s',label) . "\t" . word let complete_items["abbr"] = abbr endif if s:vimim_disable_popup_extra_text < 1 let menu = get(pairs, 0) let complete_items["menu"] = menu endif let complete_items["dup"] = 1 let label = label + 1 call add(popupmenu_list, complete_items) endfor if len(popupmenu_list) < 2 let s:usage_update = -1 let s:keyboard_key = '' elseif popupmenu_list[0].menu == menu let s:usage_update = 1 let s:keyboard_key = menu endif return popupmenu_list endfunction " -------------------------------------------- function! VimIM_exact_match(start, key, lines) " -------------------------------------------- let match_start = a:start let keyboard = a:key let lines = a:lines let patterns = '^\(' . keyboard . '\)\@!' let result = match(lines, patterns, match_start)-1 if result - match_start < 1 return match_start endif if s:vimim_disable_quick_key < 1 if result > match_start let results = [] for line in lines[match_start : result] call extend(results, split(line)) endfor let total_chinese = len(results)-(result-match_start)-1 if total_chinese > 88 || strlen(keyboard) < 2 let patterns = '^\(' . keyboard . '\>\)\@!' let result = match(lines, patterns, match_start)-1 endif endif endif let match_end = match_start if result > 0 && result > match_start let match_end = result endif return match_end endfunction " ------------------------------------------------ function! s:VimIM_search_boundary(keyboard, lines) " ------------------------------------------------ let lines = a:lines let keyboard = a:keyboard let first_char_typed = strpart(keyboard,0,1) if (s:current_datafile =~ 'array'||s:current_datafile =~ 'phonetic') \&& first_char_typed == "." let first_char_typed = '\.' endif let patterns = '^' . first_char_typed let match_start = match(lines, patterns) let ranges = [] if match_start < 0 || len(lines) < 1 return [] endif call add(ranges, match_start) let match_next = match_start let last_line_in_datafile = lines[-1] let first_char_last_line = strpart(last_line_in_datafile,0,1) if first_char_typed == first_char_last_line let match_next = len(lines)-1 else let pattern_next = '^[^' . first_char_typed . ']' let result = match(lines, pattern_next, match_start) if result > 0 let match_next = result endif endif call add(ranges, match_next) return ranges endfunction " --------------------------------------------------- function! s:VimIM_order_new(keyboard, chinese, lines) " --------------------------------------------------- let keyboard = a:keyboard if len(keyboard) < 1 || keyboard !~ '\a' return [] endif let chinese = a:chinese if len(chinese) < 1 || chinese =~ '\w' return [] endif let lines = a:lines """ step 1/4: modify datafile in memory based on usage let one_line_chinese_list = [] let patterns = '^' . keyboard . '\s\+' let matched = match(lines, patterns) if matched < 0 return [] endif let insert_index = matched """ step 2/4: remove all entries matching key from datafile while matched > 0 let old_item = remove(lines, matched) let values = split(old_item) call extend(one_line_chinese_list, values[1:]) let matched = match(lines, patterns, insert_index) endwhile """ step 3/4: make a new order list let used = match(one_line_chinese_list, chinese) if used > 0 let head = remove(one_line_chinese_list, used) call insert(one_line_chinese_list, head) endif """ step 4/4: insert the new order list into the datafile if len(one_line_chinese_list) > 0 let new_item = keyboard .' '. join(one_line_chinese_list) call insert(lines, new_item, insert_index) endif return lines endfunction " ------------------------------------------------------ function! s:VimIM_usage(row, column, row2, column2, key) " ------------------------------------------------------ let start_row = a:row let start_column = a:column let start_row_before = a:row2 let char_start = a:column2 let char_end = start_column-1 let chinese = '' " update dynamic menu order based on past usage frequency if start_row_before == start_row && char_end > char_start let current_line = getline(start_row) let chinese = current_line[char_start : char_end] elseif start_row - start_row_before == 1 let previous_line = getline(start_row_before) let char_end = len(previous_line) let chinese = previous_line[char_start : char_end] endif if chinese =~ '\A' && len(a:key)>0 && a:key =~ '\a' let chinese = substitute(chinese,'\p\+','','g') endif return chinese endfunction " ------------------------------------ function! s:VimIM_auto_spell(keyboard) " ------------------------------------ " A sample rule for auto spelling: " tign => tign " yve => yue " -------------------------------- let rules = {} let rules['ign'] = 'ing' let rules['iou'] = 'iu' let rules['uei'] = 'ui' let rules['uen'] = 'un' let rules['mg'] = 'ng' let rules['ve'] = 'ue' " -------------------------------- let pattern = a:keyboard for key in keys(rules) let new_key = rules[key] if pattern =~ key let pattern = substitute(pattern, key, new_key, '') break endif endfor return pattern endfunction " -------------------------------------- function! s:VimIM_fuzzy_pinyin(keyboard) " -------------------------------------- " A sample rule for fuzzy pinyin: " zhengguoren => zhongguoren " chengfengqia => chongfengqia " ---------------------------------- let rules = {} let rules['eng'] = 'ong' let rules['ian'] = 'iang' let rules['uan'] = 'uang' let rules['an'] = 'ang' let rules['in'] = 'ing' " ---------------------------------- let pattern = a:keyboard for key in keys(rules) let new_key = rules[key] if pattern =~ key let pattern = substitute(pattern, key, new_key, '') break endif endfor return pattern endfunction " --------------------------------------------- function! s:VimIM_quick_English_input(keyboard) " --------------------------------------------- let keyboard = a:keyboard let results = [] let result = '' """ all capitals remain the same if keyboard !~ '\A' && keyboard ==# toupper(keyboard) let result = keyboard endif """ intial single star or double star if keyboard =~ '^*' && keyboard !~ '^\d\+\s\+' if keyboard =~ '^*\{1}\w' if s:vimim_disable_quick_english_input < 1 let result = strpart(keyboard,1) endif elseif keyboard =~ '^*\{2}\w' let chinese=copy(s:translators) let chinese.dict=s:ecdict if keyboard =~ '*\{2}casino' " **casino -> congratulations! US$88000 let casino = matchstr(localtime(),'..$')*1000 let casino = 'casino US$'.casino let casino = chinese.translate(casino) let result = casino elseif keyboard =~ '*\{2}girls' let result = chinese.translate('grass') elseif keyboard =~ '*\{2}today' || keyboard =~ '*\{2}now' " **today -> 2009 year February 22 day Wednesday if keyboard =~ '*\{2}today' let today = strftime("%Y year %B %d day %A") let today = chinese.translate(today) let result = today " **now -> Sunday AM 8 hour 8 minute 8 second elseif keyboard =~ '*\{2}now' let now = strftime("%A %p %I hour %M minute %S second") let now = chinese.translate(now) let result = now endif elseif keyboard =~ '*\{2}sign' && len(s:vimim_signature) > 1 let sign = s:vimim_signature let result = sign elseif keyboard =~ '*\{2}\d\+' let number = join(split(strpart(keyboard,2),'\ze'),' ') let number = chinese.translate(number) let number = join(split(number),'') let result = number endif endif endif " -------------------------------------------- if len(result)>0 let result .= ' ' let results = [result] endif return results endfunction " ----------------------------------- function! s:VimIM_unicode(keyboard,n) " ----------------------------------- let digit = str2nr(a:keyboard,a:n) let results = [] if digit > 19968 && digit < 40870 let unicode = nr2char(digit) let results = [unicode] endif return results endfunction " ------------------------------ function! s:VimIM_localization() " ------------------------------ let localization = 0 let datafile_fenc_chinese = 0 if s:current_datafile =~? "chinese" let datafile_fenc_chinese = 1 endif " ------------ ----------------- ---- " vim encoding datafile encoding code " ------------ ----------------- ---- " utf-8 utf-8 0 " utf-8 chinese 1 " chinese utf-8 2 " chinese chinese 3 " ------------ ----------------- ---- if &encoding == "utf-8" if datafile_fenc_chinese let localization = 1 endif elseif &enc == "chinese" \|| &enc == "gb2312" \|| &enc == "gbk" \|| &enc == "cp936" \|| &enc == "euc-cn" if datafile_fenc_chinese < 1 let localization = 2 endif endif return localization endfunction " ------------------------------------ function! s:VimIM_save_datafile(lines) " ------------------------------------ let datafile = s:current_datafile let lines = a:lines if len(datafile) < 1 || len(lines) < 1 return endif if filewritable(datafile) sil!let s:datafile_lines = lines sil!call writefile(lines, datafile) endif endfunction " ----------------------------------- function! s:VimIM_get_datafile_name() " ----------------------------------- let datafile = s:vimim_datafile if !filereadable(datafile) let files = ["vimim.pinyin"] call add(files, "vimim.wubi") call add(files, "vimim.cangjie") call add(files, "vimim.quick") call add(files, "vimim.4corner") call add(files, "vimim.array30") call add(files, "vimim.phonetic") for file in files call insert(files, file.".txt") endfor call insert(files, "vimim.txt") for file in files let datafile = s:path . file if filereadable(datafile) break else continue endif endfor endif if !filereadable(datafile) let s:vimim_easter_eggs = 1 let datafile = '' endif return datafile endfunction " =============================== }}} " == "The VimIM Core FrontEnd" == {{{ " =================================== " -------------------------------- function! s:VimIM_labels_on(label) " -------------------------------- for n in range(a:label,9) sil!exe 'inoremap '.n.' VimIM_label('.n.')' endfor " ---------------------- function! VimIM_label(n) " ---------------------- if pumvisible() let label = 1 - s:vimim_enable_zero_based_label let counts = repeat("\",a:n-label) let end = '' if s:vimim_enable_label_navigation<1 || &l:iminsert==1 let end = '\' if s:usage_update == 0 let s:usage_update = 1 endif endif sil!exe 'return "' . counts . end . '"' else return a:n endif endfunction endfunction " ---------------------------- function! s:VimIM_labels_off() " ---------------------------- let s:vimim_labels_on_loaded = 0 for n in range(1,9) exe 'sil! iunmap '.n endfor endfunction " ---------------------------- function! s:VimIM_setting_on() " ---------------------------- let s:saved_completeopt=&completeopt let s:saved_lazyredraw=&lazyredraw let s:saved_iminsert=&l:iminsert let s:saved_cpo=&cpo set cpo&vim set completeopt=menuone set nolazyredraw let &l:iminsert = 1 highlight lCursor guifg=bg guibg=green endfunction " ----------------------------- function! s:VimIM_setting_off() " ----------------------------- let &cpo=s:saved_cpo let &completeopt=s:saved_completeopt let &lazyredraw=s:saved_lazyredraw let &l:iminsert=s:saved_iminsert highlight ICursor guifg=bg guibg=fg endfunction " --------------------------- function! s:VimIM_insert_on() " --------------------------- let s:vimim_insert = 1 sil!call s:VimIM_setting_on() if s:vimim_disable_chinese_punctuation < 1 for key in keys(s:punctuations) let value = s:punctuations[key] sil!exe 'inoremap '. key .' '. value endfor endif if s:vimim_disable_dynamic_menu < 1 for char in s:vimim_keys sil!exe 'inoremap ' . char . ' \ =pumvisible()?"\C-E>":""'. char . \ '=VimIM_check("\C-X>\C-U>")' endfor " ----------------------------- function! VimIM_check(map) " ----------------------------- if getline(".")[col(".")-2] !~# s:char_valid sil! return "" else sil! return a:map endif endfunction " ------------------------- function! VimIMSpace() " ------------------------- if pumvisible() if s:usage_update == 0 let s:usage_update = 1 endif sil! return "\" else sil! return " " endif endfunction inoremap =VimIM_check \("\C-X>\C-U>")=VimIMSpace() else inoremap =VimIM_SpaceKey() " ------------------------ function! VimIM_SpaceKey() " ------------------------ if pumvisible() if s:usage_update == 0 let s:usage_update = 1 endif return "\\" else return " " endif endfunction endif if s:vimim_disable_popup_label < 1 sil!call s:VimIM_labels_on(1) endif endfunction " --------------------------- function! VimIM_OneKey() " --------------------------- if s:vimim_labels_on_loaded < 1 sil!call s:VimIM_labels_on(1) let s:vimim_labels_on_loaded = 1 endif if pumvisible() if s:vimim_enable_label_navigation<1 || &l:iminsert==1 if s:usage_update == 0 let s:usage_update = 1 endif sil!return "\" else sil!return "\" endif else set completeopt=menu sil!return "\\\\" endif endfunction " ---------------------------- function! s:VimIM_insert_off() " ---------------------------- let s:vimim_insert = 0 sil!call s:VimIM_setting_off() if s:vimim_disable_chinese_punctuation < 1 for key in keys(s:punctuations) exe 'sil! iunmap '. key endfor endif if s:vimim_disable_dynamic_menu < 1 for char in s:vimim_keys exe 'sil!iunmap ' . char endfor endif if s:vimim_disable_popup_label < 1 sil!call s:VimIM_labels_off() endif sil!iunmap endfunction " ---------------------------------- function! VimIM_insert_toggle() " ---------------------------------- if s:vimim_disable_smart_space_autocmd < 1 && has("autocmd") " ---- courtsey of Yue Wu on newsmth.net for all smart_space sil!au InsertEnter sil!call s:vimim_insert_on() sil!au InsertLeave sil!call s:VimIM_insert_off() sil!au BufUnload autocmd! InsertEnter,InsertLeave endif if s:vimim_insert < 1 sil!call s:VimIM_insert_on() else sil!call s:VimIM_insert_off() endif return "\\:redraw\" endfunction " --------------------------- function! s:VimIM_seed_data() " --------------------------- if s:vimim_seed_data_loaded return else let s:vimim_seed_data_loaded = 1 endif " -------------------------------- let punctuations = {} let punctuations["#"]="#" let punctuations["%"]="%" let punctuations["$"]="¥" let punctuations["&"]="※" let punctuations["{"]="『" let punctuations["}"]="』" let punctuations["["]="【" let punctuations["]"]="】" let punctuations["<"]="《" let punctuations[">"]="》" let punctuations["'"]="“" let punctuations['"']="”" let punctuations["!"]="!" let punctuations["@"]="・" let punctuations["~"]="~" let punctuations["("]="(" let punctuations[")"]=")" let punctuations["\\"]="。" let punctuations["^"]="……" let punctuations["_"]="——" let punctuations["+"]="+" if (s:current_datafile!~'array' && s:current_datafile!~'phonetic') let punctuations[","]="," let punctuations[";"]=";" let punctuations["-"]="-" let punctuations["?"]="?" endif if (s:current_datafile!~'array' && s:current_datafile!~'phonetic') \&& s:vimim_disable_wildcard_search > 0 let punctuations["."]="。" endif let s:punctuations = punctuations " -------------------------------- let ecdict = {} let ecdict['casino']='中奖啦!' let ecdict['grass']='天涯何处无芳草!' let ecdict['january']='一月' let ecdict['february']='二月' let ecdict['march']='三月' let ecdict['april']='四月' let ecdict['may']='五月' let ecdict['june']='六月' let ecdict['july']='七月' let ecdict['august']='八月' let ecdict['september']='九月' let ecdict['october']='十月' let ecdict['november']='十一月' let ecdict['december']='十二月' let ecdict['am']='上午' let ecdict['pm']='下午' let ecdict['year']='年' let ecdict['day']='号' let ecdict['hour']='时' let ecdict['minute']='分' let ecdict['second']='秒' let ecdict['monday']='星期一' let ecdict['tuesday']='星期二' let ecdict['wednesday']='星期三' let ecdict['thursday']='星期四' let ecdict['friday']='星期五' let ecdict['saturday']='星期六' let ecdict['sunday']='星期日' let ecdict['0']='○' let ecdict['1']='一' let ecdict['2']='二' let ecdict['3']='三' let ecdict['4']='四' let ecdict['5']='五' let ecdict['6']='六' let ecdict['7']='七' let ecdict['8']='八' let ecdict['9']='九' let ecdict[',']=',' let ecdict['.']='。' let s:ecdict = ecdict " -------------------------------- let s:dummy=copy(s:translators) let s:dummy.dict=copy(s:ecdict) " -------------------------------- let s:easter_eggs = ["vi 文本编辑器"] call add(s:easter_eggs, "vim 最牛文本编辑器") call add(s:easter_eggs, "vim 精力 生氣") call add(s:easter_eggs, "vimim 中文输入法") " -------------------------------- endfunction " -------------------------------------------- function! VimIM_dummy_translator(english) " -------------------------------------------- if s:vimim_dummy_dictionary_loaded < 1 let s:vimim_dummy_dictionary_loaded = 1 let dictionary_lines = readfile(s:current_dictionary) if len(dictionary_lines) > 1 let localization = s:VimIM_localization() for line in dictionary_lines if len(line) < 1 continue endif if localization == 1 let line = iconv(line, "chinese", "utf-8") elseif localization == 2 let line = iconv(line, "utf-8", &enc) endif let items = split(line) let s:dummy.dict[items[0]] = items[1] endfor else return endif endif let english = substitute(a:english,'\A',' & ','g') let chinese = s:dummy.translate(english) let chinese = substitute(chinese,"[ ']",'','g') let chinese = substitute(chinese,'\a\+',' & ','g') let chinese = substitute(chinese,nr2char(12290),'&\n','g') return chinese endfunction let s:translators = {} " ------------------------------------------ function! s:translators.translate(line) dict " ------------------------------------------ return join(map(split(a:line),'get(self.dict,tolower(v:val),v:val)')) endfunction " ---------------------------- function! s:VimIM_initialize() " ---------------------------- let G = [] call add(G, "g:vimim_datafile") call add(G, "g:vimim_signature") call add(G, "g:vimim_menu_order_update_frequency") call add(G, "g:vimim_disable_quick_key") " ------------------------------------------------ call add(G, "g:vimim_disable_direct_unicode_input") call add(G, "g:vimim_disable_wildcard_search") call add(G, "g:vimim_disable_fuzzy_search") call add(G, "g:vimim_disable_one_key") call add(G, "g:vimim_disable_smart_space") call add(G, "g:vimim_disable_smart_space_autocmd") call add(G, "g:vimim_disable_chinese_punctuation") call add(G, "g:vimim_disable_popup_extra_text") call add(G, "g:vimim_disable_popup_label") call add(G, "g:vimim_disable_dynamic_menu") call add(G, "g:vimim_disable_quick_english_input") " ------------------------------------------------ call add(G, "g:vimim_enable_xingma_preference") call add(G, "g:vimim_enable_label_navigation") call add(G, "g:vimim_enable_auto_spell") call add(G, "g:vimim_enable_fuzzy_pinyin") call add(G, "g:vimim_enable_zero_based_label") " ------------------------------------------------ for variable in G let s_variable = substitute(variable,"g:","s:",'') if !exists(variable) exe 'let '. s_variable . '=0' else exe 'let '. s_variable .'='. variable exe 'unlet! ' . variable endif endfor " ------------------------------------------------ let s:vimim_easter_eggs = 0 let datafile = s:VimIM_get_datafile_name() let s:current_datafile = datafile if len(datafile) > 0 if s:vimim_enable_xingma_preference > 0 \|| datafile =~? 'wubi' \|| datafile =~? 'cangjie' \|| datafile =~? 'quick' \|| datafile =~? 'corner' \|| datafile =~? 'array' \|| datafile =~? 'phonetic' let s:vimim_disable_fuzzy_search = 1 let s:vimim_disable_quick_key = 1 let s:vimim_menu_order_update_frequency = 999 endif endif " ------------------------------------------ " define valid characters for input key code let s:char_valid = "[*.0-9A-Za-z]" " ------------------------------------------------ if s:current_datafile =~ 'array' let s:char_valid = "[*a-z.,;/?]" elseif s:current_datafile =~ 'phonetic' let s:char_valid = "[*0-9a-z.,;/?\-]" endif " --------------- courtsey of Tony Mechelynck on vim_use function! s:VimIM_expand_character_class(character_class) " ------------------------------------------------------ let character_string = "" let i = 0 while i < 256 let x = nr2char(i) if x =~# a:character_class let character_string .= x endif let i += 1 endwhile return character_string endfunction " ------------------------------------------------ let key = s:VimIM_expand_character_class(s:char_valid) let keys = split(key, '\zs') let keys_ext = ["", ""] let s:vimim_keys = extend(keys, keys_ext) " ------------------------------------------------ let s:vimim_insert = 0 let s:vimim_labels_on_loaded = 0 let s:vimim_seed_data_loaded = 0 let s:vimim_datafile_loaded = 0 let s:datafile_lines = [] let s:punctuations = {} " ------------------------------------------------ let s:start_row_before = 0 let s:start_column_before = 0 let s:keyboard_key = '' let s:keyboard_chinese = '' let s:keyboard_counts = 0 let s:usage_update = -1 " ------------------------------------------------ let s:vimim_dummy_dictionary_loaded = 0 let s:current_dictionary='' let dictionary = s:path . "vimim.english.txt" if filereadable(dictionary) let s:current_dictionary = dictionary endif endfunction " ============================== }}} " == "The VimIM Core Mapping" == {{{ " ================================== " profile start /tmp/vimim.profile scriptencoding utf-8 let s:path=expand(":p:h")."/" sil!call s:VimIM_initialize() sil!call s:VimIM_seed_data() if s:vimim_disable_one_key < 1 if len(s:current_dictionary) > 0 xnoremap y:put!=VimIM_dummy_translator(@0) endif inoremap VimIM_OneKey() map! VimIM_OneKey() endif if s:vimim_disable_smart_space < 1 inoremap VimIM_insert_toggle() endif " ========== }}} " ---------- " References " ---------- " http://groups.google.com/group/vimim " http://groups.google.com/group/vim_use/topics " http://maxiangjiang.googlepages.com/vimim.html