update at 2026-07-06 14:20:29
This commit is contained in:
@@ -24,6 +24,7 @@ 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
|
||||
@@ -38,96 +39,89 @@ if !exists('g:imselect_english_im')
|
||||
endif
|
||||
|
||||
if !exists('g:imselect_chinese_im')
|
||||
let g:imselect_chinese_im = 'auto-detect' " 将自动检测
|
||||
let g:imselect_chinese_im = 'com.apple.inputmethod.SCIM.ITABC'
|
||||
endif
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" Functions:
|
||||
|
||||
" 离开 Insert 模式:保存当前输入法名称,然后切换到英文
|
||||
function! IMSelect2en()
|
||||
" 保存当前输入法名称
|
||||
let current_im = substitute(system("im-select 2>/dev/null"), '\n', '', 'g')
|
||||
let g:imselect_last_insert_im_name = current_im
|
||||
|
||||
" 切换到英文输入法(使用后台任务并重定向所有输出)
|
||||
function! IMSelectCurrentIM() abort
|
||||
return substitute(system(shellescape(s:imselect_cmd) . ' 2>/dev/null'), '[\r\n]', '', 'g')
|
||||
endfunction
|
||||
|
||||
function! IMSelectSwitch(im) abort
|
||||
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 im-select ' . shellescape(g:imselect_english_im) . ' >/dev/null 2>&1 &'])
|
||||
silent! call job_start([s:imselect_cmd, a:im], {'out_io': 'null', 'err_io': 'null'})
|
||||
else
|
||||
" Fallback: nohup in background
|
||||
call system('nohup im-select ' . shellescape(g:imselect_english_im) . ' >/dev/null 2>&1 &')
|
||||
silent! call system(shellescape(s:imselect_cmd) . ' ' . shellescape(a:im) . ' >/dev/null 2>&1 &')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" 进入 Insert 模式:根据保存的输入法名称恢复
|
||||
function! IMSelect2zh()
|
||||
" 如果上次保存的输入法名称为空,说明是第一次进入,保持英文
|
||||
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 == ''
|
||||
return
|
||||
endif
|
||||
|
||||
" 如果上次是英文输入法,保持英文(不需要做任何事)
|
||||
if g:imselect_last_insert_im_name == g:imselect_english_im
|
||||
return
|
||||
endif
|
||||
|
||||
" 上次是中文输入法,恢复到那个输入法(使用后台任务并重定向所有输出)
|
||||
if has('job')
|
||||
call job_start(['sh', '-lc', 'nohup im-select ' . shellescape(g:imselect_last_insert_im_name) . ' >/dev/null 2>&1 &'])
|
||||
else
|
||||
call system('nohup im-select ' . shellescape(g:imselect_last_insert_im_name) . ' >/dev/null 2>&1 &')
|
||||
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:
|
||||
|
||||
" 进入 Insert 模式一次后的处理
|
||||
function! IMSelect2zhOnce()
|
||||
call IMSelect2zh()
|
||||
call UnBindIMSelectAu()
|
||||
endfunction
|
||||
|
||||
function! BindIMSelectAu2zhOnce()
|
||||
augroup IMSelect
|
||||
au InsertEnter * call IMSelect2zhOnce()
|
||||
augroup END
|
||||
endfunction
|
||||
|
||||
" 绑定自动命令
|
||||
function! BindIMSelectAu()
|
||||
augroup IMSelect
|
||||
" 离开 Insert 模式:保存输入法状态并切换到英文
|
||||
au InsertLeave * call IMSelect2en()
|
||||
autocmd!
|
||||
" 离开 Insert 模式前:先保存输入法状态
|
||||
autocmd InsertLeavePre * call IMSelectRemember()
|
||||
" 离开 Insert 模式:切换到英文
|
||||
autocmd InsertLeave * call IMSelect2en()
|
||||
" 进入 Insert 模式:恢复上次的输入法状态
|
||||
au InsertEnter * call IMSelect2zh()
|
||||
" Vim 启动时:切换到英文
|
||||
au VimEnter * call IMSelect2en()
|
||||
autocmd InsertEnter * call IMSelect2zh()
|
||||
" Vim 启动后:切换到英文
|
||||
autocmd VimEnter * call timer_start(100, {-> IMSelectStart()})
|
||||
augroup END
|
||||
endfunction
|
||||
|
||||
function! UnBindIMSelectAu()
|
||||
au! IMSelect InsertLeave *
|
||||
au! IMSelect InsertEnter *
|
||||
augroup IMSelect
|
||||
autocmd!
|
||||
augroup END
|
||||
endfunction
|
||||
|
||||
" 延迟初始化:首次进入 Insert 模式时才绑定自动命令
|
||||
let g:imselect_called_bind = 0
|
||||
function! IMSelectEchoBind()
|
||||
if (g:imselect_called_bind==0)
|
||||
call BindIMSelectAu()
|
||||
endif
|
||||
let g:imselect_called_bind = 1
|
||||
endfunction
|
||||
|
||||
autocmd InsertEnter * call IMSelectEchoBind()
|
||||
call BindIMSelectAu()
|
||||
|
||||
" 多光标支持:在选择多个光标前后的处理
|
||||
function! IMSelect_multiple_cursors_before()
|
||||
call UnBindIMSelectAu()
|
||||
call BindIMSelectAu2zhOnce()
|
||||
endfunction
|
||||
|
||||
function! IMSelect_multiple_cursors_after()
|
||||
|
||||
Reference in New Issue
Block a user