helix-editor / helix

A post-modern modal text editor.
https://helix-editor.com
Mozilla Public License 2.0
31.8k stars 2.35k forks source link

IME control #5086

Open hh9527 opened 1 year ago

hh9527 commented 1 year ago

Vim has this feature for many years.

This feature is very useful for non-western document writing.

for example, I use helix to edit a markdown file:

这是一句中文 this is a Chinese sentence.

When I enter the insert mode, I switch to use Chinese IME, input some Chinese chars, and then I switch back to normal mode, want to move cursor to next line by press j, the IME input pane will popup.

What is the behaviour I need is same as Vim, when I switch back normal mode, the IME is auto disabled, and when re-enter insert mode, IME is restored automaticaly.

I found all other editors except vim (vim-for-vscode, neovim, neovim-qt) are not smart like vim. I hope this can be done in helix.

erasin commented 1 year ago

This is a config for mac, I use macism / im-select controll ime with shell.

~/config/helix/config.toml

[keys.normal]
"esc" = [":sh macism com.apple.keylayout.ABC", "normal_mode"]

[keys.insert]
"esc" = [":sh macism com.apple.keylayout.ABC", "normal_mode"]

vscode / nvim has used im-select. im-select support macos/window/linux.

This is a tmeporary way, if you want more ,may be need wait a plugin that somebody write. 这个是临时解决用法,如果需要智能的部分,大概率要等插件系统来实现了,或者等待有人实现。

hh9527 commented 1 year ago

@erasin thank you, 谢谢

I know this work-around, and use it in vscode, but it is not a perfect solution.

This approach is about switching input method, not disabling IME. That means: if I switch from/to anothing desktop application, the input method is switched unexpected.

zhenyuanlau commented 1 year ago

@erasin It works. But there is a slight mistake here, using "keys.normal" instead of "key.normal".

@hh9527 Turn on "Automatically switch to a document’s input source" for macOS. It will keep the previous input method source when switching back to the desktop application. I think there is no need to disable IME, at least for macOS.

pickfire commented 1 year ago

Although there is something like https://github.com/vim-scripts/fcitx.vim/blob/master/plugin/fcitx.vim for only fcitx but I don't think there is a common protocol for other ime like ibus.

erasin commented 1 year ago

@hh9527

ramdomPTM commented 11 months ago

I managed to get a solution for Fcitx5 users.

我有了一个对Fcitx5用户有用的解决方案。

For some reason I found that running shell command in Helix cannot set variables so I write the fcitx5 state to /tmp/fcitx5state when entering normal mode. So here goes my clunky solution. Hope you find it useful. I use shuangpin and please replace it with your input method. You can get it by execute fcitx5-remote -n.

不知为何在Helix中执行shell命令无法设置变量,所以我只能把进入普通模式时Fcitx5的状态写入/tmp/fcitx5state。总之能用但有点蹩脚,希望对有类似需要的人有所帮助。我使用双拼,请将配置中的shuangpin替换为您使用的输入法,通过执行fcitx5-remote -n获取。

In .config/helix/config.toml:

.config/helix/config.toml中:

[keys.insert]
"esc" = [":sh echo $(fcitx5-remote -n) > /tmp/fcitx5state; fcitx5-remote -c", "normal_mode"]

[keys.normal]
"i" = [":sh if [ -e \"/tmp/fcitx5state\" ] && [ $(cat /tmp/fcitx5state) = \"shuangpin\" ]; then fcitx5-remote -o; fi", "insert_mode"]
"a" = [":sh if [ -e \"/tmp/fcitx5state\" ] && [ $(cat /tmp/fcitx5state) = \"shuangpin\" ]; then fcitx5-remote -o; fi", "append_mode"]
"c" = [":sh if [ -e \"/tmp/fcitx5state\" ] && [ $(cat /tmp/fcitx5state) = \"shuangpin\" ]; then fcitx5-remote -o; fi", "change_selection"]
ramdomPTM commented 9 months ago

I managed to get a solution for Fcitx5 users.

我有了一个对Fcitx5用户有用的解决方案。

If you happens to be a fcitx5-rime user, I managed to come up with a new solution thanks to the dbus interface fcitx5-rime provides.

如果您使用fcitx5-rime扩展,可使用如下配置,使用Fcitx5的dbus服务来切换rime自身的中英文状态。

[keys.insert]
"esc" = [":sh echo $(busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 IsAsciiMode) > /tmp/rime-state; busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b true", "normal_mode"]

[keys.normal]
"i" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "insert_mode"]
"a" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "append_mode"]
"c" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "change_selection"]
"o" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "open_below"]
"I" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "insert_at_line_start"]
"A" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "insert_at_line_end"]
"O" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "open_above"]
Lucas-Wye commented 2 months ago

I managed to get a solution for Fcitx5 users. 我有了一个对Fcitx5用户有用的解决方案。

If you happens to be a fcitx5-rime user, I managed to come up with a new solution thanks to the dbus interface fcitx5-rime provides.

如果您使用fcitx5-rime扩展,可使用如下配置,使用Fcitx5的dbus服务来切换rime自身的中英文状态。

[keys.insert]
"esc" = [":sh echo $(busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 IsAsciiMode) > /tmp/rime-state; busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b true", "normal_mode"]

[keys.normal]
"i" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "insert_mode"]
"a" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "append_mode"]
"c" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "change_selection"]
"o" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "open_below"]
"I" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "insert_at_line_start"]
"A" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "insert_at_line_end"]
"O" = [":sh if [ -e \"/tmp/rime-state\" ] && [ \"$(cat /tmp/rime-state)\" = \"b false\" ]; then busctl call --user org.fcitx.Fcitx5 /rime org.fcitx.Fcitx.Rime1 SetAsciiMode b false; fi", "open_above"]

thx, it works for me.

erasin commented 2 months ago

This is my sciprt config for ime switch in helix editor.

This script will record the input method in insert mode and automatically switch between the next insert mode. Back normal mode will switch english input (your set ime name).

Mac uses macism, and Linux uses the ibus rime.

[keys.normal]
"esc" = ["normal_mode", ":pipe-to bash ~/.config/helix/shells/ime-switch"]
i = ["insert_mode", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]
I = ["insert_at_line_start", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]
# use `li` or remap `after insert`
a = ["move_char_right", "insert_mode", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]
A = ["insert_at_line_end", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]
o = ["open_below", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]
O = ["open_above", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]

[keys.insert]
"esc" = ["normal_mode", ":pipe-to bash ~/.config/helix/shells/ime-switch"]