Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] IM could switch intelligently maybe.... #24

Open
MagicMarvel opened this issue Mar 17, 2024 · 3 comments
Open

[Feature Request] IM could switch intelligently maybe.... #24

MagicMarvel opened this issue Mar 17, 2024 · 3 comments

Comments

@MagicMarvel
Copy link

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

@keaising
Copy link
Owner

Great idea!

PR welcome.

The only thing I'd like to mention is to keep compatibility with current configurations, I'd like to see the user's current configurations remain available and unaffected when the new update is used, only users who have actively set up the use of intelligently toggles and configured the treesitter correctly will be able to use this feature.

@MagicMarvel
Copy link
Author

Thank you for sharing your thoughts. I'll ensure that the current configurations remain intact. Users who have set up intelligent toggles and treesitter correctly will benefit from this feature.

@keaising
Copy link
Owner

keaising commented May 28, 2024

Thanks for you work, it looks good.

And I have several questions:

  1. What will happen if user set smart_switch = true and do not add "nvim-treesitter/nvim-treesitter" into the dependencies?
  2. Do user need to install treesitter parsers for every language they are editting? If parsers are needed, what will happend if user don't install these parsers?
  3. Cound you please put the functions for treesitter into a single file? I want to keep the main file as small as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants