Files
vim-im-switch/vim-im-switch.vim
2025-11-04 20:25:12 +08:00

145 lines
4.2 KiB
VimL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

" 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