├── AIMSwitcher
├── AIMSwitcher.vcxproj.user
├── AIMSwitcher.vcxproj.filters
├── main.cpp
└── AIMSwitcher.vcxproj
├── LICENSE
├── AIMSwitcher.sln
└── README.md
/AIMSwitcher/AIMSwitcher.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/AIMSwitcher/AIMSwitcher.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | 源文件
20 |
21 |
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 A23187
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/AIMSwitcher.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.3.32929.385
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AIMSwitcher", "AIMSwitcher\AIMSwitcher.vcxproj", "{A452978C-668D-488B-9DAE-6FCD3B175859}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {A452978C-668D-488B-9DAE-6FCD3B175859}.Debug|x64.ActiveCfg = Debug|x64
17 | {A452978C-668D-488B-9DAE-6FCD3B175859}.Debug|x64.Build.0 = Debug|x64
18 | {A452978C-668D-488B-9DAE-6FCD3B175859}.Debug|x86.ActiveCfg = Debug|Win32
19 | {A452978C-668D-488B-9DAE-6FCD3B175859}.Debug|x86.Build.0 = Debug|Win32
20 | {A452978C-668D-488B-9DAE-6FCD3B175859}.Release|x64.ActiveCfg = Release|x64
21 | {A452978C-668D-488B-9DAE-6FCD3B175859}.Release|x64.Build.0 = Release|x64
22 | {A452978C-668D-488B-9DAE-6FCD3B175859}.Release|x86.ActiveCfg = Release|Win32
23 | {A452978C-668D-488B-9DAE-6FCD3B175859}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {2456C611-4886-40EF-A6BA-98508EDF117B}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/AIMSwitcher/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | #pragma comment(lib, "imm32.lib")
7 |
8 | #define IMC_GETCONVERSIONMODE 0x01
9 | #define IMC_SETCONVERSIONMODE 0x02
10 |
11 | int GetCurrentInputMethod() {
12 | HWND hWnd = GetForegroundWindow();
13 | DWORD threadId = GetWindowThreadProcessId(hWnd, nullptr);
14 | HKL hKL = GetKeyboardLayout(threadId);
15 | uintptr_t langId = reinterpret_cast(hKL) & 0xFFFF;
16 | return static_cast(langId);
17 | }
18 |
19 | void SwitchInputMethod(int langId) {
20 | HWND hWnd = GetForegroundWindow();
21 | PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 0, static_cast(langId));
22 | }
23 |
24 | int GetCurrentInputMethodMode() {
25 | HWND hWnd = GetForegroundWindow();
26 | HWND hIMEWnd = ImmGetDefaultIMEWnd(hWnd);
27 | LRESULT mode = SendMessage(hIMEWnd, WM_IME_CONTROL, IMC_GETCONVERSIONMODE, 0);
28 | return static_cast(mode);
29 | }
30 |
31 | void SwitchInputMethodMode(int mode) {
32 | HWND hWnd = GetForegroundWindow();
33 | HWND hIMEWnd = ImmGetDefaultIMEWnd(hWnd);
34 | SendMessage(hIMEWnd, WM_IME_CONTROL, IMC_SETCONVERSIONMODE, static_cast(mode));
35 | }
36 |
37 | void ShowUsage() {
38 | std::cout
39 | << "AIMSwitcher, An Input Method Switcher\n"
40 | << "Usage: AIMSwitcher [OPTION]... [ARG]...\n"
41 | << "\n"
42 | << " --im [INPUTMETHOD] show the current input method if INPUTMETHOD is omitted,\n"
43 | << " otherwise switch to the specified input method\n"
44 | << " --imm [INPUTMETHODMODE] show the current input method mode if INPUTMETHODMODE is omitted,\n"
45 | << " otherwise switch to the specified input method mode\n"
46 | << std::endl;
47 | }
48 |
49 | int main(int argc, char** argv) {
50 | if (argc == 1) {
51 | ShowUsage();
52 | }
53 | else if (strcmp(argv[1], "--im") == 0) {
54 | if (argc == 2)
55 | std::cout << GetCurrentInputMethod() << std::endl;
56 | else
57 | SwitchInputMethod(atoi(argv[2]));
58 | }
59 | else if (strcmp(argv[1], "--imm") == 0) {
60 | if (argc == 2)
61 | std::cout << GetCurrentInputMethodMode() << std::endl;
62 | else
63 | SwitchInputMethodMode(atoi(argv[2]));
64 | }
65 | else {
66 | ShowUsage();
67 | }
68 | return 0;
69 | }
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # **AIMS**witcher
2 | **AIMS**witcher, **A**n **I**nput **M**ethod **S**witcher that **AIMS** to support switching between Chinese and English input methods or between Chinese and English modes in one input method when switching between Vim's insert and normal modes
3 |
4 | > Note: This tool is only available for Windows
5 |
6 | ## Installation
7 | Just download the executable file from the [releases page](https://github.com/A-23187/AIMSwitcher/releases/latest)
8 |
9 | ## Usage
10 | ```
11 | AIMSwitcher, An Input Method Switcher
12 | Usage: AIMSwitcher [OPTION]... [ARG]...
13 |
14 | --im [INPUTMETHOD] show the current input method if INPUTMETHOD is omitted,
15 | otherwise switch to the specified input method
16 | --imm [INPUTMETHODMODE] show the current input method mode if INPUTMETHODMODE is omitted,
17 | otherwise switch to the specified input method mode
18 | ```
19 |
20 | ### Examples
21 | AIMSwitcher uses the language identifier (i.e., the locale ID) to switch to the corresponding input method. And the locale ID of Simplified Chinese (zh_CN) is 2052, the locale ID of American English (en_US) is 1033. You can use the option `--im` without argument to discover the locale ID of your current input method
22 | ```sh
23 | # show the locale ID of the current input method
24 | AIMSwitcher.exe --im
25 | ```
26 |
27 | For me, I installed Microsoft Pinyin input method for Simplified Chinese (2052), and US Keyboard input method for American English (1033). So for switching between these two input methods:
28 | ```sh
29 | # switch to Microsoft Pinyin IM
30 | AIMSwitcher.exe --im 2052
31 | # switch to US Keyboard IM
32 | AIMSwitcher.exe --im 1033
33 | ```
34 |
35 | Microsoft Pinyin IM supports two language modes: Chinese and English. AIMSwitcher can switch between these two modes like below:
36 | ```sh
37 | # switch to Chinese mode
38 | AIMSwitcher.exe --imm 1025
39 | # switch to English mode
40 | AIMSwitcher.exe --imm 0
41 |
42 | # you can use this option without argument to find the key of your current mode
43 | AIMSwitcher.exe --imm
44 | ```
45 | > Note: The functionality of switching input method mode has only been tested with Microsoft Pinyin IM, and contributions for testing with other input methods are welcome.
46 |
47 | ### AIMSwitcher + Vim
48 | - Switch to English input method when leaving insert mode to normal mode
49 | ```vim
50 | autocmd InsertLeave * silent !AIMSwitcher.exe --im 1033
51 | ```
52 | - Switch to English mode of Chinese input method instead of switching input method when leaving insert mode to normal mode
53 | ```vim
54 | autocmd InsertLeave * silent !AIMSwitcher.exe --imm 0
55 | ```
56 |
57 | ### AIMSwitcher + [VSCodeVim](https://github.com/VSCodeVim/Vim)
58 | - Switch input method
59 | ```json
60 | "vim.autoSwitchInputMethod.enable": true,
61 | // Use English input method by default
62 | "vim.autoSwitchInputMethod.defaultIM": "1033",
63 | "vim.autoSwitchInputMethod.obtainIMCmd": "AIMSwitcher.exe --im",
64 | // Switch to English input method when leaving insert mode to normal mode,
65 | // And the additional argument {im} is just a placeholder, as required by VSCodeVim
66 | "vim.autoSwitchInputMethod.switchIMCmd": "AIMSwitcher.exe --im 1033 {im}"
67 | ```
68 | - Switch input method mode
69 | ```json
70 | "vim.autoSwitchInputMethod.enable": true,
71 | // Use Chinese input method by default (for me, I use Microsoft Pinyin IM)
72 | "vim.autoSwitchInputMethod.defaultIM": "2052",
73 | "vim.autoSwitchInputMethod.obtainIMCmd": "AIMSwitcher.exe --imm",
74 | // Switch to English mode of the Chinese input method when leaving insert mode to normal mode,
75 | // And the additional argument {im} is just a placeholder, as required by VSCodeVim
76 | "vim.autoSwitchInputMethod.switchIMCmd": "AIMSwitcher.exe --imm 0 {im}"
77 | ```
78 | About VSCodeVim's `autoSwitchInputMethod` feature, find more information [here](https://github.com/VSCodeVim/Vim#input-method)
79 |
80 | ## Credits
81 | - [daipeihust/im-select](https://github.com/daipeihust/im-select)
82 | - [yfzhao20/Shift-IM-for-VSCode](https://github.com/yfzhao20/Shift-IM-for-VSCode)
83 | - [how to change input method when press in vim? - Stack Overflow](https://stackoverflow.com/a/71523260)
84 |
85 | ## License
86 | [MIT License](https://github.com/A-23187/AIMSwitcher/blob/master/LICENSE)
--------------------------------------------------------------------------------
/AIMSwitcher/AIMSwitcher.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 16.0
23 | Win32Proj
24 | {a452978c-668d-488b-9dae-6fcd3b175859}
25 | AIMSwitcher
26 | 10.0
27 |
28 |
29 |
30 | Application
31 | true
32 | v143
33 | Unicode
34 |
35 |
36 | Application
37 | false
38 | v143
39 | true
40 | Unicode
41 |
42 |
43 | Application
44 | true
45 | v143
46 | Unicode
47 |
48 |
49 | Application
50 | false
51 | v143
52 | true
53 | Unicode
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | Level3
76 | true
77 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
78 | true
79 |
80 |
81 | Console
82 | true
83 |
84 |
85 |
86 |
87 | Level3
88 | true
89 | true
90 | true
91 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
92 | true
93 |
94 |
95 | Console
96 | true
97 | true
98 | true
99 |
100 |
101 |
102 |
103 | Level3
104 | true
105 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
106 | true
107 |
108 |
109 | Console
110 | true
111 |
112 |
113 |
114 |
115 | Level3
116 | true
117 | true
118 | true
119 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
120 | true
121 |
122 |
123 | Console
124 | true
125 | true
126 | true
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------