" vim-im-switch-select.vim - 智能记忆输入法状态 (使用 im-select) " Author: Gavin Chan " Modified by: codefalling, enhanced with smart IM state memory " Version: 2.0.0 " Description: 记住退出 Insert 模式时的输入法状态,下次进入时自动恢复 " 使用 im-select 而不是 fcitx-remote 切换输入法 " --------------------------------------------------------------------- " Load Once: if exists('g:imselect_loaded') finish endif if &ttimeoutlen <= 0 || &ttimeoutlen > 50 set ttimeoutlen=50 endif if (has("win32") || has("win95") || has("win64") || has("win16")) " Windows 下不要载入 finish endif if exists('$SSH_TTY') finish endif if !executable("im-select") finish endif let s:imselect_cmd = exepath('im-select') let s:keepcpo = &cpo let g:imselect_loaded = 1 set cpo&vim " --------------------------------------------------------------------- " 全局变量:记住上次 Insert 模式的输入法名称 let g:imselect_last_insert_im_name = '' " 英文和中文输入法的 ID(可以通过 im-select 获取) if !exists('g:imselect_english_im') let g:imselect_english_im = 'com.apple.keylayout.ABC' endif if !exists('g:imselect_chinese_im') let g:imselect_chinese_im = 'com.apple.inputmethod.SCIM.ITABC' endif " --------------------------------------------------------------------- " Functions: function! IMSelectCurrentIM() abort return substitute(system(shellescape(s:imselect_cmd) . ' 2>/dev/null'), '[\r\n]', '', 'g') endfunction function! IMSelectSwitch(im) abort if has('job') silent! call job_start([s:imselect_cmd, a:im], {'out_io': 'null', 'err_io': 'null'}) else silent! call system(shellescape(s:imselect_cmd) . ' ' . shellescape(a:im) . ' >/dev/null 2>&1 &') endif endfunction function! IMSelectStart() abort call IMSelectSwitch(g:imselect_english_im) endfunction function! IMSelectEnsureTarget(timer) abort if g:imselect_last_insert_im_name != '' call IMSelectSwitch(g:imselect_last_insert_im_name) endif endfunction " 离开 Insert 模式前:保存当前输入法名称 function! IMSelectRemember() abort let current_im = IMSelectCurrentIM() if current_im != '' let g:imselect_last_insert_im_name = current_im endif endfunction " 离开 Insert 模式:切换到英文 function! IMSelect2en() abort call IMSelectSwitch(g:imselect_english_im) endfunction " 恢复 Insert 模式输入法 function! IMSelectRestore(timer) abort if g:imselect_last_insert_im_name == '' let g:imselect_last_insert_im_name = g:imselect_chinese_im endif call IMSelectSwitch(g:imselect_last_insert_im_name) call timer_start(200, function('IMSelectEnsureTarget')) endfunction " 进入 Insert 模式:延迟恢复保存的输入法 function! IMSelect2zh() abort call timer_start(80, function('IMSelectRestore')) endfunction " --------------------------------------------------------------------- " Autocmds: " 绑定自动命令 function! BindIMSelectAu() augroup IMSelect autocmd! " 离开 Insert 模式前:先保存输入法状态 autocmd InsertLeavePre * call IMSelectRemember() " 离开 Insert 模式:切换到英文 autocmd InsertLeave * call IMSelect2en() " 进入 Insert 模式:恢复上次的输入法状态 autocmd InsertEnter * call IMSelect2zh() " Vim 启动后:切换到英文 autocmd VimEnter * call timer_start(100, {-> IMSelectStart()}) augroup END endfunction function! UnBindIMSelectAu() augroup IMSelect autocmd! augroup END endfunction call BindIMSelectAu() " 多光标支持:在选择多个光标前后的处理 function! IMSelect_multiple_cursors_before() call UnBindIMSelectAu() endfunction function! IMSelect_multiple_cursors_after() call IMSelect2en() call BindIMSelectAu() endfunction " --------------------------------------------------------------------- " Restoration And Modelines: let &cpo=s:keepcpo unlet s:keepcpo let g:imselect_loaded = 1 " vim:fdm=expr:fde=getline(v\:lnum-1)=~'\\v"\\s*-{20,}'?'>1'\:1