A highly configurable & flexible input method(im) auto-switch plugin for neovim, inspired by VSCodeVim
- 🛺Auto switch input methods when necessary(e.g. keep im default in normal mode, restore im in other modes)
- 📚Manage input method states per buffer respectively
- ⚙️High configurability and flexibility for different input methods, im switch behaviors and OSs
- 🚀Blazingly fast because external commands are executed asynchronously
- 💻VSCode Neovim compatible
- neovim >= 0.10.0
- An im switch tool is needed. For Linux, if you use fcitx, check
fcitx-remote
orfcitx5-remote
; for Windows or MacOS, checkim-select
: im-select.
Installing this plugin is very easy!
With lazy.nvim
-- e.g. fcitx5 v5.0.14
{
"Old-Farmer/im-autoswitch.nvim",
event = "BufEnter",
opts = {
cmd = {
-- default im
default_im = "1",
-- get current im
get_im_cmd = "fcitx5-remote",
-- cmd to switch im. the plugin will put an im name in "{}"
-- or
-- cmd to switch im between active/inactive
switch_im_cmd = "fcitx5-remote -t",
},
},
}
For more Installation and Configuration examples, check here examples.
You can also take a look of im-select usage.
Default Configuration
require("imas").setup {
-- fallback cmd, check "cmd_os" bellow
cmd = {
--- these three just show the options, the plugin doesn't set them
default_im = "", -- default im
get_im_cmd = "", -- get current im, output will be trimmed by this plugin
switch_im_cmd = "", -- cmd to switch im; use {} as an im placholder
-- or just a cmd which switches im between active/inactive
},
cmd_os = {}, -- specify your per OS cmd here, the plugin will check your current environment
-- and fallback to "cmd" if necessary
-- leave it empty and only set "cmd" if you use only one OS
-- see the following example!!
-- keys in "cmd_os" can be set to different OS names:
-- for linux is "linux", for windows is "windows" and for macos is "macos"
-- for other OSs, use `vim.uv.os_uname().sysname` to get your OS name, then
-- use this name as a key in cmd_os
--[[
-- e.g. to specify your linux cmd
cmd_os = {
linux = {
default_im = "",
get_im_cmd = "",
switch_im_cmd = "",
}
}
--]]
-- im swich behaviors per mode.
-- set this table to configure im switch behavior when events are triggered
mode = {
-- mode spec:
-- "autoswitch"(string): smart im-autoswitch
-- "default"(string): always back to default im
-- "enter_default"(string): back to default im at enter
-- "leave_default"(string): back to default im at leave
-- false(boolean): do nothing
insert = "autoswitch", -- im-autoswitch trigger at InsertEnter/InsertLeave
search = "autoswitch", -- im-autoswitch trigger at CmdlineEnter/CmdlineLeave(/ or \?)
cmdline = "leave_default", -- not back to default im at CmdlineEnter(:) by default
-- because some ims can't produce ":" directly;
-- back to default im at CmdlineLeave(:)
terminal = "default", -- always back to default im at TermEnter/TermLeave
},
-- set keymaps because some special neovim commands which don't trigger events
keymap = {
-- in this table, key is the original commands in neovim,
-- and value is the keymap spec
-- keymap spec:
-- "xxx"(string): key sequence, this extension will use this sequence as {lhs} in vim.keymap.set
-- false(bolean): do nothing
r = "r", -- remap "r" to do im switch when executing original r{char} command
gr = false, -- don't remap "gr" to do im switch. This is because gr{char} command is not so
-- common in use and is usually remapped to some lsp stuff
-- all above share the same im switch behavior with mode.insert
},
async = true, -- true as switching asynchronously, false otherwise
macos_sync_enter = true, -- workaround for macos users if async switching leads to a strange behavior,
-- i.e. typing while switching im asynchronously and then the im loses effect.
-- can be disabled if you don't meet this problem
}
- No effect in ssh. This plugin will not be loaded in ssh environment. While it is technically possible to control the local input method via SSH tunneling to a remote Neovim instance, I find this solution rather inelegant. I would much prefer for Neovim to provide more robust, native support for remote development, rather than depending on such compromises to achieve essential functionality.
You can call module functions of im-autoswitch.nvim directly for more flexible use.
-- just go back to default im
-- param async is a bool, false only means possibly sync, same as following two functions
require("imas").im_default(async)
-- or
-- first name a mode(string). "insert" "search" "cmdline" "terminal" are all reserved
local mode = "xxx"
-- then use the following two functions to switch im as you need
-- the type of buf is number, and can be get from vim.api.nvim_get_current_buf()
-- or autocmd callback parameter: opts.buf
require("imas").im_enter(mode, buf, async) -- restore im if your are in default im
require("imas").im_leave(mode, buf, async) -- go back to default im, and store current im state
PRs
of any kind are welcome!