" fcitx-osx.vim - 智能记忆输入法状态 " Author: Gavin Chan " Modified by: codefalling, enhanced with smart IM state memory " Version: 2.0.0 " Description: 记住退出 Insert 模式时的输入法状态,下次进入时自动恢复 " --------------------------------------------------------------------- " Load Once: if exists('g:fcitx_remote') 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("fcitx-remote") finish endif let s:keepcpo = &cpo let g:loaded_fcitx = 1 set cpo&vim " --------------------------------------------------------------------- " 全局变量:记住上次 Insert 模式的输入法名称 let g:fcitx_last_insert_im_name = '' " 英文和中文输入法的 ID(可以通过 fcitx-remote -n 获取) if !exists('g:fcitx_english_im') let g:fcitx_english_im = 'com.apple.keylayout.ABC' endif if !exists('g:fcitx_chinese_im') let g:fcitx_chinese_im = 'auto-detect' " 将自动检测 endif " --------------------------------------------------------------------- " Functions: " 离开 Insert 模式:保存当前输入法名称,然后切换到英文 function! Fcitx2en() " 保存当前输入法名称 let current_im = substitute(system("fcitx-remote -n 2>/dev/null"), '\n', '', 'g') let g:fcitx_last_insert_im_name = current_im " 切换到英文输入法(使用后台任务并重定向所有输出) if has('job') " Use nohup in a shell backgrounded process. Some Vim builds don't accept " the 'detach' option; calling via sh -lc with nohup/& keeps process " disassociated while avoiding unsupported job_start options. call job_start(['sh', '-lc', 'nohup fcitx-remote -s ' . shellescape(g:fcitx_english_im) . ' >/dev/null 2>&1 &']) else " Fallback: nohup in background call system('nohup fcitx-remote -s ' . shellescape(g:fcitx_english_im) . ' >/dev/null 2>&1 &') endif endfunction " 进入 Insert 模式:根据保存的输入法名称恢复 function! Fcitx2zh() " 如果上次保存的输入法名称为空,说明是第一次进入,保持英文 if g:fcitx_last_insert_im_name == '' return endif " 如果上次是英文输入法,保持英文(不需要做任何事) if g:fcitx_last_insert_im_name == g:fcitx_english_im return endif " 上次是中文输入法,恢复到那个输入法(使用后台任务并重定向所有输出) if has('job') call job_start(['sh', '-lc', 'nohup fcitx-remote -s ' . shellescape(g:fcitx_last_insert_im_name) . ' >/dev/null 2>&1 &']) else call system('nohup fcitx-remote -s ' . shellescape(g:fcitx_last_insert_im_name) . ' >/dev/null 2>&1 &') endif endfunction " --------------------------------------------------------------------- " Autocmds: " 进入 Insert 模式一次后的处理 function! Fcitx2zhOnce() call Fcitx2zh() call UnBindAu() endfunction function! BindAu2zhOnce() augroup Fcitx au InsertEnter * call Fcitx2zhOnce() augroup END endfunction " 绑定自动命令 function! BindAu() augroup Fcitx " 离开 Insert 模式:保存输入法状态并切换到英文 au InsertLeave * call Fcitx2en() " 进入 Insert 模式:恢复上次的输入法状态 au InsertEnter * call Fcitx2zh() " Vim 启动时:切换到英文 au VimEnter * call Fcitx2en() augroup END endfunction function! UnBindAu() au! Fcitx InsertLeave * au! Fcitx InsertEnter * endfunction " 延迟初始化:首次进入 Insert 模式时才绑定自动命令 let g:called_bind = 0 function! EchoBind() if (g:called_bind==0) call BindAu() endif let g:called_bind = 1 endfunction autocmd InsertEnter * call EchoBind() " 多光标支持:在选择多个光标前后的处理 function! Multiple_cursors_before() call UnBindAu() call BindAu2zhOnce() endfunction function! Multiple_cursors_after() call Fcitx2en() call BindAu() endfunction " --------------------------------------------------------------------- " Restoration And Modelines: let &cpo=s:keepcpo unlet s:keepcpo let g:fcitx_remote = 1 " vim:fdm=expr:fde=getline(v\:lnum-1)=~'\\v"\\s*-{20,}'?'>1'\:1