First of all, I wanted to express my gratitude for creating such an impressive plugin!
I have a suggestion: it would be great if it could intelligently recognize which input method (IM) is needed. As a Chinese user, I use English in normal mode and also in insert mode, except when inputting comments and strings. Therefore, by using treesitter to logically analyze the current position, it can infer which language should be used at the moment.
However, currently, this plugin seems to only support switching between the default input method (IM) and the IM used by the user last time. Adding this logic would lead to huge changes in the codebase. I am very willing to contribute code to this repository and would like to hear your thoughts.
-- get node right before user's cursor
local function get_node_before_cursor()
local cursor_pos = vim.api.nvim_win_get_cursor(0)
-- because nvim_win_get_cursor is (1, 0)-indexed
-- but vim.treesitter.get_node is (0, 0)-indexed
-- so row must decrease 1
-- and in insert mode, cursor's position is in cursor right
-- but we need detect the char just before the cursor
-- so col need decrease 1
local row, col = cursor_pos[1] - 1, cursor_pos[2] - 1
if col < 0 then
return nil
end
local node = vim.treesitter.get_node({ pos = { row, col } })
return node
end
local function would_alternative_im_better(t)
local specific_type = { "comment", "comment_content", "string_content", "string" }
for _, v in ipairs(specific_type) do
if t == v then
return true
end
end
return false
end
local function determine_which_IM_and_switch(ignore_last_node_type)
local current_node = get_node_before_cursor()
if current_node == nil then
return
end
local current_node_type = current_node:type()
-- when type comment or string, switch IM to alternative IM
if would_alternative_im_better(current_node_type) then
if ignore_last_node_type or not would_alternative_im_better(last_node_type) then
switch_to_alternative_im()
end
end
-- when type comment or string finish, switch IM to default IM
if not would_alternative_im_better(current_node_type) then
if ignore_last_node_type or would_alternative_im_better(last_node_type) then
switch_to_default_im()
end
end
last_node_type = current_node:type()
end
M.setup = function(opts)
-- some code here .......
local group_id = vim.api.nvim_create_augroup("im-select", { clear = true })
if #C.set_default_events > 0 then
vim.api.nvim_create_autocmd(C.set_default_events, {
callback = switch_to_default_im,
group = group_id,
})
end
vim.api.nvim_create_autocmd({ "InsertEnter" }, {
callback = function()
determine_which_IM_and_switch(true)
end
})
vim.api.nvim_create_autocmd({ "TextChangedI" }, {
callback = function()
determine_which_IM_and_switch(false)
end
})
-- some code here .......
end
In this code, alternative_im
means zh
, default _im
means en