改善编程体验: IdeaVimExtension介绍

动机

Intellij IDEA是个非常优秀的开发环境,提供了相当好用的快捷键,让用户有机会脱离鼠标来使用IDE.

另外官方还提供了IdeaVim插件,熟悉vim的用户可以使用几乎与vim相同的方式操作IDEA的编辑器来编写代码.但是作为非英文用户,却有一个”输入法切换”的痛点.

考虑如下两种情况:

  1. 编辑器中在insert模式下,编写了一段中文注释,然后需要回到normal模式移动光标到其他位置继续编写代码.
  2. 正在编辑器normal模式下操作,此时突然有紧急邮件或者钉钉消息需要回复,输入法切换为中文回复后再回到编辑器.

类似上面两种场景,当回到normal模式编辑器时,我们都不得不人工操作一次输入法切换,即使您已经为输入法切换设置了非常好用的快捷键(按一下Shift),这个操作依然是恼人的,经常会忘记,输入几个字符后才发现,这可能带来误操作.

我们的期望只有一个:

在任何情况下,进入normal模式,输入法必是英文状态.

因此我基于IdeaVim的扩展点开发了一个帮助切换输入法的小插件IdeaVimExtension

IdeaVimExtension安装使用

  1. 如果您已经是IdeaVim的用户,那么直接在Intellj IDEA的插件中心搜索IdeaVimExtension进行安装.或者到IdeaVimExtension插件主页进行下载安装.

    IdeaVimExtension是依赖IdeaVim的,需要事先安装IdeaVim

  2. 确保你的操作系统已经开启了英文输入法

    • Windows需要开启en_USimage-20190320104934233输入法

    • macOS需要开启ABCimage-20190320104604867

      或en_USimage-20190320104634422输入法

    • Linux 需要使用小企鹅输入法(Fcitx)

  3. 安装重启IDEA后,输入法自动切换功能会默认启用

    也可以通过打开任意代码编辑器在normal模式下输入如下两个命令来激活IdeaVimExtension插件

    • :set keep-english-in-normal : 在normal模式保持英文状态(这也是默认启用的状态)
    • :set keep-english-in-normal-and-restore-in-insert : 在normal模式保持英文状态,并在回到insert时恢复输入法到原来的状态.例如,编写一段中文注释,用中文输入法写了一段文字,进入normal模式移动光标到下一行,再回到插入模式继续使用中文编辑.
  4. 上面两个命令在每次IDEA重启后都需要重新输入,也可以通过在用户目录下添加.ideavimrc文件,将命令添加到该文件中,这样在IDEA重启时可以自动执行该文件中的指令.另外,该文件中也可以添加其他受支持的vim指令.类似vim的.vimrc文件.

  5. 如果要关闭输入法切换功能直接直接输入对应的:set nokeep-english-in-normal[-and-restore-in-insert]

接下来就可以愉快的使用全键盘操作来编写代码了.

额外一点分享

相信很多同学都是使用苹果电脑的.苹果电脑的键盘设计对vim用户越来越不友好了.对vim用户来说ESC是个非常高频的按键.但是苹果键盘的ESC设计比较小,且位置偏远,有bar的新MBP的ESC是虚拟的基本没有任何按键反馈.我的处理方法是使用karabiner软件将ESC和不常用的~进行交换.

另外键盘上的方向键,新MBP的上下被缩小到一个按键的面积偏小,且需要移动右手去按,对编写代码这样的文字工作是不友好的在使用vim编辑器是可以通过hkjl来替换,但也总有非vim环境需要使用方向键,比如IDEA的Project视图等.我的处理方法是设置Ctrl+hkjl来替换方向键,为了纠正习惯将原始的方向键禁用了.

最后CapsLock键用处不大,有时会误按造成vim-normal模式下的误操作,所以我将该键跟左下角的Ctrl交换了.这样既改善了Ctrl的按键体验,也可以避免误按CapsLock

Windows用户请自行寻找键位映射工具.

在此提供我的配置文件,可以直接copy到~/.config/karabiner/karabiner.json来使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
{
"global": {
"check_for_updates_on_startup": true,
"show_in_menu_bar": false,
"show_profile_name_in_menu_bar": false
},
"profiles": [
{
"complex_modifications": {
"parameters": {
"basic.simultaneous_threshold_milliseconds": 50,
"basic.to_delayed_action_delay_milliseconds": 500,
"basic.to_if_alone_timeout_milliseconds": 1000,
"basic.to_if_held_down_threshold_milliseconds": 500
},
"rules": [
{
"description": "Vi Mode [left_control + hjkl]",
"manipulators": [
{
"from": {
"key_code": "h",
"modifiers": {
"mandatory": [
"control"
],
"optional": [
"caps_lock",
"command",
"option",
"shift",
"fn"
]
}
},
"to": [
{
"key_code": "left_arrow"
}
],
"type": "basic"
},
{
"from": {
"key_code": "j",
"modifiers": {
"mandatory": [
"control"
],
"optional": [
"caps_lock",
"command",
"option",
"shift",
"fn"
]
}
},
"to": [
{
"key_code": "down_arrow"
}
],
"type": "basic"
},
{
"from": {
"key_code": "k",
"modifiers": {
"mandatory": [
"control"
],
"optional": [
"caps_lock",
"command",
"option",
"shift",
"fn"
]
}
},
"to": [
{
"key_code": "up_arrow"
}
],
"type": "basic"
},
{
"from": {
"key_code": "l",
"modifiers": {
"mandatory": [
"control"
],
"optional": [
"caps_lock",
"command",
"option",
"shift",
"fn"
]
}
},
"to": [
{
"key_code": "right_arrow"
}
],
"type": "basic"
}
]
}
]
},
"name": "Default profile",
"selected": true,
"simple_modifications": [
{
"from": {
"key_code": "caps_lock"
},
"to": {
"key_code": "left_control"
}
},
{
"from": {
"key_code": "escape"
},
"to": {
"key_code": "grave_accent_and_tilde"
}
},
{
"from": {
"key_code": "grave_accent_and_tilde"
},
"to": {
"key_code": "escape"
}
},
{
"from": {
"key_code": "left_control"
},
"to": {
"key_code": "caps_lock"
}
},
{
"from": {
"key_code": "right_command"
},
"to": {
"key_code": "left_control"
}
}
],
"virtual_hid_keyboard": {
"country_code": 0
}
}
]
}