140 lines
3.9 KiB
VimL
140 lines
3.9 KiB
VimL
" 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
|