巧用 capslang 工具实现evil模式下的中英文输入法自动切换

以下在Windows8.1环境测试通过

思路来自 fcitx vim for osx ,调用一条命令行就可以依据当前模式切换输入法, 苦于一直没找到合适的软件,直到搜到 caps min alt shift noexit 这个小工具「a simple console program. Enables you to switch the layout using Caps Lock」,后台静默运行无配置就实现CAPS切换输入语言,试用后感觉不错,想着 @xcodebuild 的方法,在evil exit&entry-hook 时执行一次模拟CAPS按键,所以autohotkey派上用场,最终成功实现需求,可以凑合着用。

先编译smartSwitchIMEcn.ahk得到exe文件放到环境变量路径处

#SingleInstance
Send, {CapsLock}
Sleep, 200

emacs 中的配置

(defun evil-mode-smart-switch-ime ()
  "between evil insert and normal state auto switch input method"
  ;; (interactive)
  (shell-command "smartSwitchIMEcn"))

(add-hook 'evil-insert-state-exit-hook 'evil-mode-smart-switch-ime)
(add-hook 'evil-insert-state-entry-hook 'evil-mode-smart-switch-ime)

PS:

  • 务必先添加新的美式键盘布局的语言输入源,默认Alt+Shift切换
  • 中英状态反过来了,可以直接按CAPS恢复
  • capslang有几个版本,caps min alt shift noexit虽没退出的快捷键,但使用体验最好

最后对以上用到的工具的作者表示感谢,现在很好地解决了Windows上使用Emacs和Vim编辑器的痛点,想着又能愉快的码字了就会高兴

参考

Vim也是OK

" from fcitx.vim bundle
if exists("g:loaded_fcitx")
  finish
endif
let g:loaded_fcitx = 1
function FcitxToggle()
  silent call system("smartSwitchIMEcn") "有弹出窗口的问题 
endfunction

function BindAu()
  augroup Fcitx
  au InsertLeave * call FcitxToggle()
  au InsertEnter * call FcitxToggle()
  augroup END
endfunction

function UnBindAu()
  au! Fcitx InsertLeave *
  au! Fcitx InsertEnter *
endfunction

if (has("win32") || has("win95") || has("win64") || has("win16"))
  call BindAu()
endif
6 个赞

思路很好呀,就是实现的太绕弯。。。。。

确实,但全局的快捷键切换倒是方便,统一了各处的按键,只是Emacs中调用有点频繁,会不会对打字快的人来说有稍许延迟。capslang的主页有说计划支持remote desktop protocol,还蛮期待的

也许这个对你有帮助

额。。。好巧。。其实我前段时间已经初步写好了 fcitx-remote-for-windows,实现是通过 SendInput 模拟按键来的,已经能正常工作。但在 Windows 下 SendInput 函数有时候会有延时,所以在一些情况下会有一些小问题,比如 fcitx.el 中通过 prefix-keys 来激活/关闭输入法的时候,如果你按键速度非常快,就不能及时关闭输入法,我当时没想到好的其他想法,所以拖了一段时间没去动代码了。

代码本身很简单,c++ 六七十行的样子,编译成 fcitx-remote 以后直接就能被 fcitx.el 使用了。我今天找个时间把代码文档整理一下放到 GitHub 上,如果有兴趣可以帮忙提交 PR。

PS: 对于你这个办法,如果用了 ahk 的话应该可以用 ahk 直接发送输入法切换的按键,是不是并不一定需要 capslang?

EDIT: 见我发的这个新的主题

1 个赞

已经转到用你写的工具,比这个好用多了,延时问题我能接受,还解决了扰人的任务栏弹出后台窗口的问题,太妙了。 纯ahk模拟按键试了一下,依然没有效果,只会用Send命令搞不定。 capslang我还继续用着,因为是全局有效,处处方便。

请问eLisp有什么办法Send按键吗?(在代码中执行组合按键动作) 比如使用EVIL时,我想在退出NORMAL状态下触发C-SPC组合键操作,以切换输入法。

(add-hook 'evil-normal-state-entry-hook XXX)

XXX 的地方需要一个函数以触发组合键C-SPC

好像AHK CapsLock::Escape 这样就行了啊!

Mac下有什么实现方法吗?